IEEE 754浮點數表示標準

二進制數的科學計數法

C++中使用的浮點數包括採用的是IEEE標準下的浮點數表示方法。咱們知道在數學中能夠將任何十進制的數寫成以10爲底的科學計數法的形式,以下html

其中顯而易見,由於若是a比10大或者比1小都可以再次寫成10的指數的形式,如ui

然而要想在二進制的世界中將數字寫成以10爲底的科學計數法的形式,着實有點麻煩,由於你首先須要將二進制的數先化成10進制的表示方法,而後才能寫成科學計數法的形式。可是若是咱們稍微變通一下科學計數法的標記方法,問題就變得特別的簡單了。之因此數學上使用的科學計數法選用10爲底,是由於咱們一般使用的計數方式是十進制的。在計算機的世界中咱們使用的數倒是二進制的,因此咱們在這個世界中應該改用以2爲底的科學計數法而不是10爲底的科學計數法。此時咱們使用的科學計數法就表示成了以下形式,spa

對於一個二進制的數來講是不言而喻的,以爲例.net

IEEE 754標準下的存儲策略

IEEE標準下的浮點數存儲包括三個基本的組成:符號位、指數、尾數(the sign, the exponent, the mantissa),尾數是由小數部分和一個隱含的前導數位組成。至於前導數位隱含的緣由很簡單(下面將會解釋)。code

下面的表格展現了計算機存儲單精度和雙精度浮點數的層次結構,包括每一部分的比特位(比特範圍用方括號括出,00表示最低位)htm

Floating Point Components
  Sign Exponent Fraction
Single Precision 1 [31] 8 [30-23] 23 [22-00]
Double Precision 1 [63] 11 [62-52] 52 [51-00]
  • 符號位

符號位很是簡單,位於存儲浮點數的最高比特位,且只佔1比特。0表示正數,1表示負數。經過改變該比特位的值能夠改變該浮點數的符號。blog

  • 指數位

由於指數位既須要可以表示正指數也須要可以表示負指數,爲了可以作到這一點,須要將真實的指數數值加上一個偏移值得到用來存儲的指數值。對於IEEE標準下的單精度浮點數,這個偏移值是127。所以當真實的指數爲0的時候,咱們存儲的指數位爲127。若是存儲的指數值是200,那麼真實的指數值就應該是(200-127),即73。後面的緣由會指出,指數爲-127(指數位全爲0)和+128(指數位全爲1)會被用來存儲特殊的數值。ip

對於雙精度的浮點數,指數位的長度位11比特,偏移量位1023。內存

  • 尾數

尾數也被稱爲有效數位(significand),決定浮點數的精確度。它由隱含的前導數位(小數點左邊的部分)和小數部分(小數點右邊的部分)組成,由於咱們採用以2爲底的科學計數法表示二進制數,那麼小數點左邊的尾數部分天然是固定值1(),因此前導數位咱們不須要明確的表示出來,咱們只須要存儲尾數的小數部分就能夠了。ci

浮點數存儲示例

下面就以單精度浮點數來浮點數的存儲策略。

十進制數0.1562510 寫成二進制的形式爲0.001012。經過乘以以2爲底的指數,將小數點向右移動3位後獲得

這個時候咱們就可以肯定它的尾數的小數部分和指數分別是多少了,尾數的小數部分位.012,指數爲-3。具體存儲方法見下圖,

在IEEE 745標準下,咱們用三部分來表示一個浮點數:

  • sign = 0, 由於該浮點數爲正數(用1表示負數);
  • 真實的指數是-3,可是咱們用來存儲的指數要在真實的指數上加上偏移量。在單精度浮點數中,這個偏移量是127,在雙精度浮點數中這個偏移量是1023;因此咱們這裏用來存儲的指數應該爲(-3+127),即124。

浮點數的範圍

咱們先來考慮單精度浮點數的範圍問題。注意到咱們用來存儲雙精度浮點數的是一塊長爲32bits的內存,咱們從新解釋了一下該快內存中數字的存儲規則使得表示數的範圍大大增長。可是咱們看看這樣子帶來了什麼問題?

對於32bits的無符號整數來講,它能夠表示0~232-1範圍內的任意整數。可是單精度的浮點數卻作不到這一點,由於浮點數的存儲策略中用來存儲尾數的長度只有24bits,這個時候單精度浮點數就會把將底位的部分截斷,例如

11110000 11001100 10101010 10101111  // 32-bit integer
= +1.1110000 11001100 10101011 x 2^31     // Single-Precision Float
=   11110000 11001100 10101011 00000000  // Corresponding Value

 這樣的方法能夠近似32bits的值,可是並不能獲得準確的結果。忽略精確度的問題,浮點數可以表示的範圍是2127,而32bits整數的表示範圍是232

特殊值

按照上面的浮點數表示方法,咱們發現並不能表示出數值0的大小。由於咱們認爲前導數位的值永遠爲0,這個時候不管尾數的小數部分和指數部分怎麼取,浮點數的值都不會是0。爲此咱們規定,當指數位所有爲0且尾數的小數位全爲0時,這個時候浮點數的值爲0。注意,+0和-0時兩個不一樣的浮點數,即便他們的數值同樣,可是浮點數的表示方式不同。

  • 非標準化的值

當指數部分全爲0,但時小數位不全爲0的時候,這個時候浮點數表示的值就是非標準化的值。這個時候咱們認爲該浮點數的前導數位爲0,所以這個時候的單精度浮點數大小爲(−1)s × 0.f × 2−126,雙精度浮點數的大小爲(−1)s × 0.f × 2−1022,其中s爲符號位上的數值,2爲底的指數分別是-126和-1022,而不是-127和-1023。具體緣由很簡單,由於標準化所能表示的最小值是(−1)s × 1 × 2−126和(−1)s × 1× 2−1022。提出非標準化的目的就是爲了表示更小的值從而提升精確度。

  • 無窮大

當指數位全爲1,而尾數的小數部分全爲0時表示+∞和−∞,同時經過符號位來區分+∞和−∞。因此採用IEEE 754標準表示浮點數能夠很好的處理無窮大的狀況。

  • 非數字(NaN)

NaN(Not a Number)用來表示非數字的值,當指數位全爲1且尾數的小數部分不爲0時表示NaN值。一共有兩類NaN值,靜態非數(QNaN, Quiet NaN)和警告非數(SNaN, Signalling NaN)。

在一個NaN的值中,若是尾數小數部分首位被置位則表示QNaN。QNaN是很重要的一類非數,四則運算常常傳遞QNaN值,該值一般表示不被數學上定義的運算結果,好比除數爲零的時候。

在一個NaN的值中,若是尾數小數部分首位被置0則表示SNaN。它別用來表示操做中的一個異常,能夠用來表示一個未被初始化變量的過早使用。

 

 Reference:

[1] http://steve.hollasch.net/cgindex/coding/ieeefloat.html

[2] https://en.wikipedia.org/wiki/IEEE_754-1985

相關文章
相關標籤/搜索