原则:当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。
实例:
........
signed char a=0xe0; //127~~-128 1110 0000b=-32
unsigned int b=a;//
unsigned char c=a;//
.................
测试环境:32位arm
结果:
十进制表示
二进制表示
补码概念整理:
计算机中的符号数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同。
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
- 正整数的补码是其二进制表示,与原码相同;
- 负整数的补码,将其对应正数二进制表示所有位取反(包括符号位,0变1,1变0)后加1;
分析:
ANSI C 提供了3种字符类型,分别是char、signed char、unsigned char。char相当于signed char或者unsigned char,但是这取决于编译器!
signed char a=0xe0 --在计算机系统中,使用的是补码表示、存储,格式:1110 0000b
unsigned int b=a; --将signed char类型的数据给unsigned int 类型,先按照a的类型扩展宽度(signed char ->signed int) ,后确定符号类型(signed int-->unsigned int)。导致上边的结果;如果a为unsigned char -->b为signed int,结果:b=00000000000000000000000011100000b,先按照a的类型宽展,后再确定符号。
unsigned char c=a;
二进制的数据a=1110 0000b就在那里,按照不同的规则(signed /unsigned )读取,得到结果不同。
总结:
在计算机中整形是以补码表示的!正数的补码就是二进制形式,不用改变;对于负数的补码,是负数绝对值取反加一得到。
a=-32 //负数,
这里,赋值表达式执行时,a作为操作数,会自动转换为无符号类型
赋值u32的b,实质是先a绝对值 取反 加一
即 b=(~(u32)abs(a))+1;
同理c=(~(u8)abs(a))+1;