2011-06-17 59 views
1


有沒有人可以向我解釋爲什麼這個程序的執行進入不可行的時候?
我知道雙精度和浮點精度問題的存在,但我不明白在這個例子中的問題。C雙加錯誤

注:我用GCC 4.4.5

#include <stdio.h> 

#define NUM_JOINTS 1 

typedef struct { 
    double t1; 
    double t2; 
    double t3; 
} jointProfile; 

jointProfile jp[NUM_JOINTS]; 

int main() { 
    jp[0].t1 = 0.51639777949432230652604403076111339032649993896484375; 
    jp[0].t2 = 0.00000000000000000000000000000000000000000000000000000; 
    jp[0].t3 = 0.77459666924148340427791481488384306430816650390625000; 

    double maxTime = (jp[0].t1 + jp[0].t2 + jp[0].t3); 

    if ((jp[0].t1 + jp[0].t2 + jp[0].t3) < maxTime) { 
     printf("Infeasible\n"); 
    } 

    return 0; 
} 
+0

你有沒有嘗試在if中添加if作爲double? – mrK

+0

是的,但結果是一樣的 – user803437

回答

2

那麼編譯它的Ubuntu 10.10,顯然你不知道有足夠的瞭解浮點計算的微妙之處。

參見例如http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html

如果你在32位Ubuntu上這樣做,問題可能是maxtime溢出到內存,從而丟失位。

一個解決方法是,將條件改變爲

 

if (fabs(jp[0].t1 + jp[0].t2 + jp[0].t3 - maxtime) < DBL_EPSILON) { 
... 
} 
 
+0

我不需要代碼修復,但問題的確切來源。不過,非常感謝! – user803437

1

在處理器,浮點寄存器是80位(10個字節)寬。在內存中,double是64位(8字節)寬。

if中計算總和並留在CPU寄存器中,而從存儲器中讀取maxTime可能會被截斷。可以解釋奇怪的行爲。

2

這裏是什麼C FAQ說:

要小心,有些機器比存儲在存儲器雙 值更 精度提供浮點 計算寄存器,它可以 導致浮動如果兩個值 只是必須相等,那麼點數不等式 。

所以除非你非常確定你的編譯器存儲了哪些值,否則你不能確定結果。