1. 程式人生 > >為什麼Byte是8位,但是卻只能表示到127,而不是255?

為什麼Byte是8位,但是卻只能表示到127,而不是255?

第一個問題:我們都知道一個二進位制8位能表示的最大值是 1111 1111 == 255,但為什麼最大表示到127?

因為對於計算機來說,一個二進位制的數字它的最高位是符號位,0表示正數,1表示負數。
所以 1111 1111 表示的 -127, 而 0111 1111 表示的是127,範圍區間應該是[-127,127]之間。那麼第二個問題來了

第二個問題:我們都知道一個Byte能表達的數字範圍是[-128,127],那麼這個-128是怎麼來的呢?

這裡面就涉及到計算機的原碼、反碼、和補碼的相關知識了。

正數:

原碼 == 反碼 == 補碼
即:原:0000 0001 ----- 反: 0000 0001 ------ 補:0000 0001

負數:

反碼 == 原碼的非符號位取反
補碼 == 反碼+1

即 原: 1000 0001 ------ 反: 1111 1110 ------ 補: 1111 1111

原碼、反碼、補碼都可以表示同一個數字

計算機內部是用補碼來儲存一個數的

為什麼要用補碼來存呢?
既然規定了最高位是符號位,那麼對於一個人來說正常的加減一個數(比如: 0010 1101 + 0111 1100, 0001 1011 - 1011 0011)可以把這個二進位制轉成帶符號的十進位制自然進行加減。
而對於計算機來說,同樣需要識別符號位來判斷是要加還是要減,也就這樣勢必會加大計算機的複雜性。因此希望符號位也可以參與到運算中,也就是 100 - 50 == 100 + (-50)。把減法也可以轉化成加法。

這裡舉一個最簡單的例子:

1-1 == 1+(-1) == 0
那如果是兩個原碼相加是什麼樣的
0000 0001
+
1000 0001
=
1000 0010 == -2 結果肯定是不正確的

那如果兩個反碼相加
0000 0001
+
1111 1110
=
1111 1111 轉成原碼 就是 1000 0000 == -0 負0
結果沒有問題,但從數學的角度來說,一個整數包括負整數,0,正整數,而這裡出現了負0,-0和0其實都表示0,但是這裡從編碼來說卻出現了兩個值, 1000 0000 和 0000 0000

最後看下兩個補碼相加
0000 0001
+
1111 1111
=
0000 0000 (超過8位的值被截掉) 轉成原碼 還是 0000 0000 =0,
可以看出,結果不僅正確,還同時解決了正負0的問題。
而對於補碼的加運算來說,是不可能出現1000 0000的情況,因為兩數相加想出現1000 0000的情況,就必然是兩個正數相加(如 0000 0001 + 0111 1111 = 1000 0000),而兩個正數相加是肯定不會出現負數的,所以1000 0000這個數肯定不會相加出現。

因此計算機規定,補碼:1000 0000 就表示 -128

所以8位二進位制數可表達的範圍是[-2^7, 2^7-1]=[-128,127]
所以總結一下,補碼不僅能正確的運算,同時還可以多表示一個最低位,所以計算機用補碼來儲存數字。

同理,16位,32位等等的其他二進位制位的表示範圍也就是[-2^15, 2^15-1], [-2^31, 2^31-1]



作者:想起個帥氣的頭像
連結:https://www.jianshu.com/p/d0a8ff006f5c
來源:簡書

簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。

最後,如果是無符號的話,byte最大可以表示255的整數