請問float的最大值是怎麼來的?

根據api上寫得,float的最大值是(2-2^-23)·2^127,我想知道的是這裡為什麼不是2^128,而要 先減去一個2^(-23)?


因為有隱藏位(hidden bit),最大的 mantissa 值為二進位 1.111...(小數點後23個1),所以是 2-2^23。


float為4位元組變數,即有32位。以向量形式表示: [x_{31},x_{30},...,x_1,x_0]

其中 x_{31} 為符號位,0表示為非負數,1表示為負數。暫記為s(sign)。

[x_{30},x_{29},...,x_{24},x_{23}] 這八位為指數位,暫記為exp.

[x_{22},x_{21},...,x_1,x_0] 剩下的23位為小數位。記 M=1.x_{22}x_{21}...x_{0}

那麼這32位如何表示某一數字呢?

n=(-1)^sM2^{exp-127}

(至於為什麼是這個樣子表示的…… 去問IEEE叭)

所以最大的float值在機器中表示為:0111111111...1111。

對應的M為1.1111111111111111111111(小數點後面23個1),對應的十進位值便是(2-2^-23)。所以float的最大值是 (2-2^{-23})cdot2^{127}

(不知道自己表述清楚了沒,再放一張CMU的15213課件幫忙理解叭:)


IEEE的浮點標準規定階碼欄位在規格化值區域的編碼要減去一個偏置,這個偏置的大小是2^(k-1)-1,這裡的k是階碼欄位的長短。

之所以要減去這個偏置是為了擴大浮點數在表達比1小的數的範圍內的精度。因為frac欄位的值一般是大於1的,而階碼欄位的編碼是無符號數,也即指數部分大於等於0,無法表示比1小的數。非規格化區域內也是一樣,要減去一個偏置。

總之能用來表示的排列組合是確定的,最大值變小的結果自然就是表示範圍內的數值有了更多的可能,更加精密。


階碼8位 規格化的情況下最大為254 ,減去偏置值127後為127 即為2的指數。而後面最多23個1再加上前面的隱藏1,所以2-2^-23。 符號位取正。所以最大就是你所寫出來的(2-2^(-23))x 2^127。

上個圖你應該會很清楚了


CSAPP第二章 浮點數。

應該可以直接跳到這一段看。


IEEE 754 CSAPP第二章講的非常詳細


推薦閱讀:

寫程序時中間變數用cnm,是什麼心態?
這一段 C++ 代碼有什麼樣的問題?
為什麼C語言不引入類這種語法?
Linux內核應該怎麼去學習?
問一個函數指針問題?

TAG:Java | CC | float | IEEE754 |