在這篇博文中,我希望能從數學的角度幫助你理解計算機中的補碼世界,並嘗試解釋以下問題:
-
符號位為什么是最高位,為什么
1
表示負,0
表示正?0
表示正,1
表示負,為啥不是0
表示負,1
表示正? -
為什么補碼
1000 0000
表示-128
? -
為什么補碼能夠實現減法運算?
關於原碼、反碼、補碼的計算這里就不贅述了,但是如果你對於原碼、反碼、補碼的計算還是通過一個數 -> 二進制原碼 -> 正數不變,負數保持符號位,其他位取反 得反碼 -> 反碼+1得補碼
另外也有上面的3個疑問的話
我強烈建議你忘掉之前關於原碼、反碼和補碼的認知
我首先拋出三個問題,希望你帶着這三個問題去閱讀,當你能給出這兩個問題的答案的時候,上面的3個問題也有答案了
- 同余的定義和意義是什么?
- 在4位系統中,怎么去表示負數?
- 在8位系統中,怎么做減法運算?
1. 環形系統、模、同余
在一個環形系統中,能表示的數是有限的。例如在下面的表盤中,你能表示的數只有0~11,大於等於12的數,會被舍棄一部分,再在表盤上表示出來,在計算機中,我們管這叫「溢出」。
比如15點,在鍾表上表現的是3。當表針越過11的時候,又從0開始,直到3。如果在鍾表的世界里,要表示27呢?鍾表上無法表示准確的數字,27在這里只能被表示為3。准確地說,在超出這個系統極限值的時候,也就是說溢出了,這個系統只能用「余數」來計量
在這里,所有被12除,余數為3的數,都被歸為1類。在這里,還有余數為0、1、2...11的類
而15和27,稱為 15和27關於模12同余,它們的余數就是3
在這個系統中,能表示的數只有「余數」,表盤上的數字都是被12除后的余數
我們可以這樣理解這個系統:這個系統將整數分成了12類——被12除余0、1、2、3、4、5、6、7、8、9、10、11的類
我們來看看「什么是奇數?什么是偶數?」
偶數是被2除余0的整數,奇數是被2除余1的整數。
通過模2我們將整數分成了兩類:余0和余1的數,也就是偶數和奇數
回到我們的表盤,通過模12,所有的整數也能被分成12類,分別是余0、1、2、3、4、5、6、7、8、9、10、11的類
所有的整數對模12做取模運算,按照它們的余數我們可以給它們分類。
1、13、-11、-23是同一類!
到這里,我們可以給出第一個問題的答案了。關於同余是這樣定義的:如果兩個數a、b除以模m,余數一樣,就稱整兩個數關於模m同余,記為
同余的意義就是分類!
2. 計算機世界
很容易理解計算機實際上就是一個環形系統。我們以4位bit來看看
在這個系統中,我們怎么表示負數呢?比如說 -2
?既然這是一個環形系統,結合同余來看這個世界會變得極其容易。
根據同余,-2
在這里和14
是同一類!所以我們可以用 14
的機器碼來表示 -2
14
的機器碼是 1110
現在問題出現了,1110
原來就是表示正數的14的,現在又要表示-2。那么當機器給我們這個二進制的時候,我們到底是把它看做14還是-2呢?
我們有一種做法:就是把0
`15`個數分成了兩組,`0`7
的機器碼還是代表原來的0
`7`,`8`15
的機器碼表示了-8
~-1
當我們采用了上述這種分法的時候,歡迎來到補碼的世界。這正是我們現在的計算機世界——補碼世界
我們分別算一下-8
~-1
的關於模16的同余數以及同余數的二進制機器碼
這些表示是不是很熟悉?最高位的 1
表示負號,補碼 1111
轉反碼 1110
轉原碼 1001
= -1
。符號位 1
表示負數,0
表示正數,不是拍腦袋決定的,而是基於同余的思想
說到底,補碼的世界就是同余的世界啊!!!
到這里,我們可以解釋負數在4位系統中的表示了。通過引入了同余,將這個世界中一半的大數轉為了小數對應的負數
3. 8位系統中的減法運算
通過引入同余/補碼,我們可以表示負數,可以只用加法器實現減法運算
在這個補碼/同余的世界里,原生支持減法運算!!!
很容易得到,在8位系統中,mod = 1 0000 0000 = 256
,負數的范圍是-128 ~ -1
,正數是0 ~ 127
來看兩個例子:
「例子1」: 30 - 70 = ?
記住這是一個補碼的世界,我們沒必要管原碼和反碼,讓它們見鬼去吧!!!
30
的補碼是0001 1110
,這個很順利,我們直接轉二進制就行了,因為 30 三 30 (mod 256)
-70
有點波折,因為我們需要知道它占用了哪個同余數的機器碼,256 - |-70| = 186
。它占用了186
的機器碼,也就是 1011 1010
兩個機器碼直接相加得到 1101 1000
。這是補碼!!直接轉是216。但是這個值大於127,我們知道這個數的機器碼被它的同余數-40
占用了
因為256 - |-40| = 216
「例子2」: 100 - 50 = ?
在這里,我們嘗試進入補碼世界,但是不用二進制表示,為了符合我們直觀
記住這是一個環形世界,306
在這個世界和 50
是一類。 306 三 50 (mod 256)
,50
的機器碼並沒有被占用,所以最終的答案就是 50
總結一下上面兩個例子,在8位系統中,模是256。能表示的數是 -128 ~ 127
。超出這個范圍的數都會根據同余被歸到其中的一類
為了說明補碼原生支持減法。我們想象一個8位系統,我們希望它能表示的數的范圍是 -100 ~ 155
現在計算 50 - 30
和 30 - 50
看到了嗎?在這個補碼的世界里,才不管你是怎么分的,分成-128 ~ 127
也好,分成 -100 ~ 155 也罷
,老子天然支持減法運算
4. 帶着補碼武功進入8位系統江湖中
為了幫助你融會貫通補碼這門武功,我決定帶着你闖盪一遍8位系統的江湖。在這里,不用管1
和 0
,二進制也好,16進制也好,思想都是一樣的。
我們再來計算 109 - 9
和 9 - 109
,記住,不要用 1
和 0
的機器碼,我們純用補碼的思想(也就是同余)來搞事
到了這里,是不是覺得補碼也就那么回事了。
現在,你是不是可以自己解決開篇的三個疑問了呢?帶着同余的思想去干掉這三個疑問吧!!