原、反、補碼以及取反操作
一、相關概念
1.1 機器數與真值
·機器數 計算機中儲存的資料都是帶符號的二進位制數,例如:5 → 0000 0101 , -5 → 1000 0101 此類數值稱之為機器數。
·真值 為區別起見,將帶符號位的機器數對應的真正數值稱為機器數的真值。如:1000 0101的形式值為133,但它實際表示的值為-5,-5稱之為真值。
1.2 原、反、補碼
·原碼 符號位加上真值的絕對值。如+5和-5的原碼分別為:0000 0101和1000 0101
·反碼 正數的反碼是它本身,負數的反碼是將它原碼的符號位不變,其餘各位按位取反。 如+5和-5的反碼分別為:0000 0101和1111 1010
·補碼 正數的補碼是它本身,負數的補碼是將它原碼的符號位不變,其餘各位按位取反再加1(其實就是反碼+1)。如+5和-5分補碼分別為:0000 0101和1111 1011
二、為何要用原、反、補碼
2.1 符號位的問題
我們已知正數的原、反、補碼都是相同的,但對於負數來說確是完全不同。在處理加減乘除等運算時,若是人腦來進行,我們可以將符號位抽象出來然後直接操作真值即可。但若交由計算機完成,若還需提前去識別符號位,則會大大增加計算機基礎電路的複雜度,故需要考慮帶著符號位進行計算。
考慮一個1-1的問題:
·原碼計算:1-1 = 1+(-1)= [0000 0001]原 + [1000 0001]原 = [1000 0010]原 =-2 結果顯然不對
·反碼計算:1-1 = 1+(-1)
= [0000 0001]原 + [1000 0001]原
= [0000 0001]反 + [1111 1110]反
= [1111 1111]反
= [1000 0000]原 = -0
從結果來看,真值部分是對的,但0前面出現負號是無意義的。反而會引入1000 0000的機器碼錶示數值0,從而與0000 0000表示的0引起衝突,故而補碼碼應運而生。
·補碼計算:1-1 = 1+(-1)
= [0000 0001]原 + [1000 0001]原
= [0000 0001]補 + [1111 1111]補
= [0000 0000]補
= [0000 0000]原 = 0
可見,使用補碼運算解決了符號位帶入的問題和0的符號問題。值得注意的是,在補碼的運算結果中,[1000 0000]補 代表的數值為-128,但由於該補碼使用的是之前-0的原碼,故-128是沒有原碼和反碼錶示的。有此也可以引申出,8位二進位制值的原碼或反碼的表示範圍為[-127,127],而補碼的則為[-128,127]。
2.2 總結
·數位電路的CPU中僅實現了加法器,為實現減法器,減法都是通過轉換為加法進行計算的。
·負數在計算機中是以補碼的形式儲存的,計算過程也是用補碼實現的。
三、反碼與取反
初學時容易將兩個概念混淆,前面已經提到,計算機中資料的儲存和計算都是以補碼的形式進行的。故取反這一過程也是圍繞補碼展開的,與反碼這一概念並無關係。
看一個+5和-5取反的過程:
+5 = [0000 0101]原 → [0000 0101]補 →按位取反→ [1111 1010]補 → [1000 0110]原 = -6
-5 = [1000 0101]原 → [1111 1011]補 →按位取反→ [0000 0100]補 → [0000 0100]原 = 4
可見,對一個數取反都是先求得該數的補碼,對補碼進行按位取反,然後對結果再求補碼即可。快速計算方法:對數a取反,結果為-(a+1)。