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

C#与Python for循环计算e^x结果差异问题咨询

问题核心原因

你遇到的所有异常现象,本质都是C#版本里自定义的Factorial方法使用了整数类型存储阶乘结果,触发了整数溢出,和Python版本的数值类型行为完全不匹配,和泰勒级数本身的收敛特性没有关系。

为什么100次循环直接输出无穷大

阶乘的增长速度远超过普通整数类型的存储上限:

  • int类型最大值约21亿,13!就已经超出这个范围,C#默认关闭整数溢出检查的配置下,溢出后会返回无意义的乱值,甚至可能是0、负数
  • long类型最大值约9e18,21!就会超出这个范围触发溢出
    你用溢出后的错误阶乘值做除法,要么得到异常大的数,要么触发除零,累加值很快就会超过double类型的最大可表示值,最终返回无穷大。
    而Python的math.factorial返回的是任意精度整数,不存在溢出问题,哪怕算100!也能得到精确的整数值,参与除法运算时会自动转换为浮点类型,自然不会出现无穷大的问题。

为什么10次循环的结果和Python跑100次接近

e^x的泰勒级数sum(x^n/n!)收敛速度确实很快:当项数n超过2x之后,新增项的绝对值会快速衰减,n比2x大10左右时,项值就已经小于double类型的最小分辨精度(约1e-16),后续再加多少项都不会改变最终存储的double结果。
比如x=3时,第18项的大小已经不到1e-15,后面80多项累加了也不会对结果产生任何影响。你循环跑10次的时候,n还没到阶乘溢出的阈值,前10项本来就覆盖了最终结果的99.9999%以上,看起来自然和Python跑100次的结果差不多。

为什么循环到20、30次时x>3的结果偏差极大

当j超过整数类型的阶乘溢出阈值后,Factorial(j)返回的就已经不是正确的阶乘值了:要么是溢出后的负数,要么是毫无规律的乱值。这时候你算出来的Math.Pow(x,j)/Factorial(j)项要么是错误的负数,要么是异常大/小的垃圾值,把这些错误项累加进去,结果自然会出现极大偏差。

正确的C#实现

不要单独写返回整数的阶乘方法,直接递推计算每一项,全程用double类型运算,从根源避免大数溢出:

static double Exp(double x)
{
    double result = 1.0; // n=0的初始项
    double currentTerm = 1.0;
    for (int n = 1; n < 100; n++)
    {
        // 递推得到第n项:第n-1项 * x / n 就是x^n/n!,不需要单独计算幂和阶乘
        currentTerm *= x / n;
        result += currentTerm;
        // 当前项已经小到不会影响结果,直接提前退出循环
        if (Math.Abs(currentTerm) < double.Epsilon * Math.Abs(result))
            break;
    }
    return result;
}

这个实现不会出现整数溢出问题,计算结果和Python版本、.NET内置的Math.Exp方法结果完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:48:17