signed unsigned 的数值概念

来源:互联网 发布:linux 网卡驱动位置 编辑:程序博客网 时间:2024/05/16 12:43

1. signed 和 unsigned 是两种类型,对存储器中的内容作不同的数值上的解释,可以理解为一个解码过程

(signed, unsigned 控制存储空间中最高位的使用,char, int等控制访问的字节数):

如:

(signed char)0x81的数学上的值是-127

(或者十六进制表示为-7F,符号和进制无关,所以存储的内容到数学上的值,需要一个理解上的转化过程)

(用printf("%d", char(0x81)打印)

       :

0x81是有符号数值的补码表示,转化到数学上的数值的方法是,符号位为1为负"-",绝对值是剩下的7位的反码+1;数学上的操作都是以-127来运算的,运算得到的结果又要保存到存储空间中,这是一个编码的过程,和上面的过程相反。涉及到机器指令的话,数学上的加减操作,一步就位了,涉及到程序语言的话,分抽象化的数学运算和对存储的编解码,更容易理解一点。

 

(unsigned char)0x81数学上的值为+129(或者十六进制表示为+81):没有符号位,8位全部表示值。

 

所以同样的存储内容,unsigned 和 signed 对其内容的数值上的理解是不一样的。

 

注意:对于同样的编码的字符串,保存在存储器上的内容是一样的,这里并不涉及到数值的概念。

 

 

2. char 有可能是signed char 也有可能是unsigned char,编译器可以设置,具体情况待研究?。

 

3. 位操作

signed char ch = 0x81;

printf("%d", (int)(ch >> 1));

printf("%X", (int)(ch >> 1));

打印结果是-64和FFFFFFC0,有符号高位需要符号位的扩展。(高位指高出char的三个字节中的bits)

这里的移位过程是这样的:

  1. 从sign char 到 signed int先符号扩展成0xFFFFFF81

  2. 0xFFFFFF81向右移动一位0x7FFFFFC0

  3. 左侧空出的一位用符号位填充0xFFFFFFC0

步骤2和3可以合成一个操作。

 

以上过程可以体现出用补码表示数据的好处。如果不用补码回事怎么样呢?

 

4. 上面涉及到类型转化时的高位扩展,这里可以有很多情况。

a) 字节少的到字节多的转化

signed char --> signed int : 都是补码表示,符号位扩展即可,如0x81-->0xFFFFFF81;

unsigned char --> signed int : 高位用0填充,0x81-->0x00000081;

 

signed char --> unsigned int : 高位符号扩展,如:0x81-->0xFFFFFF81;

unsigned char --> unsigned int : 高位用0填充,0x81-->0x00000081;

 

所以,符号位的扩展与否,取决于被扩展的类型。

 

b) 同样字节数类型转化

unsigned char --> signed char : 字节拷贝,不做任何其他操作,0x81 --> 0x81;

signed char --> unsigned char : 字节拷贝,不做任何其他操作,0x81 --> 0x81;

 

a) 字节多的到字节少的转化:

unsiened int --> signed char : 低位字节拷贝,不考率符号,0x80000001-->0x01;

signed int --> signed char : 低位字节拷贝,不考虑符号,0x80000001-->0x01,这已经能保证signed char 能表示的数的正确转化了;

 

signed int --> unsigned char : 同上,0x80000001-->0x01

unsigned int --> unsigned char : 同上,ox8000001-->0x01

 

 

 

原创粉丝点击