補碼

補碼

計算機系統中一種處理方法
補碼(two's complement)在計算機系統中,數值一律用補碼來表示和存儲。原因在于,使用補碼,可以将符号位和數值域統一處理;同時,加法和減法也可以統一處理。[1]此外,補碼與原碼相互轉換,其運算過程是相同的,不需要額外的硬件電路。計算機中的符号數有三種表示方法,即原碼、反碼和補碼。三種表示方法均有符号位和數值位兩部分,符号位都是用0表示“正”,用1表示“負”,而數值位,三種表示方法各不相同。對于計算機,其概念和方法完全一樣。n位計算機,設n=8,所能表示的最大數是11111111,若再加1成為100000000(9位),但因隻有8位,最高位1自然丢失。又回了00000000,所以8位二進制系統的模為2^8。在這樣的系統中減法問題也可以化成加法問題,隻需把減數用相應的補數表示就可以了。把補數用到計算機對數的處理上,就是補碼。
    中文名:補碼 外文名: 别名: 英文名:two's complement 所屬領域:計算機 作用:存儲數值

特性

1、一個整數(或原碼)與其補數(或補碼)相加,和為模。

2、對一個整數的補碼再求補碼,等于該整數自身。

3、補碼的正零與負零表示方法相同。

模的概念可以幫助理解補數和補碼。

“模”是指一個計量系統的計數範圍。如時鐘等。計算機也可以看成一個計量機器,它也有一個計量範圍,即都存在一個“模”。例如:

時鐘的計量範圍是0~11,模=12。表示n位的計算機計量範圍是0~2^(n)-1,模=2^(n)。

“模”實質上是計量器産生“溢出”的量,它的值在計量器上表示不出來,計量器上隻能表示出模的餘數。任何有模的計量器,均可化減法為加法運算。

例如:假設當前時針指向10點,而準确時間是6點,調整時間可有以下兩種撥法:一種是倒撥4小時,即:10-4=6;另一種是順撥8小時:10+8=12+6=6

在以12模的系統中,加8和減4效果是一樣的,因此凡是減4運算,都可以用加8來代替。對“模”而言,8和4互為補數。實際上以12模的系統中,11和1,10和2,9和3,7和5,6和6都有這個特性。共同的特點是兩者相加等于模。

對于計算機,其概念和方法完全一樣。n位計算機,設n=8, 所能表示的最大數是11111111,若再加1成為100000000(9位),但因隻有8位,最高位1自然丢失。又回了00000000,所以8位二進制系統的模為2^8。在這樣的系統中減法問題也可以化成加法問題,隻需把減數用相應的補數表示就可以了。把補數用到計算機對數的處理上,就是補碼。

另外兩個概念:(一):補碼(two's complement) 指的是正數=原碼,負數=反碼加一(二):反碼(ones' complement) 指的就是通常所指的反碼。

整數補碼

求給定數值的補碼分以下兩種情況:

正數

正整數的補碼與原碼相同。

【例1】+9的補碼是00001001。(備注:這個+9的補碼是用8位2進制來表示的,補碼表示方式很多,還有16位二進制補碼表示形式,以及32位二進制補碼表示形式,64位進制補碼表示形式等。每一種補碼表示形式都隻能表示有限的數字。)

負數

求負整數的補碼,原碼符号位不變,先将原碼減去1,最後數值各位取反。(但由于2進制的特殊性,通常先使數值位各位取反,最後整個數加1。)

同一個數字在不同的補碼表示形式中是不同的。比如-15的補碼,在8位二進制中是11110001,然而在16位二進制補碼表示中,就是1111111111110001。以下都使用8位2進制來表示。

【例2】求-5的補碼。

因為給定數是負數,則符号位為“1”。

後七位:-5的原碼(10000101)→符号位不變(10000101)→數值位取反(11111010)→加1(11111011)

所以-5的補碼是11111011。

【例3】數0的補碼表示是唯一的。

[+0]補=[+0]反=[+0]原=00000000

[ -0]補=11111111+1=00000000

轉化為原碼

已知一個數的補碼,求原碼的操作其實就是對該補碼再求補碼:

⑴如果補碼的符号位為“0”,表示是一個正數,其原碼就是補碼。

⑵如果補碼的符号位為“1”,表示是一個負數,那麼求給定的這個補碼的補碼就是要求的原碼。

【例4】已知一個補碼為11111001,則原碼是10000111(-7)。

因為符号位為“1”,表示是一個負數,所以該位不變,仍為“1”。

其餘七位1111001取反後為0000110;

再加1,所以是10000111。

補碼的絕對值

(稱為真值)

【例5】-65的補碼是10111111

若直接将10111111轉換成十進制,發現結果并不是-65,而是191。

事實上,在計算機内,如果是一個二進制數,其最左邊的位是1,則我們可以判定它為負數,并且是用補碼表示。

若要得到一個負二進制補碼的真值,隻要對補碼全部取反并加1,就可得到其真值。

如:二進制值:10111111(-65的補碼)

各位取反:01000000

加1:01000001(+65)

小數補碼求法

一種簡單的方式,符号位保持1不變,數值位從右邊數第一個1及其右邊的0保持不變,左邊按位取反。

代數加減運算

補碼加法

[X+Y]補 = [X]補 + [Y]補

【例6】X=+0110011,Y=-0101001,求[X+Y]補

[X]補=00110011 [Y]補=11010111

[X+Y]補 = [X]補 + [Y]補 = 00110011+11010111=00001010

注:因為計算機中運算器的位長是固定的(定長運算),上述運算中産生的最高位進位将丢掉,所以結果不是100001010,而是00001010,。

補碼減法

[X-Y]補 = [X]補 - [Y]補 = [X]補 + [-Y]補【1】

【例7】1-1 [十進制]

1的原碼00000001 轉換成補碼:00000001

-1的原碼10000001 轉換成補碼:11111111

1+(-1)=0

00000001+11111111=00000000

00000000轉換成十進制為0

0=0所以運算正确。

【例8增】-7-(-10) [十進制]

改為加法形式:-7-(-10)=-7+(-(-10))

-7的補碼:11111001

-(-10)的補碼:-10的原碼為10001010,-(-10)的原碼為00001010,

-(-10)的補碼就是其原碼,為00001010

-7 - (-10)= -7 + 10 = 3

11111001+00001010 = 00000011

轉換成十進制為3

補碼乘法

補碼的乘法不具備【X*Y】補=【X】補×【Y】補的性質。但是【X*Y】補==【X】補×Y,所得結果再取補碼,如x=101,y=011,[x*y]補=-[(-101)*011]=-[011*011]=-01001=10111

其中,若【Y】補=y31y30……y0,則 Y=-y31*2^31+y30*2^30+……+y0*2^0

補碼總結

補碼隻是一種相對合理的編碼方案。這個方案在負數的機器表示中解決了3個問題:

數的表示

在數的表示上通過人為的定義來消除編碼映射的不唯一性,對轉換後的10000000強制認定為-128。當然對原碼和反碼也可以做這種強制認定,那為什麼原碼和反碼沒有流行起來?

數的運算

原碼和反碼沒有流行起來,是因為在數的運算上對符号位的處理無法用當時已有的機器物理設計來實現

由于原碼和反碼在編碼時采用了硬性的人工設計,這種設計在數理上無法自動的通過模來實現對符号位的自動處理,符号位必須人工處理,必須對機器加入新的物理部件來專門處理符号位,這加大了機器設計難度,加大的機器成本,不到萬不得已,不走這條路。

設計補碼時,有意識的引用了模運算在數理上對符号位的自動處理,利用模的自動丢棄實現了符号位的自然處理,僅僅通過編碼的改變就可以在不更改機器物理架構的基礎上完成的預期的要求,所以補碼沿用至今。

自身邏輯意義的完整性

補碼這個編碼方案要解決的是如何在機器中表示負數,其本質意義為用一個正數來表示這個正數對應的負數。所謂-20的補碼是指:如何在機器中用補碼形式表示-20。具體過程是這樣的:将20的二進制形式直接寫出00010100,然後所有位取反變成11101011,再加1變成了11101100。最簡單的補碼轉換方式,不必去理會轉換過程中的符号位,隻關注轉換前和最終轉換後的符号位就行了。

那麼對11101100求出其補碼又具有什麼現實含義呢?對一個數求補,邏輯過程是對這個數的所有的二進制位按位取反再加1。現實含義是求出這個數對應的負數形式。對11101100求補就是求出這個數對應的負數的形式,直接操作下11101100,先所有位取反00010011,再加上1就成了00010100。對11101100求出其補碼的含義:11101100按照現行補碼碼制表示的有符号數是-20,對于-20求補就是求出其對應的負數-(-20),現實中-(-20)是+20,那麼求補運算的結果符合現實情況嗎,00010100轉換成有符号數正是+20,這就說明了補碼自身邏輯意義是完整的,是不會自相矛盾的。

最後,補碼的總前提是機器數,不要忘了機器數的符号位含義,最高位為0表示正數,最高位為1表示負數,而最高位是指機器字長的最左邊一位。字節數100B,最高位為00000100中的最左邊的0。

【1】 在上一個版本中有如下說明:

“其中[-Y]補 稱為負補,求負補的方法是:負數的絕對值的原碼所有位按位取反;然後整個數加1。(恢複本來解釋。請路人真正理解并實際驗證後再修改。以免誤導大衆。另外,例6不具典型性,新增例7。)”

私以為, 不必要提出負補的概念以使問題複雜化,盡管該解法是正确的,但卻完全沒有必要增加新的運算方法及運算結構。求[-Y]補,隻需,先将符号位取反,求出-Y, 再求-Y的補碼即可。盡管這與求負補的方法實際上是一緻的, 但是卻簡化了概念,僅僅是對過去概念以及運算結構的複用。

相應的,原例7(現例8)重新作了修改。

----某路人

相關詞條

相關搜索

其它詞條