![](/img/trans.png)
[英]the same regex but different results on Linux and Windows only C++
[英]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)可能會給你一個非常接近你的實際答案的數字,但它們並不完全相同。 因為它會截斷結果。 整個字段專用於浮點運算。 簡而言之,從不在比較中使用浮點數,因為您可能會得到相互矛盾的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.