補碼的產生與應用

有興趣的同學可以移步筆者的個人博客 更多博客

基本概念

在計算機中,二進制數據有三種形式:原碼、反碼和補碼,要弄清楚補碼的意義,首先讓我們來了解三種形式的定義。

假設字長爲4,其中最高位爲符號位:正數爲0,負數爲1。剩下的3位表示該數的絕對值。
正數的原碼反碼補碼都是一樣的。

1.原碼

+3的原碼:0011

-3的原碼:1011

2.反碼

反碼就是在原碼的基礎上,符號位不變其他位按位取反(就是0變1,1變0)就可以了。

+3的反碼:0011

-3的反碼:1100

3.補碼

補碼也非常的簡單,就是在反碼的基礎上按照正常的加法運算加1。

+3的補碼:0011

-3的補碼:1101

從前面的三種數字編碼類型的定義,我們可以看出數據的原碼,使用符號位來區分了正負數,更加符合人腦直觀識別並且用於計算的表達方式。但是在計算機中,是通過補碼的形式保存數據,下面將解釋爲什麼計算機系統要用補碼存放數據。

週期系統

若一組事件或現象按同樣的順序重複出現,則把完成這一組事件或現象的時間或空間間隔,稱爲週期。

週期性原碼累加系統

定義一個字長爲4的二進制累加系統,該系統的規則就是從左到右依次累加0001;

0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 0000
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0

如果最高位是符號位時,圖表第二行表示原碼對應的10進制數,不難發現,如果在確定字長爲4時,累加過程是符合週期性變化的,原因就是當1111+1時會出現字節溢出的情況,10000的最高位溢出失效,導致結果變爲0000;

週期性時鐘系統

在這裏插入圖片描述
在現實生活中,時鐘顯然是符合週期性的,12點過後是1點,人們早已習慣了這種思維方式,所以會忽略對時鐘這種表示時間方式的思考。凌晨12點加1個小時,其實表式的時間是天數加1之後的1點,但是對於時鐘系統而言,天數不是自己所能表示的,這就相當於上面圖表中1111+1=0000(1|0000 1是溢出位,在字長爲4的系統中是不能表示的)。

時鐘系統和二進制數原碼的累加系統都有週期性,具有週期性的原因是當前層次系統中有其不能表示或未能感知的其他層次系統。

計算機運算系統正是利用了週期性的這一特性。

週期系統中的加減轉化

時鐘系統加減法轉化

假設時針向順時針方向撥動爲加,逆時針撥動爲減。

7點順時針撥動1格表示的是:7+1=8

7點逆時針撥動1格表示的是:7-1=6

7點順時針撥動11格表示的是:7+11=6

所以很容易發現,在時鐘中7-1=7+11,這就是週期系統中加減法發的轉化方式,其實和簡單,也很符合我們的直覺。

所以重新考慮原碼的減法問題,n-m = n+(MAX-m),其中MAX就是該週期中所能表示的所有數的數量,放到上面原碼的例子中就是16個,而放到時鐘系統中就是12個。如:

週期性的時鐘系統:

12 - 1 = 12 + (12 -1);

7 - 4 = 7 +(12-4);

累加系統加減法轉化

在說原碼累加系統加減法轉化例子之前,我們再看下圖表

A 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 0000
A1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0
A2 0 1 2 3 4 5 6 7 -0 -1 -2 -3 -4 -5 -6 -7 0
B 0000 0001 0010 0011 0100 0101 0110 0111 1111 1110 1101 1100 1011 1010 1001 1000 0000
B1 0 1 2 3 4 5 6 7 -7 -6 -5 -4 -3 -2 -1 -0 0
B2 0 1 2 3 4 5 6 7 -8 -7 -6 -5 -4 -3 -2 -1 0

爲了方便說明在每一行的開始定義了該行的名稱分別爲A、A1、A2、B、B1、B2.

累加系統不同於週期系統的一點是會有負數的概念出現,A2行就是最高位表示符號位時原碼解碼後表示的十進制數。在圖表中發現,當有符號位時二進制原碼的累加轉換爲十進制數時,出現了與我們現實生活數學公理相違背的現象,錯誤發生在最高位爲1後,如1001+1=1010(-1+1=-2),原因是在定義這個累加系統在運算時就沒有讓系統知道高位0與1有不同之處,也就是累加的計算過程中無法感知符號。

解決問題的方式有兩種

  1. 去重新完善這個累加系統,讓他在最高位爲1換一套計算方式,也就是說在運算過程中去感知最高位的意義。
  2. 轉化出現問題的狀態,使狀態轉移爲當前系統能使用的,也就是在編碼過程中去讓無法感知符號的運算系統計算出正確的結果。

在計算機系統中,解決這個問題的方式顯然是用第二種,cpu是無法感知符號位的,這樣做可以減少cpu設計難度,極大地提高運行效率。

所以也就是說cpu運算時還是按照A行進行累加,但在解碼運算結果時做一些處理,即將A轉變爲B,而B1是不考慮溢出和臨界值時的十進制正確結果。A解碼爲B的算法就是當最高位爲1時,符號位不變,其他位取反,不難發現這就是反碼的定義。

當這樣轉化後會發現出現了0和-0兩個0並且會出現0 - 1 = -0這種情況(將0向左移動)。所以還得做一個簡單的處理,就是去加一個1,也就是B1轉化爲B2,而B2就是最終的正確十進制值。

其實按照直覺可以發現,當符號位轉化時,其他位應該取反才能得到正確結果,正數越加越大,負數越加越小。

根據我們的努力將A通過反碼的解碼方式轉變爲B,而讓B的解碼結果加1(補碼),得到了B2,從而使累加系統當出現負數時變得合理起來。在轉變爲B2之後,我們需要解決的是如何用累加系統去表示減法。本質上和前面的時鐘系統轉化是一樣的。可以藉助上面的時鐘系統以及下面的例子去理解累加系統的減法運算。

在看例子之前,稍微介紹一下“模” 的概念:
模是指一個計量系統的計數範圍,取模運算實質上是計量器產生“溢出”的量,前面的週期系統中n-m = n+(MAX-m)得出的加減轉化其實就是用到了模的概念,MAX就是模。

計算 4 - 3

  1. 編碼 0100 - 0011

//n-m = n+(MAX-m) ==》(10000-0011) 其結果就是0011的補碼

  1. 轉化爲 0100 + (10000-0011) = 0100 + 1101

  2. cpu調用加法器得出 10001

  3. 最高位溢出 0001

  4. 解碼 1

重新計算 3 - 4

  1. 編碼 0011 - 0100

  2. 轉化爲 0011 + (10000-0100) = 0011 + 1100

  3. cpu調用加法器得出 1111

//參考A轉變B2(也就是原碼轉補碼)

  1. 解碼-0001= -1

總結

在計算機系統中,計算整數加減法時,需要經過以下步驟:

  1. 轉變爲2進制數;

  2. 運算時原碼解碼爲補碼;n-m = n+(MAX-m),(MAX-m)也就是m的補碼,理解時參考時鐘系統。

  3. cpu調用加法器;

  4. 解碼;再進行一次補碼解碼,理解時參考A轉化爲B2。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章