2015-04-06 160 views
0

考慮以下幾點:評估和打印階乘

double fact(int n) 
{ 
    int i; 
    double res = 1; 
    for (i = 1; i <= n; i++) 
     res *= i; 

    return res; 
} 

double f = 1; 
for (int i = 0; i < 16; i++) 
{ 
    printf("%lf \n", fact(2*i + 1)); 
    f *= (f + 1)*(f + 2); 
    printf("%lf \n", f); 
} 

爲什麼fact(2*i+1)結果的正確值,而f結果1.#INF00一個奇怪的值?

+0

據我所看到的,其實' ()'是一個函數,'f'是代碼中的一個變量和一個無意義的'for'循環。你介意一點點? – 2015-04-06 07:48:02

回答

1

因爲它溢出。

f後16次迭代的值大於如果你的代碼看起來像這樣和你最初的f爲2:

f *= f*f; 

這是一樣的

f = f*f*f 

所以你需要立方體16次 - 這是巨大的!

2^3 = 8

8^3 = 512

512^3 = 134217728

...

+0

但即使'f * =(f + 1)'溢出。爲什麼? – Elimination 2015-04-06 07:52:13

+1

相同的原因 - 採取正方形16次是巨大的...什麼是你想要實現的。 – 2015-04-06 07:53:20

+0

「事實」功能的相同行爲 – Elimination 2015-04-06 07:54:04

1

論的未定義的行爲的話題,l長度修改在%lf僅針對使用整數類型的轉換說明符進行定義。如果你打算使用%Lf,那麼你的論點應該是long double。也許你打算使用%f,這對應於double參數(floats在將它們傳遞給可變參數函數(如printf)時最終升級爲double)。

正如Peter Ivanov解釋的那樣,你的計算會導致溢出,這種IIRC也是未定義的行爲。

正如你可能已經猜到了,你可能會發現,通過使用long double型整個代碼到你的問題的解決方案(以及相應的%Lf格式說明)......