非整形的二進(jìn)制數(shù)
在第一章討論數(shù)制的時(shí)候,我們只討論了整形。顯然,和十進(jìn)制一樣,其它進(jìn)制必須也能表示非整形數(shù)。在十進(jìn)制中,在小數(shù)點(diǎn)右邊的數(shù)字關(guān)聯(lián)了10的負(fù)乘方值:
不必驚訝,二進(jìn)制也是以同樣的方法表示:
這個(gè)辦法與第一章中的整形辦法相結(jié)合就可以用來(lái)轉(zhuǎn)換一個(gè)一般數(shù)值:
將十進(jìn)制轉(zhuǎn)換成二進(jìn)制也不是很難。一般來(lái)說(shuō),需將十進(jìn)制數(shù)分成兩塊:整數(shù)部分和分?jǐn)?shù)部分。使用第一章中的方法來(lái)將整數(shù)部分轉(zhuǎn)換成二進(jìn)制。分?jǐn)?shù)部分的轉(zhuǎn)換可以使用下面描述的方法。
考慮一個(gè)用a、b、c···標(biāo)記比特位的二進(jìn)制分?jǐn)?shù)。這個(gè)數(shù)用二進(jìn)制表示為:
0.abcdef...
將此數(shù)乘2.新得到的數(shù)的二進(jìn)制表示將是:
a.bcdef...
注意,第一個(gè)比特位現(xiàn)在在權(quán)值為1的位置。用0替換a得到:
0.bcdef...
再乘以2得到:
b.cdef...
現(xiàn)在第二個(gè)比特位(b)在權(quán)值為1的位置。重復(fù)這個(gè)過(guò)程,直到得到了需要的盡可能多的比特位。圖6.1展示了一個(gè)實(shí)例:將0.5625轉(zhuǎn)換成二進(jìn)制。這種方法當(dāng)分?jǐn)?shù)部分為0了才停止。
另一個(gè)例子,將23.85轉(zhuǎn)換成二進(jìn)制。將整數(shù)部分
轉(zhuǎn)換成二進(jìn)制是容易的,但是分?jǐn)?shù)部分呢?圖6.2展示了這個(gè)計(jì)算的開(kāi)始部分。如果你仔細(xì)看了這個(gè)數(shù)值,就會(huì)發(fā)現(xiàn)一個(gè)無(wú)限循環(huán)。這就意味著0.85是一個(gè)無(wú)限循環(huán)的二進(jìn)制數(shù)(與基數(shù)為10的無(wú)限循環(huán)十進(jìn)制數(shù)相對(duì)應(yīng))。這里顯示了這個(gè)數(shù)的計(jì)算模式。在這個(gè)模式中,你可以看到
。因此,
。
上面計(jì)算的一個(gè)重要結(jié)論是23.85不可以用有限的比特位來(lái)精確表示成二進(jìn)制數(shù)。(就像
不能表示成有限的十進(jìn)制數(shù)。)正如這一章展示的,C語(yǔ)言中的float和double變量是以二進(jìn)制儲(chǔ)存的。因此,類似23.85的數(shù)值不能精確地儲(chǔ)存到這些變量中。只能儲(chǔ)存23.85的近似值。
為了簡(jiǎn)化硬件,采用固定的格式來(lái)儲(chǔ)存浮點(diǎn)數(shù)。這種格式采用科學(xué)計(jì)數(shù)法(但是是在二進(jìn)制中,是2的乘方,不是10)。例如,23.85或10111.11011001100110...?將儲(chǔ)存為:
(其中指數(shù)(100)是二進(jìn)制形式)。規(guī)范的浮點(diǎn)數(shù)有下面的形式:
其中1:sssssssssssss是有效數(shù)而eeeeeeee是指數(shù)。
IEEE浮點(diǎn)表示法
IEEE(Institute of Electrical and Electronic Engineers,電氣與電子工程師學(xué)會(huì))是一個(gè)國(guó)際組織,它已經(jīng)設(shè)計(jì)了存儲(chǔ)浮點(diǎn)數(shù)的特殊的二進(jìn)制格式。這種格式應(yīng)用在大多數(shù)(但不是全部)現(xiàn)在的電腦上。通常電腦本身的硬件就支持它。例如,Intel的數(shù)學(xué)協(xié)處理器(從Pentium開(kāi)始,就嵌入到所有它的CPU中了)就使用它。IEEE為不同的精度定義了不同的格式:?jiǎn)位螂p精度。在C語(yǔ)言中,float變量使用單精度,而double變量使用雙精度。
Intel數(shù)學(xué)協(xié)處理器使用第三種,更高的精度,稱為擴(kuò)展精度。事實(shí)上,在數(shù)學(xué)協(xié)處理器自身里的所有數(shù)據(jù)都是這種格式。當(dāng)數(shù)據(jù)從協(xié)處理器儲(chǔ)存到內(nèi)存中時(shí),將自動(dòng)轉(zhuǎn)換成單或雙精度。跟IEEE的浮點(diǎn)雙精度格式相比,擴(kuò)展精度使用了一種有細(xì)微差別的格式,所以將不在這討論。
IEEE單精度
單精度浮點(diǎn)使用32個(gè)比特位來(lái)編碼數(shù)字。通常它精確到小數(shù)點(diǎn)后七位。相比于整數(shù),浮點(diǎn)數(shù)的儲(chǔ)存格式更復(fù)雜。圖6.3展示了IEEE單精度數(shù)的基本格式。這種格式有幾個(gè)古怪的地方。負(fù)的浮點(diǎn)數(shù)并不使用補(bǔ)碼表示法。它們使用符號(hào)量值表示法。如圖顯示,第31位決定數(shù)的符號(hào)。二進(jìn)制的指數(shù)并不會(huì)直接儲(chǔ)存。取而代之的是將指數(shù)和7F的和儲(chǔ)存到位23 30中。這個(gè)偏置指數(shù)總是非負(fù)的。
分?jǐn)?shù)部分假定是一個(gè)規(guī)范的有效數(shù)(格式為1:sssssssss)。因?yàn)榈谝粋€(gè)比特位總是1,所以領(lǐng)頭的1是不儲(chǔ)存的!這就允許在后面儲(chǔ)存一額外的比特位,稍微地?cái)U(kuò)展了精度。這個(gè)想法稱為隱藏一的表示法。
怎樣儲(chǔ)存23.85呢? 首你必須永遠(yuǎn)記?。哼@些字 先,它是個(gè)正數(shù),所以符號(hào)位為0。其次,真實(shí)的指數(shù)為4,所以偏置指數(shù)為
。最后,分?jǐn)?shù)部分應(yīng)表示為01111101100110011001100 (記住領(lǐng)頭的1是隱藏的)。把這些放到一起得到(為了幫助澄清浮點(diǎn)格式的不同部分,符號(hào)位和分?jǐn)?shù)部分都加了下劃線,而且所有的比特位都分成了四個(gè)比特位一組。):
這不是準(zhǔn)確的23.85(因?yàn)樗且粋€(gè)無(wú)限循環(huán)的二進(jìn)制數(shù))。如果你將上面的數(shù)值轉(zhuǎn)換回十進(jìn)制形式,你會(huì)發(fā)現(xiàn)它大約等于23.849998474。這個(gè)數(shù)與23.85非常接近,但是它并不準(zhǔn)確。實(shí)際上,在C語(yǔ)言中,23.85的描述和上面的是一樣的。因?yàn)樵摂?shù)的精確描述被截去后的最左邊的位為1,所以最后一個(gè)比特位經(jīng)四舍五入后為1。因此單精度數(shù)23.85將表示成十六進(jìn)制41 BE CC CD。將這個(gè)轉(zhuǎn)換成十進(jìn)制得23.850000381,這個(gè)數(shù)就更接近23.85。怎么描述-23.85呢?只需要改變符號(hào)位得:C1 BE CC CD。不要使用補(bǔ)碼!
IEEE浮點(diǎn)格式中,e和f 的某些組合有特殊的含義。表6.1描述了這些特殊的值。溢出或除以0將產(chǎn)生一個(gè)無(wú)窮數(shù)。一個(gè)無(wú)效的操作將產(chǎn)生一個(gè)不確定的結(jié)果,例如:試圖求一個(gè)負(fù)數(shù)的平方根,將兩個(gè)無(wú)窮數(shù)相加,等等。規(guī)范的單精度數(shù)的數(shù)量級(jí)范圍為從

