[负数在内存中的存储] 0x80000000 = -2147483648

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$ 

以上验证了十进制补码和十六进制原码表示的数值均符合 符号位 + 序号位 的原则。

原文地址:https://www.cnblogs.com/shiyublog/p/10910370.html