原码:计算机对数值的二进制定点表示法,其最高位为0表示正数,为1表示负数,原码可以直观的表示数值,但不能参与运算。
反码:正数的反码是其本身;负数的反码是其原码的符号位不变,其余各位取反。
补码:正数的补码是其本身;负数的补码是其反码+1;数值以补码的形式存储在内存中,直接用来参与运算。
例如:short s1 = 1; //[+1] = [00000000 00000001]原 = [00000000 00000001]反 = [00000000 00000001]补
short s2 = -1; //[-1] = [10000000 00000001]原 = [11111111 11111110]反 = [11111111 11111111]补
All of 6.3.1.3 Signed and unsigned integers:
1 When a value with integer type is converted to another integer type other than _Bool,if the value can be represented by the new type, it is unchanged.
2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.
3 Otherwise, the new type is signed and the value cannot be represented in it; the result is implementation-defined.
无精度损失:
unsigned short us1 = 0x0fff;
short s1 = us1; //us1没超过s1的取值范围,s的值为495
unsigned short us2 = s1; //s1没超过us2的取值范围,us2的值为495
unsigned short us3 = 0xfff0; //us3的补码为11111111 11110000
short s2 = us3; //us3超过s2的取值范围, s2的补码为11111111 11110000,
//符号位为负,补码-1,符号位不变其余各位取反,得原码为10000000 00010000,s2的值为-16
unsigned short us4 = s2; //s2超过us4的取值范围,-16%(65535+1)得us4的值为65520
有精度损失:
unsigned short us1 = 0x0fff;
unsigned char uc = us1; //us1超过uc的取值范围,us1%(255+1)得uc的值为255
char c = us1; //us1超过c的取值范围,c的补码取us1补码的低八位,即11111111,原码为10000001,值为-1
unsigned short us2 = c; //c超过us2的取值范围,c的符号位为1,提升为unsigned short时扩展的高八位都补充为1,
//所以us2的补码为11111111 11111111