浮點數計算務必考慮浮點表示誤差並使用epsilon

對於浮點數的計算非常容易產生懶惰的想法而試圖忽視掉浮點表示的缺陷。最簡單的例子是浮點表示某些數值會有誤差,這個時候必須考慮使用epsilon。比如我要比較abs(a/b - c/d)的最小值,如果數值一樣就取字典最小序。如下版本是有問題的:

double ans = abs(elements[v[0]] * 1.0 / elements[v[1]] - elements[v[2]] * 1.0 / elements[v[3]]);
if (ans < bestAns) {
    bestAns = ans;
    bestSolution = v;
}

比如abs(9995/10000 - 9994/10000)的結果就大於abs(9995/10000 - 9996/10000)的結果,雖然它們的結果本來是一樣的。這時必須記住要使用epsilon來避免這樣的問題:

double ans = abs(elements[v[0]] * 1.0 / elements[v[1]] - elements[v[2]] * 1.0 / elements[v[3]]);
if (bestAns - ans > std::numeric_limits<double>::epsilon()) {
    bestAns = ans;
    bestSolution = v;
}
浮點數還經常容易出的問題是數值很大時同樣會丟掉小數值部分的精度。這個問題就更麻煩一些,以後再整理。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章