2.6我們進(jìn)行了二進(jìn)制整數(shù)運(yùn)算的最后一役,本次LZ將和各位一起進(jìn)入浮點(diǎn)數(shù)的世界,這里沒有無符號(hào),沒有補(bǔ)碼,但是有各種各樣的驚奇。倘若你真正的進(jìn)入了浮點(diǎn)數(shù)的世界,一定會(huì)發(fā)現(xiàn)它原來是這么有意思,而不是像之前一樣,覺得了解浮點(diǎn)數(shù)的內(nèi)容沒什么用,只要會(huì)簡單的使用就行了。當(dāng)然,這其中也可能有部分猿友是覺得這部分內(nèi)容太難,而對它失去了學(xué)習(xí)的興趣。
就像之前的LZ一樣,曾經(jīng)對IEEE標(biāo)準(zhǔn)望而卻步,不過相信這幾章浮點(diǎn)數(shù)的介紹會(huì)讓你有種頓悟的感覺。倘若你有了這樣的感覺,也不要忘了“點(diǎn)個(gè)推薦哦。”
引言
整數(shù)運(yùn)算雖然能解決計(jì)算機(jī)當(dāng)中有關(guān)信息的很大一部分儲(chǔ)存、運(yùn)算等功能,但卻是仍然不夠的。否則假設(shè)我們要做一個(gè)超市的庫存管理系統(tǒng),那么所有商品的價(jià)格都只能是整數(shù),這是不是讓你難以接受呢。
因此有時(shí)候我們需要更精確的數(shù)值表示,這就需要浮點(diǎn)數(shù)出場了。對于浮點(diǎn)數(shù)的表示以及運(yùn)算規(guī)則,在以前是各個(gè)計(jì)算機(jī)制造商各自有一套自己的標(biāo)準(zhǔn),這給程序的可移植性造成了很大的困擾。
有需求就有創(chuàng)新,最終在1985年左右,浮點(diǎn)數(shù)標(biāo)準(zhǔn)IEEE754就應(yīng)運(yùn)而生了。它就像一代秦始皇一樣,一統(tǒng)浮點(diǎn)數(shù)世界。秦始皇統(tǒng)一了文字、貨幣等,而IEEE754統(tǒng)一了浮點(diǎn)數(shù)的標(biāo)準(zhǔn)。
浮點(diǎn)數(shù)不僅僅是為了讓數(shù)值的表示更加精確,也是為了表示一些整數(shù)無法達(dá)到的數(shù)字,比如一些接近于0的數(shù)字,或者一些非常大的數(shù)值。因此浮點(diǎn)數(shù)對于計(jì)算機(jī)的意義,可以說是相當(dāng)之大。
二進(jìn)制小數(shù)
盡管我們本章的主要內(nèi)容應(yīng)該是IEEE標(biāo)準(zhǔn),不過我們先來看看二進(jìn)制是如何表示小數(shù)的,這有助于我們理解浮點(diǎn)數(shù)的表示。如果是一個(gè)十進(jìn)制小數(shù),相信各位都再熟悉不過了,對于12345.6789來說,它的值是由下列式子得到的。
12345.6789 = 1 * 104 + 2 * 103 + 3 * 102 + 4 * 101 + 5 * 100 + 6 * 10-1 + 7 * 10-2 + 8 * 10-3 + 9 * 10-4
這對我們來說應(yīng)該是常識(shí),那么對于二進(jìn)制小數(shù)也是類似的,考慮這樣一個(gè)小數(shù)10010.1110,它的值則可以由以下式子得到。
10010.1110 = 1 * 24 + 0 * 23 + 0 * 22 + 1 * 21 + 0 * 20 + 1 * 2-1 + 1 * 2-2 + 1 * 2-3 + 0 * 2-4 = 16 + 2 + 1/2 + 1/4 + 1/8 = 18.875
從這個(gè)角度來看,二進(jìn)制小數(shù)其實(shí)與十進(jìn)制小數(shù)是一樣的計(jì)算方式,只是這里是2的整數(shù)次冪而已。
在書中給出了二進(jìn)制小數(shù)的公式,對于一個(gè)形式為bm....b0.b-1....b-n的二進(jìn)制小數(shù)b來說,它的值為以下計(jì)算方式。
這里需要提醒的是,二進(jìn)制小數(shù)不像整數(shù)一樣,只要位數(shù)足夠,它就可以表示所有整數(shù)。二進(jìn)制小數(shù)無法精確的表示任意小數(shù),比如最簡單的,十進(jìn)制小數(shù)0.3這樣一個(gè)小數(shù),二進(jìn)制是無法精確的表示它的。
IEEE標(biāo)準(zhǔn)
IEEE標(biāo)準(zhǔn)采用類似于科學(xué)計(jì)數(shù)法的方式表示浮點(diǎn)小數(shù),即我們將每一個(gè)浮點(diǎn)數(shù)表示為 V = (-1)s * M * 2E 。
這其中s為符號(hào)位,為0時(shí)為正,為1時(shí)為負(fù)。M為尾數(shù),是一個(gè)二進(jìn)制小數(shù),它的范圍是0至1-ε,或者1至2-ε(ε的值一般是2-k次方,其中設(shè)k > 0)。E為階碼,是一個(gè)二進(jìn)制整數(shù),可正可負(fù),為了給尾數(shù)加權(quán)。
浮點(diǎn)格式分為兩種,一種是單精度,一種是雙精度。單雙精度分別對應(yīng)于編程語言當(dāng)中的float和double類型。其中float是單精度的,采用32位二進(jìn)制表示,其中1位符號(hào)位,8位階碼以及23位尾數(shù)。double是雙精度的,采用64位二進(jìn)制表示,其中1位符號(hào)位,11位階碼以及52位尾數(shù)。
從上面的位數(shù)上就能看出,雙精度浮點(diǎn)數(shù)所表示的范圍將遠(yuǎn)遠(yuǎn)大于單精度浮點(diǎn)數(shù)。針對階碼E的值,浮點(diǎn)數(shù)的值可以分為三種不同的情況,分別是規(guī)格化的,非規(guī)格化的以及特殊值,這三種情況就是浮點(diǎn)數(shù)的奧義所在了。