第一個(gè)問(wèn)題:我們都知道一個(gè)二進(jìn)制8位能表示的最大值是 1111 1111 == 255,但為什么最大表示到127?
因?yàn)閷?duì)于計(jì)算機(jī)來(lái)說(shuō),一個(gè)二進(jìn)制的數(shù)字它的最高位是符號(hào)位,0表示正數(shù),1表示負(fù)數(shù)。
所以 1111 1111 表示的 -127, 而 0111 1111 表示的是127,范圍區(qū)間應(yīng)該是[-127,127]之間。那么第二個(gè)問(wèn)題來(lái)了
第二個(gè)問(wèn)題:我們都知道一個(gè)Byte能表達(dá)的數(shù)字范圍是[-128,127],那么這個(gè)-128是怎么來(lái)的呢?
這里面就涉及到計(jì)算機(jī)的原碼、反碼、和補(bǔ)碼的相關(guān)知識(shí)了。
正數(shù):
原碼 == 反碼 == 補(bǔ)碼
即:原:0000 0001 ----- 反: 0000 0001 ------ 補(bǔ):0000 0001
負(fù)數(shù):
反碼 == 原碼的非符號(hào)位取反
補(bǔ)碼 == 反碼+1
即 原: 1000 0001 ------ 反: 1111 1110 ------ 補(bǔ): 1111 1111
原碼、反碼、補(bǔ)碼都可以表示同一個(gè)數(shù)字
計(jì)算機(jī)內(nèi)部是用補(bǔ)碼來(lái)存儲(chǔ)一個(gè)數(shù)的
為什么要用補(bǔ)碼來(lái)存呢?
既然規(guī)定了最高位是符號(hào)位,那么對(duì)于一個(gè)人來(lái)說(shuō)正常的加減一個(gè)數(shù)(比如: 0010 1101 + 0111 1100, 0001 1011 - 1011 0011)可以把這個(gè)二進(jìn)制轉(zhuǎn)成帶符號(hào)的十進(jìn)制自然進(jìn)行加減。
而對(duì)于計(jì)算機(jī)來(lái)說(shuō),同樣需要識(shí)別符號(hào)位來(lái)判斷是要加還是要減,也就這樣勢(shì)必會(huì)加大計(jì)算機(jī)的復(fù)雜性。因此希望符號(hào)位也可以參與到運(yùn)算中,也就是 100 - 50 == 100 + (-50)。把減法也可以轉(zhuǎn)化成加法。
這里舉一個(gè)最簡(jiǎn)單的例子:
1-1 == 1+(-1) == 0
那如果是兩個(gè)原碼相加是什么樣的
0000 0001
+
1000 0001
=
1000 0010 == -2 結(jié)果肯定是不正確的
那如果兩個(gè)反碼相加
0000 0001
+
1111 1110
=
1111 1111 轉(zhuǎn)成原碼 就是 1000 0000 == -0 負(fù)0
結(jié)果沒(méi)有問(wèn)題,但從數(shù)學(xué)的角度來(lái)說(shuō),一個(gè)整數(shù)包括負(fù)整數(shù),0,正整數(shù),而這里出現(xiàn)了負(fù)0,-0和0其實(shí)都表示0,但是這里從編碼來(lái)說(shuō)卻出現(xiàn)了兩個(gè)值, 1000 0000 和 0000 0000
最后看下兩個(gè)補(bǔ)碼相加
0000 0001
+
1111 1111
=
0000 0000 (超過(guò)8位的值被截掉) 轉(zhuǎn)成原碼 還是 0000 0000 =0,
可以看出,結(jié)果不僅正確,還同時(shí)解決了正負(fù)0的問(wèn)題。
而對(duì)于補(bǔ)碼的加運(yùn)算來(lái)說(shuō),是不可能出現(xiàn)1000 0000的情況,因?yàn)閮蓴?shù)相加想出現(xiàn)1000 0000的情況,就必然是兩個(gè)正數(shù)相加(如 0000 0001 + 0111 1111 = 1000 0000),而兩個(gè)正數(shù)相加是肯定不會(huì)出現(xiàn)負(fù)數(shù)的,所以1000 0000這個(gè)數(shù)肯定不會(huì)相加出現(xiàn)。
因此計(jì)算機(jī)規(guī)定,補(bǔ)碼:1000 0000 就表示 -128
所以8位二進(jìn)制數(shù)可表達(dá)的范圍是[-2^7, 2^7-1]=[-128,127]
所以總結(jié)一下,補(bǔ)碼不僅能正確的運(yùn)算,同時(shí)還可以多表示一個(gè)最低位,所以計(jì)算機(jī)用補(bǔ)碼來(lái)存儲(chǔ)數(shù)字。
同理,16位,32位等等的其他二進(jìn)制位的表示范圍也就是[-2^15, 2^15-1], [-2^31, 2^31-1]