diff options
author | Christopher Faylor <me@cgf.cx> | 2000-02-17 19:39:52 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2000-02-17 19:39:52 +0000 |
commit | 8a0efa53e44919bcf5ccb1d3353618a82afdf8bc (patch) | |
tree | 68c3dbf3f2c6fd5d49777def9914d77b5cd4589d /newlib/libm/mathfp/s_sine.c | |
parent | 1fd5e000ace55b323124c7e556a7a864b972a5c4 (diff) | |
download | cygnal-8a0efa53e44919bcf5ccb1d3353618a82afdf8bc.tar.gz cygnal-8a0efa53e44919bcf5ccb1d3353618a82afdf8bc.tar.bz2 cygnal-8a0efa53e44919bcf5ccb1d3353618a82afdf8bc.zip |
import newlib-2000-02-17 snapshot
Diffstat (limited to 'newlib/libm/mathfp/s_sine.c')
-rw-r--r-- | newlib/libm/mathfp/s_sine.c | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/newlib/libm/mathfp/s_sine.c b/newlib/libm/mathfp/s_sine.c new file mode 100644 index 000000000..9642f4a56 --- /dev/null +++ b/newlib/libm/mathfp/s_sine.c @@ -0,0 +1,166 @@ + +/* @(#)z_sine.c 1.0 98/08/13 */ +/****************************************************************** + * The following routines are coded directly from the algorithms + * and coefficients given in "Software Manual for the Elementary + * Functions" by William J. Cody, Jr. and William Waite, Prentice + * Hall, 1980. + ******************************************************************/ + +/* +FUNCTION + <<sin>>, <<cos>>, <<sine>>, <<sinf>>, <<cosf>>, <<sinef>>---sine or cosine +INDEX +sin +INDEX +sinf +INDEX +cos +INDEX +cosf +ANSI_SYNOPSIS + #include <math.h> + double sin(double <[x]>); + float sinf(float <[x]>); + double cos(double <[x]>); + float cosf(float <[x]>); + +TRAD_SYNOPSIS + #include <math.h> + double sin(<[x]>) + double <[x]>; + float sinf(<[x]>) + float <[x]>; + + double cos(<[x]>) + double <[x]>; + float cosf(<[x]>) + float <[x]>; + +DESCRIPTION + <<sin>> and <<cos>> compute (respectively) the sine and cosine + of the argument <[x]>. Angles are specified in radians. +RETURNS + The sine or cosine of <[x]> is returned. + +PORTABILITY + <<sin>> and <<cos>> are ANSI C. + <<sinf>> and <<cosf>> are extensions. + +QUICKREF + sin ansi pure + sinf - pure +*/ + +/****************************************************************** + * sine + * + * Input: + * x - floating point value + * cosine - indicates cosine value + * + * Output: + * Sine of x. + * + * Description: + * This routine calculates sines and cosines. + * + *****************************************************************/ + +#include "fdlibm.h" +#include "zmath.h" + +#ifndef _DOUBLE_IS_32BITS + +static const double HALF_PI = 1.57079632679489661923; +static const double ONE_OVER_PI = 0.31830988618379067154; +static const double r[] = { -0.16666666666666665052, + 0.83333333333331650314e-02, + -0.19841269841201840457e-03, + 0.27557319210152756119e-05, + -0.25052106798274584544e-07, + 0.16058936490371589114e-09, + -0.76429178068910467734e-12, + 0.27204790957888846175e-14 }; + +double +_DEFUN (sine, (double, int), + double x _AND + int cosine) +{ + int sgn, N; + double y, XN, g, R, res; + double YMAX = 210828714.0; + + switch (numtest (x)) + { + case NAN: + errno = EDOM; + return (x); + case INF: + errno = EDOM; + return (z_notanum.d); + } + + /* Use sin and cos properties to ease computations. */ + if (cosine) + { + sgn = 1; + y = fabs (x) + HALF_PI; + } + else + { + if (x < 0.0) + { + sgn = -1; + y = -x; + } + else + { + sgn = 1; + y = x; + } + } + + /* Check for values of y that will overflow here. */ + if (y > YMAX) + { + errno = ERANGE; + return (x); + } + + /* Calculate the exponent. */ + if (y < 0.0) + N = (int) (y * ONE_OVER_PI - 0.5); + else + N = (int) (y * ONE_OVER_PI + 0.5); + XN = (double) N; + + if (N & 1) + sgn = -sgn; + + if (cosine) + XN -= 0.5; + + y = fabs (x) - XN * __PI; + + if (-z_rooteps < y && y < z_rooteps) + res = y; + + else + { + g = y * y; + + /* Calculate the Taylor series. */ + R = (((((((r[6] * g + r[5]) * g + r[4]) * g + r[3]) * g + r[2]) * g + r[1]) * g + r[0]) * g); + + /* Finally, compute the result. */ + res = y + y * R; + } + + res *= sgn; + + return (res); +} + +#endif /* _DOUBLE_IS_32BITS */ |