Deathkamp Drone
Deathkamp Drone

Reputation: 282

Calculation of cos(x) using a Maclaurin series approximation

So, I'm trying to create a program that calculates cos(x) by using a Taylor approximation.

The program is really simple: The user inputs a parameter x (x being an angle in radians) and a float ε, which is the precision of the value of cos(x).

Basically, the only thing the program has to do is to calculate this sum: x^0/0! - x^2/2! + x^4/4! - x^6! + x^8/8! - ..., until the terms are smaller than ε, that is, the value for cos(x) it'll be within our range of precision.

So, here's the code:

#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;
}

At first, I tried to solve it by calculating the factorials on a separate variable "fact", though that caused an overflow even with reasonable large values for ε.

To solve this, I noticed that I could just multiply the previous term by -x² / (k(k - 1)), increasing k by 2 in every iteration, to get the next term. I thought that would solve my problem, but then again, it is not working.

The program compiles fine, but for example, if I input:

3.141593 0.001

The output is:

cos(3.141593) = -3.934803

...and that is obviously wrong. Can someone help me?

Upvotes: 3

Views: 12354

Answers (2)

Viktor Latypov
Viktor Latypov

Reputation: 14467

Just adding to Charliehorse55's answer.

Usually one does an argument reduction using simple trigonometry

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

to reduce the argument to [0..SmallAngle] range and only then calculate the Taylor expansion.

Upvotes: 4

charliehorse55
charliehorse55

Reputation: 2000

The bug lies in the condition of your while loop:

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

It's not the correct condition. While it could be fixed by fixing the logic:

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

You should just use the standard floating point abs function, fabs, as it makes the function of your code more obvious:

while (fabs(term) >= epsilon)

After applying that change and compiling your program I used it to compute cos(3.141593) = -1.000004, which is correct.

Upvotes: 5

Related Questions