計算機組成原理學習(二)原碼,反碼,補碼


數據在計算機中以二進制串存儲,這種01序列叫“機器數”。

每個機器數都有對應的值,比如0001換算就是現實里十進制的1,這個值叫它的“真值”。

 

1.原碼

為了表示負數的前面的符號,一種辦法是采用“最高一位表示符號而非數值”的編碼方式——原碼。

如八位的運算器,機器數0000 0001的真值為1,1000 0001的真值為-1。第一位為符號位,剩下的位表示真值。

解決了符號表示問題,但是引出了新的問題,那就是1000 0001不能按照常識意義上來換算了,按正常二進制轉十進制的換算,1000 0001實際上代表129。

這樣在硬件電路設計時會帶來麻煩,要讓機器能夠先辨識符號位,再進行真值的計算。

 

2.反碼

任何減法都可以轉化為加上一個負數,如 1+1 = 1+(-1)。做加法比減法簡單,要是能用一種新的編碼方法把-1表示出來,然后和+1做加法,最后結果按照這種編碼方式還是正確的,那就太好了。於是為了讓符號位也能參與計算,反碼誕生了。

反碼的表示方法基於原碼,最高位仍然是符號位。正數的反碼是其本身,負數的反碼符號位不變,剩下的位全部取反

+1 原碼0000 0001,反碼 0000 0001

-1 原碼1000 0001,反碼1111 1110

人們發現,采用這種編碼方式,算出來的值是正確的。

用反碼計算:

1-1 = 1+(-1) = 0000 0001 + 1111 1110 = 1111 1111

而1111 1111的反碼是1000 0000,即 -0。

采用反碼的編碼方式看似解決了符號位參與運算的問題,但仍存在一個明顯的問題,那就是0的表示不唯一

0000 0000代表 +0,1000 0000代表 -0,這是自原碼就有的問題,是沒有意義的。

你會發現——

用原碼表示,8位表示的機器數的范圍是 [1111 1111, 0111 1111]即[-127,127]。

[-127,127]按現實意義理解的話其實只有255個數,而8個位能理論上表示2^8 = 256個數,少掉的那一位就是用來表示0的正負號了。

 

3.補碼

人們希望有一種更好的編碼方式,既能解決符號參與運算的問題,又能讓0的表示唯一,由此誕生了補碼。

補碼是一種基於取模同余的模運算系統的編碼方法,這樣說有點復雜,實際上用鍾表來理解很容易。

時鍾的最上方從0開始,順時針依次為1,2,3……直到12。12同時也是0,時鍾表示了0到11總共12個數。

 

 

在這個系統中,計算這一行為就可以抽象為撥動指針。

比如我想做加法計算,如1+1,自然等於2,那也可以理解為:指針在1,我順時針撥一格,停在了2。減法運算1-1,就是時針在1,逆時針撥一格,結果為0。

加法就是順時針,減法就是逆時針,最后指針停在的位置就是結果。

那么,從6撥到4,有兩種撥法,要么順時針撥10格,要么逆時針撥2格(當然順時針撥22格也是可以的,也就是多轉一圈)。即 6+10 和 6-2 的結果是等價的。或者說在一個計算式中, +10 和 -2 是等價的。

6 + 10  = 16,6 - 2 = 4,何以等價呢?只要讓:16對12取模(16除以12得出的余數),結果就是4了。

該規律對於系統內的任何加減運算都是適用的,通過取模同余的方式,把減法轉換成了加法,即 -2 可以通過 +10 再對 12 取模來計算

-1 = +11 mod 12

-2 = +10 mod 12

-3 = +9 mod 12

不難發現,左邊負數的絕對值和右邊整數的和總是12,時鍾是一個模12運算系統。

我們稱 -1 的補碼是 +11 、-2 的補碼是 +10、-3的補碼是+9,即一個負數的補碼模運算系統的模減去它的絕對值

有了補碼的概念,1-1 的意思就可以轉述為 1 加上 1 的補碼,即正數減去負數的計算,轉化為該正數加上負數的補碼。

 

4.補碼的深入

一個負數的補碼 = 模運算系統的模減去它的絕對值

照這么說,一個4位的運算器可以表示 2^4 = 16 個數,把它視為一個模16運算系統的話——

4位運算器負數的補碼 = 16 - 該負數的絕對值

那么設有一個負數 -x,上式就轉化為:

-x[補] = 2^4 - x

舉個例子,-1的補碼就是16-1 = 15,15表示為機器數就是1111。-2的補碼是14,表示為機器數就是1110。-8的補碼是8,表示為機器數就是1000。

按照這種編碼方式,把4位模運算系統表示的16個機器數,也畫成一個時鍾的樣子,如下。

 

16個數划分為了兩半,一半表示正數(0算在內),一半表示負數。

頂頭0000代表0,底下1000代表-8。0001到0111表示了0到7。1000到1111表示了-8到-1。

可以看到,0的表示是唯一的。

另外,假如有一減法,4 - 4。

4 - 4 = 4 + 4[補] = 4 + (2^4 - 4) = 4 + 12 = 0100 + 1100 (機器數)  = 0000

0100 與 1100 相加的結果是 1 0000,因為是4位運算器,最高一位會被舍去,保留下來的就是0000即0。

可見,補碼的編碼方式不僅解決了0表示不唯一的問題(多出來的一位還能多表示一個負數),還方便了硬件的設計(把減法轉化為加法),解決了符號參與計算的問題。故現代計算機普遍采用補碼的編碼方式。

 

一樣不難發現,划分成了正數一半(0算在內)、負數一半,最高一位其實仍然表示了符號

1000之前都是正數,除去最高位的后三位表示了機器數的真值,從1000開始變成負數,這是和原碼反碼一樣的特性。

 

綜上,因此有兩個結論。

 

1.假設有n位運算器,負數 -x 的補碼

-x[補] = 2^n - x

減法的計算,等於加上負數的補碼。

 

2.機器數的最高一位指示了正負號,0為正,1為負,同時也就划分了正數一半(包括0),負數一半。

假設有n位運算器,它用補碼表示的數據范圍

[-2^(n-1), +2^(n-1)-1]

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM