[英]Comparing floating point numbers in C
我有一個打印為0.000000
的double
精度數,我試圖將其與0.0f
進行比較,但未成功。 為什么這里有區別? 確定您的雙倍是否為零的最可靠方法是什么?
要確定它是否足夠接近零,它將打印為0.000000
到小數點后六位,例如:
fabs(d) < 0.0000005
不過,處理浮點計算中的小錯誤通常會變得相當復雜。
如果您想更好地了解您所獲得的價值,請嘗試使用%g
而不是%f
進行打印。
你可以做一個范圍。 比如 -0.00001 <= x <= 0.00001
這是現代計算機上浮點運算的基本問題。 它們本質上是不精確的,無法可靠地進行比較。 例如,語言 ML 明確禁止對真實類型進行相等比較,因為它被認為太不安全。 另請參閱 David Goldberg 關於此主題的出色(如果有點長且面向數學)論文。
編輯:tl;博士:你可能做錯了。
此外,浮點數的一個經常被忽視的特征是非規范化數。 這是具有最小指數的數字,但不適合 0.5-1 范圍。
這些數字低於浮點數的 FLT_MIN 和雙精度數的 DBL_MIN。
使用閾值的一個常見錯誤是比較兩個值,或使用 FLT_MIN/DBL_MIN 作為限制。
例如,這會導致不合邏輯的結果(如果您不了解非規范化):
bool areDifferent(float a, float b) {
if (a == b) return false; // Or also: if ((a - b) == FLT_MIN)
return true;
}
// What is the output of areDifferent(val, val + FLT_MIN * 0.5f) ?
// true, not false, even if adding half the "minimum value".
非規范化通常還意味着計算中的性能損失。 但是,您不能禁用它們,否則此類代碼仍可能產生除以零浮點異常(如果啟用):
float getInverse(float a, float b) {
if (a != b)
return 1.0f / (a-b); // With denormals disabled, a != b can be true, but (a - b) can still be denormals, it'll rounded to 0 and throw the exception
return FLT_MAX;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.