I have to implement my own version of the double cos(double x)
function present in the <math.h>
library of C.
There are some things that I don't understand about the implementation of this function.
Principally, I have to:
receive user input (a double x
, for example), implement the Taylor series of a cosine upon that double x
then return a double number.
I need to compare my implementation with the built-in double cos(double x)
, and print it out as well.
My function needs to be precise to the level of 1.0e-6 (which is 1 millionth, 7 decimal points after the number)
It seems that I lack the basic understanding of such implementation, since I stumble upon many problems here.
My user input is incorrect. I applied a double number, and not only it prints out the wrong number, it prints out a random number every time.
The way I have calculated the cosine value, using the Taylor series of a cosine is probably incorrect as well.
The built-in double cos(double x)
function is having the same behavior, printing the wrong numbers, and a random number every time.
I have used the GCC complier, and compiled the files with the following line:
gcc -ansi -Wall -pedantic my_cos.c -lm
As you can, every thing about those results is just... wrong:
Here is my my_cos.h file:
#define PI 3.1415926535
double my_cos(double);
Here is my my_cos.c file:
#include <stdio.h>
#include <math.h>
#include "my_cos.h"
double my_cos(double x) {
double cos = 1 - ((pow(x, 2)) / (2)) + ((pow(x, 4)) / (24))
- ((pow(x, 6)) / (1 * 2 * 3 * 4 * 5 * 6))
+ ((pow(x, 8)) / (1 * 2 * 3 * 4 * 5 * 6 * 7 * 8))
- ((pow(x, 10)) / (1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10));
return cos * ((PI) / (180));
}
int main() {
double x;
printf("Please insert a number:");
scanf("%f", &x);
printf("Your number is: %f\n", x);
printf("using my function:");
printf("%.7f\n", my_cos(x));
printf("Using C's function:");
printf("%f\n", cos(x));
return 0;
}
This long line double cos = 1 - ((pow(x,2))/(2)) + ((pow(x,4))/(24)) - ((pow(x,6))/(1*2*3*4*5*6)) + ((pow(x,8))/(1*2*3*4*5*6*7*8)) - ((pow(x,10))/(1*2*3*4*5*6*7*8*9*10));
is an implementation of the Taylor series of a cosine:
This line return cos * ((PI)/(180));
is supposed to be a conversion from the degrees form to the radian form, since the built in function also returns the cosine of an argument in radians.
I would more than appreciate to get advice about how to fix those problems and improve my program.
You have to convert the argument of cosine to radians, not the result. Your routine works fine if you just return cos;
. Then it matches the cos()
function pretty well.
As noted in the comments, the calculation can be considerably simplified and sped up by factoring:
double my_cos(double x) {
x *= x;
return 1 - x/2 * (1 - x/12 * (1 - x/30 * (1 - x/56 * (1 - x/90))));
}
(That, of course, takes the argument in radians. As any self-respecting cosine implementation should. You should do the conversion before calling the function.)
Also as noted in the comments, for accuracy this should be used only in the range of 0 to π/2 (or –π/2 to π/2 if that makes the code simpler), with values outside of that converted into that range with the appropriate sign for the result.
Use M_PI
from math.h instead of your own defined (and incorrect) constant.
Use %lf
instead of %f
when doing a scanf()
into a double
.