1的補碼及2的補碼

2022-09-17 02:03:11 字數 3643 閱讀 8525

一、計算機的負數表示

二、1的補碼one's complement——反碼

三、2的補碼two's complement——補碼

資料在計算機中由乙個乙個的0,1位元表示,所以在表示負數的時候,不能直接新增符號'-'來表示這是個負數,必須採用一些規範或者約定來區分正數和負數。

有四種比較有名的表示負數的方法:原碼(sign-and-magnitude),1的補碼(one's complement),2的補碼(two's complement),以及excess-k(即offset binary)。

1、特性

1的補碼比較簡單,它在表示負數的時候簡單把該負數的絕對值(即相應的正數)的二進位制位全部反轉。比如1用0000 0001表示,那麼-1就用1111 1110表示。

比較有意思的是由於+0用0000 0000表示,反轉後1111 1111就表示-0。所以在1的補碼裡有兩個零。

binary value

ones' complement interpretation

unsigned interpretation

00000000+00

0000000111

⋮⋮⋮01111101

125125

01111110

126126

01111111

127127

10000000

−127

12810000001

−126

12910000010

−125

130⋮⋮⋮

11111101

−2253

11111110

−1254

11111111

−0255

from

以上表舉例來看:(-1)+1 = 0,對應的1的補碼加法

0000 0001 ——-1

+1111 1110 ——1

*****====

1111 1111——-0

由於負數都是由相應的正數二進位制位全反轉得到的,所以這裡有個特性就是把它們相加的話會得到乙個二進位制位為全1的數,在1的補碼的表示方法中,全1表示-0。這也是為什麼這種表示方法叫做"1的補碼"。1的補碼在ip,tcp,udp,icmp等協議頭中應用於計算校驗和。

還有一點很有意思的是,在1的補碼表示的數中,所有的正數最高位元都是0,而所有的負數最高位元都是1。而且它的正最大值是127,沒有向上加過去表示128。在我們平常來看,最高位表示符號位0代表正,1代表負是極為正常的事。但是在1的補碼裡,沒有設定符號位,之所以造成這樣的"巧合",存在著一定的必然性。我們假設它能表示到128,即1000 0000,那麼-128就表示成0111 1111,可是0111 1111已經用來表示127了,這就造成了衝突。其實問題很簡單,我們可以把最高位的0,1看作是字首碼,用這位字首碼保證對正數的反轉操作不存在衝突。這也是為什麼正數最大只能表示到127。

更有意思的是,國內將1的補碼翻譯成反碼,其求負數的反碼時,"保留符號位,將其餘的位元進行反轉"。但是這樣就不能解釋為什麼有-0的存在。更不能解釋在ip,tcp,udp,icmp協議頭里求校驗和時所謂的"反碼求和"是怎麼回事。

想象有一根數軸,兩端分別向正無窮和負無窮延伸,從中間0的位置一刀劈下去(0有兩個),分成非負和非正的兩半。

這根軸看起來很對稱。

如果我們從+0開始數數,即從0000 0000開始不斷加1(0000 0001,0000 0002,0000 0003…),我們會發現我們不停在迴圈('0'-'127','-127'-'0')。原因是當我們數到127(0111 1111)時,再加1變成-127(1000 0000)。這個時候看起來是這樣的:

2、1的補碼的加法

1的補碼的加法跟其它的加法是一樣的,只是它有個迴圈進製(end-around carry)概念。它要求把最後結果的進製加回到最後的結果中去。

比如計算(-1)+2:

1111 1110

+0000 0010

*****====

(1)0000 0000

+ 1 進製

*****====

0000 0001

為什麼要這樣呢?

我們考慮在①+127處,我們加1變成-127,在-127處我們再減1,同樣會出錯。在應用的時候我們要注意這種超出範圍的錯誤。②處,由於我們有兩個零,在做加法時,我們要加回乙個0去。比如還是計算(-1)+2,

我們拿上面的圈來想象計算的過程,繞著圈順時針走步,圈上的每乙個數字對應乙個走步,計算(-1)+2,也即在(-1)處走兩步,我們走到+0處。由於正常的運算中沒有兩個0,我們在最後回加乙個1。

由於溢位,得到的結果等於0(0000 0000),就是因為中間-0占用了乙個計數,我們把進製1加最後結果上,得到正確結果1:

1111 1110

+0000 0010

*****====

(1)0000 0000

+ 1

*****====

0000 0001

減法可以用加法來表示。

1、從1的補碼的角度來理解補碼加法

負數的補碼經常用反碼加一來計算。將補碼與1的補碼加法聯絡起來可以理解為什麼可以用補碼加法代替減法。

將1的補碼中-0的編碼空出來給-1用,後續數值依次前移,最後1000 0000會空出來,我們給它分配-128。因此,我們可以取值[-1,-128]u[0,127]。

因此,補碼根據反碼(即前文1的補碼)加一來計算其實就是把-0擠掉,留了個位置給-128。

binary value

two's complement interpretation

unsigned interpretation

0000000000

0000000111

⋮⋮⋮01111110

126126

01111111

127127

10000000

−128

12810000001

−127

12910000010

−126

130⋮⋮⋮

11111110

−2254

11111111

−1255

from

那為什麼可以用補碼來計算減法呢?理解了反碼的加法,其實就不難理解為什麼補碼可以直接用來計算減法了。

2、快速寫出補碼

正數的補碼是它本身。

負數的補碼:

從右往左看,從第乙個1出現的位置的下一位開始,反轉位元,符號位不反轉。比如(11010110) 的補碼為10101010。

128的補碼及原碼 反碼 補碼

乙個位元組佔8位 乙個字長為n的機器數能表示不同的數字的個數是固定的2 n個,n 8時2 n 256 用來表示有符號數,數的範圍就是 2 n 1 2 n 1 1,n 8時,這個範圍就是 128 127。用來表示無符號數,就不需要用一位來表示符號位,n位機器數全部用來表示是數值,這時表示數的範圍就是0...

關於2的補碼

日期 2009年8月 5日 問乙個基本的問題。負數在計算機中如何表示?舉例來說,8在計算機中表示為二進位制的1000,那麼 8怎麼表示呢?很容易想到,可以將乙個二進位制位 bit 專門規定為符號位,它等於0時就表示正數,等於1時就表示負數。比如,在8位機中,規定每個位元組的最高位為符號位。那麼,8就...

關於2的補碼

問乙個基本的問題。負數在計算機中如何表示?舉例來說,8在計算機中表示為二進位制的1000,那麼 8怎麼表示呢?很容易想到,可以將乙個二進位制位 bit 專門規定為符號位,它等於0時就表示正數,等於1時就表示負數。比如,在8位機中,規定每個位元組的最高位為符號位。那麼,8就是00001000,而 8則...