2011-02-23 64 views
0

當我期待{-0.707107,0,0.707107}時,我正在做一些計算,導致值爲{-0.707107,9.61481e-017,0.707107} 。第二個組成部分雖然基本爲零,但會不會導致問題出現?我應該做些什麼嗎?使用C++雙打。導致數字基本爲零的浮點運算

+1

這真的取決於您的應用程序所需的準確性。舍入錯誤會隨着時間累積,只有您知道它是否適用於您的應用程序。 – driis 2011-02-23 19:01:48

回答

6

這很大程度上取決於您打算在路上做什麼。 :-)但是,獲得與「數學」結果應該非常接近但不完全相等的結果是使用浮點數時必須遵守的。一個常見的解決方案是定義一些「epsilon」值(例如,1e-10),並在所有比較中接受epsilon的錯誤 - 因此x == y將變爲fabs(x - y) < epsilon

+1

如果您正在使用的計算總是導致小數數量有限(你顯然不會,因爲你的數字似乎非常接近'的sqrt(2)'),例如貨幣計算,你應該避免浮點/在雙工作所有的成本,並使用固定的精度數據類型(例如從[GNU多精度算術庫](http://gmplib.org/)),或縮放所有數字,以便您可以使用整數。 – 2011-02-23 19:07:21

+0

Erm - 'sqrt(2)/ 2',即... – 2011-02-23 19:18:58

1

是的,他們可能會導致問題,當與0.比較使用==:這將返回false。 @driis指出,這種舍入誤差也可能會累積。

您可以對此做些什麼:不是使用==進行比較,而是使用允許舍入誤差的比較和/或在算法中適當的點丟棄低於合理閾值的值,具體取決於您想要做的價值觀。

查看任何關於數值算法的好書。

0

您只能安全地使用==比較某些值的浮點數,並且即使只有當您直接賦值這些值時,也不能將其用於任何計算結果。

通常你定義一個函數

bool isEqual(double a,double b) { 
    return fabs(a-b) < 0.0000001; // depends on the precision of your application 
} 

bool isClose(double a,double b) { 
    return fabs(a-b) < 0.001; 
} 
5

他們只會「造成的問題」如果你(一)正在做一個數值不穩定計算(你可能都沒有)或(b)以後會嘗試比較他們使用嚴格的平等。一般來說,你不應該「做些什麼」,你應該確保你的算法不會對少量的不精確性過度敏感。