為什麼 Float和Double會有誤差 (浮點數儲存原理)

  • 31247
  • 0
  • c#
  • 2018-11-11

大家都知道float和double會有誤差 

但原因是什麼呢? 

今天就跟大家分享Float和Double會誤差的原因

一. 浮點數介紹

    一開始先對於float和double做身家調查

浮點類型的範圍

類型 最小值 最大值
float 1.175494351 E – 38 3.402823466 E + 38
double 2.2250738585072014 E – 308 1.7976931348623158 E + 308

浮點類型

類型 有效數字 位元組數
float 6 – 7 4
double 15 – 16 8

 

二. 浮點數產生

float來說可以儲存4 byte  = 32 bit  是說最多可以存32個 0 or 1

floatint都是 32 bit 使用方式卻完全不一樣

浮點數計算方式是由 IEEE 754 進位浮點數算術標準創立

他把浮點數分成三部分 Sign(符號), Exponent(指數), Mantissa(尾數) 來表示他的值

表示方式 1111 1111 1111 1111 1111 1111 1111 1111

  1. Sign(符號)  第1個 bit ​ (紅色)
    1. 0 = 正數
    2. 1 = 負數
  2. Exponent(指數) 第2個  ~ 第9個 bit (藍色)
    1. 總共8 bit 最大值 255 (二進至值)
    2. 127 為中間值原點 
  3. Mantissa(尾數) 第10個  ~ 第32個 bit (棕色)
    1. 計算之後的尾數

到目前因該是有看沒有懂XD

等等帶個範例大家就會比較清楚了

 

三. 實例解說

後面看到 X 代表等待計算的值

12.5f 為例子 如何計算出 32 bit 如何儲存這個值?

  1. 判斷是正數還是負數決定Sign(符號)
    1. 因為12.5f是正數  0XXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
  2. 計算Exponent(指數)​​ 
    1. 將12.5f轉成二進制 12.5f  = 1100.1
    2. 將數值底數變成 1<底數<2   1100.1​ = 1.1001 * 2 ^ 3 
    3. 2^3 二的三次方就是  指數​要加的值  127 + 3 = 130 (1000 0010)
    •    1011 1111 1XXX XXXX XXXX XXXX XXXX XXXX
    • + 0000 0001 1XXX XXXX XXXX XXXX XXXX XXXX  
    • -----------------------------------------------------------------------
    •    1100 0001 0XXX XXXX XXXX XXXX XXXX XXXX
  3.  Mantissa(尾數)​ 計算​
    1. 最後將 1.1001 小數點後的值 .1001追加到(指數​)後面
    •    ​1100 0001 0000 0000 0000 0000 0000 0000 ​​
    • + 0000 0000 0100 1000 0000 0000 0000 0000 ​
    • ---------------------------------------------------------------
    •    0100 0001 0100 1000 0000 0000 0000 0000

所以我們可以得出 12.5f 在 32bit 中是 

0100 0001 0100 1000 0000 0000 0000 0000

 

這裡有個工具  Float (IEEE754 Single precision 32-bit) 可以方便我們來驗算值是否正確

他很貼心幫我們列出  Sign(符號), Exponent(指數), Mantissa(尾數)  位置給我們對應

四,為什麼會不精準

現在我們知道計算 Exponent(指數)​​ 需要將值轉成二進制 ,但如果是12.53f 轉成二進制會變成這樣1100.100000111100111....... 極限值就會和原本的值出現誤差

如圖 我們可以看到 12.53f 其實會變成  1.252999973297119140625E1  這就是float不準確的原因

float介紹完了 double和float概念一樣只是儲存空間更大而已^^

 

小結

因為為了節省空間浮點數 使用特別儲存方式來節省空間,有一好沒兩好這樣就少了精準度


如果本文對您幫助很大,可街口支付斗內鼓勵石頭^^