评估和打印阶乘

时间:2015-04-06 07:44:35

标签: c

请考虑以下事项:

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值?

2 个答案:

答案 0 :(得分:1)

因为它溢出了。

16次迭代后f的值大于代码看起来如此且初始f为2的情况:

f *= f*f;

相同
f = f*f*f

所以你拿了一个立方体16次 - 这太棒了!

2 ^ 3 = 8

8 ^ 3 = 512

512 ^ 3 = 134217728

...

答案 1 :(得分:1)

关于未定义行为的主题,l中的%lf长度修饰符仅为使用整数类型的转换说明符定义。如果您打算使用%Lf,那么您的论证应该是long double。也许您打算使用%f,它对应于double参数(float最终提升为double时将其传递给printf等可变参数函数)。

正如Peter Ivanov所解释的那样,你的计算导致了溢出,IIRC也是未定义的行为。

正如您可能已经猜到的那样,您可以在整个代码中使用long double类型(以及相应的%Lf格式说明符)找到问题的解决方案......