2的補碼

此文是基於阮一峯大神的文章-關於2的補碼的學習總結,便於加深印象和回顧,若想看原文,請走剛纔的傳送門~

負數在計算機中如何表示呢?

在計算機內部採用2的補碼(Two’s Complement)表示負數。

什麼是2的補碼?

它是一種數值的轉換方法,要分二步完成:

  • 第一步,每一個二進制位都取反值,0變成11變成0。比如:00001000取反爲11110111
  • 第二步,將上一步的得到的值+1。即:

    11110111 + 1 = 11111000;

所以,1111100000001000的補碼,也就是說-8在計算機中用11111000表示;

爲什麼要用補碼來表示負數呢?

對於計算機,加減乘除是最基本的運算,要儘量設計的很簡單;

  • 運算法則減去一個數等於是加上這個數的負數;
  • 計算機的基礎電路只有加法,使得設計更加簡單;

由於對於二進制的編碼有三種方式:原碼反碼補碼

  • 使用原碼進行正數 + 負數的類減法所得的結果並不正確;
  • 使用反碼進行計算時,結果的真值部分是正確的,但是會有一個特殊的值:0。由於0是具有符號位是沒有任何意義的,並且會有1000 00000000 0000兩個編碼表示0;
  • 使用補碼進行計算可以完美解決真值、符號位和0的問題,同時由於(-1) - (-127) = -128,補碼會以1000 0000表示 -128,即還能夠表示一個最低數。
  • 原碼和反碼錶示的範圍爲[ -127, 127 ],而補碼可以表示[ -128, 127 ]

2的補碼的本質:

負數可以換成是 0 - 正數 得到的,因此 對於 -8 可以看做是 0 - (+8) 得到的;
那麼對於二進制的來說即如下形式:

           0 0 0 0 0 0 0 0
        -  0 0 0 0 1 0 0 0
    -------------------------- 
           1 1 1 1 1 0 0 0

因爲 被減數 0000 0000 小於減數 0000 1000,因此需要向上一位借1,因此實質上被減數是1 0000 0000

          1 0 0 0 0 0 0 0 0
       -    0 0 0 0 1 0 0 0
    -------------------------- 
            1 1 1 1 1 0 0 0

進一步觀察可以發現,1 0000 0000 是由 1111 1111 + 0000 0001 所得,因此:

            1 1 1 1 1 1 1 1
       -    0 0 0 0 1 0 0 0
    -------------------------- 
            1 1 1 1 0 1 1 1
       +    0 0 0 0 0 0 0 1
    --------------------------            
            1 1 1 1 1 0 0 0

2的補碼的轉換步驟就是這麼來的;

爲什麼正數加法適用於2的補碼?

事實上,我們要證明的是X - YX + (-Y)可以用X + Y的2的補碼完成;
根據上面的所說的,Y的2的補碼可以用1111 1111 - Y + 1來表示;
即:X + (-Y) => X + ( 1111 1111 - Y + 1 ) = Z

基於以上算式,分爲 兩種 情況討論:

  • 第一種,X < Y,Z 應該爲負數,那麼對 Z 採用2的補碼的逆運算求出正數值然後在加一個負號即可得到
    Z = -[ 1111 1111 - ( Z - 1 ) ] 
    Z = -[ 1111 1111 - ( X + ( 1111 1111 - Y + 1 ) )  + 1 ] = X - Y;
  • 第二種,X > Y,那麼 Z 肯定大於 1111 1111,但是我們假定這是8位機,最高位第9位溢出被捨棄,相當於減去1 0000 0000,因此:
    Z = Z - 1 0000 0000 = X + ( 1111 1111 - Y + 1 ) - 1 0000 0000 = X - Y

另外,還有一種方法證明:

Z = X - Y = X + 1111 1111 - Y + 1 = X - Y + 1 0000 0000,

由於是8位機,是不可能出現第9位的(被捨去),即

Z = X - Y + 0000 0000 = X - Y;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章