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

为何计算自然常数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;
}

关键修正说明

  1. 提前声明fact和e函数,解决未声明调用导致的类型匹配问题。
  2. 将fact的返回值改为double,避免整数溢出,支持计算更大的阶乘。
  3. 调整e函数的参数为int(精度代表迭代次数,用整数更合理),返回值改为double,保证计算精度。
  4. 在e函数中只调用一次fact(i)并保存结果,避免重复计算和副作用干扰。
  5. 调整循环方向为从1到precision,更贴合e的泰勒展开公式逻辑(e = 1 + 1/1! + 1/2! + ... + 1/n!)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 00:05:24