I want to calculate trigonometric ratio in c using series
sinx = x - x3/3! + x5/5! - x7/7! + a
and want to compare my result with standard math lib function. where a = constant
Any help would be appreciated!!
If the question is how to sum up the series, you could just update the term one by one:
double sum_the_series(double x, size_t number_of_terms)
{
const double x2 = x * x;
double term = x;
double result = term;
for (size_t i = 1; i < number_of_terms; ++i)
{
term = term * x2 / (double(2*i) * double(2*i+1));
if (i % 2 == 0) result += t;
else result -= t;
}
return result;
}
Factorial tends to become huge very fast (12! does not fit into a 32 bit variable); if you don't care too much about precision details and more, you can implement it very naively like
double fact(unsigned int n)
{
double r = 1.0;
if (n == 0 || n == 1) return 1.0;
// memoizing here can help
while(n-- > 0) r *= (double)(n+1);
return r;
}
double part(double x, int n)
{
return (n%2 == 0? -1 : 1)*pow(x, 2*n - 1)/fact(2*n-1);
}
double sinx(double x)
{
static const double a = 0.0020202; // a number
int i;
double r = 0.0;
for (i = 1; i < MAXP; i++)
r += part(x, i);
return r + a;
}
or something like this (I have no tested it). Of course, it is not the exact way sin can be computed correctly.
Apart from the use of the function part, which holds a single "term" of the sum, this is a direct (naive) obvious translation of the mathematical formula. Let us see how to put the formula in a way that it is better to be implemented and has better performance though, to taste any difference you need to compute likely 1M sin-s or more. (This SO does not understand TeX markup as other SO sites?)
x0 = x = x/1!
x1 = -x^3/3! = -x/1! * x^2/(2 * 3) = x0 * x^2/(2 * 3)
x2 = x^5/5! = x^3/3! * x^2/(4 * 5) = -x1 * x^2/(4 * 5)
x3 = -x^7/7! = -x^5/5! * x^2/(6 * 7) = -x2 * x^2/(6 * 7)
.
.
.
xn = -x(n-1) * x^2/(2n * (2n + 1)) for n > 0
The code given in the other answer is the translation of this "formula", not of the original one. So the code, translating this formula, would be as the other answer, more or less:
double sinx(double x, size_t t)
{
double term = x;
double result = term;
size_t i;
for(i = 1; i < t; i++)
{
term *= -x*x/( (double)(2*i*(2*i + 1)) );
result += term;
}
return current + trunc_err(x, t);
}
where trunc_err is a function that computes the error because of the truncation of the serie. (As before, checking if everything is right is left as an exercise)
精彩评论