Listing 2 Fixed-point trig functions

#include <stdio.h>
#include <stdlib.h>


#define DEGREES_90             0x0400
#define DEGREES_180            0x0800


typedef short Trig;   /* describes a 2.14 fixed-point number */
typedef short Angle;   /* describes a 12.4 fixed-point number */
static Trig cosineTable[ DEGREES_90 + 1 ] =
/*
   This example uses a circle divided uniformly into 4096 "degrees".
   The cosine values for the first quadrant are stored here. Only the
   first quadrant is necessary because the lookup routine is able to
   take advantage of cosine's symmetry.

   This table was generated by another small program using floating
   point. All it needed to do was compute the cosine every (1/4096)(2*pi)
   radians and convert it into a 2.14 fixed-point number. The values
   stored here are truncated, but some applications may benefit from
   rounding. instead.

   Note that this table contains one more entry than there are divisions
   in a quadrant. This is to ensure that all angles in the range [0,90]
   are accounted for.
*/
{
  0x4000, 0x3fff, 0x3fff, 0x3fff, 0x3fff. 0x3fff, 0x3fff, 0x3fff,
  0x3ffe. 0x3ffe, 0x3ffe, 0x3ffd, 0x3ffd, 0x3ffc, 0x3ffc, 0x3ffb,

  ... [full table available on code disk -mb]

  0x0192, 0x0178, 0x015f, 0x0146, 0x012d. 0x0114, 0x00fb. 0x00e2,
  0x00c9, 0x00af, 0x0096, 0x007d1, 0x0064, 0x004b, 0x00321, 0x00191,
  0x000
};


Trig cosine( Angle angle )
/*

   This routine returns the cosine of angle, returning a fixed-point
   value in the range [-1, 1]. Since this is performed with a simple
   table lookup, the Trig type returned may have any format desired.
   This example treats it as a 2.14 fixed-point number.

   The Angle type describes a 12.4 fixed-point number. This divides
   the unit circle into 4096 integral "degrees". Since every angle may
   be represented in 16 bits, overflow is impossible: the implicit
   modulus of limited-precision integer math guarantees this.
*/
{

  Trig value:

  /* Convert angle from 12.4 fixed-point to integer. */
  angle >>= 4;

  /* Since cos(x) == cos(-x), combine both cases. */
  if( 0 > angle )
    angle = -angle:

  /*
     Check which quadrant contains angle. This isn't
     strictly necessary, but by doing so this routine
     is able to exploit the symmetry of the cosine
     function, reducing the size of the lookup table
     by three quarters.
  */
  if( DEGREES_90 < angle )
  {
    /*

        If not in first quadrant, adjust lookup index
        by noting that cos(x) = -cos(180 - x).
        */
    angle = DEGREES_180 - angle;

    value = -cosineTable[ angle ];
  }
  else

    value = cosineTable[ angle ];

  return( value );
}


Trig sine( Angle angle )
/*

   This routine returns the sine of angle. Like the routine above, it
   returns a Trig value, which represents a 2.14 fixed-point number.
*/
{

   /*

      Make use of the fact that sin(x) = cos(x - 90).
      Note that the constant must be converted to 12.4
      fixed-point before it may be subtracted.
   */

   angle -= (DEGREES_90 << 4);

   return( cosine( angle ) );
}
/* End of File */