diff options
Diffstat (limited to 'newlib/libm/mathfp/s_tan.c')
-rw-r--r-- | newlib/libm/mathfp/s_tan.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/newlib/libm/mathfp/s_tan.c b/newlib/libm/mathfp/s_tan.c new file mode 100644 index 0000000..725aeec --- /dev/null +++ b/newlib/libm/mathfp/s_tan.c @@ -0,0 +1,139 @@ + +/* @(#)z_tan.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 + <<tan>>, <<tanf>>---tangent + +INDEX +tan +INDEX +tanf + +ANSI_SYNOPSIS + #include <math.h> + double tan(double <[x]>); + float tanf(float <[x]>); + +TRAD_SYNOPSIS + #include <math.h> + double tan(<[x]>) + double <[x]>; + + float tanf(<[x]>) + float <[x]>; + + +DESCRIPTION +<<tan>> computes the tangent of the argument <[x]>. +Angles are specified in radians. + +<<tanf>> is identical, save that it takes and returns <<float>> values. + +RETURNS +The tangent of <[x]> is returned. + +PORTABILITY +<<tan>> is ANSI. <<tanf>> is an extension. +*/ + +/****************************************************************** + * Tangent + * + * Input: + * x - floating point value + * + * Output: + * tangent of x + * + * Description: + * This routine calculates the tangent of x. + * + *****************************************************************/ + +#include "fdlibm.h" +#include "zmath.h" + +#ifndef _DOUBLE_IS_32BITS + +static const double TWO_OVER_PI = 0.63661977236758134308; +static const double p[] = { -0.13338350006421960681, + 0.34248878235890589960e-2, + -0.17861707342254426711e-4 }; +static const double q[] = { -0.46671683339755294240, + 0.25663832289440112864e-1, + -0.31181531907010027307e-3, + 0.49819433993786512270e-6 }; + +double +_DEFUN (tan, (double), + double x) +{ + double y, f, g, XN, xnum, xden, res; + int N; + + /* Check for special values. */ + switch (numtest (x)) + { + case NAN: + errno = EDOM; + return (x); + case INF: + errno = EDOM; + return (z_notanum.d); + } + + y = fabs (x); + + /* Check for values that are out of our range. */ + if (y > 105414357.0) + { + errno = ERANGE; + return (y); + } + + if (x < 0.0) + N = (int) (x * TWO_OVER_PI - 0.5); + else + N = (int) (x * TWO_OVER_PI + 0.5); + + XN = (double) N; + + f = x - N * __PI_OVER_TWO; + + /* Check for values that are too small. */ + if (-z_rooteps < f && f < z_rooteps) + { + xnum = f; + xden = 1.0; + } + + /* Calculate the polynomial. */ + else + { + g = f * f; + + xnum = f * ((p[2] * g + p[1]) * g + p[0]) * g + f; + xden = (((q[3] * g + q[2]) * g + q[1]) * g + q[0]) * g + 1.0; + } + + if (N & 1) + { + xnum = -xnum; + res = xden / xnum; + } + else + { + res = xnum / xden; + } + + return (res); +} + +#endif /* _DOUBLE_IS_32BITS */ |