2012-12-13 52 views
-4

我想知道下面的C程序是否可能打印其他的東西然後0?加法和減法時的數值問題

double f(double x, double y) { 
    return x*x/x+x*x*x; // or whatever operations using *, /, +, - 
} 
int main(int argc, char** argv) { 
    double x = 4.0; 
    double y = 5.0; 
    double z = f(x,y); 
    x += 1e-7; 
    x -= 1e-7; 
    printf("%f\n", (f(x,y+1e-7)-z)/1e-7);  
    return 0; 
} 

任何人都可以啓發我關於此? 乾杯,

+0

你爲什麼不試試看? – SomeWittyUsername

+0

只是因爲我無法重現它。我只是想看看這個代碼總是會打印0,無論在函數f中使用什麼操作。 – syl

回答

1

如果x必須是4,那麼no,因爲在使用64位IEEE 754二進制浮點算法時,將x加1e-7然後再減去x不會改變x。這意味着x的相同兩個值將被傳遞給f的兩個調用,因此將返回相同的結果,並且它們的差值將爲零。

如果x是可以改變的,那麼你可以通過設置x到0x3.ffffffffffff8p0並通過f改變的聲明得到一個非零值有:

return x*x*x*x*x*x; 
0

忽視您的評論「//或無論使用*,/,+, - 「的操作,你函數f完全忽略y,並且只使用x來返回x + x^3。跟蹤代碼:

z = x + x^3 
f(x, y+1e-7) is also x+x^3, hence equal to z. 

最後要打印

(f(x, y+1e-7) - z)/1e-7 

由於我們建立F(X,Y + 1E-7)等於Z,你正在做的(ZZ)/ 1E-7 。根據定義,0除以任何數字爲0.

請注意,由於兩個數字都以理想方式達成,所以您甚至沒有任何浮點樂趣的機會(其中兩個浮點數實際上是相等的)。因此,對於代碼你可以得到非零打印,除非你有一些硬件或編譯器,或...錯誤。

+0

這假定'f(x,y + 1e-7)'使用與前面的'f(x,y)'相同的'x'值。然而,如果我們允許「x」可能不是「x」,而是'x'='ee' 4.0'在示例代碼中顯示。 –

+0

確實如此。很好的修正。 –