2013-02-21 61 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]範圍,然後才計算泰勒展開的參數減少。