這是"IEEE754標(biāo)準(zhǔn)系列"的第二篇文章. 主要討論32位浮點(diǎn)數(shù) (或者說float類型) 的取值范圍到底是如何計(jì)算出來的.
本章主要參考自 IEEE754 wiki
一. wiki中, 32位浮點(diǎn)數(shù)的取值范圍
這里先直接給出維基上的取值范圍:

可見float類型, 或者說32位浮點(diǎn)數(shù)的取值范圍是:
或者說是:
直觀表示的話就是:
[-340000000000000000000000000000000000000, -0.0000000000000000000000000000000000000118] ∪ [0.0000000000000000000000000000000000000118, 340000000000000000000000000000000000000]
二. 前置概念
在詳細(xì)介紹這個(gè)范圍是怎么計(jì)算出來的之前, 我們必須先了解一些概念.只有了解了這些概念, 才能真正的理解浮點(diǎn)數(shù)的取值范圍是如何計(jì)算出來的.
而且此處假定你已經(jīng)對(duì)IEEE754浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)方式有所了解, 還不了解的話也可以參考本系列的第一篇文章.
那這就開始吧
概念1: normal number(規(guī)格數(shù))? & subnormal number(非規(guī)格數(shù))
根據(jù)IEEE754的規(guī)定, 按照尾數(shù)位隱藏的整數(shù)部分是 1. 還是0. 可以將浮點(diǎn)數(shù)劃分為兩類: normal number(規(guī)格數(shù))? 和 subnormal number(非規(guī)格數(shù))
下面以32位浮點(diǎn)數(shù)為例來解釋這些概念.
normal number(規(guī)格數(shù))
就是尾數(shù)位隱藏的整數(shù)部分是1.的數(shù), 這種數(shù)叫做normal number, 可以理解為"正常的數(shù)"
一般來說, 我們遇到的都是normal number
舉例: 20.5在內(nèi)存中表示為: 0? 1000 0011? 0100 1000 0000 0000 000
其中尾數(shù)部分(即上面的加粗部分), 去掉后面補(bǔ)的零之后為: 01001
但事實(shí)上, 真實(shí)的尾數(shù)部分應(yīng)該是: 1.01001, 即前面省略了整數(shù)部分1.
subnormal number(非規(guī)格數(shù))
尾數(shù)位隱藏的整數(shù)部分為0.的數(shù), 叫做subnormal number, 也叫作denormal number, 可以理解為"低于正常數(shù)的數(shù)"
引入subnormal number這個(gè)概念, 是為了在浮點(diǎn)數(shù)下溢時(shí), 可以逐位的損失精度, 以盡可能精確的表達(dá)0附近的極小數(shù), 之后的章節(jié)會(huì)具體講解.
為了表示subnormal number, IEEE754規(guī)定: 如果將指數(shù)位全部填充為0, 則表示這個(gè)數(shù)是個(gè)subnormal number
舉例: 以32位浮點(diǎn)數(shù)為例, 當(dāng)你看到類似于 * 00000000 *********************** 這樣內(nèi)存狀態(tài)的數(shù)時(shí), (即指數(shù)位全部為0的數(shù)), 就應(yīng)該知道, 這是個(gè)subnormal number, 此時(shí)這個(gè)數(shù)的尾數(shù)位隱藏的整數(shù)不是1.? 而是0.
概念2: non-number(特殊數(shù))
和subnormal number類似, IEEE754對(duì)于指數(shù)位全為1的狀態(tài)也做了特殊規(guī)定:
當(dāng)指數(shù)位全部被1填充, 即指數(shù)位表示的值為255時(shí), 用于表示這個(gè)浮點(diǎn)數(shù)處在一種非正常數(shù)(non-number)的狀態(tài): 即這個(gè)數(shù)可能是±infinity或NaN.
注: Infinity和NaN是兩個(gè)特殊數(shù), 分別表示無窮和Not a Number. 我們后文還會(huì)詳細(xì)討論這兩個(gè)特殊數(shù)
The biased-exponent field is filled with all 1 bits to indicate either infinity or an invalid result of a computation.
所以: 當(dāng)你看到類似于 * 11111111 *********************** 這樣內(nèi)存狀態(tài)的數(shù)時(shí), (即指數(shù)位全部為1的數(shù)), 就應(yīng)該知道, 這是個(gè)non-number, 它用于表示特殊數(shù).
三. 計(jì)算方法
在了解了上面兩個(gè)概念之后, 再看計(jì)算方法就很簡(jiǎn)單了.
如上所述, IEEE754規(guī)定, 當(dāng)指數(shù)位全部為0或者全部為1時(shí), 用于表示兩種特殊狀態(tài)的數(shù): subnormal number 和 non-number, 所以現(xiàn)在可以得到如下示意圖, 以32位單精度浮點(diǎn)數(shù)為例:

