給你轉(zhuǎn)個(gè)貼吧,慢慢看!
附1:關(guān)于原碼反碼和補(bǔ)碼的問(wèn)題
http://zhidao.baidu.com/question/25035076.html?si=4數(shù)值有正負(fù)之分,計(jì)算機(jī)就用一個(gè)數(shù)的最高位存放符號(hào)(0為正,1為負(fù)).這就是機(jī)器數(shù)的原碼了.假設(shè)機(jī)器能處理的位數(shù)為8.即字長(zhǎng)為1byte,原碼能表示數(shù)值的范圍為
(-127~-0 +0~127)共256個(gè).
有了數(shù)值的表示方法就可以對(duì)數(shù)進(jìn)行算術(shù)運(yùn)算.但是很快就發(fā)現(xiàn)用帶符號(hào)位的原碼進(jìn)行乘除運(yùn)算時(shí)結(jié)果正確,而在加減運(yùn)算的時(shí)候就出現(xiàn)了問(wèn)題,如下: 假設(shè)字長(zhǎng)為8bits
( 1 ) 10- ( 1 )10 = ( 1 )10 + ( -1 )10 = ( 0 )10
(00000001)原 + (10000001)原 = (10000010)原 = ( -2 ) 顯然不正確.
因?yàn)樵趦蓚(gè)整數(shù)的加法運(yùn)算中是沒(méi)有問(wèn)題的,于是就發(fā)現(xiàn)問(wèn)題出現(xiàn)在帶符號(hào)位的負(fù)數(shù)身上,對(duì)除符號(hào)位外的其余各位逐位取反就產(chǎn)生了反碼.反碼的取值空間和原碼相同且一一對(duì)應(yīng). 下面是反碼的減法運(yùn)算:
( 1 )10 - ( 1 ) 10= ( 1 ) 10+ ( -1 ) 10= ( 0 )10
(00000001) 反+ (11111110)反 = (11111111)反 = ( -0 ) 有問(wèn)題.
( 1 )10 - ( 2)10 = ( 1 )10 + ( -2 )10 = ( -1 )10
(00000001) 反+ (11111101)反 = (11111110)反 = ( -1 ) 正確
問(wèn)題出現(xiàn)在(+0)和(-0)上,在人們的計(jì)算概念中零是沒(méi)有正負(fù)之分的.(印度人首先將零作為標(biāo)記并放入運(yùn)算之中,包含有零號(hào)的印度數(shù)學(xué)和十進(jìn)制計(jì)數(shù)對(duì)人類文明的貢獻(xiàn)極大).
于是就引入了補(bǔ)碼概念. 負(fù)數(shù)的補(bǔ)碼就是對(duì)反碼加一,而正數(shù)不變,正數(shù)的原碼反碼補(bǔ)碼是一樣的.在補(bǔ)碼中用(-128)代替了(-0),所以補(bǔ)碼的表示范圍為:
(-128~0~127)共256個(gè).
注意:(-128)沒(méi)有相對(duì)應(yīng)的原碼和反碼, (-128) = (10000000) 補(bǔ)碼的加減運(yùn)算如下:
( 1 ) 10- ( 1 ) 10= ( 1 )10 + ( -1 )10 = ( 0 )10
(00000001)補(bǔ) + (11111111)補(bǔ) = (00000000)補(bǔ) = ( 0 ) 正確
( 1 ) 10- ( 2) 10= ( 1 )10 + ( -2 )10 = ( -1 )10
(00000001) 補(bǔ)+ (11111110) 補(bǔ)= (11111111)補(bǔ) = ( -1 ) 正確
所以補(bǔ)碼的設(shè)計(jì)目的是:
⑴使符號(hào)位能與有效值部分一起參加運(yùn)算,從而簡(jiǎn)化運(yùn)算規(guī)則.
⑵使減法運(yùn)算轉(zhuǎn)換為加法運(yùn)算,進(jìn)一步簡(jiǎn)化計(jì)算機(jī)中運(yùn)算器的線路設(shè)計(jì)
所有這些轉(zhuǎn)換都是在計(jì)算機(jī)的最底層進(jìn)行的,而在我們使用的匯編、C等其他高級(jí)語(yǔ)言中使用的都是原碼。
附2:算術(shù)運(yùn)算的溢出問(wèn)題
關(guān)于算術(shù)運(yùn)算的溢出問(wèn)題,曾經(jīng)我也迷茫過(guò),而且不知道為什么整型變量溢出后會(huì)是模運(yùn)算的結(jié)果呢,以前還以為是不可以預(yù)測(cè)的,不過(guò)弄懂了原碼、補(bǔ)碼的概念后,就發(fā)現(xiàn)其實(shí)都是有規(guī)律可循的,如果你還不太清楚補(bǔ)碼什么東西,建議先看看8月1日的隨筆『計(jì)算機(jī)中的原碼、反碼和補(bǔ)碼』,弄清楚整型數(shù)據(jù)在計(jì)算機(jī)中是如何儲(chǔ)存的。相信我的傻老婆看完了那篇文章后,很快也能弄懂這個(gè)問(wèn)題的。
在那篇文中,我們講述了為什么我們把-1強(qiáng)制成無(wú)符號(hào)短整型輸出后會(huì)得到65535,在這里我們不對(duì)它進(jìn)行類型轉(zhuǎn)換,我們只是超出它的范圍看看。
還是定義一個(gè)2字節(jié)大小的短整型short int n;,學(xué)了前面的知識(shí),我們知道這里n的范圍是-32768~32767,而且通過(guò)前面知識(shí)我們也知道:
這里的-32768在計(jì)算機(jī)中特殊表示為10000000 00000000
0~32767是00000000 00000000~01111111 11111111
-1~-32767是11111111 11111111~10000000 00000001
當(dāng)我們賦值n=32767,我們先n+1,超出它的范圍,再輸出n看看,結(jié)果是-32768,為什么?我們來(lái)分析一下,32767在內(nèi)存中是以01111111 11111111儲(chǔ)存的,我們對(duì)這個(gè)二進(jìn)制碼加1運(yùn)算看看,結(jié)果是10000000 00000000,它表示的數(shù)是多少,哈哈,這不就是-32768嗎?不甘心,也許是巧合呢,那我們?cè)偌?看看,結(jié)果是10000000 00000001,表示的是-32767,再多試幾個(gè)也一樣的。哦,原來(lái)不是巧合呀,正因?yàn)槿绱,所以我們就不用這么繁瑣了,直接進(jìn)行模運(yùn)算就可以了!
下面我把書上的例子再拿出來(lái)給你講你就明白了。
-------------------------------------------------------
在16位機(jī)器上進(jìn)行下面的操作://為什么強(qiáng)調(diào)16位機(jī)器?因?yàn)?6位機(jī)器上的int型的存儲(chǔ)空間是2個(gè)字節(jié)
int weight=42896;
如果你把輸出,在16位機(jī)器中將不能得到42896,而是-22640。因?yàn)橛蟹?hào)整數(shù)的表示范圍是-32768~32767(共65536個(gè)數(shù)),所以它只能得到42896的補(bǔ)碼-22640(42896-65536=-22640)。
一個(gè)整型類型的變量,用任何一個(gè)超過(guò)表示范圍的整數(shù)初始化,得到的值為用該整數(shù)范圍作模運(yùn)算后的值。例如:
int weight=142896;
則當(dāng)weight是2字節(jié)整型數(shù)時(shí),得到值為11824。因?yàn)?42896-2*65536=11824。為什么不是用142896-3*65536=-53712呢,因?yàn)閣eight的范圍是-32768~32767,顯而易見,-53712不在這個(gè)范圍內(nèi)。
-------------------------------------------------------
關(guān)于溢出,還有個(gè)強(qiáng)制轉(zhuǎn)換時(shí)遇到的溢出問(wèn)題,比如說(shuō)我們把一個(gè)4字節(jié)的整型轉(zhuǎn)換成2字節(jié)的短整型時(shí)就會(huì)遇到這個(gè)問(wèn)題,如果要推算出顯示結(jié)果,那就是知道數(shù)據(jù)在4字節(jié)整型中是怎么儲(chǔ)存的,在2字節(jié)的短整型中又是如何儲(chǔ)存的,而且還要弄清楚2字節(jié)在4字節(jié)中是怎么截取的,這些問(wèn)題我們暫時(shí)就不討論了。
以上皆為引用![ 此帖被qinshengyue在2009-09-03 10:13重新編輯 ]