簡體   English   中英

相同的C ++'if'語句,在Linux / Windows上有不同的結果

[英]Same C++ 'if' statement, different results on Linux/Windows

我發現了一個有趣的案例,相同的C ++代碼在不同的系統上產生不同的結果。

#include <cstdio>
int main()
{
    int a=20, b=14;
    if(a*1.0/b*(a+1)/(b+1)==2) printf("YES!");
    else printf("NO!");
}

使用GCC 4.6.3在Ubuntu Linux 12.04上編譯,輸出YES!

使用GCC 4.6.2在Windows 7上編譯,輸出NO!

但是,使用:

double  c = a*1.0/b*(a+1)/(b+1);
if (c==2) printf("YES!");
...

將返回YES! 在兩台機器上。

有什么想法出現這種差異? 這是由編譯器版本不匹配引起的(路徑級版本號應該不重要)? 為什么它實際輸出NO! 在Windows機器上,這種情況顯然是真的嗎?

因為您正在對浮點類型進行相等性比較,這通常不應該依賴於機器之間(或從編譯器到編譯器等)的特定位精確行為。

可能的原因包括編譯器選擇何時從寬(80位)浮點寄存器中移出浮點結果(語言標准和IEEE-754浮點標准都沒有強加任何特定要求,AFAIK)。

這只是猜測,您需要查看編譯器的匯編輸出才能確定。

一個編譯器可能會將中間結果存入浮點寄存器,而另一個編譯器將結果寫入存儲器,將其從80位舍入到64位。也可能是使用SSE而另一個不使用SSE。

這是因為浮點運算,請嘗試使用epsilon比較:

#define EPSILON_EQUAL(a,b) ( fabs((a)-(b)) < (0.0001f) )

float f = a*1.0/b*(a+1)/(b+1);
if(EPSILON_EQUAL(f,2.0f)) printf("YES!");

因為由於精度問題而比較浮點數是不正確的。

在數學2/3 =(0.6666666 .....到無窮大)//小學數學:)沒有問題。

在計算中,該計算在浮點單元上執行(類似於CPU,但專用於浮點計算)。 現在這個浮點單元(FPU)可能會給你一個非常接近你的實際答案的數字,但它們並不完全相同。 因為它會截斷結果。 整個字段專用於浮點運算。 簡而言之,從不在比較中使用浮點數,因為您可能會得到相互矛盾的結果。

測試浮點數之間的相等性是有問題的。 這是因為舍入錯誤,互聯網上有很多很多文本。

你可以在這里這里這里這里這里看到這一點 ,基本上是google搜索floating point equality任何結果。

暫無
暫無

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

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