深入理解補碼

補碼黑歷史

對於每個計算機專業的同學,剛開始都會接觸到二進制轉換、原碼、反碼、補碼的知識。

國內教材上是如下定義的:

原碼:最高位爲符號位,0代表整數,1代表複數,非符號位爲改數字絕對值的二進制表示。如127的原碼爲 0111 1111,-127的原碼爲 1111 1111。

反碼:正數的反碼與原碼一致;負數的反碼是對原碼按位取反(符號位不變)。如127的反碼爲 0111 1111,-127的反碼爲 1000 0000。

補碼:正數的補碼與原碼一致;負數的補碼是該數的反碼加1。如127的補碼爲 0111 1111,-127的補碼爲 1000 0001。

記住上述的定義和轉換方法,通過考試so easy。可是,如果做個有心人,難免會有兩點疑惑:1)爲什麼負數和正數的規則會不同,這和我們學習其他概念方式差別很大;2)補碼到底有什麼用,引入補碼本質是爲了解決什麼問題?

帶着上面的疑問,對比下國外的計算機教材的講解,國內的教材只寫結論,對技術產生的背景幾乎完全忽略,實際上是本末倒置。如果理解了補碼背景,徹底理解補碼並不太難。

爲什麼需要補碼

補碼是一個工程問題,它是爲解決特定工程問題而引入的。

對於8比特的二進制編碼,最多可以表示256個不同的值,如果沒有負數,我們可以用來表示0~255,如果有負數,我們可以分別表示-128~127。

計算機應該如何表示負數呢?

以4比特二進制數爲例,最多可以表示16個數,如下表,我們至少有三種方式表示負數:

偏移碼

我們以二進制最大值1111對應十進制最大值8,二進制最小值0000對應十進制最小值-7,中間編碼進行線性對齊。

符號碼

符號碼更直觀,固定使用最高位表示符號,0表示正數,1表示負數,非符號位的二進制數值爲要表達數字的絕對值。這種編碼相對更直觀,但是存在0和-0,所以表示範圍要少一個。

補碼:

0000表示0,以0爲中心,依次向上是每個數加1(1 = 0001、2 = 0010、3 = 0011);依次向下,每個數字減1(因爲只有4位,減法操作時向上借位),-1 = 0000 - 1 = 1111, -2 = 1111 - 1 = 1110, -3 = 1110 - 1 = 1101。

對比上述三種編碼優劣,偏移碼和符號碼對我們理解起來很容易,但是對硬件設計卻是個難題。對於A = B + C,硬件設計者需要理解B和C每一位代表的意義,設計規則相對複雜,而對於補碼,則非常自然,只存在一個規則。

特別需要指出的,計算機內部,並沒有設計減法器,對於A = B - C,編譯器會將其轉換成 A = B + (-C),加入C是整數,B - C在計算機內部,是直接B的補碼和C的補碼相加。

補碼對我們來說,比較難理解,爲方便換算,人們總結出上一節補碼的轉換方法,也就是我們在學習時記住的結論。

補碼的數學原理

我們繼續回到人類的世界,還是按10進制舉例,加入只有1位10進制,一共可以表示0個編碼,可以表示爲0~9,也可以表示-5~4。

按補碼思路,對應的補碼, -5 = 5,-4 = 6, -3 = 7, -2 = 8, -1 = 9 , 0 = 0, 1 = 1, 2 = 2, 3 = 3, 4 = 4。

如果計算 4 + (-2),4 + (-2) = 4 + 10 - 2 = 4 + 8 = 12 = 2。

實際上,補碼是向高位借了一位,然後和當前數值進行求和計算,由於計算機位數有限制,會進行截取,所以高位接過來的一位對要計算的數值結果並無影響。

在只能表示一位的10進制裏,A = B + C 、A = (10 + B) + C 、A = B + (10 + C)、 A = (10 + B) + (10 + C)結果是相同的,如果是負數,和10進行結合後的結果就是補碼。

 

 

 

 

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