# Thread: Sine (Sin) Algorithm Help

1. Originally Posted by StaticKyle
Okay, I implemented yours, laserlight, and I tested it and the answer that I got with setting the loop count or n to 15 wasn't close to the value that I got from my calculated value.
well in that case try this
Code:
```double sine(float x)
{
int i,n;
int sign = -1;
double sum = x,power=x,fact = 1.0,psum=0.0;
for (i = 1; fabs(fabs(sum) - fabs(psum)) > 0.0000000001; ++i)
{
psum=sum;
power = power * x *x;
n = (2*i+1);
fact = fact * n * (n-1);
sum += sign * power/fact;
sign = -sign;
}
printf("n value is &#37;d\n",i);
return sum;
}```
the angle is expressed in radians ,Am i right?

2. Yes, I am given the number in degrees, but I convert it to radians.

I plug 45 into the program, and it returns .707107
but when I plug it into my calculator, I get .8509035245

sin(45 degrees)=0.7071

What I meant to say was: Maybe your calculator is in radian mode.

4. Lol, awesome. Thank you. Now I just feel like a retard.

Now to try and figure out the other method. Is there any way for me to simply use this one and do an if else statement?

5. YAY! I just want everyone to know that I got it working right. Thanks for all of the help guys!

6. That's good. What is your current working solution?

7. Code:
```double sine(float angle)
{
#define EPSILON 0.000001
#define PI 3.14159265358979323846264338327950288419716939937510582097494459
double x = (angle * PI) / 180;
int i;
int sign = 1;
double sum = 0.0;
double temp = 0.0;
double temp2 = 0.0;
for (i = 0; i < 14; ++i)
{
sum += sign * (pow(x, 2 * i + 1) / factorial(2*i+1));
printf("%f  ", sum);
printf("%d \n", i);
if (sign > 0)
{
temp = sum;
}
else
{
temp2 = sum;
}
if (temp - temp2 < EPSILON)
{
i = 14;
}
printf("%f ", temp);
printf("%f \n", temp2);
sign = -sign;
}
return sum;
}```
It probably isn't efficient, but it is due tomorrow, and so I did what I could. I am also having a problem with using multiple libraries (files...) with a single header file. I try to do what I did with this one and it does something strange with the library files. Like, it compiles the first go around, and then I try to compile the main program again so that it works and it gives me an error.

8. It probably isn't efficient, but it is due tomorrow, and so I did what I could.
Well, it's better to try than to be spoonfed.

If you are interested, my answer follows. If it is still not yet past your deadline, I hope that you have the honesty not to copy

Consider the sine computation expressed in summation notation:
From n = 0 to infinity
sine(x) = sum of (-1)^n * (x^(2n+1) / (2n+1)!)

(-1)^n just gives us the sign of the term, so it is not so interesting. What is interesting is the term itself, excluding the sign. As mentioned, it is expensive to calculate the power and the factorial on each iteration, and we risk overflow. What we can do is express the term in relation to the previous term, i.e., a recurrence relation:

0th term = x
nth term = (n-1)th term * (x^2 / (2n * (2n+1)))

Now, x^2 is a loop invariant: it does not change on each iteration. (2n * (2n+1)) is relatively quick to compute and will not overflow unless n is large. Consequently, (x^2 / (2n * (2n+1))) tends to 0 as n tends to infinity. So, all we need to do is keep looping as long as (x^2 / (2n * (2n+1))) is greater than 0.000001.

As such, a solution presents itself:
Code:
```#include <stdio.h>

const double EPSILON = 0.000001;

double sine_nonneg(double x)
{
double term = x;
double sum = x;
int sign = -1;
double x_squared = x * x;
int i;

for (i = 1; term > EPSILON; ++i)
{
term *= x_squared / ((i + i) * (i + i + 1));
sum += sign * term;
sign = -sign;
}

return sum;
}

double sine(double x)
{
return x < 0.0 ? -sine_nonneg(-x) : sine_nonneg(x);
}

int main(void)
{
printf("&#37;f\n", sine(-12.34));
return 0;
}```
I chose to use the sine_nonneg function so as to more easily handle the sine of a negative angle by having sine_nonneg compute the sine of the corresponding non-negative angle.