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

C++计算余弦泰勒级数时n大于15返回nan问题求助

问题成因
  • 无符号整型阶乘溢出:你使用的unsigned int类型最大可存储值为4294967295,而13! = 6227020800已经超过该上限,无符号整数溢出会发生值回卷,得到非预期的极小值甚至0,后续运算出现除0错误,最终返回nan。即便换用更大的整型比如unsigned long long,20!就会达到其存储上限,依然无法支撑n到100的计算需求。
  • 分开计算幂次和阶乘的冗余风险:单独计算pow(x, 2*i)和阶乘的方式,即便不出现整型溢出,当x较大时也容易出现分子分母的数值超出浮点精度范围的问题,引入额外精度损失。
  • 补充:pow(-1, i)的写法效率较低,不过不是触发nan的核心原因。
解决办法

核心思路是通过前一项迭代推导后一项的值,避免单独计算阶乘和高次幂,从根源上解决溢出问题:
观察级数的项的规律,第i项和第i-1项的关系为:
a_i = a_{i-1} * (-x²) / (2i * (2i - 1))
其中初始项a₀ = 1,累加和初始值为1,每次迭代计算当前项后更新累加和即可。

修正后的代码如下:

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

double exFive(int n, double x)
{
    double sum = 1.0;
    double term = 1.0; // 存储当前项的值,初始为第0项1
    double x_sq = x * x; // 提前计算x的平方,避免重复运算
    for (int i = 1; i <= n; ++i)
    {
        term = term * (-x_sq) / ((2 * i - 1) * 2 * i);
        sum += term;
        // 可选优化:当项的绝对值小于double精度阈值时提前终止循环
        // if (fabs(term) < 1e-15) break;
    }
    return sum;
}

void fiveIO()
{
    int n = 1;
    double x;
   
    cout << "Input n: ";
    cin >> n;
    while ((n < 1) || (n > 100))
    {
        cout << "Wrong number, input again: ";
        cin >> n;
    } 

    cout << "Input x: ";
    cin >> x;

    cout << "Result is " << fixed << setprecision(2) << exFive(n, x);
}

int main()
{
    fiveIO();
    return 0;
}

修正后的代码完全移除了阶乘计算逻辑,无整型溢出风险,运算过程都是浮点小数乘除,不会出现大数溢出问题,n到100也可以正常计算,同时减少了pow函数调用,运算效率更高,精度也更稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 02:57:04