2010-04-30 65 views
2

對,我想我真的是一個夢想。我有以下的代碼段,其餘編譯和AIX機器上運行:什麼時候是>真實的?

AIX 3 5 
PowerPC_POWER5 processor type 
IBM XL C/C++ for AIX, V10.1 
Version: 10.01.0000.0003 


#include <stdio.h> 
#include <math.h> 

#define RADIAN(x) ((x) * acos(0.0)/90.0) 

double nearest_distance(double radius,double lon1, double lat1, double lon2, double lat2){ 
    double rlat1=RADIAN(lat1); 
    double rlat2=RADIAN(lat2); 
    double rlon1=lon1; 
    double rlon2=lon2; 
    double a=0,b=0,c=0; 

    a = sin(rlat1)*sin(rlat2)+ cos(rlat1)*cos(rlat2)*cos(rlon2-rlon1); 
    printf("%lf\n",a); 
    if (a > 1) { 
     printf("aaaaaaaaaaaaaaaa\n"); 
    } 
    b = acos(a); 
    c = radius * b; 

    return radius*(acos(sin(rlat1)*sin(rlat2)+ 
     cos(rlat1)*cos(rlat2)*cos(rlon2-rlon1))); 

} 

int main(int argc, char** argv) { 
    nearest_distance(6367.47,10,64,10,64); 
    return 0; 
} 

現在,的值「a」的計算報告爲「1」後。而且,在這臺AIX機器上,當我的'if'進入時,看起來1> 1是真的!而我認爲'1'的答案會返回NanQ,因爲1大於1.請問這怎麼可能?我不知道該怎麼想!

代碼工作的其他架構就好其中「a」真正需要的是什麼,我認爲是1和ACOS(a)爲0。

+1

我寧願使用RADIAN(X)(((X)* M_PI )/ 2),你正在調用函數,這是不必要的,也是較慢的。 – nothrow 2010-04-30 10:10:14

+1

回答你的問題,'a> a'永遠不應該是真的,但如果a看起來像1,你可能仍然有'a> 1',所以你需要解決你的問題,因爲標題是誤導性的,你不是實際上比較一個自己。 – 2010-04-30 10:21:27

+1

你們都很漂亮,謝謝!因爲代碼在不同的體系結構/編譯器上工作,所以感到困惑。在AIX上,'a'最終具有類似'1.00000000000000022204'的值。猜猜我現在必須實施epsilon比較。 – Cricri 2010-04-30 10:26:54

回答

8

如果你做一個比較,其中結果和expctedResult是浮動類型:

if (result == expectedResult) 

然後,它是不太可能的比較將是真實的。如果比較是真的,那麼它可能是不穩定的 - 輸入值,編譯器或CPU的微小變化可能會改變結果並使比較結果爲假。

有小量的比較 - 絕對錯誤

if (fabs(result - expectedResult) < 0.00001) 

Comparing floating point numbers


What Every Computer Scientist Should Know About Floating-Point Arithmetic

+0

+1很好的參考 – Juliano 2010-04-30 17:22:13

4

打印出位的值。你可能會被浮點數顯示中的一些舍入誤差愚弄。

1

1.000000000000000000001大於1.你確定你只是看不到足夠的小數位嗎?如果該檢查通過,我會下注你的問題。

通常的解決方案是使用某種形式的epsilon來阻止您擔心舍入錯誤。也就是說,如果你有雙應該再被嘗試做

if (a > 1.00001f) 

它大概足夠接近一個以免造成您的問題:)

4

printf功能,無指定精度,只會秀你的前6位數字。因此,嘗試以更高的精度進行打印...... a可能略大於1,但只有一點點。如果你想使事情更健壯,而不是(a> 1),你可以使用(a-1)> epsilon獲得epsilon的某個值。

相關問題