级数法计算e^x的C语言代码大x值结果失真,求问题排查与解决
问题分析
你的程序计算误差随x增大而显著增大,核心问题出在这几个方面:
- 阶乘溢出:
fact函数用long prod存储阶乘结果,而long的最大值通常是2147483647,当i≥13时,13! = 6227020800已经超出这个范围,会触发整数溢出,得到错误的阶乘值(甚至变为0或负数),直接破坏后续计算。 - sum未重置:外层循环遍历不同x时,
sum仅在程序开头初始化一次,每次计算新的x时,sum是在上一个x的结果上继续累加,完全不符合e^x的级数定义。 - 固定项数不足:你只计算了级数的前10项,对于较大的x(比如x=20),10项远远不足以让级数收敛到足够精确的结果。
- 低效且易溢出的项计算方式:使用
pow(x,i)/fact(i)计算每一项,不仅效率低,还会因为pow和阶乘的溢出提前导致计算错误。
修正后的代码
通过递推计算级数项、重置sum、动态控制项数、避免阶乘溢出这几个点修复程序:
#include <stdio.h> #include <math.h> int main() { float x; // 遍历x从1到19 for(x = 1; x < 20; x++) { double sum = 1.0; // 每个x都重置sum为级数第一项(i=0时的项) double term = 1.0; // 初始项为i=0的项,后续递推计算 int i = 1; // 当项的绝对值大于1e-15时继续累加,保证精度 while(fabs(term) > 1e-15) { term = term * x / i; // 递推计算第i项:term_i = term_{i-1} * x / i sum += term; i++; } printf("by code e^%.1f = %.15lf\n", x, sum); printf("by libfnc e^%.1f = %.15lf\n", x, exp(x)); printf("quotient = %.15lf\n\n", sum / exp(x)); } return 0; }
修正说明
- 递推计算项:通过
term = term * x / i直接得到每一项,避免了单独计算pow和阶乘,彻底解决阶乘溢出问题,同时提升计算效率。 - 每次重置sum:在每个x的循环内初始化sum,确保每个x的级数计算都是从0开始累加。
- 动态控制项数:通过判断项的绝对值是否小于精度阈值(1e-15)来停止累加,保证对于任何x都能计算到足够收敛的项数。
- 移除冗余的fact函数:不再需要单独计算阶乘,简化代码结构。
内容的提问来源于stack exchange,提问作者Ibtida Bin Ahmed
相关产品推荐
相关产品推荐

