You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何泰勒展开实现的e^x函数在x≥0.6时输出'inf'?

问题分析与解决方案

咱们来拆解下你的代码为什么在x≥0.6时会输出inf——哪怕你设置了res != res_old的终止条件,核心问题出在阶乘溢出和终止条件的触发时机上:

1. 阶乘函数的int溢出问题

你的fak函数用int类型存储阶乘结果,但int的最大值通常只有2^31-1(约21亿)。咱们算一下:

  • 12! = 479001600,还在int范围内
  • 13! = 6227020800,直接超出int上限,会发生溢出,变成负数或者无意义的小值

当阶乘溢出后,pow(x,k)/fak(k)的分母会变成错误值(比如负数或者极小的正数),导致这一项的数值突然变得极大,直接让res累加溢出成inf(无穷大)。这时候你的终止条件res != res_old已经没用了——因为inf和任何数值比较都是不相等的,循环会继续,但结果已经是inf了。

2. 终止条件的逻辑漏洞

你想用res != res_old判断“累加项小到无法改变double精度”从而终止循环,但这个前提是每一项的计算都是正确的。如果在触发这个条件之前,阶乘已经溢出,导致某一项突然爆炸式增长,res直接溢出到inf,那么终止条件就完全失效了。

修复后的代码

解决这个问题的关键是避免直接计算大阶乘,改用递推的方式计算每一项,这样既不会溢出,也更高效:

#include <stdio.h>
#include <math.h>

// 把x作为参数传入,方便测试不同值
double func_e(double x) {
    double res = 1.0;       // k=0时的项是1,作为初始结果
    double current_term = 1.0;  // 当前项的初始值(k=0)
    int k = 1;

    while (1) {
        // 递推计算下一项:第k项 = 第k-1项 * x/k
        current_term *= x / k;
        double res_old = res;
        res += current_term;

        // 当累加后结果不再变化,说明精度已达极限,终止循环
        if (res == res_old) {
            break;
        }
        k++;
    }
    return res;
}

int main(void) {
    printf("e^1 = %.10f\n", func_e(1.0));
    printf("e^0.6 = %.10f\n", func_e(0.6));
    printf("e^2.0 = %.10f\n", func_e(2.0)); // 测试更大的x值
    return 0;
}

修复说明

  • 递推计算项:不用单独算阶乘和pow(x,k),而是用前一项乘以x/k得到当前项,全程用double存储,能处理大得多的k值,不会轻易溢出。
  • 正确的初始值:指数函数的泰勒展开第一项是k=0时的1,所以res和current_term都从1开始。
  • 稳定的终止条件:现在只有当累加项小到无法改变double的精度时才会终止,不会在中途因为溢出导致错误。

这样修改后,别说x=0.6,就算x=2、x=10都能正常输出正确结果啦~

内容的提问来源于stack exchange,提问作者Builderhummel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 23:57:48