大家都知道數(shù)據(jù)在計(jì)算機(jī)中都是按字節(jié)來(lái)儲(chǔ)存了璃谨,1個(gè)字節(jié)等于8位(1Byte=8bit)沙庐,而計(jì)算機(jī)只能識(shí)別0和1這兩個(gè)數(shù)鲤妥,所以根據(jù)排列,1個(gè)字節(jié)能代表256種不同的信息拱雏,即28(0和1兩種可能棉安,8位排列),比如定義一個(gè)字節(jié)大小的無(wú)符號(hào)整數(shù)(unsigned char)铸抑,那么它能表示的是0~255(0~28-1)這些數(shù)垂券,一共是256個(gè)數(shù),因?yàn)橄刍懊嬲f(shuō)了菇爪,一個(gè)字節(jié)只能表示256種不同的信息。別停下柒昏,還是一個(gè)字節(jié)的無(wú)符號(hào)整數(shù)凳宙,我們來(lái)進(jìn)一步剖析它,0是這些數(shù)中最小的一個(gè)职祷,我們先假設(shè)它在計(jì)算機(jī)內(nèi)部就用8位二進(jìn)制表示為00000000(從理論上來(lái)說(shuō)也可以表示成其他不同的二進(jìn)制碼氏涩,只要這256個(gè)數(shù)每個(gè)數(shù)對(duì)應(yīng)的二進(jìn)制碼都不相同就可以了),再假設(shè)1表示為00000001有梆,2表示為00000010是尖,3表示為00000011,依次類推泥耀,那么最大的那個(gè)數(shù)255在8位二進(jìn)制中就表示為最大的數(shù)11111111饺汹,然后,我們把這些二進(jìn)制碼換算成十進(jìn)制看看痰催,會(huì)發(fā)現(xiàn)剛好和我們假設(shè)的數(shù)是相同的兜辞,而事實(shí)上,在計(jì)算機(jī)中夸溶,無(wú)符號(hào)的整數(shù)就是按這個(gè)原理來(lái)儲(chǔ)存的逸吵,所以告訴你一個(gè)無(wú)符號(hào)的整數(shù)的二進(jìn)制碼,你就可以知道這個(gè)數(shù)是多少缝裁,而且知道在計(jì)算機(jī)中扫皱,這個(gè)數(shù)本身就是以這個(gè)二進(jìn)制碼來(lái)儲(chǔ)存的。比如我給你一個(gè)2個(gè)字節(jié)大小的二進(jìn)制碼捷绑,首先聲明它表示的是無(wú)符號(hào)的整數(shù):00000000 00000010韩脑,我們把前面的0省略,換算一下胎食,它表示的也是數(shù)值2扰才,和前面不同的是允懂,它占了2個(gè)字節(jié)的內(nèi)存厕怜。不同的類型占的內(nèi)存空間不同,如在我的電腦中char是1個(gè)字節(jié),int是4個(gè)字節(jié)粥航,long是8個(gè)字節(jié)(你的可能不同琅捏,這取決于不同的計(jì)算機(jī)設(shè)置),它們的不同之處僅僅是內(nèi)存大的能表示的不同的信息多些递雀,也就是能表示的數(shù)范圍更大些(unsigned int能表示的范圍是0~28*4-1)柄延,至于怎么算,其實(shí)都是一樣的缀程,直接把二進(jìn)制與十進(jìn)制相互轉(zhuǎn)換搜吧,二進(jìn)制就是它在計(jì)算機(jī)中的樣子,十進(jìn)制就是我們所表示的數(shù)(誤解:不同的計(jì)算機(jī)儲(chǔ)存的原理是不同的杨凑,取決于商家的喜好呢)滤奈。無(wú)符號(hào)的整數(shù)根本就沒有原碼、反碼和補(bǔ)碼撩满。
只有有符號(hào)的整數(shù)才有原碼蜒程、反碼和補(bǔ)碼的!其他的類型一概沒有伺帘。雖然我們也可以用二進(jìn)制中最小的數(shù)去對(duì)應(yīng)最小的負(fù)數(shù)昭躺,最大的也相對(duì)應(yīng),但是那樣不科學(xué)伪嫁,下面來(lái)說(shuō)說(shuō)科學(xué)的方法领炫。還是說(shuō)一個(gè)字節(jié)的整數(shù),不過(guò)這次是有符號(hào)的啦张咳,1個(gè)字節(jié)它不管怎么樣還是只能表示256個(gè)數(shù)驹吮,因?yàn)橛蟹?hào)所以我們就把它表示成范圍:-128-127。它在計(jì)算機(jī)中是怎么儲(chǔ)存的呢晶伦?可以這樣理解碟狞,用最高位表示符號(hào)位,如果是0表示正數(shù)婚陪,如果是1表示負(fù)數(shù)族沃,剩下的7位用來(lái)儲(chǔ)存數(shù)的絕對(duì)值的話,能表示27個(gè)數(shù)的絕對(duì)值泌参,再考慮正負(fù)兩種情況脆淹,27*2還是256個(gè)數(shù)。首先定義0在計(jì)算機(jī)中儲(chǔ)存為00000000沽一,對(duì)于正數(shù)我們依然可以像無(wú)符號(hào)數(shù)那樣換算盖溺,從00000001到01111111依次表示1到127。那么這些數(shù)對(duì)應(yīng)的二進(jìn)制碼就是這些數(shù)的原碼铣缠。到這里很多人就會(huì)想烘嘱,那負(fù)數(shù)是不是從10000001到11111111依次表示-1到-127昆禽,那你發(fā)現(xiàn)沒有,如果這樣的話那么一共就只有255個(gè)數(shù)了蝇庭,因?yàn)?0000000的情況沒有考慮在內(nèi)醉鳖。實(shí)際上,10000000在計(jì)算機(jī)中表示最小的負(fù)整數(shù)哮内,就是這里的-128盗棵,而且實(shí)際上并不是從10000001到11111111依次表示-1到-127,而是剛好相反的北发,從10000001到11111111依次表示-127到-1纹因。負(fù)整數(shù)在計(jì)算機(jī)中是以補(bǔ)碼形式儲(chǔ)存的,補(bǔ)碼是怎么樣表示的呢琳拨,這里還要引入另一個(gè)概念——反碼辐怕,所謂反碼就是把負(fù)數(shù)的原碼(負(fù)數(shù)的原碼和和它的絕對(duì)值所對(duì)應(yīng)的原碼相同,簡(jiǎn)單的說(shuō)就是絕對(duì)值相同的數(shù)原碼相同)各個(gè)位按位取反从绘,是1就換成0寄疏,是0就換成1,如-1的原碼是00000001僵井,和1的原碼相同陕截,那么-1的反碼就是11111110,而補(bǔ)碼就是在反碼的基礎(chǔ)上加1批什,即-1的補(bǔ)碼是11111110+1=11111111农曲,因此我們可以算出-1在計(jì)算機(jī)中是按11111111儲(chǔ)存的∽ふ總結(jié)一下乳规,計(jì)算機(jī)儲(chǔ)存有符號(hào)的整數(shù)時(shí),是用該整數(shù)的補(bǔ)碼進(jìn)行儲(chǔ)存的合呐,0的原碼暮的、補(bǔ)碼都是0,正數(shù)的原碼淌实、補(bǔ)碼可以特殊理解為相同冻辩,負(fù)數(shù)的補(bǔ)碼是它的反碼加1。下面再多舉幾個(gè)例子拆祈,來(lái)幫助大家理解恨闪!
十進(jìn)制 → 二進(jìn)制 (怎么算放坏?要是不知道看計(jì)算機(jī)基礎(chǔ)的書去)
47 → 101111
有符號(hào)的整數(shù) 原碼 反碼 補(bǔ)碼
47 00101111 00101111 00101111(正數(shù)補(bǔ)碼和原碼咙咽、反碼相同,不能從字面理解)
∮倌辍-47 10101111 11010000 11010001(負(fù)數(shù)補(bǔ)碼是在反碼上加1钧敞,符號(hào)位不參與運(yùn)算)
再舉個(gè)例子蜡豹,學(xué)C語(yǔ)言的同學(xué)應(yīng)該做過(guò)這道題:
把-1以無(wú)符號(hào)的類型輸出,得什么結(jié)果犁享?(程序如下)
#include
void main()
{
short int n=-1;
cout<<(unsigned short int)n<<ENDL;
}
首先在我的電腦中short int類型的儲(chǔ)存空間是2個(gè)字節(jié),你的可能不同豹休,我說(shuō)過(guò)炊昆,這取決于你的計(jì)算機(jī)配置。它能儲(chǔ)存28*2=65536個(gè)不同的數(shù)據(jù)信息威根,如果是無(wú)符號(hào)那么它的范圍是065535(0216-1)凤巨,如果是有符號(hào),那么它的范圍是-3276832767(-215215-1)洛搀。這道題目中敢茁,開始n是一個(gè)有符號(hào)的短整型變量,我們給它賦值為-1留美,根據(jù)我們前面所說(shuō)的彰檬,它在計(jì)算機(jī)中是以補(bǔ)碼11111111 11111111儲(chǔ)存的,注意前面說(shuō)了是2個(gè)字節(jié)谎砾。如果把它強(qiáng)制為無(wú)符號(hào)的短整型輸出的話逢倍,那么我們就把剛才的二進(jìn)制把看成無(wú)符號(hào)的整型在計(jì)算機(jī)中儲(chǔ)存的形式,對(duì)待無(wú)符號(hào)的整型就沒有什么原碼景图、反碼和補(bǔ)碼的概念了较雕,直接把11111111 11111111轉(zhuǎn)化成十進(jìn)制就是65535,其實(shí)我們一看都是一就知道它是范圍中最大的一個(gè)數(shù)了挚币。呵呵亮蒋,就這么簡(jiǎn)單。你個(gè)把上面的源代碼編譯運(yùn)行看看妆毕,如果你的電腦short int也是兩個(gè)字節(jié)慎玖,那就會(huì)和我得一樣的結(jié)果。你可以先用這個(gè)語(yǔ)句看看:cout<<<endl;<>看看你的電腦里的短整型占多少的儲(chǔ)存空間笛粘,也可以用sizeof來(lái)看其它任何類型所分配的儲(chǔ)存空間凄吏。
最后提醒一句,關(guān)于數(shù)據(jù)如何在計(jì)算機(jī)中儲(chǔ)存的闰蛔,這里只適用于整型的數(shù)據(jù)痕钢,對(duì)于浮點(diǎn)型的是另一種方式,這里我們暫時(shí)就不深究了序六。
FeedBack:
1.為什么使用補(bǔ)碼形式:
其實(shí)計(jì)算機(jī)中的數(shù)值用補(bǔ)碼來(lái)表示任连,一是為了防止0有2個(gè)編碼,其次就是為了把減法運(yùn)算用加法運(yùn)算表示出來(lái)例诀,以達(dá)到簡(jiǎn)化電路的作用随抠。具體內(nèi)容請(qǐng)參看一些專業(yè)書籍裁着,比如華中科技大出版的《邏輯設(shè)計(jì)》(呵呵,我大二的課本)拱她。
為什么用補(bǔ)碼表示有符號(hào)整數(shù)二驰。比如8位整數(shù)表示的范圍是-128~127,而不是-127~128呢秉沼?想過(guò)沒有桶雀,為什么二進(jìn)制10000000在原碼和反碼中表示0,在補(bǔ)碼中它不表示0唬复,保證了0表示的唯一性矗积,但是它為什么表示負(fù)數(shù),而不是整數(shù)敞咧,你也許會(huì)說(shuō)棘捣,因?yàn)樗?hào)位是1呀,表示負(fù)數(shù)呀休建,對(duì)乍恐,繼續(xù),+128我們用補(bǔ)碼怎么表示测砂,包括符號(hào)位禁熏,表示為010000000,超過(guò)了2個(gè)字節(jié)邑彪,如果截取低8位瞧毙,那么是10000000,最高位(符號(hào)位)是1寄症,表示的是一個(gè)負(fù)數(shù)宙彪,我們?cè)倏纯?128的機(jī)器碼是多少,原碼110000000有巧,反碼101111111释漆,補(bǔ)碼110000000,截取低8位即10000000篮迎,表示的是一個(gè)負(fù)數(shù)男图。
其實(shí)呀,這些總結(jié)出來(lái)的東西都是玩巧甜橱,也并不是說(shuō)非要這樣實(shí)現(xiàn)逊笆,學(xué)了計(jì)算機(jī)邏輯原理,就知道岂傲,其實(shí)這樣做是由于物理?xiàng)l件關(guān)系难裆。因?yàn)檫\(yùn)算器里這樣做更容易實(shí)現(xiàn)計(jì)算
2.
int x=-70;
int y=2;
int z=x>>y
z的值是多少?主要是不明白負(fù)數(shù)移位該怎么算?
在C語(yǔ)言中 int 是兩個(gè)字節(jié)所以 70在計(jì)算機(jī)中表示為 0000 0000 0100 0110
-70用補(bǔ)碼表示即 1111 1111 1011 1010
右移2位 C語(yǔ)言中采用的是算術(shù)右移
所以補(bǔ)進(jìn)位和原符號(hào)位相同即 1111 1111 1110 1110
取反加一求它的相反數(shù) 0000 0000 0001 0010 等于 17
所以右移后的結(jié)果是 -17
有個(gè)規(guī)則如果左移1位相當(dāng)于乘以2 右移1位相當(dāng)于除以2 取整
我們驗(yàn)證一下用-70除以2*2 結(jié)果取整正好是我們推算的 -17
在C++中 int 是四個(gè)字節(jié)但是結(jié)果也是一樣的原因自己可以推算一下
- 在8位運(yùn)算中65-15具體怎么通過(guò)補(bǔ)碼計(jì)算啊~~~
15的原碼是0000 1111 補(bǔ)碼也是0000 1111
因?yàn)槭钦龜?shù)符號(hào)位(最高位)為0
-15的原碼是1000 1111(←注意這個(gè)地方你弄錯(cuò)了)符號(hào)為為1表示負(fù)
反碼就是 1111 0000(注意原碼反碼補(bǔ)碼之間轉(zhuǎn)換的時(shí)候千萬(wàn)不要把符號(hào)位考慮進(jìn)去) 補(bǔ)碼就是 1111 0001
如果你已經(jīng)求出了15的補(bǔ)碼這里有個(gè)簡(jiǎn)便的方法求-15的補(bǔ)碼:
直接把15的補(bǔ)碼包含符號(hào)位一起求反即可即
15補(bǔ)碼 1111 0001 那么-15的補(bǔ)碼 0000 1110
補(bǔ)碼計(jì)算的時(shí)候符號(hào)位是要直接參與二進(jìn)制運(yùn)算了而不是單獨(dú)考慮
所謂多余8位的進(jìn)位舍去其實(shí)就是比如補(bǔ)碼1111 1111再加任意非0數(shù)原來(lái)這個(gè)補(bǔ)碼表示的數(shù)就會(huì)發(fā)生溢出(比如加上 0000 0001原先符號(hào)位1表示負(fù)數(shù)加后表示正數(shù))
這里也許你覺得沒有必要因?yàn)楸旧碇荒苋菁{8位多余的當(dāng)然要舍去
可是你可能不知道如果是反碼進(jìn)行運(yùn)算的話不是舍去多余進(jìn)位而是把多余的進(jìn)位加到最低位稱為循環(huán)進(jìn)位
4乃戈。補(bǔ)碼溢出如何處理
這就要看你處理數(shù)據(jù)的范圍褂痰,比如我用8位二進(jìn)制記錄數(shù)據(jù)。
只能儲(chǔ)存-128~127之間的數(shù)據(jù)症虑,如果超過(guò)127或小于-128就會(huì)溢出缩歪。
比如127+1=-128 就是這個(gè)道理
就好象最大值和最小值連成了一個(gè)環(huán),超過(guò)了循環(huán)計(jì)算
這樣做才使得數(shù)據(jù)有規(guī)律性和周期性
為了實(shí)現(xiàn)這個(gè)所以 補(bǔ)碼是舍掉進(jìn)位 而反碼是循環(huán)進(jìn)位 前面說(shuō)過(guò)了
解決的辦法就是 如果8位的數(shù)據(jù)不過(guò)你就用16位的
如果 整型不夠就用長(zhǎng)整型撒 實(shí)在不行就用浮點(diǎn)型的
聲明:文章非原創(chuàng) 原文鏈接