1. 程式人生 > >關於0x80000000為什麽等於-2147483648和負數在內存上儲存的問題

關於0x80000000為什麽等於-2147483648和負數在內存上儲存的問題

表示 bsp font 同時 十六進制 知識 str 32位系統 思路

轉載自大佬的博客https://blog.csdn.net/youyou362/article/details/72667951/

1·先說明負數怎麽儲存

(1)十進制負數是以其補碼儲存在內存上。

驗證:求-8在內存上以二進制形式1的個數

思路是:拿變量,令值為1,與-8的二進制碼的每一位做與運算,若與運算結果為1,則該位為1。

代碼:

int NumberOf1(int n)
{
    int count = 0;
    unsigned int  value = 1;
    while (value != 0)
    {
        
if (value&n) { count++; } value = value << 1; //左移右邊補0,當移完32為value為0. } return count; }

結論:

輸入-8,結果為29。

在32位系統上,-8的儲存

-8的儲存是以-8的補碼,儲存在內存上。

-8的原碼 1000 0000 0000 0000 0000 0000 0000 1000

取反 由於第一位是符號位 不用改變 得:1111 1111 1111 1111 1111 1111 1111 0111

補碼=反碼+1 得::1111 1111 1111 1111 1111 1111 1111 1000

得到1的數量正好為29,所以-8的補碼就是-8儲存在內存上的二進制碼

(2)但是在十六進制,負數在內存中儲存的是原碼

驗證:

對int test = 0x80000001 (對應十進制為-1) 檢查其內存上的1的個數,發現只有2個1

故內存上原碼為 1000 0000 0000 0000 0000 0000 0000 0001.

對十六進制的-8也是2個1

(3)我們來看看0x80000000的輸出

0x80000000 的二進制位

原碼 1000 0000 0000 0000 0000 0000 0000 0000

若最高位為符號位,則為-0,可是輸出int i = 0x80000000 發現i= -(2^31)

原因是在十六進制中負數的二進制原碼的最高位是符號位,後面的31位為序號位,不是值位。1後面的000 0000 0000 0000 0000 0000 0000 0000,表示序號1,表示負數中,從小到大的第一位。

由於int的最小值為-2^31,排在負數從小到大的序號1,所以int i = 0x80000000 輸出為 -(2^31)

我們來看看0xFFFFFFFF

原碼 1111 1111 1111 1111 1111 1111 1111 1111

最高位為1 ,為負數,序號位為第(2^31)-1位 (111 1111 1111 1111 1111 1111 1111 1111=(2^31-1) 所以0xFFFFFFFF為負數從小到大 第2^31-1位 ,即

-2^31+2^31-1= -1

輸出int i = 0xFFFFFFFF 為 -1 符合

(4)十進制的補碼也符合 符號位+序號位的原則

就拿-8來做例子:

-8的補碼:1111 1111 1111 1111 1111 1111 1111 1000 可以看出最高位為1 序號位為第2^(31)-8位,(111 1111 1111 1111 1111 1111 1111 1000 = 2^(31)-8 )

則該補碼表示的值為2^31- 2^(31)-8 = -8 符合

------------------------------------------------------------------------

相關知識點補充:

十六進制用最高位作為符號位,1位負數,0為正數。

負數的位右移運算:

原則:若右移的數字為負值,則向右移動N位同時N個1補充在左邊

若為正值,則以N個0補充在左邊
---------------------

關於0x80000000為什麽等於-2147483648和負數在內存上儲存的問題