轉至:http://jinguo.iteye.com/blog/212049html
理解有符號數和無符號數負數在計算機中如何表示呢?
這一點,你可能聽過兩種不一樣的回答。
一種是教科書,它會告訴你:計算機用「補碼」表示負數。但是有關「補碼」的概念一說就得一節課,這一些咱們須要在第6章中用一章的篇幅講2進制的一切。再者,用「補碼」表示負數,其實一種公式,公式的做用在於告訴你,想得問題的答案,應該如何計算。卻並無告訴你爲何用這個公式就能夠和答案?
另外一種是一些程序員告訴你的:用二進制數的最高位表示符號,最高位是0,表示正數,最高位是1,表示負數。這種說法自己沒錯,但是若是沒有下文,那麼它就是錯的。至少它不能解釋,爲何字符類型的-1用二進制表示是「1111 1111」(16進製爲FF);而不是咱們更能理解的「1000 0001」。(爲何說後者更好理解呢?由於既然說最高位是1時表示負數,那1000 0001不是正好是-1嗎?)。
讓咱們從頭提及。
一、你自已決定是否須要有正負。
就像咱們必須決定某個量使用整數仍是實數,使用多大的範圍數同樣,咱們必須自已決定某個量是否須要正負。若是這個量不會有負值,那麼咱們能夠定它爲帶正負的類型。
在計算機中,能夠區分正負的類型,稱爲有符類型,無正負的類型(只有正值),稱爲無符類型。
數值類型分爲整型或實型,其中整型又分爲無符類型或有符類型,而實型則只有符類型。
字符類型也分爲有符和無符類型。
好比有兩個量,年齡和庫存,咱們能夠定前者爲無符的字符類型,後者定爲有符的整數類型。
二、使用二制數中的最高位表示正負。
首先得知道最高位是哪一位?1個字節的類型,如字符類型,最高位是第7位,2個字節的數,最高位是第15位,4個字節的數,最高位是第31位。不一樣長度的數值類型,其最高位也就不一樣,但老是最左邊的那位(以下示意)。字符類型固定是1個字節,因此最高位老是第7位。
(紅色爲最高位)
單字節數: 1111 1111
雙字節數: 1111 1111 1111 1111
四字節數: 1111 1111 1111 1111 1111 1111 1111 1111
當咱們指定一個數量是無符號類型時,那麼其最高位的1或0,和其它位同樣,用來表示該數的大小。
當咱們指定一個數量是無符號類型時,此時,最高數稱爲「符號位」。爲1時,表示該數爲負值,爲0時表示爲正值。
三、無符號數和有符號數的範圍區別。
無符號數中,全部的位都用於直接表示該值的大小。有符號數中最高位用於表示正負,因此,當爲正值時,該數的最大值就會變小。咱們舉一個字節的數值對比:
無符號數: 1111 1111 值:255 1* 27 + 1* 26 + 1* 25 + 1* 24 + 1* 23 + 1* 22 + 1* 21 + 1* 20
有符號數: 0111 1111 值:127 1* 26 + 1* 25 + 1* 24 + 1* 23 + 1* 22 + 1* 21 + 1* 20
一樣是一個字節,無符號數的最大值是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。
然而,事實上計算機中的規定有些相反,請看下錶:
二進制值(1字節) 十進制值
1000 0000 -128
1000 0001 -127
1000 0010 -126
1000 0011 -125
... ...
1111 1110 -2
1111 1111 -1
首先咱們看到,從-1到-128,其二進制的最高位都是1(表中標爲紅色),正如咱們前面的學。
而後咱們有些奇怪地發現,1000 0000 並無拿來表示 -0;而1000 0001也不是拿來直觀地表示-1。事實上,-1 用1111 1111來表示。
怎麼理解這個問題呢?先得問一句是-1大仍是-128大?
固然是 -1 大。-1是最大的負整數。以此對應,計算機中不管是字符類型,或者是整數類型,也不管這個整數是幾個字節。它都用全1來表示 -1。好比一個字節的數值中:1111 1111表示-1,那麼,1111 1111 - 1 是什麼呢?和現實中的計算結果徹底一致。1111 1111 - 1 = 1111 1110,而1111 1110就是-2。這樣一直減下去,當減到只剩最高位用於表示符號的1之外,其它低位全爲0時,就是最小的負值了,在一字節中,最小的負值是1000 0000,也就是-128。
咱們以-1爲例,來看看不一樣字節數的整數中,如何表達-1這個數:
字節數 二進制值 十進制值
單字節數 1111 1111 -1
雙字節數 1111 1111 1111 1111 -1
四字節數 1111 1111 1111 1111 1111 1111 1111 1111 -1
可能有同窗這時會混了:爲何 1111 1111 有時表示255,有時又表示-1?因此我再強調一下本節前面所說的第2點:你自已決定一個數是有符號仍是無符號的。寫程序時,指定一個量是有符號的,那麼當這個量的二進制各位上都是1時,它表示的數就是-1;相反,若是事選聲明這個量是無符號的,此時它表示的就是該量容許的最大值,對於一個字節的數來講,最大值就是255。
原碼、反碼、補碼
咱們已經知道計算機中,全部數據最終都是使用二進制數表達。
咱們也已經學會如何將一個10進制數如何轉換爲二進制數。
不過,咱們仍然沒有學習一個負數如何用二進制表達。
好比,假設有一 int 類型的數,值爲5,那麼,咱們知道它在計算機中表示爲:
00000000 00000000 00000000 00000101
5轉換成二制是101,不過int類型的數佔用4字節(32位),因此前面填了一堆0。
如今想知道,-5在計算機中如何表示?
在計算機中,負數以其正值的補碼形式表達。
什麼叫補碼呢?這得從原碼,反碼提及。
原碼:一個整數,按照絕對值大小轉換成的二進制數,稱爲原碼。
好比 00000000 00000000 00000000 00000101 是 5的 原碼。
反碼:將二進制數按位取反,所得的新二進制數稱爲原二進制數的反碼。
取反操做指:原爲1,得0;原爲0,得1。(1變0; 0變1)
好比:將00000000 00000000 00000000 00000101每一位取反,得11111111 11111111 11111111 11111010。
稱:11111111 11111111 11111111 11111010 是 00000000 00000000 00000000 00000101 的反碼。
反碼是相互的,因此也可稱:
11111111 11111111 11111111 11111010 和 00000000 00000000 00000000 00000101 互爲反碼。
補碼:反碼加1稱爲補碼。
也就是說,要獲得一個數的補碼,先獲得反碼,而後將反碼加上1,所得數稱爲補碼。
好比:00000000 00000000 00000000 00000101 的反碼是:11111111 11111111 11111111 11111010。
那麼,補碼爲:
11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011
因此,-5 在計算機中表達爲:11111111 11111111 11111111 11111011。轉換爲十六進制:0xFFFFFFFB。
再舉一例,咱們來看整數-1在計算機中如何表示。
假設這也是一個int類型,那麼:
一、先取1的原碼:00000000 00000000 00000000 00000001
二、得反碼: 11111111 11111111 11111111 11111110
三、得補碼: 11111111 11111111 11111111 11111111
可見,-1在計算機裏用二進制表達就是全1。16進製爲:0xFFFFFF。
碼、反碼、補碼
結束了各類進制的轉換,咱們來談談另外一個話題:原碼、反碼、補碼。
咱們已經知道計算機中,全部數據最終都是使用二進制數表達。
咱們也已經學會如何將一個10進制數如何轉換爲二進制數。
不過,咱們仍然沒有學習一個負數如何用二進制表達。
好比,假設有一 int 類型的數,值爲5,那麼,咱們知道它在計算機中表示爲:
00000000 00000000 00000000 00000101
5轉換成二制是101,不過int類型的數佔用4字節(32位),因此前面填了一堆0。
如今想知道,-5在計算機中如何表示?
在計算機中,負數以其正值的補碼形式表達。
什麼叫補碼呢?這得從原碼,反碼提及。
原碼:一個整數,按照絕對值大小轉換成的二進制數,稱爲原碼。
好比 00000000 00000000 00000000 00000101 是 5的 原碼。
反碼:將二進制數按位取反,所得的新二進制數稱爲原二進制數的反碼。
取反操做指:原爲1,得0;原爲0,得1。(1變0; 0變1)
好比:將00000000 00000000 00000000 00000101每一位取反,得11111111 11111111 11111111 11111010。
稱:11111111 11111111 11111111 11111010 是 00000000 00000000 00000000 00000101 的反碼。
反碼是相互的,因此也可稱:
11111111 11111111 11111111 11111010 和 00000000 00000000 00000000 00000101 互爲反碼。
補碼:反碼加1稱爲補碼。
也就是說,要獲得一個數的補碼,先獲得反碼,而後將反碼加上1,所得數稱爲補碼。
好比:00000000 00000000 00000000 00000101 的反碼是:11111111 11111111 11111111 11111010。
那麼,補碼爲:
11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011
因此,-5 在計算機中表達爲:11111111 11111111 11111111 11111011。轉換爲十六進制:0xFFFFFFFB。
再舉一例,咱們來看整數-1在計算機中如何表示。
假設這也是一個int類型,那麼:
一、先取1的原碼:00000000 00000000 00000000 00000001
二、得反碼: 11111111 11111111 11111111 11111110
三、得補碼: 11111111 11111111 11111111 11111111
可見,-1在計算機裏用二進制表達就是全1。16進製爲:0xFFFFFF。
計算機原理-原碼、反碼、補碼
更多內容:http://www.juqingshow.com/jsjyuanli/200701/7687.html
首先要說的是:計算機中的帶符號數通常用補碼錶示
計算機中的帶符號數用補碼錶示的優勢:
一、負數的補碼與對應正數的補碼之間的轉換能夠用同一種方法——求補運算完成,能夠簡化硬件;
二、可將減法變爲加法,省去減法器;
三、無符號數及帶符號數的加法運算能夠用同一電路完成。
帶符號數的表示
先引進兩個名詞:機器數和真值。
將一個數在機器中的表示形式,即編碼稱爲機器數,數的自己稱爲真值。日常咱們常常用的帶符號的數就是真數,如:+50,-10.5等等。
經常使用的機器數有三種:原碼、補碼和反碼。
1.原碼
通俗定義
將數的符號數碼化,即用一個二進制位表示符號:對正數,該位取0,對負數,該位取1。
而數值部分保持數的原有形式(有時須要在高位部分添幾個0)。這樣所得結果爲該數的原碼錶示。
例,x=+1001010,y= -1001010,z= 一1110(= 一0001110)。當原碼爲8位時,x、y和z的原碼分別是:
[x]原=01001010;
[y]原=11001010;
[Z]原=10001110.
其中最高位爲符號位。
2)正規定義
2.反碼
反碼:正數的反碼爲原碼,負數的反碼是原碼符號位外按位取反。
例如:
X1=+67=+100 0011B ,[X1]反=0100 0011B X2=-67=-100 0011B ,[X2]反=1011 1100B
對正數,其反碼與原碼相同,也與補碼相同。對負數,其反碼等於原碼除符號位外,按位求反(末位不加1)。利用反碼也可以使帶符號數的加、減法轉化爲單純的加法,但麻煩一些。
通常把求反碼做爲求補的中間過程,即 [x]補=[x]反+1。
3.補碼
1)補碼的引進和定義
據統計,在全部的運算中,加、減運算要佔到80%以上,所以,可否方便地進行正、負數加、減運算,直接關係到計算機的運行效率。
把一個負數加模的結果稱爲該負數的補碼(結果是一個正數,它和該負數是等價的,確切地說,是一對一的,於是可看做是該負數的編碼),定義正數的補碼就是它自己,符號位取0,即和原碼相同。這就是補碼的通俗定義。將這個定義用數學形式表示出來,就可獲得補碼的正規定義:
其中n爲補碼的位數。這個定義實際也將真值的範圍給出來了,當n=8時,一27≤x<27。和原碼相比,補碼錶示可多表示一個數。當n=8時,多表示的數是一27=一128。
2)補碼的求法
對正數,補碼同原碼。
例如,x=+0101001,[x]補=[x]原=00101001。
對負數,由定義求補碼,需作減法,不方便。經推導可知,負數的補碼等於其原碼除符號位外按位「求反」(1變0,0變1),末位再加1。
例如,y=一0001100,[y]原=10001100,[Y]補=11110011+1=11110100。
•算法:1.正數的補碼與原碼相同; 2.負數的補碼由原碼除符號位保持不變外,其他各位按位取反,再在末位加1。 [x]補=[x]反+1 •
多作幾例,可得出一種心算求補的方法——從最低位開始至找到的第一個1均不變,符號位不變,這之間的各位「求反」(該方法僅用於作題)。程序員