摘要:本章首先介紹了信息在計(jì)算機(jī)中的表示方法抠艾,其次主要介紹了整數(shù)和浮點(diǎn)數(shù)在計(jì)算機(jī)中的二進(jìn)制表示方法及其運(yùn)算盆昙。
關(guān)鍵詞:大端和小端洞翩;無(wú)符號(hào)數(shù)編碼;有符號(hào)數(shù)編碼近迁;浮點(diǎn)數(shù)
目錄:
??1 信息的表示
??2 無(wú)符號(hào)整數(shù)
????2.1無(wú)符號(hào)整數(shù)編碼
????2.2無(wú)符號(hào)整數(shù)的運(yùn)算
??3 有符號(hào)數(shù)
????3.1有符號(hào)數(shù)編碼
????3.2有符號(hào)數(shù)運(yùn)算
??4 浮點(diǎn)數(shù)
????4.1 浮點(diǎn)數(shù)表示方法
????4.2 浮點(diǎn)數(shù)運(yùn)算
1 信息的表示
數(shù)據(jù)在計(jì)算機(jī)中都是用二級(jí)制表示艺普,可以簡(jiǎn)單的將其理解為一個(gè)很大很大的數(shù)組,數(shù)組中的每個(gè)元素就是一個(gè)字節(jié)(Byte),一個(gè)字節(jié)是8 位(Bit)鉴竭,一個(gè)位的值要么是0要么是1歧譬。由此可見,計(jì)算機(jī)系統(tǒng)找元素的最小單位是字節(jié)搏存,而不是位瑰步。
每種高級(jí)編程語(yǔ)言根都有其基本的數(shù)據(jù)類型,比如字符型璧眠、整型缩焦、布爾型,每種語(yǔ)言規(guī)定這些基本的數(shù)據(jù)類型占用的字節(jié)數(shù)可能都不一樣责静。一個(gè)數(shù)據(jù)類型的占用的字節(jié)數(shù)稱為字長(zhǎng)袁滥。比如C語(yǔ)言規(guī)定某類型字長(zhǎng)是4字節(jié)也就是32bit。
對(duì)于字長(zhǎng)是多個(gè)字節(jié)的數(shù)據(jù)類型而言灾螃。表示該數(shù)據(jù)的這些字節(jié)题翻,是按照正常的從左到右的方式放入數(shù)組中,還是倒過來把本來在最右邊的字節(jié)放到最左邊腰鬼。正常的就是小端法放置嵌赠,倒過來就是大端法放置,不同的機(jī)器放置的方法是不同的熄赡。如果你的程序要用到數(shù)據(jù)類型在底層的字節(jié)表示姜挺,那么程序在不同機(jī)器上運(yùn)行的時(shí)候一定要小心,以免輸出相反的字節(jié)信息彼硫。
指針由于用于指示該元素在大數(shù)組的哪個(gè)位置炊豪,相當(dāng)于索引,索引的范圍當(dāng)然是越大越好拧篮,因此指針的位數(shù)和計(jì)算機(jī)的位數(shù)是一樣的溜在,也就是盡可能大,在32位機(jī)器上他托,索引的范圍大約4Gb掖肋。也就是說該大數(shù)組最多能裝下4Gb數(shù)據(jù),再多就就沒有索引可用了赏参,而64位的機(jī)器索引范圍要大得多志笼,就可以配置很大的內(nèi)存了沿盅。索引由于如果用2進(jìn)制表示的,他顯得很啰嗦很長(zhǎng)纫溃,64位的機(jī)器腰涧,其索引有64位長(zhǎng)。因此索引一般用16進(jìn)制表示紊浩,以O(shè)x開頭表示16進(jìn)制窖铡。
2 無(wú)符號(hào)整數(shù)
無(wú)符號(hào)整數(shù)在很多編程語(yǔ)言中是沒有的,比如JAVA坊谁,但C語(yǔ)言有费彼,如果你要做系統(tǒng)級(jí)的開發(fā)工作,也許會(huì)接觸到口芍。
2.1 無(wú)符號(hào)編碼
對(duì)于程序員而言箍铲,我們面對(duì)的都是10進(jìn)制的數(shù)據(jù),而計(jì)算機(jī)都是二進(jìn)制表示鬓椭,所以必須要有一套標(biāo)準(zhǔn)颠猴,來實(shí)現(xiàn)他們之間的轉(zhuǎn)換或者說映射。對(duì)于無(wú)符號(hào)數(shù)小染,有無(wú)符號(hào)的編碼規(guī)則翘瓮,他表明了一個(gè)無(wú)符號(hào)的二進(jìn)制數(shù)表示為10進(jìn)制的方式:
B表示binary,U表示usigned裤翩,2表示to春畔,x表示該二進(jìn)制數(shù)X的每一個(gè)位。
用這個(gè)無(wú)符號(hào)編碼可以方便的將一個(gè)無(wú)符號(hào)二進(jìn)制編碼岛都,轉(zhuǎn)換位無(wú)符號(hào)的10進(jìn)制。
那么反過來振峻,無(wú)符號(hào)的10進(jìn)制的到二進(jìn)制有沒有一個(gè)這樣的公式來表示呢臼疫?嗯,沒有扣孟。我們只能用常用的除2取余來計(jì)算烫堤,遇到很大的數(shù)時(shí),建議用計(jì)算機(jī)程序幫助你做轉(zhuǎn)換凤价。
2.2 無(wú)符號(hào)運(yùn)算
2.2.1 位運(yùn)算
包括
非~鸽斟、與&、或|利诺、異或^運(yùn)算富蓄。他們都是位級(jí)的,因此將對(duì)一個(gè)無(wú)符號(hào)數(shù)的每一位執(zhí)行慢逾。
2.2.2 邏輯運(yùn)算
&&立倍、||灭红、!口注,他們是數(shù)據(jù)級(jí)別的運(yùn)算变擒。也就是該數(shù)據(jù)的10進(jìn)制值的邏輯運(yùn)算。
2.2.3 算術(shù)運(yùn)算
- 無(wú)符號(hào)加法和減法:就和進(jìn)制加法和減法一樣寝志,沒什么特別娇斑。
- 無(wú)符號(hào)乘法和除法:也和10進(jìn)制的乘法和除法一樣,只不過由于除法可能會(huì)出現(xiàn)小數(shù)材部,但會(huì)最終結(jié)果將仍然是整數(shù)毫缆,因?yàn)闀?huì)發(fā)生舍入。對(duì)于無(wú)符號(hào)乘法和除法的時(shí)候败富,當(dāng)乘以2的冪或除以2的冪時(shí)悔醋,可以用移位來進(jìn)行。另外如果乘以任意常數(shù)而不是2的冪時(shí)兽叮,可以將該常數(shù)分解為幾個(gè)2的冪相加芬骄,因此如果乘以任意常數(shù),可以通過幾個(gè)移位操作和加法操作來代替乘法操作鹦聪。但除法無(wú)法實(shí)行這個(gè)轉(zhuǎn)換账阻。具體該使用移位還是使用乘法指令,需要更具具體情況確定泽本。乘法指令往往要比加法和移位指令消耗更多的時(shí)鐘周期淘太。
3 有符號(hào)數(shù)
3.1 有符號(hào)數(shù)編碼方式:補(bǔ)碼
有符號(hào)數(shù)除了可以表示正數(shù)還可以表示負(fù)數(shù)。對(duì)于同樣的位數(shù)例如8位规丽,他將會(huì)以最高位來表示符號(hào)蒲牧。0表示整數(shù),1表示符數(shù)赌莺。同樣都是8位因此和無(wú)符號(hào)數(shù)表示的數(shù)據(jù)個(gè)數(shù)是一樣多的冰抢,但是范圍不一樣。0開頭的數(shù)和1開頭的數(shù)各占一半艘狭,但是全零是非負(fù)數(shù)挎扰。因此能表示的正數(shù)個(gè)數(shù)比負(fù)數(shù)個(gè)數(shù)要少一個(gè),0既不是正數(shù)也不是負(fù)數(shù)巢音。
補(bǔ)碼編碼給出了如何將一個(gè)二進(jìn)制的補(bǔ)碼轉(zhuǎn)換為10進(jìn)制的符號(hào)數(shù):
符號(hào)數(shù)的編碼方式和無(wú)符號(hào)數(shù)編碼的唯一區(qū)別在于最高位的權(quán)重是負(fù)值
同樣的遵倦,我們?cè)趺窗岩粋€(gè)10進(jìn)制的數(shù)變成二進(jìn)制的數(shù)呢?有公式嗎官撼?沒有梧躺。對(duì)于將10進(jìn)制的數(shù)用補(bǔ)碼表示的時(shí)候分兩種情況:
正數(shù)轉(zhuǎn)換為補(bǔ)碼:
??1. 將其轉(zhuǎn)換為二進(jìn)制表示
??2. 在最高位補(bǔ)零
負(fù)數(shù)轉(zhuǎn)換為補(bǔ)碼:
??1.將求其對(duì)應(yīng)正數(shù)的補(bǔ)碼
??2.再求反碼
??2.再加1
是麻煩了一點(diǎn)。
3.2 有符號(hào)數(shù)的運(yùn)算
有符號(hào)數(shù)和無(wú)符號(hào)數(shù)的運(yùn)算是一樣的傲绣,計(jì)算機(jī)機(jī)器級(jí)指令不會(huì)區(qū)分有符號(hào)和無(wú)符號(hào)
3.3 有符號(hào)和無(wú)符號(hào)之間的轉(zhuǎn)換
由于有符號(hào)和無(wú)符號(hào)之間在計(jì)算機(jī)底層是不會(huì)區(qū)分的燥狰。只要在高級(jí)語(yǔ)言層上才有區(qū)別棘脐。因此他們之間做強(qiáng)制類型轉(zhuǎn)換時(shí)在位模式上是不會(huì)有變化的,而只改變了其表示成10進(jìn)制的方法(即一個(gè)用無(wú)符號(hào)編碼龙致,一個(gè)用補(bǔ)碼)
4 浮點(diǎn)數(shù)
4.1 浮點(diǎn)數(shù)的編碼方式
浮點(diǎn)數(shù)的編碼方式和整數(shù)的不一樣蛀缝,浮點(diǎn)數(shù)的表示相當(dāng)于科學(xué)計(jì)數(shù)法表示,而寫編碼分為四種情況目代,就如同分段函數(shù)一樣屈梁,所以來,跟我一塊看看榛了,浮點(diǎn)數(shù)怎么編碼
可以看到构哺,位級(jí)表示有三個(gè)部分:
s(符號(hào)位):1表示負(fù)數(shù)0表示正數(shù)
exp(指數(shù)部分):該部分是無(wú)符號(hào)表示的
frac(小數(shù)部分):該部分實(shí)際上是小數(shù),只是把小數(shù)點(diǎn)前面的0去掉了战坤,實(shí)際上是(0.frac)
上述的位級(jí)表述除了有S之外曙强,M和E并沒有表示出來,那么他到底和exp(指數(shù)部分)和frac(小數(shù)部分)有什么關(guān)系呢途茫?其之間的關(guān)系會(huì)更具指數(shù)部分的形式不同而不同碟嘴,因此就分為了四種情況,也是IEEE的標(biāo)準(zhǔn)囊卜。
- 規(guī)格化數(shù)娜扇。規(guī)格化數(shù)是指數(shù)部分既不是全0也不是全1的數(shù)。此時(shí)SME之間的轉(zhuǎn)換關(guān)系為:
S = s栅组;M = 1+0.f雀瓢;E = exp-Bias
Bias = 2k-1
k為exp部分的位數(shù),32位時(shí)位8玉掸,64位時(shí)為11
exp是無(wú)符號(hào)編碼
- 非規(guī)格化數(shù)刃麸。非規(guī)格數(shù)指數(shù)部分全為0,非規(guī)格數(shù)可以將0表示為正0和負(fù)0排截,他們有不同的用途。SME的計(jì)算公式為:
S = s辐益;M = 0.f断傲;E = 1-Bias
Bias = 2k-1
k為exp部分的位數(shù),32位時(shí)位8智政,64位時(shí)為11
exp按理應(yīng)該是0认罩,但是為了光滑過度到別的類型數(shù)據(jù),而取了1
- 無(wú)窮大续捂。指數(shù)部分全為1垦垂,同時(shí)小數(shù)部分全為0的數(shù)據(jù)宦搬。此時(shí)SME沒有計(jì)算公式了,s=1的時(shí)候是負(fù)無(wú)窮劫拗,s=0的時(shí)候是正無(wú)窮间校。
- NaN∫晨叮空值憔足,指數(shù)部分全為1,小數(shù)部分不為0.
可以看到浮點(diǎn)數(shù)轉(zhuǎn)化為10進(jìn)制數(shù)據(jù)是比較麻煩的酒繁,需要分情況換算滓彰。非規(guī)格化數(shù)據(jù)最靠近零,其次是規(guī)格化數(shù)據(jù)州袒,再其次是無(wú)窮揭绑。
同樣,如果想將10進(jìn)制的數(shù)郎哭,轉(zhuǎn)化為2進(jìn)制的浮點(diǎn)數(shù)表示怎么做呢他匪?比如10.24。首先你要將其換算成定點(diǎn)表示的小數(shù)彰居,例如1010.101101然后表示成1.010101101x23诚纸。接下來再一步一步根據(jù)指數(shù)的取值逆運(yùn)算得到2進(jìn)制浮點(diǎn)表示。相對(duì)來說陈惰,更加麻煩畦徘。最好不要手工操作。
4.2 浮點(diǎn)數(shù)的運(yùn)算
我們知道抬闯,整數(shù)的運(yùn)算我們可以手工操作况芒,正常和10進(jìn)制的數(shù)一樣加減乘除就可以了。但我們看到浮點(diǎn)數(shù)如果這樣做的話愧薛,就不行砰左,比如1.1-1.1,就不等于0睡榆。因?yàn)楦↑c(diǎn)數(shù)其實(shí)他更像是源碼表示萍肆,就是正數(shù)和負(fù)數(shù),除了符號(hào)位不同胀屿,其他都相同塘揣。所以估計(jì)他有自己的一套源碼的運(yùn)算法則。不管是做整數(shù)的運(yùn)算還是浮點(diǎn)數(shù)的運(yùn)算宿崭,由于是在計(jì)算機(jī)中有限的位上進(jìn)行亲铡,就會(huì)產(chǎn)生溢出,所以一些比如交換律、結(jié)合律奖蔓、分配律可能不適用了赞草。(a+b)+c和a+(b+c)可能就會(huì)產(chǎn)生不一樣的結(jié)果。
4.3 舍入
浮點(diǎn)運(yùn)算舍入時(shí)候吆鹤,第一先向最近的值舍入厨疙,如果有兩個(gè)最近的值,向偶數(shù)舍入檀头,即使得最低有效位為偶數(shù)轰异,0為偶數(shù)1為奇數(shù)。注意不是四舍五入暑始。比如2.5他離2和3一樣近搭独,但他舍入到2會(huì)使得最低有效位2是偶數(shù),因此2.5會(huì)向2舍入廊镜。