关于补码的详解
怎么在計算機(jī)中表示負(fù)數(shù)?
正數(shù)在計算機(jī)中的表示,我們都比較清楚,轉(zhuǎn)為二進(jìn)制,也知道如何表示。那負(fù)數(shù)在計算機(jī)上如何表示呢?
比如,8在計算機(jī)中的二進(jìn)制表示是00001000。
那么比較很容易想到,可以將一個二進(jìn)制位(bit)專門規(guī)定為符號位,它等于0時就表示正數(shù),等于1時就表示負(fù)數(shù)。比如,在8位機(jī)中,規(guī)定每個字節(jié)的最高位為符號位。那么,+8就是00001000,而-8則是10001000。
但是,隨便找一本《計算機(jī)原理》,都會告訴你,實(shí)際上,計算機(jī)內(nèi)部采用2的補(bǔ)碼(Two’s Complement)表示負(fù)數(shù)。
什么是2的補(bǔ)碼呢?
它是一種數(shù)值的轉(zhuǎn)換方法,要分兩步完成:
1、每一個二進(jìn)制位都要取反,0變成1,1變成0.比如,00001000變成11110111。
2、將上一步得到的值加1,11110111就變成了11111000。
所以,00001000的2的補(bǔ)碼就是11111000,也就是說8的補(bǔ)碼在計算機(jī)中用11111000表示。
那么為什么非要用這種取反加一的方式表示負(fù)數(shù)呢,直接用最高符號位表示不更方便嗎?
現(xiàn)在就來解釋下這樣做的原因。
為什么用2的補(bǔ)碼表示負(fù)數(shù)?
首先,要明確一點(diǎn),在計算機(jī)內(nèi)部用什么表示負(fù)數(shù),其實(shí)是無所謂的,只要你能夠保持一一對應(yīng)的關(guān)系,就可以用任意的方式來表示負(fù)數(shù)。所以,既然可以任意選擇,那我們就要選擇一種最方便的方式。
2的補(bǔ)碼呢,就是最方便的方式,它的便利體現(xiàn)在,所有的加法運(yùn)算都可以使用同一種電路來完成。
還是以-8來作為例子。
假定有兩種表示方法,一種就是最高符號位方法,即10001000。一種是2的補(bǔ)碼表示法,即11111000。請問哪一種方法在加法運(yùn)算中更方便呢?
隨便寫一個計算式,16+(-8)=?
16的二進(jìn)制表示是00010000,所以用最高符號位方法,加法就要寫成:
00010000
+10001000
---------
10011000
可以看到按照正常的加法規(guī)則,得到了10011000的結(jié)果,轉(zhuǎn)成十進(jìn)制就是-24。顯然,這就是錯誤的答案。也就是說,在這種情況下,正常的加法規(guī)則不適用正數(shù)與負(fù)數(shù)的加法,因此必須要制定兩套運(yùn)算規(guī)則,一套用于正數(shù)加正數(shù),一種用于正數(shù)加負(fù)數(shù)。從電路上來說,就是必須要為加法運(yùn)算做兩種電路。這…
現(xiàn)在,再來看2的補(bǔ)碼表示法:
00010000
+11111000
---------
100001000
可以看到按照正常的加法規(guī)則,得到100001000的結(jié)果。注意一下,這是一個9位的二進(jìn)制。因為我們已經(jīng)假設(shè)這是一個8位機(jī),因此最高的第9位是一個溢出位,會被自動舍去。所以結(jié)果就變成了00001000,轉(zhuǎn)成十進(jìn)制就是8,也就是正確答案啦。這就說明2的補(bǔ)碼表示法可以將加法運(yùn)算規(guī)則,擴(kuò)展到整個數(shù)據(jù)集,從而一套電路就可以實(shí)現(xiàn)全部正數(shù)的加法,用一套規(guī)則舉行。
2的補(bǔ)碼的本質(zhì)以及正確性
我們要看先一下模的概念“模”是指一個計量系統(tǒng)的計數(shù)范圍。如時鐘等。計算機(jī)也可以看成一個計量機(jī)器,它也有一個計量范圍,即都存在一個“模”。例如:時鐘的計量范圍是0~11,模=12。表示n位的計算機(jī)計量范圍是0~2n?10~2^{n-1}0~2n?1,模就是2n2^n2n。“模”實(shí)質(zhì)上是計量器產(chǎn)生“溢出”的量,它的值在計量器上表示不出來,計量器上只能表示出模的余數(shù)。任何有模的計量器,均可化減法為加法運(yùn)算。
例如: 假設(shè)當(dāng)前時針指向10點(diǎn),而準(zhǔn)確時間是6點(diǎn),調(diào)整時間可有以下兩種撥法:你可以往回?fù)?個小時,也可以向前撥8個小時(12-10+6,在鐘表系統(tǒng)里模是12)在以12模的系統(tǒng)中,加8和減4效果是一樣的,因此凡是減4運(yùn)算,都可以用加8來代替。
對“模”而言,8和4互為補(bǔ)數(shù)。實(shí)際上以12模的系統(tǒng)中,11和1,10和2,9和3,7和5,6和6都有這個特性。共同的特點(diǎn)是兩者相加等于模。
對于計算機(jī),其概念和方法完全一樣。n位計算機(jī),設(shè)n=8, 所能表示的最大數(shù)是11111111,若再加1稱為100000000(9位),但因只有8位,最高位1自然丟失。又回了00000000,所以8位二進(jìn)制系統(tǒng)的模為2^8。 在這樣的系統(tǒng)中減法問題也可以化成加法問題,只需把減數(shù)用相應(yīng)的補(bǔ)數(shù)表示就可以了。
再次重申一下這句話:
在以12模的系統(tǒng)中,加8和減4效果是一樣的,因此凡是減4運(yùn)算,都可以用加8來代替。
所以對應(yīng)模為100000000的8位機(jī)來說,-b 就等于加上10000 0000-b。
而(10000 0000-b)是什么?恰好就是b的補(bǔ)碼
補(bǔ)碼怎么求,“取反加一” 這口訣怎么來的?
承認(rèn)了8 - 5 = 8 + (-5的補(bǔ)碼)這個事實(shí)后,我們來看-5的補(bǔ)碼怎么求,“取反加一”怎么來的
其實(shí)看完了上面的模的問題,該問題的答案基本已經(jīng)出來了
-5的補(bǔ)碼是 10000 0000 - 5 = 1111 1111 + 1 -5 = (1111 1111 - 5) + 1
1111 1111 - 0000 0101 +1 =1111 1010 +1 =1111 1011
然后,用8+1111 1011,即0000 1000 + 1111 1011 =10000 0011,8位機(jī),即0000 0011,轉(zhuǎn)為十進(jìn)制就是3。也就是正確答案。
所以,2的補(bǔ)碼的本質(zhì)就是模的計算,減去一個數(shù),都可以用加上補(bǔ)數(shù)(模減去它)來算的。
總結(jié)
- 上一篇: Leetcode-区域和检索 - 数组不
- 下一篇: android开发 bug问题解决:O