計算機中負數表示法

2021-06-25 19:39:59 字數 3476 閱讀 7331

問乙個基本的問題。

負數在計算機中如何表示?

舉例來說,

+8在計算機中表示為二進位制的

1000

,那麼-8

怎麼表示呢?

很容易想到,可以將乙個二進位制位(

bit)專門規定為符號位,它等於

0時就表示正數,等於

1時就表示負數。比如,在

8位機中,規定每個位元組的最高位為符號位。那麼,

+8就是

00001000

,而-8

則是10001000

。但是,隨便找一本《計算機原理》,都會告訴你,實際上,計算機內部採用

2的補碼(

two'scomplement

)表示負數。

什麼是

2的補碼?

它是一種數值的轉換方法,要分二步完成:

第一步,每乙個二進位制位都取相反值,0變成

1,1變成

0。比如,

00001000

的相反值就是

11110111

。第二步,將上一步得到的值加1。

11110111

就變成11111000

。所以,

00001000的2

的補碼就是

11111000

。也就是說,

-8在計算機(

8位機)中就是用

11111000

表示。不知道你怎麼看,反正我覺得很奇怪,為什麼要採用這麼麻煩的方式表示負數,更直覺的方式難道不好嗎?

昨天,我在一本書裡又看到了這個問題,然後就花了一點時間到網上找資料,現在總算徹底搞明白了。

2

的補碼的好處

首先,要明確一點。計算機內部用什麼方式表示負數,其實是無所謂的。只要能夠保持一一對應的關係,就可以用任意方式表示負數。所以,既然可以任意選擇,那麼理應選擇一種最方便的方式。

2的補碼就是最方便的方式。它的便利體現在,所有的加法運算可以使用同一種電路完成。

還是以-8

作為例子。

假定有兩種表示方法。一種是直覺表示法,即

10001000

;另一種是

2的補碼表示法,即

11111000

。請問哪一種表示法在加法運算中更方便?

隨便寫乙個計算式,

16 + (-8) = ?

16的二進位制表示是

00010000

,所以用直覺表示法,加法就要寫成:

00010000

+10001000

---------

10011000

可以看到,如果按照正常的加法規則,就會得到

10011000

的結果,轉成十進位制就是

-24。顯然,這是錯誤的答案。也就是說,在這種情況下,正常的加法規則不適用於正數與負數的加法,因此必須制定兩套運算規則,一套用於正數加正數,還有一套用於正數加負數。從電路上說,就是必須為加法運算做兩種電路。

現在,再來看

2的補碼表示法。

00010000

+11111000

---------

100001000

可以看到,按照正常的加法規則,得到的結果是

100001000

。注意,這是乙個

9位的二進位制數。我們已經假定這是一台

8位機,因此最高的第

9位是乙個溢位位,會被自動捨去。所以,結果就變成了

00001000

,轉成十進位制正好是

8,也就是

16 +(-8)

的正確答案。這說明了,

2的補碼表示法可以將加法運算規則,擴充套件到整個整數集,從而用一套電路就可以實現全部整數的加法。

2

的補碼的本質

在回答2的補碼為什麼能正確實現加法運算之前,我們先看看它的本質,也就是那兩個步驟的轉換方法是怎麼來的。

要將正數轉成對應的負數,其實只要用

0減去這個數就可以了。比如,

-8其實就是

0-8。已知8

的二進位制是

00001000,-8

就可以用下面的式子求出:

00000000

-00001000

---------

因為00000000

(被減數)小於

0000100

(減數),所以不夠減。請回憶一下小學算術,如果被減數的某一位小於減數,我們怎麼辦?很簡單,問上一位借

1就可以了。

所以,0000000

也問上一位借了

1,也就是說,被減數其實是

100000000

,算式也就改寫成:

100000000

-00001000

---------

11111000

進一步觀察,可以發現

100000000 = 11111111 + 1

,所以上面的式子可以拆成兩個:

11111111

-00001000

---------

11110111

+00000001

---------

11111000

2的補碼的兩個轉換步驟就是這麼來的。

為什麼正數加法適用於

2的補碼?

實際上,我們要證明的是,

x-y或

x+(-y)

可以用x加上y

的2的補碼完成。y的

2的補碼等於

(11111111-y)+1

。所以,x加上

y的2的補碼,就等於:

x +(11111111-y) + 1

我們假定這個算式的結果等於z,即

z = x+ (11111111-y) + 1

接下來,分成兩種情況討論。

第一種情況,如果x小於

y,那麼

z是乙個負數。這時,我們就對z採用

2的補碼的逆運算,求出它對應的正數絕對值,再在前面加上負號就行了。所以,

z =-[11111111-(z-1)] = -[11111111-(x + (11111111-y) + 1-1)] = x - y

第二種情況,如果x大於

y,這意味著

z肯定大於

11111111

,但是我們規定了這是

8位機,最高的第

9位是溢位位,必須被捨去,這相當於減去

100000000

。所以,

z = z -100000000 = x + (11111111-y) + 1 - 100000000 = x - y

這就證明了,在正常的加法規則下,可以利用

2的補碼得到正數與負數相加的正確結果。換言之,計算機只要部署加法電路和補碼電路,就可以完成所有整數的加法。

對計算機中負數表示的思考

我們都知道計算機中負數用補碼表示,即 取反 加1,那為什麼這麼蛋疼的表示呢,既然要區分正負數,直接用最高位來區分不就行了嗎?仔細思考了下,負數用補碼表示是為了實現加法和減法的統一 更確切說就是為了實現減法 設要表示的整數 i 由 b 位儲存,那麼 i 2 b 1。下面討論均是整數。設有一正整數i1,...

計算機中正負數表示

在32位系統中,int型別佔4個位元組,一共是32個2進製位,int型別的首位是符號位,0代表正數,1代表負數,int的最大值是0x7fffffff 即除了最高的1bit其他31位都為1 而最小值是0x80000000 除了最高1bit,其他31位都為0 但是我有幾個問題,在這裡記錄解答一下 關於補...

負數在計算機中的表示

今天,老大讓我調查乙個浮點數轉換為整數的問題。自己就查了些資料,順便複習一下原碼 反碼和補碼。原碼 將乙個整數,轉換成二進位制,就是其原碼。如單位元組的5的原碼為 0000 0101 5的原碼為1000 0101。反碼 正數的反碼就是其原碼 負數的反碼是將原碼中,除符號位以外,每一位取反。如單位元組...