请考虑以下事项:
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
值?
因为它溢出了。
16 次迭代后 f
的值大于代码如下所示且初始f
为 2 时的值:
f *= f*f;
这与
f = f*f*f
所以你拿一个立方体 16 次 - 这是巨大的!
2^3 = 8
8^3 = 512
512^3 = 134217728
。
关于未定义行为的主题,%lf
中的l
长度修饰符仅为使用整数类型的转换说明符定义。如果你打算使用%Lf
,那么你的论点应该是一个long double
。也许你打算使用 %f
,它对应于一个double
参数(当将它们传递给可变参数函数(如 printf
时,float
最终被提升为 double
(。
正如彼得·伊万诺夫所解释的那样,您的计算会导致溢出,IIRC也是未定义的行为。
正如您可能已经猜到的那样,您可以通过在整个代码中使用 long double
类型(以及相应的%Lf
格式说明符(来找到问题的解决方案......