給定數據類型的補碼錶示,不能簡單的用取反加一的方法來求反碼的,介紹下2的補碼系統


首先聲明常用的幾點,想了解更多詳細內容讀完全文(包括二進制補碼系統的簡單介紹):

1,

表示一個數值要先說明是用多少bit,例如:
用8bit表示數值時,(-128)沒有相對應的原碼和反碼, (-128)補碼 = (1000  0000) 
同理(2B=16bit)表示:(-32768)補碼=(1000  0000  0000  0000),後面回給出證明,
因爲它是不能簡單的用取反加一的方法來求反碼的。

2,

證明:用(2B=16bit)表示:(-32768)補碼=(1000  0000  0000  0000)

(1)32767(正數補碼與原碼相同)是0111  1111  1111  1111
(2)-1的補碼,其原碼取反在加一得 1111  1111  1111  1111
(3)0111 1111 1111 1111+1000  0000  0000  0000=1111 1111 1111 1111
(4)(令上式x==1000  0000  0000  0000)即:32767+x=-1
(5)x=-32768


至於用(2B=16bit)表示,取反加一求(-32768)的補碼,還望哪個高手指點簡單的證明過程。
希望大家以後在被問爲什麼(-128)補碼 = (1000  0000),
(-32768)補碼=(1000  0000  0000  0000)不要在說什麼取反加一的話,
那樣你證明我看看。給出證明,免得人家不明白還以爲你在談什麼高深的話題,
結果卻是被忽悠了。

3,

下面舉例說明求負數的補碼的補碼

-1的補碼是0xFFFF. 它是這樣求的:

-1的原碼:        1000  0000  0000  0001 ,
數值位按位求反:       0xFFFE==1111 1111 1111 1110,
末位加1:           0xFFFF==1111 1111 1111 1111

現在還按這個補碼的求法, 作用在0xFFFF上,
0xFFFF  :          1111 1111 1111 1111
數值位按位求反:       1000  0000  0000  0000
末位加1:           1000 0000 0000 0001,

這樣又得到了-1。

就像求負數的絕對值,彼此導來導去都可以。

***************************************************************************

***************************************************************************

補碼的計算和引進補碼的原因:

數值有正負之分,計算機就用一個數的最高位存放符號(0爲正,1爲負).
這就是機器數的原碼了.假設機器能處理的位數爲8.即字長爲1byte,
原碼能表示數值的範圍爲(-127~-0 +0~127)共256個.
有了數值的表示方法就可以對數進行算術運算.
但是很快就發現用帶符號位的原碼進行乘除運算時結果正確,
而在加減運算的時候就出現了問題,如下: 假設字長爲8bits

( 1 ) 10-  ( 1 )10 =  ( 1 )10 + ( -1 )10 =  ( 0 )10

(00000001)原 + (10000001)原 = (10000010)原 = ( -2 ) 顯然不正確.

因爲在兩個整數的加法運算中是沒有問題的,於是就發現問題出現在帶符號位的負數身上,
對除符號位外的其餘各位逐位取反就產生了反碼.反碼的取值空間和原碼相同且一一對應. 
下面是反碼的減法運算:

( 1 )10 -  ( 1 ) 10=  ( 1 ) 10+ ( -1 ) 10=  ( 0 )10

(00000001) 反+ (11111110)反 =  (11111111)反 =  ( -0 )  有問題.

( 1 )10 -  ( 2)10 =  ( 1 )10 + ( -2 )10 =  ( -1 )10

(00000001) 反+ (11111101)反 =  (11111110)反 =  ( -1 ) 正確

問題出現在(+0)和(-0)上,在人們的計算概念中零是沒有正負之分的.




於是就引入了補碼概念. 負數的補碼就是對反碼加一,而正數不變,正數的原碼反碼補碼是一樣的.
在補碼中用(-128)代替了(-0),所以補碼的表示範圍爲:(-128~0~127)共256個.已知某數的補碼,
先求某數的反碼,然後在對反碼+1,就得到某數的原碼.比如:
已知某個數的補碼是:10100110
先對10100110求反,得:11011001
再對11011001加1,得: 11011010
那麼這個數爲-86

原碼錶示的範圍爲:-(2^(n-1)-1)~+(2^(n-1)-1),
反碼錶示的範圍爲與原碼一樣.
補碼錶示的範圍爲:-2^(n-1)~+(2^(n-1)-1),
其中n爲機器字長。

注意:
0的補碼是唯一的,爲0000,0000    [+0]補=[-0]補=0000,0000    -0的反碼爲1111,1111
8bit表示數值時(-128)沒有相對應的原碼和反碼, (-128) = (10000000)  

