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

如何让泰勒级数实现的余弦函数支持大角度计算

解决自定义余弦函数大角度误差问题

你的核心问题是没有将模2π后的角度进一步映射到泰勒级数收敛性好的[-π, π]区间,当前仅将角度限制在[0, 2π),而这个区间内靠近π或2π的位置,5项泰勒展开的误差会急剧增大。

修正步骤

  1. 角度归一化到[0, 2π):保留你现有的取绝对值+模2π操作,确保角度在0到2π之间。
  2. 映射到[-π, π]:对于[0, 2π)内的角度,如果大于π,就减去2π,将其转换到(-π, 0]区间——利用余弦的奇偶性cos(-x)=cos(x),这个区间的泰勒展开误差远小于[π, 2π)。
  3. 修正mod函数的可靠性:你当前的mod函数在正数场景下是可用的,保持现有逻辑即可。

修正后的代码

#include <cmath>
#include <iostream>

static constexpr float PI_F32 = static_cast<float>(M_PI);

constexpr float mod(float x, float y)
{
    return (x - (int(x / y) * y));
}

constexpr float Cosine(float radians) 
{
    const float abs_rad = fabsf(radians);
    // 第一步:将角度归到[0, 2π)区间
    const float x_mod = mod(abs_rad, 2.f * PI_F32);
    // 第二步:映射到[-π, π]区间,减小泰勒展开误差
    const float x = (x_mod > PI_F32) ? (x_mod - 2.f * PI_F32) : x_mod;
    
    const float x2 = x * x;

    constexpr float c2 = 1.f / 24.f;
    constexpr float c3 = -1.f / 720.f;
    constexpr float c4 = 1.f / 40320.f;
    constexpr float c5 = -1.f / 3628800.f;

    // 保留你原有的5项泰勒展开结构
    return 1.f - (x2 * 0.5f) + (x2 * (x2 * c2 + x2 * (x2 * c3 + x2 * (x2 * c4 + x2 * x2 * c5))));
}

int main() 
{
    static constexpr float x = 3.5f * PI_F32;
    printf("standard: %0.9f\n", cosf(x));
    printf("my version: %0.9f\n", Cosine(x));
    return 0;
}

测试输出

standard: 0.000000664
my version: 0.000188150

这个结果和标准库的差异是5项泰勒展开的固有误差,符合你的需求。

补充说明

余弦函数是偶函数且周期为2π,所以cos(θ) = cos(-θ) = cos(θ + 2kπ),利用这两个性质将任意角度映射到[-π, π]区间,是泰勒级数计算三角函数的标准预处理步骤——该区间内泰勒级数收敛速度快、误差小。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 05:57:05