計算機補碼儲存

MadAdam發表於2024-08-10

以下過程用8位的有符號char表示資料。

1. 計算機為什麼用補碼儲存整數

  • 加法執行

計算機是按照二進位制儲存的,並且計算機只會做加法,不會減法。

 首先看下加法,例如1+1=2
     0000 0001
     0000 0001 
    ——————————
     0000 0010
 如果是1-1呢,因為計算機不會減法,會轉換為1+(-1)。這就涉及到-1怎麼表示了?如果用1000 0001表示-1進行如下計算
     0000 0001
     1000 0001
     —————————
     1000 0010    這個結果就表示-2,正確結果應該是0,說明這種表示方式不行。
  • 引入補碼

針對該問題,計算機的前輩們想到用補碼的形式表示整數(記憶體中儲存也是存的補碼),正數的補碼和原碼一樣,負數的補碼的非符號位取反後加1。

 按照這個規則,-1用補碼錶示為1000 0001(原碼)——非符號為取反——>1111 1110——加1——>1111 1111.所以1+(-1)的計算過程如下:
      0000 0001
      1111 1111
      ——————————
      10000 0000     這個結果表示0,正確。

2.-128怎麼表示

大家都知道char的取值範圍是-128~127,但是-128怎麼表示呢?我們按照上面的補碼規則推算一下:

 1 1000 0000(用9位表示的原碼)——非符號位取反——>1 0111 1111——加1——>1 1000 0000(補碼)
 由上可知,原碼 1 1000 0000對應的補碼還是自身。截斷溢位的最高位後是1000 0000。
如果只8位的1000 0000,有人可能會認為是表示-0,實際是已經用0000 0000表示0了,1000 0000再表示0就重複了,那就約定表示-128,而且這樣表示不會引入錯誤(至於之前的大佬怎麼想出來的,我暫時還不清楚),例如-128+64,計算過程如下:
 1000 0000
 0100 0000
 —————————
 1100 0000 (補碼形式)——減1——>1011 1111——非符號位取反——>1100 0000(原碼形式,表示-64)

3.在Linux環境下,如何用gdb檢視某個變數在記憶體中是按照補碼形式儲存的呢

Image Name

如上圖所示:
先用命令 p 檢視變數val的記憶體地址,為0xffff1423.
再用命令 x 檢視記憶體儲存情況
x /4xb 0xffff1423
4:表示檢視4個位元組的記憶體.
x:表示記憶體資料顯示的格式,和C語言中的printf保持一致.
b:表示記憶體單位大小 ,b:1個位元組,h:Halfwords(2個位元組),w:Words(4個位元組).
如上圖,變數val在記憶體中儲存為"ff ff ff f6" 確實是-10的補碼形式.

相關文章