原碼 反碼 補碼#
一:為什麼會有原碼反碼補碼?#
為了讓計算機更簡單的計算數值。所以計算機用補碼
具體怎麼實現,後邊會說,接下來先看一下 什麼是原碼 反碼和補碼
二:正數的原碼 反碼 補碼#
網上大多都是按 原碼 反碼 補碼 分別去介紹,博主 (本人) 感覺這樣的方法並不方便理解。所以改用 正數和負數來說
如果按 int 來的話,0 太多了,看著不方便,就是 8 位來表示吧.
正數就是 把十進制的數 變成二進制而已
正數的原碼 反碼 補碼是相同的
[+1] = [00000001](原碼) = [00000001](反碼) = [00000001](補碼)
三:負數的原碼 反碼 補碼#
原碼:最高位為1
代表這個數是負數
反碼: 符號位不變
, 其他位取反
補碼: 反碼 + 1
[-1] = [10000001](原碼) = [11111110](反碼) = [11111111](補碼)
四:原碼 反碼 補碼出現的意義#
他們的出現都是為了讓計算機計算的更加簡單,從而性能更好.
知識: 1 - 1 = 1 + (-1) 所以機器可以只有加法.
首先如果只是原碼計算,人可以很方便的計算出數值,因為人可以分清符號位.
可是計算機想識別符號位,是很麻煩的。有什麼方法能讓計算機更簡單的計算呢,於是就有了反碼.
接下來看,反碼的計算
1 - 1 = 1 + (-1)
= [0000 0001]原 + [1000 0001]原
= [0000 0001]反 + [1111 1110]反
= [1111 1111]反
= [1000 0000]原
= -0
反碼已經可以讓計算機計算更簡單。但是為什麼還有補碼呢.
因為反碼中 0 的編碼 可以是 [1111 1111] 反 = [-0] 和 [0000 0000] 反 =[+0]
正負 0 是沒有意義的,所以補碼是為了解決 0 有兩個編碼的問題.
(其實到這裡 反碼是不能直接看出來它代表哪個數,就需要理解了,補碼再反碼的基礎上 + 1, 就更加難理解,我也嘗試用更簡單的方法來表達出來,有問題可以提出寫到評論裡)
補碼中規定:0的編碼為[0000 0000]補 = [+0]
在這裡先不要去想二進制代表的十進制數,只想像它是編碼
首先 8 位的二進制,就只有 0000 0000 到 1111 1111 這麼多編碼 (從 0000 0000 開始 + 1)
然後正數原碼反碼補碼 都是相同的,那麼咱們去掉 0000 0000 到 0111 1111
剩下的就是 1000 0000 到 1111 1111 這些數值這些都是負數 (因為符號位是 1)
這些編碼挨個 + 1 是這樣的
1000 0000
1000 0001
1000 0010
....
1111 1101
1111 1110
1111 1111
首先這些編碼 如果是原碼那麼對應成十進制就是
-0
-1
-2
....
-125
-126
-127
反碼不是可以讓計算機計算方便麼,這些編碼是反碼 對應的十進制是
-127
-126
-125
...
-2
-1
-0
不是有 - 0 麼 怎麼解決這個 - 0 呢,每個數 - 1, 不就沒有 - 0 了麼,最後變成了
-128
-127
-126
...
-3
-2
-1
完美解決 - 0 的編碼問題,而且多了一個-128
, 這就是為什麼 java 中 int 取值範圍是 $-2^{31}$ ~ $2^{31}-1$
好了現在討論反碼怎麼才能變成這些數呢,
-1 的反碼是 1111 1110 , 然後現在 - 1 的編碼
變成了 1111 1111 (這個就是 - 1 的補碼了)
綜上所述: 補碼=反碼+1
補碼就是這麼來的。所以計算機使用補碼可以更快的是實現計算.(反碼也可以,但是還是有 - 0 問題,所以還是使用補碼)