# Thread: sine function without use of math library using expansion and calling other functions

1. ## sine function without use of math library using expansion and calling other functions

Code:
```/*

A program to compute the sine of an angle using sine's series expansion and without the use of the maths library
David Tims 10319139 timsd@tcd.ie

*/

#include <stdio.h>

double dfactorial(int n); /*function prototype for dfactorial (given n, outputs n!), mypow (given x and n outputs x^n) and mysine (given x and nmax computes sin(x) for nmax the iterating value) */
double mypow(double x, int n);
double mysine(double x, int nmax);

int main()
{
double x;
int nmax;
printf("Enter a value for 'x' between (pi, -pi) for which 'sin(x)' is to evaluated\n and an iterating value 'n'\n"); /*asks user for values of 'x' and 'nmax' */
scanf("%lf" "%d", &x, &nmax);
mysine(x,nmax); /* applies mysine on 'x' and 'nmax' prducing an approx to sin(x) */
printf("sin(x)=%lf\n", mysine(x,nmax)); /* prints the approx found by mysine for sin(x) */
return 0; /* lets compiler know program has reached the end */
}

double dfactorial(int n) /* defining ifactorial */
{
double i;/*declaring i and z, two new variables to use in ifactorial */
double z;
i=1.0; /* defining i and z */
z=1.0;
if(n==0) /* For n=o the factorial is mathematically defined as 1 */
{
return(1.0); /* returns 1 */
}
else if (n>0) /* for positive n computes algorithm for factorial */
{
while(i<=n)
{
z=z*i; /* e.g case n=2: z=1*1=1 update i++ so i=1+1=2 ===> update z, z=1*2=2!=n! etc for general n */
i++;

}
return(z); /* returns final value of z i.e n! */
}
else
{
printf("You need to enter a positive integer, disregard all output and try again\n"); /* Just to let the user know n needs to be positive and the output is useless */
return(0);
}
}

double mypow(double x, int n) /* defining "mypow" */
{
int a;    /* declaring variables a, b and y to use in mypow */
double b;
double y;
y=1/x; /* need this for the case where n is negative ( i.e x^(-n) = 1/x^n = 1/x*....*1/x ) */
a=1.0;
b=1.0;
if(n==0) /* if n is 0, by definition the value of x^n is 1 (mathematically defined) */
{
return(1);
}
else if (n>0)/* computes algorithm for x^n */
{
while(a<=n)
{
b=b*x; /* e.g n=2 case: b=1*x=x, update a: a=1+1=2 ===> b=x*x=x^2=x^n etc for gen n */
a++;

}
return(b); /* returns final value of z, which is the x^n value required */
}
else /* computes algorithm for x^n when n is negative, note because n is now negative the condition for i needed to be adjusted */
{
while(a>=n+2)
{
b=b*y;
a--;

}
return(b);
}
}

double mysine(double x, int nmax) /*defining mysine function, note it calls other functions for each iteration of n */
{
double c; /* daclaring variables c and t to use in mysine */
double t;
int n;
c=0;
for (n=0; n<nmax; n++)
{

t = (mypow(-1,n))*(x)*(mypow(x,n))*(mypow(x,n))*(1/(dfactorial(2*n+1)));    /* t is the nth tern in the sine series expansion */
c=c+t; /*updates the sum after each value of n to include nth term */
n++;
}
return c;
}```

2. Basically I'm not sure where it is going wrong, it gives me ridiculous values! I made the x^n and n! programs in a sepearte exercise, then we were told to use them together to make the sine one by calling them. I know there are easier ways but this was our exercise

3. You might want to check where the computation is going awry. Is it in the computation of dfactorial()? Is it in the computation of mypow()? Or just in the computation of mysine()?

Remember, both computation of factorial and raising a number to a positive integral power give large results, and can overflow (even a double variable).

The underlying problem, however, is that you are assuming a double variable can exactly represent any real value. In reality, floating point is an approximation, and because it is an approximation, small errors can creep into any calculation and - if you do lots of calculations - small errors can add up to become big errors. There is a large field of computer science (called numerical analysis) that arises because of that fact .... when doing a calculation with floating point, it is necessary to understand where errors come from and techniques to prevent them propagating.

4. I did a full re check of dfactorial and mypow and they are both working fine. So it must be mysine, I just can't see where. In theory if you input x and 1 iteration value nmax = 1 you should get back x for sinx. But even when I do 2 iteration values it's just spitting back x which it shouldn't

5. You might want to look carefully at the scanf() statement. In particular, check that values of x and nmax are what you expect immediately after reading them. I doubt my concerns about your approach will go away, unless you restrain yourself to small values of x and nmax, though.

6. Value of n is increased twice:
Code:
```    for (n=0; n<nmax; n++)
{

t = (mypow(-1,n))*(x)*(mypow(x,n))*(mypow(x,n))*(1/(dfactorial(2*n+1)));    /* t is the nth tern in the sine series expansion */
c=c+t; /*updates the sum after each value of n to include nth term */
n++;
}```

7. Thank you! excellent spot! Will try see if this fixes it!

8. Was trying to send you a message of thanks but couldn't find the option. Thank you very much for taking the time to read the code, it did fix it. Cheers! Thanks to Grumpy and anybody else who gave it a glance