1. 程式人生 > 其它 >原碼、反碼、補碼--計算機中為什麼使用補碼

原碼、反碼、補碼--計算機中為什麼使用補碼

原因在於,使用補碼,可以將符號位和數值域統一處理;同時,加法和減法也可以統一處理。此外,補碼與原碼相互轉換,其運算過程是相同的,不需要額外的硬體電路。
補碼是現代計算機使用的編碼格式,解決了反碼的兩個缺點。正數的補碼與原碼格式相同,負數的補碼是將負數絕對值的原碼分別按位取反,並加1,

 

目錄

知識梳理:原碼、反碼、補碼的基礎概念
問題一:.為什麼有補碼?
問題二:.補碼中將減法轉化為加法後面的數學原理。
問題三: 為什麼補碼的表示範圍比原碼的表示範圍大一位?
問題四:為什麼1000 0000表示 -128?
問題五:為什麼在計算補碼的時候要取反?還要加一?

原碼、反碼、補碼的基礎概念

原碼:
定義:就是一種計算機中對數字的

二進位制定點表示方法。它的表示方法就是最高位表示符號位,1代表負,0代表正。
比如:1(原碼)= 0000 0001
-1(原碼)= 1000 0001
反碼:
定義:正數的反碼等於它本身;
負數的反碼就是負數的原碼在符號位不變的基礎上,其餘各個位取反;
+1 = 0000 0001(原)= 0000 0001(反)
-1 = 1000 0001(原)= 1111 1110 (反)
補碼
定義:正數的補碼是它本身;
負數的補碼是它的反碼再+1;
+1 = 0000 0001(原)= 0000 0001(反)= 0000 0001(補)
-1 = 1000 0001(原)= 1111 1110 (反)= 1111 1111(補)
負數在計算機裡面的儲存方式一般都是以補碼的形式存在的。

問題與思考

問題一:.為什麼有補碼?
其實就像數學中的四則運算一樣,你可以把補碼看成是用加法代替減法,比如你現在減去一個數,其實你就是加上這個數字的相反數,也就是說+(-數字),這樣的話,在計算機中,就可以用加法表示減法了,一個數字和他的相反數相加的話,那麼就是等於零。這就好比如,一個時鐘,現在是6點鐘整,你要讓它去到8點鐘整,你的做法就有順時針撥 2 小時,或者逆時針撥 10 個小時,所以說使用補碼可以將減法簡化為加法,但是具體是怎麼簡化的呢?

問題二:.補碼中將減法轉化為加法後面的數學原理。
首先,我們來了解一下模的概念,“模”是指一個計量系統的計數範圍,比如時鐘的模就是12,如果超過12,那麼就會溢位,導致進位,這裡我們不先不討論進位,13在12進位制裡面溢位了1個12單位,也就是從0時撥13個小時,時針會回到1時。為此我們記作 13 mod 12 = 1,
mod是指取模操作, 13 mod 12 = 1 即用13除以12後的餘數是1.
所以鐘錶往回撥(減法)的結果可以用往前撥(加法)替代!
現在的焦點就落在瞭如何用一個正數, 來替代一個負數. 上面的例子我們能感覺出來一些端倪, 發現一些規律. 但是數學是嚴謹的. 不能靠感覺.

首先介紹一個數學中相關的概念: 同餘
取兩個整數,a,b,若它們除以整數m所得的餘數相等,則稱a,b對於模m同餘。
記作 a ≡ b (mod m)
讀作 a 與 b 關於模m同餘。

例子:
1.正數:
5 mod 12 = 5
17 mod 12 = 5
29 mod 12 = 5
2.負數:
這裡介紹 m = k * n + r (0<r < n) , m是被除數,n是除數,r是餘數。
比如:-3 / 2 餘數為多少?
-3 = 2 x -2 +1 可得,餘數為 1 。

介紹完如何同餘定理後,我們回到用加法代替減法的原理上面。

前撥兩個小時 = 回撥 10 小時
前撥三個小時 = 回撥 9 小時
前撥四個小時 = 回撥 8 小時

同樣的在數學上面

2 mod 12 = 2
10 mod 12 = 2

2和10是同餘的,下面引用同餘定理的線性運算定理,
如果:
a = b (mod m ) , c = d (mod m)
(1) a ± c = (b ± d ) (mod 12)
(2 ) a x c = (b x d ) (mod 12)
定理證明過程:https://baike.baidu.com/item/%E5%90%8C%E4%BD%99%E5%AE%9A%E7%90%86/1212360?fr=aladdin
現在有:
-2 ≡ 10 (mod 12 ) = 10
7 ≡ 7 (mod 12)
運用線性運算定理:
7-2 ≡ 7 + 10 (mod) = 5,這裡我們就將減法轉化為加法了。

問題三: 為什麼補碼的表示範圍比原碼的表示範圍大一位?
從百度上搜索到的這張圖,可以明顯的看到,補碼的表示範圍比原碼多了一位,而且是為負數(就是-2^n)。
從圖中可以看到,原碼之中有兩個0的表示方法,一個是+0,另一個是-0,但是到了補碼裡面,0的表示方法只有一個,也就是說補碼取消掉了一個零的表示方式,零的表示方式(1000 0000)也就交給了負數。
問題四:為什麼1000 0000表示 -128?
根據問題二還有問題三,我們可以瞭解到,同餘定理還有補碼的表示範圍比原碼還要多出一位,多出來的一位給我了負數,由於原碼1000 0000表示128,128和-128 關於模256同餘,所以-128和128沒有區別,但是在補碼裡面,符號位1表示負數,所以這裡1000 0000表示-128.

問題五:為什麼在計算補碼的時候要取反?還要加一?

讓我們來想想前面說的補碼的作用,就是將減法轉化為加法,在數學上面就是轉化為他的相反數?一個數本身加上相反數會等於多少呢?沒錯就是0,那麼同樣的,原碼加上他的補碼還是會等於0的,比如 0000 0001(1) + 1111 1111(-1) = 0000 0000(0),那麼我們就有這一道等式,
對於一個數,補碼 + 原碼 = 0,補碼 = 0 - 原碼。
對於0 = 我們上面幾行文字說, 0000 0001(1) + 1111 1111(-1) = 0,那麼就可以將這一道式子進行等價代換:
對於一個數:補碼 = 1111 1111 + 0000 0001 - 原碼。
移項後有: 補碼 = 1111 1111 - 原碼 +0000 0001
對於 1111 1111 - 原碼 = ?大家可以自己算算,結果其實是這個數的反碼,(反碼就是全部取反)
例如:
對於1: 1111 1111 - 0000 0001 = 1111 1110
對於2: 1111 1111 - 0000 0010 = 1111 1101

大家可以自行運算,這就是反碼的由來,
補碼 = 1111 1111 - 原碼 +0000 0001
根據公式,可以寫成:
補碼 = 反碼 (1111 1111 - 原碼 )+0000 0001
這就是表示補碼的時候,反碼還要 + 1 .