非規(guī)范化數(shù)
非規(guī)范化數(shù)可以用來(lái)表示那些值太小了以致于不能以規(guī)范格式描述的數(shù)(也就是小于
)。例如:考慮下數(shù)
。在約定的規(guī)范格式中,這個(gè)指數(shù)太小了。但是,它可以用非規(guī)范的格式來(lái)描述:
。為了儲(chǔ)存這個(gè)數(shù),偏置指數(shù)被置為0(看表6.1),而且分?jǐn)?shù)部分是以
方式書(shū)寫(xiě)得到的所有有效數(shù)(也就是說(shuō)儲(chǔ)存了所有的比特位,包括小數(shù)點(diǎn)左邊的1).
將表示成:
IEEE雙精度
IEEE雙精度使用64位來(lái)表示數(shù)字,而且通常精確到小數(shù)點(diǎn)后15位。如圖6.4所示,基本的結(jié)構(gòu)和單精度是非常相似的。只是相比于單精度,它使用了更多的位來(lái)描述偏置指數(shù)(11)和分?jǐn)?shù)(52)。
更大范圍的偏置指數(shù)會(huì)導(dǎo)致兩個(gè)后果。一是計(jì)算的將是真實(shí)指數(shù)和3FF(1023)的和(而不是單精度中的7F)。二是,允許描述更大范圍的真實(shí)的指數(shù)(因此也可以描述更大范圍的數(shù)量級(jí))。雙精度的數(shù)量級(jí)范圍大約為從
到
。
雙精度值中增加的有效位是增大分?jǐn)?shù)字段的原因。
作為一個(gè)例子,再次考慮下。偏置指令用十六進(jìn)制表示為4 + 3FF =403。因此,該數(shù)用雙精度表示為:
或在十六進(jìn)制中為40 37 D9 99 99 99 99 9A。如果你將它轉(zhuǎn)換回十進(jìn)制,你將得到23.8500000000000014 (這有12個(gè)0!),這個(gè)數(shù)就更接近23.85。
雙精度和單精度一樣有一些特殊的值3。非規(guī)范化數(shù)同樣也是一樣的。
最主要的區(qū)別是雙精度的非規(guī)范數(shù)使用
。
更多建議: