天天看點

關于 -128 ,+128,-0,+0,-1 的反碼補碼了解(轉載自部落格園)

一. 反碼的範圍

反碼表示法規定:正數的反碼與其原碼相同。負數的反碼是對其原碼逐位取反,但符号位除外。

在規定中,8位二進制碼能表示的反碼範圍是-127~127。

此時(字長為8位), -128沒有原碼和反碼(隻有補碼)。

那麼,為什麼規定字長8位時-128沒有原碼和反碼呢?下面解釋。

首先看-0,[-0]原碼=1000 000,其中1是符号位,求反操作,算出[-0]反碼=1111 1111,

再看-128,假如它有原碼且[-128]原碼=1000 000,假如讓-128也有反碼,求反操作,則[-128]反碼=1111 1111,

你會發現,-128的反碼和-0的反碼相同,是以為了避免面混淆,有了-0的原碼,便不能有-128的原碼補碼,這是8位比特位位數限制決定的。

二. 原碼 反碼 補碼的範圍

前提:字長是8位二進制數。

原碼 -127~127 -128呢???不是說-128有原碼 是1000 0000嗎??

反碼 -127~127

補碼 -128~127

你會發現,補碼比其它碼多一位,這是為什麼呢?問題出在0上。

[+0]原碼=0000 0000, [-0]原碼=1000 0000

[+0]反碼=0000 0000, [-0]反碼=1111 1111

[+0]補碼=0000 0000, [-0]補碼=0000 0000

你會發現,+0和-0的補碼是一樣的。即 0的補碼隻有一種表示。

這裡解釋一下[-0]補碼是怎麼得來的。

負數的補碼就是反碼整體加一。符号位上的進位舍棄。(是以,舍棄了符号位的補碼的第一位是數值位,不是符号位,符号位舍棄了)

另外解釋一下原碼符号位和補碼符号位的關系,補碼的符号位不是保持原碼的第一位不變,而是 符号位不變,[-0]反碼的第一個1是符号位,尾數中的7個1是數值位,尾數加一後,數值位産生了進位,1111 1111+1=1 0000 0000(計算補碼的過程中,并不是先保證第一位不變,而是保證符号位不變,保證補碼規則是反碼整體加一)。

是以,補碼能表示的數的個數中,比原碼反碼少了一個,是以補碼可以多表示一個真值為-128的數。

但是,多表示的這個數-128比較特殊,隻有原碼和補碼,沒有反碼。

-128的補碼是1000 0000。

三.-128的補碼為什麼是1000 0000

8位二進制的原值表達範圍為:-127至127

共有256個組合序列 0000 0000 至1111 1111 。

+128的原值在8位中是表達不出來的。

下面從兩個角度了解-128的補碼為什麼是1000 0000.

(1)從補碼的意義上去了解

因為:256-128=256+(-128)的補碼 --機器中隻有加法。減法會變成補碼的加法。

而 256-128=128

是以 256+(-128)的補碼=128

是以 (-128)的補碼=256-128

=128

數學上, 128=1000 0000

故規定-128的補碼為 1000 0000

注意:隻是規定而已,下面還有原因。

8位二進制 的補碼組合序列有256個

0000 0000 - 0111 1111 0 ~+127

1000 0000 用來幹啥好呢?

1000 0001 - 1111 1111 -1~-127

再看看這個規律表

原碼 補碼 值

0111 1111 0111 1111 +127

0111 1110 0111 1110 +126

… … 補碼不斷-1…

0000 0000 0000 0000 0

1000 0001 1111 1111 -1

1000 0010 1111 1110 -2

1000 0011 1111 1101 -3

… … 補碼不斷-1…

1111 1111 1000 0001 -127

無法表達 1000 0000 -128

于是就有了規定 1000 0000 定為 -128的補碼

這種定法和上面數學層面的表述是一緻的。

這樣規定後,負數的補碼在機器中就好算了。

計算方法上是:

将該負數取絕對值,再用二進制表示出這個絕對值 (不管符号位!)

對該二進制數進行取反加一操作就得到負數的補碼了 (也就是求補操作!)

-128 絕對值是 128

128的二進制表示為:

1000 0000

取反

0111 1111

加1

1000 0000

這就是-128的補碼

這種辦法算出的結果符合“規定值”。

四.

1位元組 = 8位,是以它能表示的最大數當然是8位都是1(既然2進制的數隻能是0或1,如果是我們常見的10進制,那就8位都為9,這樣說,你該懂了?)

1位元組的二進制數中,最大的數:11111111。

雙位元組共16位。 1111111111111111。雙位元組數最大值為:

1 * 215 + 1 214 + 1 213 + 1 * 212 + 1 * 211 + 1 * 210 + …… + 1 * 22 + 1 * 21 + 1* 20 = 65535

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

這一點,你可能聽過兩種不同的回答。

一 種是教科書,它會告訴你:計算機用“補碼”表示負數。可是有關“補碼”的概念一說就得一節課,這一些我們需要在第6章中用一章的篇幅講2進制的一切。再 者,用“補碼”表示負數,其實是一種公式,公式的作用在于告訴你,想得到問題的答案,應該如何計算。卻并沒有告訴你為什麼用這個公式就可以得到答案! -----我就是被這個弄混淆的>_<

另 一種是一些程式員告訴你的:用二進制數的最高位表示符号,最高位是0,表示正數,最高位是1,表示負數。這種說法本身沒錯,可是如果沒有下文,那麼它就是 錯的。至少它不能解釋,為什麼字元類型的-1用二進制表示是“1111 1111”(16進制為FF);而不是我們更能了解的“1000 0001”。(為什麼說後者更好了解呢?因為既然說最高位是1時表示負數,那1000 0001不是正好是-1嗎?-----re!當初偶就是這麼想的,so一直在腦中打架,越打越混淆=,=)。

讓我們從頭說起。

······自已決定是否需要有正負。

就像我們必須決定某個量使用整數還是實數,使用多大的範圍數一樣,我們必須自已決定某個量是否需要正負。如果這個量不會有負值,那麼我們可以定它為帶正負的類型。

在計算機中,可以區分正負的類型,稱為有符類型,無正負的類型(隻有正值),稱為無符類型。

數值類型分為整型或實型,其中整型又分為無符類型或有符類型,而實型則隻有有符類型。

字元類型也分為有符和無符類型。

比如有兩個量,年齡和庫存,我們可以定前者為無符的字元類型,後者定為有符的整數類型。

無符号數和有符号數的範圍差別。

同樣是一個位元組,無符号數的最大值是255,而有符号數的最大值是127。原因是有符号數中的最高位被挪去表示符号了。并且,我們知道,最高位的權值也是最高的(對于1位元組數來說是2的7次方=128),是以僅僅少于一位,最大值一下子減半。

不過,有符号數的長處是它可以表示負數。是以,雖然它的在最大值縮水了,卻在負值的方向出現了伸展。我們仍一個位元組的數值對比:

無符号數: 0 ----------------- 255

有符号數: -128 ----- 0 ----- 127

同樣是一個位元組,無符号的最小值是 0 ,而有符号數的最小值是-128。是以二者能表達的不同的數值的個數都一樣是256個。隻不過前者表達的是0到255這256個數,後者表達的是-128到+127這256個數。

一個有符号的資料類型的最小值是如何計算出來的呢?

有符号的資料類型的最大值的計算方法完全和無符号一樣,隻不過它少了一個最高位(見第3點)。但在負值範圍内,數值的計算方法不能直接使用1* 26 + 1* 25 的公式進行轉換。在計算機中,負數除為最高位為1以外,還采用補碼形式進行表達。是以在計算其值前,需要對補碼進行還原。這裡,先直覺地看一眼補碼的形式:

以我們原有的數學經驗,在10進制中:1 表示正1,而加上負号:-1 表示和1相對的負值。

那麼,我們會很容易認為在2進制中(1個位元組): 0000 0001 表示正1,則高位為1後:1000 0001應該表示-1。

然而,事實上計算機中補碼的規定有些相反

——————————————————————————————————————————

我隻轉載了部分内容,

該部落客講得很詳細。

大家請去原部落格園部落客處看詳細原文吧。

部落格園原文