這就是理解單精度浮點(diǎn)數(shù)取值范圍的關(guān)鍵: 當(dāng)我們討論浮點(diǎn)數(shù)的取值范圍時(shí), 實(shí)際上討論的是: normal number (上圖中綠色部分)的范圍.
可以看出, 32位浮點(diǎn)數(shù)的指數(shù)部分其實(shí)是無法取到-127和128的, 因?yàn)?
用于表示-127的0000 0000被用來表示subnormal number了,
而用于表示128的1111 1111被用來表示non-number了.
所以實(shí)際上32位浮點(diǎn)數(shù)的指數(shù)部分只能取到只能取到[-126, 127]
再來看看尾數(shù): 對(duì)于normal number, 尾數(shù)前隱藏的整數(shù)部分始終保持為1.
所以尾數(shù)(含隱藏的整數(shù)部分)所表示的值的范圍其實(shí)是 [1.00...00, 1.11...11],
這個(gè)二進(jìn)制數(shù), 約等于十進(jìn)制的[1, 2), 因?yàn)?.11..11非常逼近十進(jìn)制的2
好啦, 現(xiàn)在我們知道, 對(duì)于32位flaot而言: 尾數(shù)(含隱藏的整數(shù)部分)的可取值為: [1 ,2), 指數(shù)位可取值[-126, 127], 且浮點(diǎn)數(shù)可正可負(fù), 根據(jù)運(yùn)算規(guī)則, 就不難算出32位float的取值范圍了:
取值范圍
注意開閉區(qū)間哦
然后為了看著順眼, 我們把上式的以2為底, 替換為以10為底:
↑ 轉(zhuǎn)換后小數(shù)位太長(zhǎng)了, 所以這里寫成了省略號(hào)的形式: 3.402823669...
從上面這個(gè)集合中, 取一個(gè)更容易表示的子集, 就是我們常見的32位float的取值范圍了:
↑ 注意, 上面這個(gè)集合其實(shí)是32位float取值范圍的子集, 不過和真正的取值范圍也沒有差太多, 表示起來也更簡(jiǎn)潔, 沒有冗長(zhǎng)的小數(shù)位, 還能寫成閉區(qū)間的形式...所以在各種資料中, 我們??吹降娜≈捣秶褪巧厦孢@個(gè).
↑ 之所以能寫成閉區(qū)間的形式, 就是因?yàn)樗皇钦嬲≈捣秶囊粋€(gè)子集. 這里特意說明一下, 防止有的同學(xué)對(duì)這里的閉區(qū)間感到困惑.
四: 補(bǔ)充
下面是 32位單精度浮點(diǎn)數(shù)的取值范圍示意圖, 可以參照此圖更好的理解一下前文內(nèi)容
下圖中, x軸代表以2為底的n次冪(即內(nèi)存中的指數(shù)部分), y軸代表尾數(shù)(含隱藏的整數(shù)部分1.)

坐標(biāo)系中任意一點(diǎn)(x, y)就代表一個(gè)浮點(diǎn)數(shù),

這一點(diǎn)到x軸, y軸所圍成的矩形的面積(即上圖中橙色區(qū)域的面積), 就是這個(gè)浮點(diǎn)數(shù)的值 (即浮點(diǎn)數(shù)的值 = 尾數(shù)(含隱藏的整數(shù)部分) * 以2為底的n次冪)
上圖中:
藍(lán)色部分: 表示normal number的取值范圍, 即, normal number類型的浮點(diǎn)數(shù)對(duì)應(yīng)的坐標(biāo)點(diǎn)只能出現(xiàn)在坐標(biāo)系中的藍(lán)色區(qū)域.
坐標(biāo)點(diǎn): 一個(gè)坐標(biāo)點(diǎn)對(duì)應(yīng)一個(gè)浮點(diǎn)數(shù)
橙色部分的面積: 表示該浮點(diǎn)數(shù)的值.
這就是32位浮點(diǎn)數(shù)取值范圍的計(jì)算方法.
下一章將詳細(xì)介紹為什么說32位浮點(diǎn)數(shù)的精度是"7位有效數(shù)", 這個(gè)7是怎么計(jì)算出來的, 下一章也將會(huì)是整個(gè)系列中最有難度, 最重要的一章.
那下一章再見吧~