I'm working at something easy...I guess, but there is something that bothers me.
double x,t,cos_aprox,eps;
int k;
t=1.0;
k=1;
cos_aprox=1.0;`
printf("Introduceti x pentru care se calculeaza cos(x) si eroarea epsilon:\n");
if(scanf("%lf%lf",&x,&eps)!=2)
{
printf("Date eronate!!\n");
exit(1);
}
else
{
do
{
t=t*(-1)*x*x/(k*(k+1));
cos_aprox+=t;
k+=2;
}
while(fabs(t)>eps);
printf("Valoarea aproximativa a lui cos(%g) este %.9g. k este %d\n",x,cos_aprox,k);
printf("Valoarea lui cos(%g), folosind functia din biblioteca, este %.9g.",x,cos(x));
}
It returns good results but when I choose any value over 39 radians there is a significant difference between it and library function cos(x)
.
OP's use of the Taylor's series suffers from numerical limitations with increasing values of x
. The addition of large alternating sign terms accumulate too much error. Amend code to see these terms.
t = t*(-1)*x*x/(k*(k+1));
printf("%e\n", t);
Both sine and cosine calculation benefit with argument reduction to a
range of [-2π ... +2π]. The following is a good 1st step and will provide reduce the error for x
over wider range.
x = fmod(x, 2*π);
Further reduction to the range [0 ... +π/4] can be employed using the usual trigonometric identities and remquo()
. Degrees example
The trouble is that the above calculation relies on an approximate value of π. π, being an irrational number, cannot be represented exactly as a double
. All finite double
are rational numbers. So instead machine pi is used.
// example
#define M_PI 3.1415926535897932384626433832795
x = fmod(x, M_PI);
To achieve accurate calculations over the entire range of double x
requires sophisticated extended precision techniques. Search for Argument reduction for huge arguments: Good to the last bit