來自:http://icebloods.blog.sohu.com/64118412.html
為敘述方便,先引進兩個名詞:機器數和真值。將一個數在機器中的表示形式,即編碼稱為機器數,將數本身稱為真值。常用的機器數有三種:原碼、補碼和反碼。
1.原碼
1)通俗定義
將數的符號數位化,即用一個二進位位表示符號:對正數,該位取0,對負數,該位取1。而數值部分保持數的原有形式(有時需要在高位部分添幾個0)。這樣所得結果為該數的原碼錶示。
例,x=+1001010,y= -1001010,z= -1110(= -0001110)。當原碼為8位時,x、y和z的原碼分別是:
[x]原=01001010;
[y]原=11001010;
[Z]原=10001110.
其中最高位為符號位。
2)正規定義
其中,x為真值,n為原碼的位元。這個定義實際是將真值的範圍給出來了,當n=8時,-127<x<127,因而,其數值部分寫成二進位形式,最多為7位。從該定義可看出,x為正數時,其原碼還是數本身,第8位(符號位)補0;x為負數時,-x等於去掉負號,但要加上127,即第8位為1(127=10000000(2))。因此,這個定義和上面的通俗定義是一致的。
3)原碼錶示的特點
原碼錶示有三個主要特點:一是直觀,與真值轉換很方便;二是進行乘、除運算方便;三是加、減運算比較麻煩。第一點是顯然的。說原碼錶示進行乘、除運算方便是因為其數值部分保持了資料的原有形式,對數值部分進行乘或除就可得到積或商的數值部分,而積或商的符號位可由兩個數原碼的符號位進行邏輯運算而得到。說原碼錶示進行加、減運算比較麻煩,以加法為例,兩個數相加需先判別符號位,若其不同,實際要做減法,這時需再判斷絕對值的大小,用絕對值大的數減絕對值小的數,最後還要決定結果的符號位。
2.補碼
1)補碼的引進和定義
據統計,在所有的運算中,加、減運算要佔到80%以上,因此,能否方便地進行正、負數加、減運算,直接關係到電腦的運行效率。
如日常生活中的一個例子——指標式鐘錶。現在時針指向11點鐘,要使其指向6點鐘,有兩種方法,一是正撥7個格,二是反撥5個格。如果把鐘錶看成一個計算機,正撥看成加運算,反撥看成減運算,那麼,在鐘錶上有:11-5=11+7,即11+(-5)=11+7。之所以這樣,是因為11+7=12+6,而在鐘錶上,12相當於0,超過12時,12就丟失了。這種運算稱為按模運算。鐘錶的模為12。所謂“模”,是指一個系統的配量,或者說一個系統所能表示的最大的數(確切地說,為最大數時加1)。按模運算是指運算結果超過模時,模丟失。當模為整數時,按模運算也可理解成除以模求餘數的過程。常用符號“mod”表示按模運算。
在電腦中,一個具體資料類型的位元是確定的。例如,位元組型資料為8位,當每一位都為1時,再加1,最高位將產生進位。如果不採取措施,這個進位將被丟失,丟失的量為2^8=256,這就是8位元據的模。從上面的例子已看到,按模運算,可以使正數加負數轉化成正數加正數(11-5=11+7),一個負數可以等價於一個正數(-5等價於+7)。看一下電腦中情況。例如,要將+0001111(15)和-0001100(-12)相加,實際是要做減法,但不這樣做,而是先將-0001100與模10000000(256)相加,得11110100(-12+256=244),再拿原被加數0001111和它(11110100)相加,得00000011(15+244=256+3=3),最高位的進位,即模丟失。
這樣,同樣得到了正確結果。由此可見,在電腦中,只要將負數加模就可以轉化成正數,使正數加負數轉化成正數加正數。
把一個負數加模的結果稱為該負數的補碼(結果是一個正數,它和該負數是等價的,確切地說,是一對一的,因而可看作是該負數的編碼),定義正數的補碼就是它本身,符號位取0,即和原碼相同。這就是補碼的通俗定義。將這個定義用數學形式表示出來,就可得到補碼的正規定義:
其中n為補碼的位元。這個定義實際也將真值的範圍給出來了,當n=8時,-127≤x<127。和原碼相比,補碼錶示可多表示一個數。當n=8時,多表示的數是-127=-128。
2)補碼的求法
對正數,補碼同原碼。例如,x=+0101001,[x]補=[x]原=00101001。對負數,由定義求補碼,需做減法,不方便。經推導可知,負數的補碼等於其原碼除符號位外按位“求反”(1變0,0變1),末位再加1。例如,y=-0001100,[y]原=10001100,[Y]補=11110011+1=11110100。
多做幾例,可得出一種心算求補的方法——從最低位開始至找到的第一個1均不變,符號位不變,這之間的各位“求反”(該方法僅用於做題)。
由求補的方法可以看出,對於補碼,其符號位和原碼的符號匣相同,也表示了真值的符號。
3)補碼的性質
①[x+y]補=[x]補+[y]補,即兩數之和的補碼等於各自補碼的和。
②[x-y]補=[x]補+[-y]補,即兩數之差的補碼等於被減數的補碼與減數相反數的補碼之和。
③[[x]補]補=[x]原,即按求補的方法,對[x]補再求補一次,結果等於[x]原。
4)利用補碼進行加、減運算
引進補碼的目的是方便帶符號數的加、減運算,這裡僅看一下加法,舉幾個例子。請注意:符號位也參與運算,符號位出現的進位為模,應丟棄。下面是三個利用補碼求和的例子。這裡假定機器數為8位。
符號位為0,真值為正,所以,x+Y,=+0001011(2)(+11)。
符號位有進位,自動丟失。符號位為1,真值為負,對[x+y]補求補得[x+Y]原=10001011,由此,x+Y= -0001011(-11)。
符號位有進位,自動丟失。符號位為O,真值為正,所以,x+Y=+0000111(+7)。
上面是三種類型的數的補碼運算:正數+正數、負數+負數、正數+負數。負數+正數和正數+負數是一樣的。由此可見,採用補碼錶示,進行數的加法運算可統一成進行數的補碼加法運算。
上面的例子只是用來說明引進補碼的好處,其運算過程不是電腦的實際過程。在電腦中不必每次都進行原碼與補碼之間的轉換,可以將運算結果以補碼形式儲存起來,以便直接參与後面的運算。
3.反碼簡介
對正數,其反碼與原碼相同,也與補碼相同。對負數,其反碼等於原碼除符號位外,按位求反(末位不加1)。利用反碼也可使帶符號數的加、減法轉化為單純的加法,但麻煩一些。一般把求反碼作為求補的中間過程,即[x]補=[x]反+1。
上面所介紹的機器數編碼主要用於組合語言編程。在進階語言中,數可帶有符號,但編譯器最終還是將其表示成機器數。
slowgrace註:在VB中,負數也是補碼錶示的。比如在立即視窗做如下測試:
?hex(clng(-1))
FFFFFFFF