微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 计算机中信息的表示与处理

计算机中信息的表示与处理

时间:12-01 来源:互联网 点击:

  1. int x1 = 0x60000000;
    printf("%d,%d,%d",x1,x1<1,x1*2);

    这段代码就说明了两个正数相乘是可以产生一个负数的,但是如果我们采用无符号数据类型进行左移操作就不会产生两个正数相乘产生负数的情况,这样能够避免很多不可思议的结果。
    右移操作中的逻辑右移主要是针对无符号数据类型,对有符号的数据类型是无效的,对于有符号的数据类型,右移操作对于大多数的编译器都认为是算术右移,算术右移能够保证数据的正负特性,不会发生左移中两个正数相乘得到负值的情况。算术右移的实质是在移位操作以后,数据的左边采用符号位填充。通常在C语言中右移实现除法操作,比如8>>1,即实现了除以2的操作,对于无符号型数据可以采用右移操作实现除法操作,但是对于有符号数据类型可能出现错误。下面说一个典型的例子:

    int x1 = -1;
    printf("%d,%d,%d",x1,x1>>1,x1/2);

    这个例子说明了有符号数据类型通过算术右移并不能完成除法操作,但是无符号的数据类型基本上可以完成除法操作。搞清楚何时是算术右移何时是逻辑右移是非常有必要的。
    对于无符号数据类型,采用左移右移的方式提高乘除法的速度是可行的,但是对有符号的数据类型最好不要采用这种实现方式,因为可能会出现意想不到的结果。虽然很多的程序书中建议少用unsigned的类型,但是在移位操作这方面最好还是处理无符号型对象比较有保证。

    强制类型转换处理
    强制类型转换是C语言中比较重要的一个主题,其中程序员老手也会忽略这种问题的发生,基本的实现方式是有符号向无符号转变,小字节数据朝大字节数据转换,当然也有高字节数据类型往低字节数据转变的问题。
    基本的转换存在两种:零扩展和符号扩展。
    零扩展是针对无符号数据类型,将一个小字节数据转换为大字节数据时,在高字节中填充零,实现数据的一致型。
    符号扩展则针对有符号数据类型,将一个小字节数据转换为大字节数据时,在高字节中填充小字节数据的符号位,填充符号位主要是为了实现补码一致原则。零扩展实际上是符号扩展的子类。
    大字节数据向小字节数据转换的过程是一个截取过程,这样可能会导致数据正负的变化,也就是说大到小的过程可能发现比较大的变化,截取数据的一部分作为小字节数据的bit向量。
    强制类型转换实质上包含了符号扩展,和零扩展,符号扩展保证了补码的一致型,零扩展则保证了数值大小的一致性,符号扩展针对有符号数据类型,而零扩展主要针对无符号数据类型。
    很多时候的强制类型转换是隐含进行的,这是就需要我们准确的把握,有符号类型到无符号类型的转变会导致很大的差别,因为无符号类型数加上有符号类型数将进行有符号到无符号数据类型的转换,这时候就会产生一个无符号的数据,不会产生有符号类型的数。
    同时还有一个技巧,在C语言中如何判断两个数的和是否越界的问题,由于很多编译器对越界并不报错,这时候可以通过判断两个数的和是否小于任何一个数即可,如果小于任何一个,则说明这个数就是越界,否则没有发生越界问题。
    具体的实现可以采用下面的代码测试:

    int test()
    {
    char x2 = -20;
    int x1 = x2;
    printf("x2 = %d, x1 = %u",x2,x1);
    x2 = 20;
    x1 = x2;
    printf("x2 = %d, x1 = %u",x2,x1);
    }

    浮点型数据类型
    浮点型数据类型在前一章中已经说明了,浮点型数据类型没有无符号和有符号之说。浮点型具有固定的编码方式,本来就是存在正负之分,即没有unsigned float之说。需要注意的是浮点型是一个近似的值不能用来比较。还有对float类型数据不能进行移位操作,因为float是有固定的编码方式的不像整形数据。

    总结
    了解计算机中的有符号整型数据一般按照补码的方式存在,有符号数据类型的扩展是按照符号扩展,而不是简单的零扩展,符号扩展是零扩展的延伸,主要是保证在延伸的过程中符号、数值保持不变。
    在移位操作过程中,有符号、无符号数据类型的左移都没有问题,但是可能会导致数据类型的改变,特别是有符号数据类型。对于对于右移操作需要注意,有符号数据类型是算术右移,而无符号数据类型是逻辑右移,右移的差别是在左端补齐的值的差别。
    在用移位来模拟数据的乘除法时特别要注意,对无符号数据类型是最有效的,左移右移的值也是我们认为正确的值,但是如果是对有符号数据类型进行右移模拟除法过程,左移模拟乘法过程时可能导致结果不是所想。因此建议只对无符号数据类型采用移位来简化乘除操作。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top