1. 程式人生 > 其它 >補碼、反碼、原碼

補碼、反碼、原碼

補碼、反碼、原碼這些都是計算機中的概念,這些概念的由來,跟計算機發展歷史中實現減法操作有關!

早期的計算機先實現了加法機,為了實現減法操作,偉人們開始想著怎麼實現一個減法機,但是他們想到,問題的產生往往是由複雜的根源引起,加法的“進位”操作已經讓計算機實現加法機時遇到了挑戰,減法有其“借位”操作,又將“頭疼”一番了。偉人們的智慧簡化了這個問題,減法可以通過加法的操作去實現,在計算機中我們就用加法機就能實現加法與減法操作了。關鍵在於“減法怎麼通過加法的操作去實現”:

十進位制的減法使用加法來實現

74-59=15,這是一個簡單的十進位制(兩位數)減法例子,我們稍微將這個式子,表示式兩邊都加上100,再進行轉換,表示式就等於
(1)74+100-59=100+15

-> (2) 74+1+99-59=1+99+15 -> (3) 75 + 40 = 100 +15 -> (4)115-100 =15
上面有關鍵的兩點需要了解:
1、因為計算的兩位數減法,所以式子兩邊相加的是100
2、把一個數從一串9中減去稱為9的補數或補碼(此補碼非標題中的補碼)
表示式轉換到(2)時,發現這裡面就一個減法,就是99-59=40,結合上面第二點,得出結論,40就是59相對於9的補數

40就是59相對於9的補數,有何意義?

當我們計算兩位數減法的時候,我們將一個數用99減去,無論這個數是什麼,它都不用做借位運算,這就是好處!比如99-98,99-12,99-42等等都不用進行借位。因為99已經是兩位數減法中最大的一個兩位數了。我們已經發現,有了這個,我們的借位問題被解決了

表示式(4)中不還是進行了減法了麼?沒完全用加法代替減法啊

是的,表示式(4)中115-100=15還是進行了減法,這個我們用二進位制來解釋

二進位制中的減法使用加法來實現

表示式轉成二進位制74-59=15 -> (1)01001010(74)-00111011(59) = 00001111(15) -> (2)11111111(255) + 00000001(1) + 01001010(74) -00111011(59) = 11111111(255)+00000001(1) + 00001111(15) -> (3)11111111(255) - 00111011(59) + 00000001(1) + 01001010(74) = 11111111(255)+00000001(1) + 00001111(15)


表示式轉成二進位制,還是使用上面十進位制同樣的方式來將減法轉換為加法,表示式兩邊都加上100000000=11111111+00000001,結合上述補數定義,得出結論表示式(3)中的11111111(255) - 00111011(59)=11000100(196)表示的是11000100(196)是00111011(59)相對於1的補數,1的補數也稱為相反數或者反碼,這就是反碼的定義,即反碼的計算方式

2的補數

2的補數就是1的補數再加上1,2的補數也被稱為二進位制中的補碼,那麼可以得出11000101(11000100+00000001)是00111011相對於2的補數,於是上述二進位制計算的表示式可以用2的補數(補碼)來計算,表示式轉換為-> 01001010(74)-00111011(59) -> 01001010(74)+[11111111(255) -00111011(59) + 00000001(1)]->01001010+11000101,計算結果等於100001111,十進位制為271,在此我們繼續第四步運算,將100001111-100000000,結果等於00001111(15),結果是正確的,但是在計算機中,這第四步的二進位制運算如果還是需要計算的話,那麼減法操作還是沒有避免啊?

溢位

上述運算中,1001010+11000101的運算產生了溢位,8位數運算結果為9位。我們需要進行減去9位的100000000,得到結果其實為000001111(9位),最後這個減法操作對於8位二進位制相加來說,其實是多餘的,因為8位二進位制相加,所得到的溢位肯定是1,那麼我們減去100000000,相當於是消去了首位的1,得到首位為0,首位為0對於結果來說沒有意義。

計算機中儲存負數

11000101是00111011相對於2的補數,那麼我們計算兩個數A與B相減的時候,相當於計算A+(-B)等於A+B的補碼,既然是如此轉換,計算機也是按這個轉換邏輯去做的,負數在計算機中儲存的是補碼。這也就是為什麼byte位元組的取值範圍為-128~127的原因。

原碼

原碼很好理解,就是原來的編碼,比如1或-1,1的原碼就是00000001,-1的原碼是10000001,第一位代表符號位。10000001是不是儲存在計算機中的-1的表示呢?不是,請記住,負數在計算機中是以補碼的形式儲存的,那麼需要將原碼轉換為補碼,轉換過程如下:10000001(-1的原碼)->11111110(-1的反碼)->11111111(-1的補碼),-1在計算機中是以11111111來儲存的。

總結:

1、補碼、反碼、原碼的由來都是因為計算機發展過程中,進行簡化減法運算而誕生的
2、負數在計算機中是以補碼的形式儲存的