-
Sine approximation Help
I've been given an assignment to approximate the value of sine of an angle in degrees by using the formula: sin(x) = x −x3/3!+x5/5!−x7/7!+x9/9!· · ·
x is an angle in radians. He wants the program outline to be like so:
1 read in a new value for angle
2 while(angle != 0){
3 convert angle to radians (multiply angle by pi/ 180 )
4 sine = 0
5 n = 1
6 while(n ≤ 15) {
7 calculate next term of series and add it to/subtract it from sine
8 increment n
9 }
10 display sine
11 read in a new value for angle
12 }
I know my problem is my factorial. Im just not sure how to go about this. Can someone please help me with this part? Thanks in advanced
Here is what i wrote:
Code:
#include<math.h>
#include<stdio.h>
#define PI 3.141592653589793
int main()
{
float angle,radian,sine,n,x,factorial,s,i;
x = 1;
printf("Enter angle in degrees (0 to quit)\n");
scanf("%f",&angle);
while (angle!=0){
radian=angle*(PI/180);
sine=0;
n=1;
while (n<=15)
{
s = (radian + (pow(-1,n+1))+(pow(radian, n)) / (n));
n++;
}
printf("sin(%f)=%f\n",angle,s);
printf("Enter angle in degrees (0 to quit): ");
scanf("%f",&angle);
}
}
return 0;
}
-
Oops, said nothing. In fact, i was wrong heh.
-
lol, thats was the funiest thing i ever heard.
-
Write a function called factorial, and call it in the appropriate place in your expression.
Much like you're using the predefined function pow().
-
I'm back!
I just retough about it before going to bed, and i wasn't completely wrong in my other post. Because when i saw the problem and the loop, i instantly tough about an iterative calcul for finding the result, and iterative calcul does ask for correct initialisation. But, and that's what i didn't see, your loop
Code:
while (n<=15)
{
s = (radian + (pow(-1,n+1))+(pow(radian, n)) / (n));
n++;
}
is doing the same thing as
Code:
s = (radian + (pow(-1,16))+(pow(radian, 15)) / (15));
// for easier read; s = radian + pow(-1, 16) + pow(radian, 15) / 15;
n = 16;
So, as you can see, your loop is useless (well, it's bad constructed, like my sentences :D ). Example, let's say we need the sine of Pi/4 (0.7853...), which the correct answer is 0.70710... the program answer is 1.7871... which i bet is equal to
s = 0.7853 + pow(-1,16) + pow(0.7853, 15) / 15
= 0.7853 + 1 + 0.0339 / 15
= 1,7875
which is what (well, guess i didn't take enough significiants numbers to get the exact same result) the program gave as answer.
Oh and by the way, you could remove some paranthesis in your equation, they make it harder to read...
-
Lol. I actually posted the wrong thing on my s variable. Its suppose to be:
s= (pow(-1,n+1)*pow(radian, 2*n+1)/2*n+1;
sin=radian-s
I know I need to calculate the factorial of n!
Doesn't this code run until n=15 and adds 1 to n each loop.
For example:
sin(pi/4)=pow(-1,1+1)*pow(0.785,2*1+1)/2*1+1
sin(0.785)=1*pow(0.785,3)/3!...................all the way until n=15
Now if i knew how to put the factorial in my code, that would work. Cause the factorial of 3 is 6. Also the pow(-1,n+1) takes care of the sign changes
Code:
while (n<=15)
{
s= (pow(-1,n+1)*pow(radian, 2*n+1)/2*n+1;
sin=radian-s
n++;
}
-
If your only problem is to calculate factorial, it's quite simple to solve: write down a little function or calculate it directly in your loop.
Note that you'll (mostly) have problems calculating 15!, since it's way behond what a 32 bit integer can hold. In fact, you need at least 41 bits to hold the value of 15 factorial... so you won't be able to calculate it with a IEEE32 number (float) neither, but you could use a IEEE64 number (double) to store it correctly... and if you do want to calculate up to 29!, now you'll really need at least a 64 bits unsigned integer (that means you'll have to write some non portable code with, for example, microsoft _int64 type)...
So, let's say you want the result from the suit up to the term x^15 / 15!
Code:
//...
double currentFacto;
double sine;
double radian;
int n;
//...
sine = 0.0;
n = 1;
currentFacto = 1.0; // 1! is 1
while (n <= 15)
{
sine = sine + pow(-1, n/2) * (pow(radian, n) / currentFacto);
currentFacto = currentFacto * ++n;
currentFacto = currentFacto * ++n;
}
This is one way to do so. There's others way to do it. Now you can try your own... and show us what you can do.
Note that you can write "sin(x) = x - x^3/3! + x^5/5! - ..." as "sin(x) = x^1/1! - x^3/3! + x^5/5! - ..."
-
You don't really need to compute the factorial directly, or call pow() at all. Just note that if you were computing the terms by hand, you could get each from the previous one by multiplying by a factor of -x^2/((n+1)*(n+2)) for the appropriate n. In addition, you can precompute x^2. So it's basically two multiplications and one division.
-
Thank you so much for all your help. Now I know how to tackle a problem like this. Not too bad for my first assignment. Thanks again.