1. 程式人生 > >詳解原碼、反碼以及補碼

詳解原碼、反碼以及補碼

很多人都只知道計算機使用的是二進位制,但很少有人瞭解計算機是以補碼的方式進行儲存資料的,之所以使用補碼而不是直接使用二進位制實際是為了解決正負運算的問題。

5在二進位制中表示為101B(B為二進位制單位),如果是在32位計算機中,我們高位補零:

00000000 00000000 00000000 00000101

這個就可以用來在32位計算機中表示數字5,但是如果我們需要表示-5呢?這個時候就出現問題了,因為計算機中沒有正負只有0和1,那麼要怎麼表示-5呢?二進位制是沒辦法直接表示-5的,為了解決這個問題原碼就誕生了。

原碼:最高位為0為正,1為負,也就是說原碼中的正數是一致的,只有為負數時最高位會為1,那麼5和-5分別表示為:

00000000 00000000 00000000 00000101 //為5

10000000 00000000 00000000 00000101 //為-5

計算機中並沒有減運算,減運算實際是加一個負數的運算,這也就是為什麼正數之間的加運算會比減運算快的原因,減運算需要做更多的處理來讓計算機解讀成能理解的加運算,例如5-5計算機要處理成5+(-5),原碼在高位用0和1解決了區分正負的問題,但是又引來的新的問題,因為我們都知道5+(-5)是等於0的,但是我們來看看原碼之間的運算結果:

00000000 00000000 00000000 00000101+10000000 00000000 00000000 00000101

=10000000 00000000 00000000 00001010

10000000 00000000 00000000 00001010的原碼並不是我們期待的0,而是-10,5+(-5)=-10這肯定不是我們要的結果,不僅如此原碼正數高位為0,所有負數高位為1,這個時候會出現兩個0的情況,一個為正0,一個為負0,這顯然不太合理,0是沒有正負的,為了解決第一個問題後來又引入了一個新的概念,那就是反碼。

反碼:反碼是在原碼的基礎上進一步改進,正數還是同原碼及普通二進位制一致,但負數則根據該負數的絕對值,也就是正數的原碼進行翻轉,如果是0就變成1,如果是1則變為0,顧名思義為反碼,反碼的出現是為了解決正負數的運算問題。

這裡實際上是運用了模的概念,例如時鐘裡的模是12,時鐘只有0-11,到12就溢位重新變為0,而在模為12的情況下,要6變為2有兩種方法,一種是-4,一種是+8,而4和8又互為補數。

這正好可以解決計算正負號運算問題,因為計算機可以看作計量機器,例如32位計算機的計量範圍是0~2^(32)-1,而模是2^(32),這樣計算機的正負號運算就可以運用模的性質轉化為兩個正數相加來達到和正數減去負數一樣的結果,從減一個負數變為加這個負數的補數。

從二進位制可以輕鬆的看出,一個正數和自身對應的負數的反碼互為補數,因此減去該正數和加上該正數對應的負數的反碼結果是一樣的。

例如5和-5

00000000 00000000 00000000 00000101 //正數5和上面原碼及普通二進位制一樣的表示

11111111 11111111 11111111 11111010 //-5的反碼是5的二進位制(或者說原碼、反碼都可以,因為都一樣)0和1的反轉

00000000 00000000 00000000 00000101+11111111 11111111 11111111 11111010 

=11111111 11111111 11111111 11111111

這裡的11111111 11111111 11111111 11111111是00000000 00000000 00000000 00000000的反碼,所以是-0,這樣反碼的出現就解決了正負數字的運算問題,但是還存在一個問題,就是上面的0是兩個,一個為正0,全為0,一個為負0,全為1。為了解決這個問題,又引入了補碼的概念。

補碼:補碼的正數和反碼以及原碼、普通二進位制的一致,沒有區別,而負數實際是在原有負數的反碼上面+1。

5的反碼:00000000 00000000 00000000 00000101

5的補碼:00000000 00000000 00000000 00000101

-5的反碼:11111111 11111111 11111111 11111010

-5的補碼:11111111 11111111 11111111 11111011 //就是在-5的反碼基礎上+1

00000000 00000000 00000000 00000101+11111111 11111111 11111111 11111011 

=00000000 00000000 00000000 00000000  //5的補碼+(-5的補碼)=0且0沒有正負號

從上面的解釋也可以看出來為什麼計算機儲存資料使用補碼而不是直接用二進位制,因為二進位制不能表示負數,而原碼雖然能表示負數,但無法進行正負數運算及兩個0的問題,反碼解決正負數運算的問題然後還保留著兩個0的問題,只有補碼完美解決了正負數運算問題同時還解決了兩個不同符號的0的問題,因此對於計算機而言,補碼是儲存的最佳選擇。