浮點數float累加誤差分析與解決

2021-09-04 05:10:00 字數 1235 閱讀 9301

1.  浮點數ieee 754表示方法

要搞清楚float累加為什麼會產生誤差,必須先大致理解float在機器裡怎麼儲存的,具體的表示參考[1] 和 [2], 這裡只介紹一下組成

由上圖可知(摘在[2]), 浮點數由: 符號位 + 指數字 + 尾數部分, 三部分組成。由於機器中都是由二進位制儲存的,那麼乙個10進製的小數如何表示成二進位制。例如: 8.25轉成二進位制為1000.01, 這是因為 1000.01 = 1*2^3 + 0*2^2 + 0*2^1 + 0*2^0 + 0*2^-1 + 2*2^-2 = 1000.01.

(2)float的有效位數是6-7位,這是為什麼呢?因為位數部分只有23位,所以最小的精度為1*2^-23 在10^-6和10^-7之間,接近10^-7, [3]中也有解釋

那麼為什麼float累加會產生誤差呢,主要原因在於兩個浮點數累加的過程。

2. 兩個浮點數相加的過程

兩浮點數x,y進行加減運算時,必須按以下幾步執行(可參考 [4] 中插圖):

(1)對階,使兩數的小數點位置對齊,小的階碼向大的階碼看齊。

(2)尾數求和,將對階後的兩尾數按定點加減運算規則求和(差)。

(3)規格化,為增加有效數字的位數,提高運算精度,必須將求和(差)後的尾數規格化。

(4)捨入,為提高精度,要考慮尾數右移時丟失的數值位。

(5)判斷結果,即判斷結果是否溢位。

關鍵就在與對階這一步驟,由於float的有效位數只有7位有效數字,如果乙個大數和乙個小數相加時,會產生很大的誤差,因為尾數得截掉好多位。例如:

123 + 0.00023456 = 1.23*10^2 + 0.000002 * 10^2 = 123.0002

那麼此時就會產生0.00003456的誤差,如果累加多次,則誤差就會進一步加大。

那麼怎麼解決這種誤差呢?

3. 誤差解決的方法

(1)kahan summation演算法,具體解釋和實現參考 [5] 和 [6]

(2)使用double型別進行計算,由於double型別的有效數字有15~16位,一般情況下產生誤差可以接受。

reference

[1] ieee 754: floating point in modern computers

[2] c++中,float double區別

[3] how to calculate double + float precision

[4] 浮點加減法的運算步驟

[5] kahan summation algorithm

浮點數 float和double

浮點數使用格式符 f 控制,預設保留小數點後6 位數字。所以當判斷浮點數是否為0的時候,要與 0.000001 和0.000001比較。if abs x 0.000001 有時我們希望自己控制列印的寬度和小數字數,這時就應該使用 m.nf 格式,其中m 表示列印的寬度,n 表示小數點後的位數。m是總...

關於誤差分析以及浮點數的精度問題

浮點,簡單的講就是實數的意思。浮點數就是可以近似表示某個任意的實數。浮點精度分為 16位 一半 二進位制16 32位 單 binary32 十進位制32 64位 double binary64 decimal64 128位 四 binary128 decimal128 256位 八進位制 binar...

計算機浮點數 float 表示

這篇文章講得比較淺顯易懂,所以轉一下。必須對計算機原理的原碼 反碼 補碼 移碼有個清晰的認識,另外參考一下ieee754,否則也會有不明白的地方。括號內為本人看法或觀點。我想浮點數的實現與編譯器也會有很大關係的。前兩天仔細看了看,覺得研究計算機如果不說說如何表示浮點數就太不厚道了.很多人也寫過,這裡...