補碼的加減運算如下:
( 1 ) 10-  ( 1 ) 10=  ( 1 )10 + ( -1 )10 =  ( 0 )10

(00000001)補 + (11111111)補 =  (00000000)補 = ( 0 ) 正確

( 1 ) 10-  ( 2) 10=  ( 1 )10 + ( -2 )10 =  ( -1 )10

(00000001) 補+ (11111110) 補=  (11111111)補 = ( -1 )  正確

所以補碼的設計目的是:

⑴使符號位能與有效值部分一起參加運算,從而簡化計算機的運算規則.

⑵使減法運算轉換爲加法運算,進一步簡化計算機中運算器的線路設計

所有這些轉換都是在計算機的最底層進行的,而在我們使用的彙編、C等其他高級語言中使用的都是原碼。
看了上面這些大家應該對原碼、反碼、補碼的知識印象更深了吧!!

**************************************************************************

**************************************************************************

下面介紹2的補碼記數法


圖1顯示了兩個完整的2的補碼系統:一個是基於長度爲3的位模式,
另一個是基於長度爲4的位模式。
這種系統的構造方法是:從相應長度的0的串(例子中用3位和4位)開始,
用二進制記數的方式一直記數到位模式是由一個0後面跟隨儘可達到的數目1組成(列中是011和0111)爲止。
這些位模式表示值0,1,3,…。表示負數的位模式是通過從相應長度的1的串開始,然後用二進制倒記數的方式記數,
一直到位模式是由一個1和隨後儘可能達到的數目0所組成爲止。
這些位模式表示值-1,-2,-3,…。
如果這種倒記數的方法使用時太困難,也可以從表最底部的位模式開始,
向上記數。即從由一個1和隨後儘可能達到的個數0組成的位模式開始一直到全
由1組成的位模式爲止。

圖一貼圖01



注意:在2的補碼系統中,一個位模式最左邊的位指示被表示數值的符號。因此,最左邊的位被稱爲符號位。
負值是用符號位爲1的位模式來表示,非負值是由符號位爲0的位模式來表示。
    在2的補碼系統中,表示相同幅度的正負值的模式之間存在着簡便的關係。從右至左讀位模式,直到包括第一個1時,
它們是等同的。繼續讀位模式,則相互之間就互補了(一個模式的補是由模式中的所有的0變爲1、所有的1變爲0而得到,
0110和1001是互補的)。例如,圖1的4位長模式中表示2和-2的模式都是以10結束,但是表示2的模式是以00開始,
而表示-2的模式以11開始。這個觀察引出了表示相同幅度的正值和負值的位模式之間進行相互轉換的一個算法,
即對原位模式從右向左逐位拷貝直到有一個1被拷貝爲止,然後對原位模式中餘下來的部分求補,把求補結果做拷貝,如圖2所示。

圖2貼圖1

在熟悉了2的補碼系統的這些特性基礎上便可引出對2的補碼錶示形式解碼的算法。如果待解碼的位模式有爲0的符號位,
該位模式就好像是二進制表示形式,只需直接讀出它的值。例如,0110表示值6,因爲0110是6的二進制表示形式。
如果待解碼的位模式符號位爲1,則表示是個負值,並且所有餘下的部分表示數值的大小。其做法是:從右向左拷貝原位模式,
直到有一個1被拷貝爲止,然後對原位模式中餘下來的部分求補,最後把所得到的模式當做是二進制表示形式進行解碼。
例如,解碼模式1010,因爲符號位爲1,則表示的是個負值。因此,將這個模式轉換爲0110,此模式代表6,從而得出原來的模式表示-6。
(2) 2的補碼記數法中的加法
要加由2的補碼記數法表示的數值,除了所有的位模式包括答案在內,都運用了與二進制加法相同的算法。
這就意味着在2的補碼系統中進行加法時,最後的進位在答案的左端產生的附加位一定要捨去。於是,加0101和0010得0111;
加0111和1011結果是0010(0111+1011=10010,捨去最左邊的1,結果爲0010,長度保持4位)。根據這種理解,
考察圖3中的三個加法問題。在每一種情況中,已經把問題轉換成2的補碼記數法(使用4位長的位模式),執行前面描述的加法過程,
並且將結果解碼返回到常用的基數10的記數法。

貼圖3貼圖3

採用2的補碼記數法的機器需要知道的只是如何去加和求反就夠了。例如,減法問題7-5與加法問題7+(-5)是相同的。
因此,如果機器被請求從7(存儲爲0111)中減5(存儲爲0101),它首先將5改變爲-5(表示爲1011),
然後執行0111+1011的加法過程取得0010,它表示2。

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