簡體   English   中英

比較 C 中的浮點數

[英]Comparing floating point numbers in C

我有一個打印為0.000000double精度數,我試圖將其與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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM