www.xbdev.net xbdev - software development
Friday October 19, 2018
home | about | contact | Donations

Sine and Cosine Functions

by bkenwright@xbdev.net

 

The math.h library contains all the useful functions that you would need.  sin(..) cos(..) rand(..) etc.  But how would you implement them?  Well two of the trickiest to implement are the sin and cos functions - as they require that you have a pretty good grasp of maths.  Especially numbers that recurs forever.  So I've gone an put a couple of functions which you can look at and possibly use in some of your projects.  There not the most optimised functions, but there not the worst either.  One thing you might want to look into, if your into optimisation and asm,  is the built in assembly opcodes which are in all new intel chips...by that I mean p3, p4 etc.

 

But using our beautiful little sin/cos functions, allows us to make pretty much platform independent code...no more relying on those built in library's..hehe

 

 

code: sine.cpp

 

// Simple sine function implementation - no lib's req.

 

// Forward Declarations.

double sine( double x);

double powerd( double x, int y);

double factorial_div( double value, int x);

 

 

/********************************************************************************/

/*                                                                              */

/*  sine( x )                                                                   */

/*                                                                              */

/********************************************************************************/

 

double sine( double x)

{

      int i=0;

      int j=1;

      int sign=1;

      double y1 = 0.0;

      double diff = 1000.0;

      if (x < 0.0)

      {

            x = -1 * x;

            sign = -1;

      }

 

      while ( x > 360.0*3.1415926/180)

      {

            x = x - 360*3.1415926/180;

      }// End while(..)

 

      if( x > (270.0 * 3.1415926 / 180) )

      {

            sign = sign * -1;

            x = 360.0*3.1415926/180 - x;

 

      }

      else if ( x > (180.0 * 3.1415926 / 180) )

      {

            sign = sign * -1;

            x = x - 180.0 *3.1415926 / 180;

 

      }

      else if ( x > (90.0 * 3.1415926 / 180) )

      {

            x = 180.0 *3.1415926 / 180 - x;

 

      }

 

      while( powerd( diff, 2) > 1.0E-16 )

      {

            i++;

            diff = j * factorial_div( powerd( x, (2*i -1)) ,(2*i -1));

            y1 = y1 + diff;

            j = -1 * j;

 

      }// End while (..)

      return ( sign * y1 );

}// End sine(..)

 

/********************************************************************************/

/*                                                                              */

/*  powerd( x, power )                                                          */

/*                                                                              */

/********************************************************************************/

 

double powerd( double x, int y)

{

      int i=0;

      double ans=1.0;

 

      if(y==0) return 1.000;

      else

      {

            while( i < y)

            {

                  i++;

                  ans = ans * x;

 

            }// End while(..)

      }// End else

      return ans;

}// End powerd(..)

 

 

 

/********************************************************************************/

/*                                                                              */

/*  factorial_div( value, x )                                                   */

/*                                                                              */

/********************************************************************************/

 

double factorial_div( double value, int x)

{

      if(x == 0) return 1;

      else

      {

            while( x > 1)

            {

                  value = value / x--;

 

            }// End while(..)

      }// End else

      return value;

}// End factorial_div(..)

 

 

And of course here is our cosine....I've broken up the sine and cosine into separate files...cosine.cpp and sine.cpp... this is so you can play around with the sine and cosine functions separately....and not worry about effecting each other...it also allows you to see how they work easier :)

 

code: cosine.cpp

 

// Simple sine function implementation - no lib's req.

 

// Forward declarations for cosine(..)

double powerd( double x, int y);

double factorial_div( double value, int x);

double cosine( double x);

 

/********************************************************************************/

/*                                                                              */

/*  cosine( x)                                                                  */

/*                                                                              */

/********************************************************************************/

 

double cosine( double x)

{

      int i=0;

      int j=1;

      int sign =1;

      double y1 = 0.0;

      double diff = 1000.0;

 

      if( x < 0) x = -1 * x;

 

      while ( x > 360.0*3.1415926/180)

      {

            x = x - 360*3.1415926/180;

      }

 

      if( x > (270 * (3.1415926/180)) )

      {

            x = 360 * (3.1415926/180) - x;

 

      }

 

      if( x > (180 * (3.1415926/180)) )

      {

            sign = -1;

            x = x - 180 * (3.1415926/180);

 

      }

 

      if( x > (90 * (3.1415926/180)) )

      {

            sign = -1;

            x = 180 * (3.1415926/180) - x;

 

      }// End if(..)

 

      while( powerd( diff, 2) > 1.0E-16 )

      {

            i++;

            diff = j * factorial_div( powerd( x, (2*i -2)) , (2*i -2));

            y1 = y1 + diff;

            j = -1 * j;

 

      }// End while(..)

      return (y1*sign);

}// End cosine(..)

 

 

/********************************************************************************/

/*                                                                              */

/*  powerd( x, power )                                                          */

/*                                                                              */

/********************************************************************************/

 

double powerd( double x, int y)

{

      int i=0;

      double ans=1.0;

 

      if(y==0) return 1.000;

      else

      {

            while( i < y)

            {

                  i++;

                  ans = ans * x;

 

            }// End while(..)

      }// End else

      return ans;

}// End powerd(..)

 

 

/********************************************************************************/

/*                                                                              */

/*  factorial( x )                                                              */

/*                                                                              */

/********************************************************************************/

 

double factorial_div( double value, int x)

{

      if(x == 0) return 1;

      else

      {

            while( x > 1)

            {

            value = value / x--;

 

            }// End while(..)

      }// End else

      return value;

}// End factorial_div(..)

 

 

 

Now don't take my word for the workings of these functions, put together a small console app and run them up....compare the output from our functions...to the output of the standard librarys :)

Here is a simple example of testing the cosine function with the math.h cos one :)

 

code: main.cpp
 

#include <math.h>  // We'll use this so we can compare our results with

                   // the internal vs cos/sin functions and compare the results

                   // we generate with our custom function.

 

#include <stdio.h> // I need this so I can use printf(..)

 

// Forward declaration of our function:

extern double cosine( double x);

 

// Program Entry Point

// This is just a test program - so we can proove that our custom cose functino producese

void main()

{

      float num = 1.0f;

      for(int i=0; i<10; i++)

      {

            printf("library cos(%d) = %02f \t", i, cos(num) );

            printf("my - cosine(%d) = %02f \n", i, cosine(num) );

 

            num+=2;

      }// end for loop

 

}// End main()

 

 

 

Sswweeetttt....nothing like really knowing how to do code, without relying on external librarys.

 

Further work, will be do to a number of smaller more optimised versions of the cosine/sine functions.

 

 

 

 

 

 

 

 

 

 

 

 

 
 Visitor: 9534626  { 209.237.238.175 } Copyright (c) 2002-2017 xbdev.net - All rights reserved.
Designated tutorial and software are the property of their respective owners.