https://blog.csdn.net/youyou362/article/details/72667951/
1. 十进制负数以其补码存储在内存上
例子:-8 在内存中表示为:1111 1111 1111 1111 1111 1111 1111 1000
验证:求-8在内存上以二进制形式1的个数
1 int NumberOf1(int n) 2 { 3 int count = 0; 4 unsigned int value = 1; 5 while(value != 0) 6 { 7 if(value & n) 8 { 9 count++; 10 } 11 value = value << 1; 12 } 13 return count; 14 } 15 16 cout << NumberOf1(-8) << endl; //29
-8在内存上以二进制形式1的个数 = 29
解析:
-8 的原码: 1000 0000 0000 0000 0000 0000 0000 1000
-8 的反码: 1111 1111 1111 1111 1111 1111 1111 0111 (符号位不变,其余各位取反)
-8 的补码: 1111 1111 1111 1111 1111 1111 1111 1000 (补码 = 反码 + 1)
其中1的数量正好为29。
2. 十六进制负数以其原码存储在内存上
以上例:-8 的十六进制,在内存中表示 只有2 个1.
3. 二者都符合 符号位 + 序号位(不是值位!)的原则
1)对于16进制的 0x80000000:
原码:1000 0000 0000 0000 0000 0000 0000 0000
最高位:符号位 (-)
后31位:序号位,不是值位。000 0000 0000 0000 0000 0000 0000 0000, 表示序号0, 表示所有31位可表示的数中,从小到大的第0位。
int的最小值 $-2^{31}$, 0x80000000为这些数从小到大的第0位,所以
1 int test_0x80000000 = 0x80000000; 2 cout << test_0x80000000 << endl; // -2147483648 3 cout << INT_MIN << endl; // -2147483648
2) 对于16进制的 0xFFFFFFFF:
原码:1111 1111 1111 1111 1111 1111 1111 1111
最高位:符号位 (-)
后31位:序号位。111 1111 1111 1111 1111 1111 1111 1111 = $2^{31} - 1$
所以 0xFFFFFFFF为负数从小到达的第2^31 - 1位,即 $-2^{31} + (2^{31} - 1) = -1$
1 int test_0xFFFFFFFF = 0xFFFFFFFF; 2 cout << test_0xFFFFFFFF << endl; // -1
3) 对于10进制的 -8:
-8 的补码:1111 1111 1111 1111 1111 1111 1111 1000
最高位:符号位 (-)
后31位:111 1111 1111 1111 1111 1111 1111 1000 = $2^{31} - 8$
所以补码表示的值为:$-2^{31} + (2^{31} - 8) = -8$
以上验证了十进制补码和十六进制原码表示的数值均符合 符号位 + 序号位 的原则。