基本介紹
- 中文名:補碼
- 外文名:two's complement representation
- 所屬領域:計算機
- 作用:存儲數值
特性,模,整數補碼,正數,負數,轉化為原碼,補碼的絕對值,小數補碼求法,代數加減運算,補碼加法,補碼減法,補碼乘法,代數解釋,補碼總結,
特性
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。在這樣的系統中減法問題也可以化成加法問題,只需把減數用相應的補數表示就可以了。把補數用到計算機對數的處理上,就是補碼。
另外兩個概念:()
用二進制表示正數不存在問題,但是在表示負數時會存在意想不到的困難。下面表中列出了用二進制數表示負整數的三個系統:
(一):ones' complement:這種表示法中,正數保持不變(因為這個方案就是要解決有效地將減法運算變成加負數的運算,所以,正數不需要變動,這裡的反,就是相對於正數的二進制形式來說的),負數用公式(n為將符號位算在內的位數)計算。可以形象的將對應的正數的二進制形式的各個位取反即可。(這裡和得到反碼的步驟不一樣。反碼,補碼,都是從原碼開始操作得到。這裡是從正數開始操作得到。但兩者除了計算的起點不同,最終得到的編碼形式是一樣的。為了區別操作過程的不同,故仍然採用英文名。)
用四位二進制數做例子。那么-7的二進制(1111)各個位取反得到其ones complement數(1000)。就是其中最左邊的一位為符號位。N=7 ,n=4,代入公式,得=-7以及其二進制形式,過程如下:
2^{4}= 10000
減1 - 0001
01111
減7 - 0111
01000加粗的這部分呈現的是-7.
(二):twos complement:由於上面一種表示法(n為將符號位算在內的位數)
觀察公式,twos complement數,相當於ones complement 數+1.
下面用4位二進制數來做例子:
2^{4}= 10000 2^{4}= 10000
減7 - 0111 減負7 - 1001
01001加粗部分表示-7 0 0111加粗部分表示+7
十進制數 | 符號位+ 二進制絕對值 的表示方式 | ones' complement | two's complement |
+7 | 0111 | 表示方式不變 | 表示方式不變 |
+6 | 0110 | 表示方式不變 | 表示方式不變 |
+5 | 0101 | 表示方式不變 | 表示方式不變 |
+4 | 0100 | 表示方式不變 | 表示方式不變 |
+3 | 0011 | 表示方式不變 | 表示方式不變 |
+2 | 0010 | 表示方式不變 | 表示方式不變 |
+1 | 0001 | 表示方式不變 | 表示方式不變 |
+0 | 0000 | 表示方式不變 | 表示方式不變 |
-0 | 1000 | 1111 | [1]0000 |
-1 | 1001 | 1110 | 1111 |
-2 | 1010 | 1101 | 1110 |
-3 | 1011 | 1100 | 1101 |
-4 | 1100 | 1011 | 1100 |
-5 | 1101 | 1010 | 1011 |
-6 | 1110 | 1001 | 1010 |
-7 | 1111 | 1000 | 1001 |
-8 | 超出4個bit所能表達範圍 | 超出4個表達範圍 | 1000 |
註: | 要設計硬體區分符號位,比較絕對值大小。 | 無需設計硬體比較大小,但零存在兩種表示方法。 | 較好的解決上述問題 。由於零隻有一種表達方式,所以,可以比別的方式多表達一個-8. |
整數補碼
求給定數值的補碼分以下兩種情況:
正數
正整數的補碼是其二進制表示,與原碼相同。
【例1】+9的補碼是00001001。(備註:這個+9的補碼是用8位2進制來表示的,補碼錶示方式很多,還有16位二進制補碼錶示形式,以及32位二進制補碼錶示形式,64位進制補碼錶示形式等。每一種補碼錶示形式都只能表示有限的數字。)
負數
求負整數的補碼,將其原碼除符號位外的所有位取反(0變1,1變0,符號位為1不變)後加1。
同一個數字在不同的補碼錶示形式中是不同的。比如-15的補碼,在8位二進制中是11110001,然而在16位二進制補碼錶示中,就是1111111111110001。以下都使用8位2進制來表示。
【例2】求-5的補碼。
-5對應正數5(00000101)→所有位取反(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
代數解釋
在十進制中我們可以把n位二進制體系中的數
a表示為:
求補碼,意味著求:
而根據等比數列求和公式:
則
因為這裡k0,k1,k2,k3……不是0就是1,所以1-k0,1-k1,1-k2的運算就是二進制下的取反
註:n位二進制,最高位為符號位,因此表示的數值範圍-2^(n-1) ——2^(n-1) -1,所以模為2^n。上面提到的8位二進制模為2^8是因為最高位非符號位,表示的數值範圍為0——2^8-1。
補碼總結
補碼只是一種相對合理的編碼方案。這個方案在負數的機器表示中解決了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的補碼即可。儘管這與求負補的方法實際上是一致的, 但是卻簡化了概念,僅僅是對過去概念以及運算結構的復用。