Integer Sine(x) program.
Greg F. Shay
gfs at abvax.UUCP
Tue May 24 00:15:43 AEST 1988
Here's my program. It is basically a straightforward power series
computation, albeit in integer. The only tricky part was keeping track
of the decimal point and making sure the intermediate calculations did not
overflow.
In my first version, I left the constant expressions like
(short)(SCALE*6.2831853) directly in the code, thinking the compiler would
do the math and store the (short) result as a constant. To my surprise, the
compiler left the computation in (@#%!* compiler!). So I resorted to sticking
the 'magic numbers' in by hand. The difficulty is now that the #defines cannot
be changed for any other values. By changing these constants and the #defines,
8 decimal points (#define SSHIFT 8 #define SCALE 256) works, but SSHIFT 9
overflows the intermediate computations.
Greg Shay
..pyramid |
..mandrill |..!abvax!gfs
..decvax |
#define SSHIFT 7
#define SCALE 128
short cosx(x)
short x;
{
/* Return power series approximation to cos(x) */
/* using only simple math functions */
short frac,sign;
int y,z;
sign = 1;
/* cos(-x) = cos(x) */
if (x<0)
x = -x;
/* cos(x+2pi) = cos(x) */
frac = x/804;
/* 804=(SCALE*6.2831853) */
x = x- frac*804;
/* cos(x) = cos(2pi-x) */
if (x > 402) /*402 = SCALE * 3.14159265 */
x = 804 - x;
/* cos(x) = -cos(pi-x) */
if (x > 201 )
{
x = 402-x;
sign = -1;
}
z = (((int)x)*x)>>SSHIFT; /* z has x^2 */
frac = SCALE-(z>>1);
y = z*z; /* y has SCALE*x^4 */
frac += y*682 >>((SSHIFT<<1)+SSHIFT);
/* 682 = ((int)(.04166667*SCALE*SCALE)) */
z = y*z>>SSHIFT; /* z has SCALE*x^6 */
frac -= z*23 >>((SSHIFT<<1)+SSHIFT);
/* 23 = (int)(.001388889*SCALE*SCALE) */
/* The following are the first 5 terms of the power series. Only the first */
/* three are needed at the seven decimal bit precision representation. *.
/*frac = 1-x*x*.5+x*x*x*x*.041666667-x*x*x*x*x*x*.00138889+x*x*x*x*x*x*x*x*
(2.4801587E-5)-x*x*x*x*x*x*x*x*x*x*(2.7557319E-7);*/
return((sign==1) ? frac : -frac);
}
short sinx(x)
short x;
{
/* Return power series approximation to sin(x) */
/* Use the fact that sin(x) = cos(x-pi/2) */
return( cosx(x-((short)(SCALE*1.5707963)) ));
}
More information about the Comp.lang.c
mailing list