【问题标题】:Calculation of cos(x) using a Maclaurin series approximation使用 Maclaurin 级数近似计算 cos(x)
【发布时间】:2013-02-21 06:41:50
【问题描述】:

所以,我正在尝试创建一个使用泰勒近似计算 cos(x) 的程序。

程序很简单:用户输入一个参数x(x是弧度的角度)和一个浮点数ε,即cos(x)值的精度。

基本上,程序唯一要做的就是计算这个总和: x^0/0! - x^2/2! + x^4/4! - x^6! + x^8/8! - ...,直到各项小于 ε,即 cos(x) 的值都在我们的精度范围内。

所以,这里是代码:

#include <stdio.h>

/* Calculates cos(x) by using a Taylor approximation:
   cos(x) = x^0/(0!) - x^2/(2!) + x^4/(4!) - x^6/(6!) + x^8/(8!) - ... */

int main(void)
{    
    int   k;         // dummy variable k

    float x,         // parameter of cos(x), in radians
          epsilon;   // precision of cos(x) (cos = sum ± epsilon)
          sum,       // sum of the terms of the polynomial series
          term;      // variable that stores each term of the summation

    scanf("%f %f", &x, &epsilon);

    sum = term = 1, k = 0;

    while (term >= epsilon && -term <= epsilon) 
    // while abs(term) is smaller than epsilon
    {
        k += 2;
        term *= -(x*x)/(k*(k-1));
        sum += term;
    }

    printf("cos(%f) = %f\n", x, sum);

    return 0;
}

起初,我尝试通过计算单独变量“fact”的阶乘来解决它,尽管即使 ε 具有合理的大值也会导致溢出。

为了解决这个问题,我注意到我可以将前一项乘以 -x² / (k(k-1)),在每次迭代中将 k 增加 2,以获得下一项。我认为这会解决我的问题,但话又说回来,它不起作用。

程序编译得很好,但是例如,如果我输入:

3.141593 0.001

输出是:

cos(3.141593) = -3.934803

...这显然是错误的。有人可以帮我吗?

【问题讨论】:

    标签: c


    【解决方案1】:

    错误在于您的 while 循环:

    while (term >= epsilon && -term <= epsilon)
    

    这不是正确的条件。虽然可以通过修复逻辑来修复它:

    while (term >= epsilon || -term >= epsilon)
    

    您应该只使用标准的浮点 abs 函数 fabs,因为它使您的代码的功能更加明显:

    while (fabs(term) >= epsilon)
    

    应用该更改并编译您的程序后,我用它来计算cos(3.141593) = -1.000004,这是正确的。

    【讨论】:

    • 并与数学库链接。
    • @ring0 - 可悲的是,近似算法有时会给出略显愚蠢的结果。如果无法容忍超出 -1..+1 范围的估计值,您可以随时添加检查以强制执行这些限制。
    • 谢谢,这很有帮助! =D 使用“&&”而不是“||”对我来说真的很愚蠢,是的,我本可以使用数学库中的 fab,但我认为这有点奇怪(我的意思是,cos(x ) 函数也在数学库中!)。无论如何,再次感谢您的帮助!
    【解决方案2】:

    只是添加到 Charliehorse55 的答案。

    通常使用简单的三角函数来简化参数

    cos(x + y) = cos(x)cos(y) - sin(x)sin(y)
    sin(x + y) = cos(x)sin(y) + sin(x)cos(y)
    

    将参数减少到 [0..SmallAngle] 范围,然后才计算泰勒展开式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-01
      • 2020-03-01
      • 1970-01-01
      • 2021-08-12
      • 2021-09-15
      • 2022-06-10
      • 1970-01-01
      • 2016-08-09
      相关资源
      最近更新 更多