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


轉載自大佬的博客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補充在左邊
---------------------

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM