計算機是不能直接做減法運算的,因為普通電腦硬件中沒有減法器,但負數的存在可以用加法器轉換成減法。但也就是因為負數的存在,原碼和反碼都不適合做計算,為什么呢?首先我們得知道什么是原碼,什么是補碼還有什么是反碼。
原碼
原碼是對自然正數(包括0)的二進制編碼,正數在計算機中直接用原碼進行存儲。
整數的正負屬性使用字節的最高位來區分,也就是從左數第一個數字來表示正負,0為正,1為負。
10進制的3,二進制就是00000011 10進制的-3,二進制就是10000011
反碼
反碼是除符號位(可以理解成左邊第一個字符)不變外,其余按位取反,這種方式對負數生效,正數取反還是保持原碼不變。計算機並不存儲反碼
為什么需要反碼?
計算機是不能直接做減法運算的,因為普通電腦硬件中沒有減法器,但我們可以用負數來做減法
反碼的作用就相當於數學中的負:3-5 =3+[-5]=[-2]
- 正數的反碼保持原碼不變:3=[0x0000011]
- 負數除正負符號位外,全部取反(0變1,1變0):-5=1x0000101 取反=[1x1111010]
- 於是3+[-5]=[-2]的計算過程為:[0x0000011]+[1x1111010]=[1x11111101]
補碼
正數的補碼是其原碼本身,而負數的補碼是先求反碼,然后再讓反碼加1。
為什么需要補碼?
因為“0”這個特殊數字的存在。
8位二進制反碼表示的正數范圍: +0 ~ +127,負數范圍: -127 ~ -0
但是,其中有兩個特殊的編碼會出現:
[0_0000000]=+0 (反碼)
[1_1111111]=-0 (反碼)
對於計算機來說,+0和-0都代表0了,這是絕對不行的,因為任何數字都只能有1個編碼。於是補碼出現了,把0當成正數,也即+0,這樣0的編碼就變成:0_0000000。那8位二進制表示的正數范圍仍然是: +0 ~ +127。而負數則為整體向后“挪動1位”(即反碼+1):只要將8位二進制表示的負數范圍從:-127 ~ -0變成:-128 ~ -1,就能成功解決問題。 {1_1111111}編碼就不再表示-0,而變成了-1。順着推,最小的編碼{1_0000000}就是-128
- 正數的補碼保持原碼不變:3={0x0000011}
- 負數先求反碼,然后再加1:-5=[1x1111010]+1={1x1111011}
- 於是3+{-5}={-2}的計算過程為:{0x0000011}+{1x1111011}={1x1111110}
所以,負數在計算機中使用補碼進行存儲,正數原碼進行儲存,在計算機的世界里,0是正數
Reference:
- https://www.jianshu.com/p/f810fd0c786d