對二進位制補碼的理解《轉》

2021-09-06 05:36:38 字數 2642 閱讀 5268

問乙個基本的問題。

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

舉例來說,+8在計算機中表示為二進位制的1000,那麼-8怎麼表示呢?

很容易想到,可以將乙個二進位制位(bit)專門規定為符號位,它等於0時就表示正數,等於1時就表示負數。比如,在8位機中,規定每個位元組的最高位為符號位。那麼,+8就是00001000,而-8則是10001000。

但是,隨便找一本《計算機原理》,都會告訴你,實際上,計算機內部採用二進位制補碼(two's complement)表示負數。

什麼是二進位制補碼?

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

第一步,每乙個二進位制位都取相反值,0變成1,1變成0。比如,00001000的相反值就是11110111。

第二步,將上一步得到的值加1。11110111就變成11111000。

所以,00001000的二進位制補碼就是11111000。也就是說,-8在計算機(8位機)中就是用11111000表示。

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

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

二進位制補碼的好處

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

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

還是以-8作為例子。

假定有兩種表示方法。一種是直覺表示法,即10001000;另一種是二進位制補碼表示法,即11111000。請問哪一種表示法在加法運算中更方便?

隨便寫乙個計算式,16 + (-8) = ?

16的二進位制表示是 00010000,所以用直覺表示法,加法就要寫成:

00010000

+10001000

---------

10011000

可以看到,如果按照正常的加法規則,就會得到10011000的結果,轉成十進位制就是-24。顯然,這是錯誤的答案。也就是說,在這種情況下,正常的加法規則不適用於正數與負數的加法,因此必須制定兩套運算規則,一套用於正數加正數,還有一套用於正數加負數。從電路上說,就是必須為加法運算做兩種電路。

現在,再來看二進位制補碼表示法。

00010000

+11111000

---------

100001000

可以看到,按照正常的加法規則,得到的結果是100001000。注意,這是乙個9位的二進位制數。我們已經假定這是一台8位機,因此最高的第9位是乙個溢位位,會被自動捨去。所以,結果就變成了00001000,轉成十進位制正好是8,也就是16 + (-8) 的正確答案。這說明了,二進位制補碼表示法可以將加法運算規則,擴充套件到整個整數集,從而用一套電路就可以實現全部整數的加法。

二進位制補碼的本質

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

要將正數轉成對應的負數,其實只要用0減去這個數就可以了。比如,-8其實就是0-8。

已知8的二進位制是00001000,-8就可以用下面的式子求出:

00000000

-00001000

---------

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

100000000

-00001000

---------

11111000

進一步觀察,可以發現100000000 = 11111111 + 1,所以上面的式子可以拆成兩個:

11111111

-00001000

---------

11110111

+00000001

---------

11111000

二進位制補碼的兩個轉換步驟就是這麼來的。

為什麼正數加法適用於二進位制補碼?

實際上,我們要證明的是,x-y或x+(-y)可以用x加上y的二進位制補碼完成。

y的二進位制補碼等於(11111111-y)+1。所以,x加上y的二進位制補碼,就等於:

x + (11111111-y) + 1

我們假定這個算式的結果等於z,即 z = x + (11111111-y) + 1

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

第一種情況,如果x小於y,那麼z是乙個負數。這時,我們就對z採用二進位制補碼的逆運算,求出它對應的正數絕對值,再在前面加上負號就行了。所以,

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

這就證明了,在正常的加法規則下,可以利用二進位制補碼得到正數與負數相加的正確結果。換言之,計算機只要部署加法電路和補碼電路,就可以完成所有整數的加法。

二進位制補碼

二進位制補碼 計算機儲存資料都是以0,1二進位制進行儲存。對於有符號整數儲存 對於浮點數待續 引入補碼概念。原碼即直接將真值轉換為其相應的二進位制形式,而反碼和補碼是對原碼進行某種轉換編碼方式。對於正整數,原碼,反碼和補碼都相一樣 對於負整數,補碼等於反碼加1,而反碼等於原碼除符號位不變其他位按位求...

二進位制補碼

計算機只能識別0和1,使用的是二進位制,而在日常生活中人們使用的是十進位制,正如 亞里斯多德早就指出的那樣,今天十進位制的廣泛採用,只不過我們絕大多數人生來具有10個手指頭這個解剖學事實的結果.儘管在歷史上手指計數 5,10進製 的實踐要比二或三進製計數出現的晚.摘自 數學發展史 有空大家可以看看哦...

二進位制補碼

二進位制補碼主要是為了解決負整數的加減法運算 減法轉化為加法 原碼表示法就是用二進位制的最高位表示符號,0表示正數,1表示負數。以8位為例 1就是表示為0000 0001,1表示為1000 0001.而補碼的規則是正整數保持不變,針對負整數,除符號位外,其他位全部取反,然後 1。注 負整數中,原碼轉...