1. 程式人生 > >計算機使用補碼儲存二進位制數的原因

計算機使用補碼儲存二進位制數的原因

今天看了java中的二進位制操作,突然發現本科上電路課程的時候就沒有理解計算機採用補碼儲存二進位制數的原因,以及補碼的推導。這次算是補課了。


1 補碼的概念

  • 正數的補碼是其本身
  • 負數的補碼:原碼->反碼->補碼(符號為變為1,除符號位取反,加1)

補碼本身就是分段函式,相當於專為負數設計。

2 使用補碼的原因

  1. 減法可以變成負數的加法,因此加法和減法可以統一處理。
  2. 使用補碼,可以將符號位和數值域統一處理,不需要單獨計算符號位(原因看後面補碼的推導過程)。
  3. 補碼與原碼相互轉換,其運算過程是相同的,不需要額外的硬體電路。

3 補碼的推導

3.1 模

模是指一個計量系統的計數範圍。如時鐘等。計算機也是一個計算器,它也是有一個計量範圍,即都存在一個“模”。如時鐘的計量範圍是0~11,模=12。32位計算機的計量範圍是232,模=232。“模”是計量器產生“溢位”的量,它的值在計量器上表示不出來,計量器上只能表示出模的餘數,如12的餘數有0,1,2,3,4,5,6,7,8,9,10,11。

3.2 補數

補碼將二進位制數的正負號放入符號位中,在推導過程中,我們先不把減法轉化為負數的加法,而是通過對二進位制數的減法推匯出負二進位制數的補碼。

假設當前時針指向11點,而準確時間是8點,調整時間可有以下兩種撥法:一種是倒撥3小時,即:11-3=8。另一種是順撥9小時:11+9=12+8=8。在以模為12的系統中,加9和減3效果是一樣的,因此凡是減3運算,都可以用加9來代替。對“模”12而言,9和3互為補數(二者相加等於模)。所以我們可以得出一個結論,即在有模的計量系統中,減一個數等於加上它的補數,從而實現將減法運算轉化為加法運算的目的。

3.3 補碼的推導

假設我們的暫存器位數為4,即最多可以存4位的二進位制數,則其計量範圍即模是2^4=16。由於最左邊位用於存放符號位,所以其能夠表示的範圍是-7~8。現在以計算5-3為例進行推導。

 # 按以上理論,減一個數等於加上它的補數,所以
 5 - 3
 # 等價於 
 5 + (16 - 3)   // 算術運算單元將減法轉化為加法
 # 用二進位制表示則為:
 0101 + (10000 - 0011)
 # 等價於
 0101 + ((1 + 1111) - 0011)
 # 等價於
 0101 + (1 + (1111 - 0011))
 # 等價於
 0101 + (1 + 1100) // 括號內是3(0011)的反碼+1,正是補碼的定義
 # 等價於
 0101 + 1101
 # 因為5-3等價於5+(-3),所以
 -3 = 1101
 # 即 `-3` 在計算機中的二進位制(補碼)為 `1101`。
 # 最後一步 0101 + 1101 等於
 10010

因為我們的暫存器是4位的,第一位“溢位”了,所以我們只儲存了4位,即0010,而當計算機去讀取時這正是我們所期望的2。

4 "0"的補碼

在計算機中,有+0和-0之分。

  • +0:原碼,反碼,補碼均為0000.
  • -0:原碼1000,反碼1111,補碼0000.

可以看到0的補碼只有一個,而原碼有兩個。這就產生了一個問題,4位的二進位制數的補碼個數比原碼個數多一個,例如1000(對於原碼是0,對於補碼我們通常將其設為8)。這就可以解釋int的範圍問題。

5 有符號左移、有符號右移,無符號右移

由於計算機中儲存二進位制的補碼,因此執行有符號的左移和右移相當於在保證符號的情況下進行冪運算。