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

基于泰勒级数的余弦计算代码为何对大于90度的角失效?

问题分析与修复:手动实现余弦函数的错误排查

你的代码核心问题在于分母的更新逻辑错误,导致泰勒展开式的后续项计算完全偏离了正确形式,无法收敛到cos(π)的正确值-1。

错误细节

余弦的泰勒展开式为:

cos(x) = 1 - x²/2! + x⁴/4! - x⁶/6! + ... + (-1)ⁿx^(2n)/(2n)! + ...

每一项的分母是**(2n)!**(双阶乘),也就是后一项的分母是前一项分母乘以(2n)*(2n-1)。但你的代码中使用了:

denominator = denominator * (denominator+1) * (denominator+2);

这完全错误:比如初始分母是2(2!),第一次循环后得到2*3*4=24(正确的4!),但第二次循环会计算24*25*26=15600,而正确的6!应该是720,这直接导致后续所有项的数值完全错误,无法正确收敛。

修复后的代码

方案1:修正分母更新逻辑(贴近你的原始代码结构)

// Program to find cos x using loop.

#include <stdio.h>

#define _USE_MATH_DEFINES
#include <math.h>

double cosine(double);

int main()
{
    double x;

    printf("Enter angle in degrees: ");
    scanf("%lf", &x);
    x = x*M_PI/180.0;

    printf("The value of cos(%lf) is %lf\n", x, cosine(x));
}

double cosine(double x)
{
    double previous, current = 1;
    double denominator = 1*2; // 初始为2!
    double numerator = x*x;
    double sign = -1;
    int current_even = 2; // 当前项对应的偶数次方的阶乘基数

    while(1)
    {
        previous = current;
        current = current + ((numerator)/(denominator))*sign;
        
        // 正确更新分母:下一个阶乘是 (current_even+2)! = current_even! * (current_even+1)*(current_even+2)
        current_even += 2;
        denominator = denominator * current_even * (current_even - 1);
        numerator = numerator*x*x;
        sign = -sign;

        if (fabs(previous - current)<=0.0001)
        {
            break;
        }
    }
    return current;
}

方案2:更简洁的项迭代方式(推荐)

这种方式直接通过前一项推导后一项,避免单独维护分子分母,逻辑更清晰,同时加入了角度归一化加速收敛:

double cosine(double x)
{
    double previous, current = 1.0;
    // 先将x归一到[-π, π],利用余弦的周期性和奇偶性,加速收敛
    x = fmod(x, 2 * M_PI);
    if (x > M_PI) {
        x -= 2 * M_PI;
    } else if (x < -M_PI) {
        x += 2 * M_PI;
    }

    double term = 1.0;
    int n = 0;
    while (1) {
        previous = current;
        n += 2;
        // 下一项 = 前一项 * (-x²)/(n*(n-1))
        term = term * (-1) * x * x / (n * (n - 1));
        current += term;

        if (fabs(previous - current) <= 0.0001) {
            break;
        }
    }
    return current;
}

效果验证

输入180度时,x转换为π弧度,修复后的代码会正确计算泰勒级数,最终收敛到接近-1的结果(受0.0001精度限制,结果会是-0.9999或更接近的值)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 02:25:48