簡體   English   中英

比較浮點0

[英]Comparing floating-point 0

如果foo是float類型,則以下表達式是有效/推薦的嗎?

(0.0f == foo * float(0))

無論foo的值如何,它都具有預期的(數學)值嗎?

C ++標准是定義行為還是特定於實現?

好吧,首先它不是C ++標准的問題。 相反,問題在於您的浮點模型標准(最可能是IEEE)。

對於IEEE浮點數,這可能是安全的,因為float(0)應該導致與0.0f相同的數字,並且乘以任何其他數字也應該是0.0f。

不安全的是做其他浮點運算(例如:用非整數加法和減法)並用0.0f檢查它們。

AFAIK,它不一定,也可能最終非常接近0。

通常最好與epsilon進行比較。 我使用這樣的函數進行這樣的比較:

float EpsilonEqual( float a, float b, float epsilon )
{
    return fabsf( a - b ) < epsilon;
}

正如其他人已經提到的那樣,NaNs和Infinites可以搞砸這種比較。

但是,還有一個陷阱:在C ++中,你不能依賴float類型的編譯時表達式,比較等於在運行時計算的相同表達式。

原因是C ++允許以任何方式無限制地擴展fp計算的精度。 例:

#include <iostream>

// This provides sufficent obfuscation so that g++ doesn't just inline results.
bool obfuscatedTrue() { return true; }

int main()
{
    using namespace std;

    double const    a   = (obfuscatedTrue()? 3.0 : 0.3);
    double const    b   = (obfuscatedTrue()? 7.0 : 0.7);
    double const    c   = a/b;

    cout << (c == a/b? "OK." : "\"Wrong\" comparision result.") << endl;
}

一個特定編譯器的結果:

C:\test> g++ --version | find "++"
g++ (TDM-2 mingw32) 4.4.1

C:\test> g++ fp_comparision_problem.cpp & a
"Wrong" comparision result.

C:\test> g++ -O fp_comparision_problem.cpp & a
OK.

C:\test> _

干杯&hth。,

- 阿爾夫

使用該特定語句,您可以非常確定結果將為0並且比較結果為true - 我認為C ++標准實際上沒有規定它,但任何合理的浮點類型實現都會有0工作。

但是,對於大多數其他計算,結果不能完全等於數學上正確的結果:

為什么我的數字,如0.1 + 0.2加起來不是很好的一輪0.3,而是我得到一個奇怪的結果,如0.30000000000000004?

因為在內部,計算機使用的格式(二進制浮點)無法准確地表示0.1,0.2或0.3之類的數字。

編譯或解釋代碼時,“0.1”已經四舍五入到該格式中最接近的數字,即使在計算發生之前也會導致小的舍入誤差。

閱讀“浮點指南”以獲取詳細說明以及如何正確地與預期值進行比較

我剛剛在msdn中閱讀了有關VisualStudio 鏈接文本中 / fp選項的這篇文章

不允許對特殊值(NaN,+ infinity,-infinity,+ 0,-0)無效的表達式優化。 優化xx => 0,x * 0 => 0,x-0 => x,x + 0 => x,0-x => -x由於各種原因都無效(參見IEEE 754和C99標准) )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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