2015-04-06 95 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格式说明)......