1. 程式人生 > >原、反、補碼以及取反操作

原、反、補碼以及取反操作

一、相關概念

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)。