2013-02-21 37 views
3

所以,我试图创建一个程序,通过使用泰勒近似来计算cos(x)。程序非常简单:用户输入一个参数x(x是一个以弧度表示的角度)和一个浮点数ε,它是cos(x)的值的精度。使用Maclaurin系列近似计算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; 
} 

起初,我试图通过一个单独的变量“事实”计算阶乘解决这个问题,虽然造成的溢出,即便在ε合理的较大值。

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

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

3.141593 0.001

的输出是:

COS(3.141593)= -3.934803

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

回答

5

的错误在于while循环的条件:

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

这不是正确的状态。

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

你应该只使用标准的浮点ABS功能,fabs,因为它使你的代码的功能更明显:

while (fabs(term) >= epsilon) 

应用后虽然可以通过固定的逻辑是固定改变和编译你的程序我用它来计算cos(3.141593) = -1.000004,这是正确的。

+1

和链接数学库。 – SparKot 2013-02-21 07:05:40

+2

'cos(x)<-1'这怎么可能是正确的:-) – 2013-02-21 07:11:26

+0

@ ring0 - 遗憾的是,近似算法有时可能会带来些许愚蠢的结果。如果在-1 .. + 1范围之外的估计值是不可容忍的,您可以随时添加检查来执行这些限制。 – Steve314 2013-02-21 07:39:42

4

只需添加到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]范围,然后才计算泰勒展开的参数减少。