为何计算自然常数e的函数调用时,阶乘值出现异常变化?
自然常数e计算代码中阶乘函数返回值异常问题分析
我编写了一段计算自然常数e的C语言代码,但调用计算e的函数时,阶乘函数fact()返回的值出现异常变化。我知道把所有代码放进main函数能解决,但核心困惑是fact函数和e函数之间的通信问题。相关代码如下:
#include <stdio.h> #include <math.h> int main() { double precision = 0; printf("\ninsert number\n"); while(precision < 1){ scanf("%lf",&precision); } printf("the value of e with precision of %.0lf is %lf",precision,e(precision)); return 0; } int fact(int num){ int ris = 1; for(int i = num;i > 0;i--){ ris = ris * i; } printf("res=%d\n",ris); return ris; } int e(double precision){ double valE = 1; for(double i = precision;i > 0 ;i--){ valE = valE + 1/fact(i); printf("\nsame res:%.1lf\n",fact(i)); } return (double)valE; }
问题根源
- 函数未提前声明:C语言要求函数调用前必须声明或定义。
main调用e()、e()调用fact()时都没提前声明,编译器会默认它们返回int类型,但e()实际要返回double,这会触发隐式转换错误,导致返回值异常。 - 参数与返回值类型不匹配:
fact()接收int参数,但e()里的循环变量i是double,传入时会隐式转成int,如果输入的precision是小数,会直接截断整数部分,破坏计算逻辑;另外e()声明返回int,实际返回double,强制转换会丢失精度。 - 重复调用阶乘函数:
e()的循环里每次调用两次fact(i),不仅浪费计算资源,还会因为函数调用的副作用(比如打印)导致输出混乱,若出现溢出,两次返回值可能不一致。 - 整数溢出:
int类型的最大值是2147483647,当num≥13时,13!的结果已经超过这个值,会发生整数溢出,返回错误的垃圾值。
修正后的代码
#include <stdio.h> #include <math.h> // 提前声明函数,让编译器知晓函数签名 double fact(int num); double e(int precision); int main() { int precision = 0; printf("\n请输入精度值(≥1的整数)\n"); while(precision < 1){ scanf("%d", &precision); } printf("精度为%d时,e的值为%.10lf\n", precision, e(precision)); return 0; } // 阶乘函数返回double类型,避免整数溢出 double fact(int num){ double ris = 1.0; for(int i = num; i > 0; i--){ ris *= i; } printf("阶乘%d! = %.0lf\n", num, ris); return ris; } // e函数返回double,参数改为int(迭代次数用整数更合理) double e(int precision){ double valE = 1.0; // 按泰勒展开顺序从1到precision累加,逻辑更清晰 for(int i = 1; i <= precision; i++){ double fact_val = fact(i); // 只调用一次阶乘,保存结果复用 valE += 1.0 / fact_val; printf("当前累加结果:%.10lf\n", valE); } return valE; }
关键修正说明
- 提前声明
fact和e函数,解决未声明调用导致的类型匹配问题。 - 将
fact的返回值改为double,避免整数溢出,支持计算更大的阶乘。 - 调整
e函数的参数为int(精度代表迭代次数,用整数更合理),返回值改为double,保证计算精度。 - 在
e函数中只调用一次fact(i)并保存结果,避免重复计算和副作用干扰。 - 调整循环方向为从1到precision,更贴合e的泰勒展开公式逻辑(
e = 1 + 1/1! + 1/2! + ... + 1/n!)。
内容的提问来源于stack exchange,提问作者user21000968
相关产品推荐
相关产品推荐

