首頁  >  文章  >  計算機中的負數為什麼要用補碼儲存?

計算機中的負數為什麼要用補碼儲存?

青灯夜游
青灯夜游原創
2020-12-08 10:34:4813808瀏覽

計算機中負數使用補碼儲存可以簡化計算機基本運算電路,使加減法都只需要用加法電路實現,用加法取代減法。補碼是負數的最小正同餘數,所以加一個負數和減一個正數都可以用加一個補碼來表示。

計算機中的負數為什麼要用補碼儲存?

本教學操作環境:windows7系統、Dell G3電腦。

1.引子

你知道電腦中以什麼形式儲存整數嗎?是符號位加值位嗎?值位元是按照正常的二進位方式儲存嗎?

如果後兩個問題你都回答是,那就表示當用3位二進位進行儲存、且符號位0表示正1表示負時,1會儲存成001 ,-1會儲存成101。可惜事實不是這樣,計算機中是用補碼的形式而不是剛剛那種看上去很自然的形式存儲整數,補碼雖然也是用符號位加值位來表示,但表示的規則不太一樣:1會存成001,-1會存成111

如果三個問題你都回答對了,你知道計算機中整數以補碼的形式存儲,但你知道為什麼要用這種形式嗎?以及「正數的補碼等於原碼;負數的補碼等於反碼加1,而反碼等於原碼符號位不變,其餘各位取反」這樣的補碼到底意味著什麼? (假設你不知道,請接著往下看吧XD)

先看使用補碼的目的,然後忘掉上面那個補碼定義,跟我從這個目的開始,一步步探索補碼的本質。
目的:為了簡化計算機基本運算電路,使加減法都只需要透過加法電路實現,也就是讓減去一個正數或加上一個負數這樣的運算可以用加上一個正數來代替。於是改變負數儲存的形式,儲存成一種可以直接當成正數來相加的形式,這種形式就是補碼。 (正數不用變,所以接下來的討論中一般略去正數)

2.補碼是怎麼把減法變成加法的?

2.1.用時鐘理解減法變加法

這是一個身邊的例子,當你校對時鐘的時候,假設發現鐘是6點,但實際上現在才2點,也就是它走快了4個小時,你可以有兩種方法進行校正,一種是逆時針撥回4個小時到2點,另一種是順時針撥6小時到12點再撥2小時,也就是順時針撥8小時到2點。所以對於時鐘的錶盤來說,設-N表示逆時針撥N個小時,N表示順時針撥動N個小時,那麼-4 = 8,同樣還會有 -1 = 11-5 = 7,甚至可以 -4 = 8 = 20 = 32 = -16. ..

這裡邊隱藏了什麼規律?其實在數學中,-4、 8、 20、 32、-16可以歸類為符合某個條件的相同類別數字 —— 對於模12同餘

中文維基上對於模和同餘的定義是:兩個整數a、b,若它們除以正整數m所得的餘數相等,則稱a、b對於模m同餘。

而在一個可溢出計數系統中,把計數系統容量當作模,那麼所有對此模同餘的數在此計數系統中都會有同樣的表示,而且運算等價。
例如上面範例中的時鐘錶盤就是一個可溢出計數系統,模為12,所以-4、 8、 20、 32、-16這些對模12同餘的數在時鐘錶盤上的表示法是一樣的,而且對時針做這些操作的結果也是一樣的,都會撥到同樣的位置。

一個n位二進位構成的計數系統,因為會捨棄溢出的高位,所以也是一個可溢出的計數系統,它的模為\(2^n\) 。 (從0數到\(2^n -1\),再多就溢出)
由此可以推理,在一個3位二進位構成的模為8的計數系統中,-2,- 10,6,14可以用同樣的二進位數來表示,同時減10和加14會得到一樣的結果。

2.2.引出補碼

所以,只要補碼是負數的正同餘數,那麼就能實現加這個正同餘補碼跟加另一個負數是一樣結果的效果。對一個負數來說,有無數個正同餘數滿足條件,為了減少不必要的運算,可以規定補碼就取其中最小的正數。

可能因為透過原碼求 補碼 是一個補模運算,所以它被稱為 補碼 。

注意,這裡的補碼都被我用特殊標識,因為這還不是計算機裡真正的存儲的補碼形式,它應該叫補數,不過相信我,已經很接近了

3.完善補碼

3.1.這種補碼表示還有點問題

透過轉換成補碼,減一個數確實變成加一個數了,看似很不錯,但卻有一個明顯的問題,那就是數本身的符號丟失了。
例如3位元二進制,正常表示0~7,使用補碼法它能取代-8~-1的運算,但它不能真正表示- 8~-1,因為你不知道它到底是正數還是負數。
我們把負數轉換成了一種在運算中更讓電腦喜歡的形式,但它卻失去了自己本身作為數的資訊。

怎麼解決這個問題,可能有人很快就會拍腦袋:那就加一位來表示正負得了。但這樣的話運算時怎麼辦,從第二位開始算麼?那進位去位的時候是不是也需要特別注意一下不要影響到符號位?你會發現這個問題並不是那麼簡單。

3.2.怎麼完善補碼

#不知道大牛怎麼想到的,問題解決得非常完美:

  • 在維持補碼特性的前提下 (也就是減數還是照樣變成加一個數)
  • 增加正負的表示 (能真正表示-8~-1了,只用看符號位是0還是1)
  • 還能讓運算時不用另外區分符號位,直接把符號位當成值位進行運算,而結果的正負號自然會符合這個正負表示法(也就是符號位的進位和值位的進位都會自然地合理)

而且解決方式真的皮,簡單到出人意料,就是前面你拍腦袋想到的辦法:加上一位來表示正負
具體做法是:在左側高位增加一個符號位,這個符號位連同前面我們推演出的 偽補碼​​ 一同構成真正完善的補碼
實現的效果:透過讀取符號位能得知數的正負,同時符號位元在加法運算中跟值位元一樣參與運算、進位、退位。

4.最後

總結一下

  • #使用補碼的目的:簡化電腦基本運算電路,使加減法都只需要用加法電路來實現,用加法取代減法。
  • 補碼為什麼能達到這個目的:n位元二進位可以構成一個可溢出計數系統,在這樣的系統中,把計數系統容量當作模,所有對此模同餘的數在此計數系統中都會有同樣的表示,而且運算等價。而補碼就是負數的最小正同餘數,所以加一個負數和減一個正數都可以用加一個補碼來表示。
  • 怎麼計算補碼:正數的補碼是它本身;對負數求最小正同餘數(模為值位的容量)放入值位,符號位置為1 ,得到負數的補碼。

想要查閱更多相關文章,請造訪PHP中文網! !

以上是計算機中的負數為什麼要用補碼儲存?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn