1 
2 /* @(#)z_tanf.c 1.0 98/08/13 */
3 /******************************************************************
4  * The following routines are coded directly from the algorithms
5  * and coefficients given in "Software Manual for the Elementary
6  * Functions" by William J. Cody, Jr. and William Waite, Prentice
7  * Hall, 1980.
8  ******************************************************************/
9 /******************************************************************
10  * Tangent
11  *
12  * Input:
13  *   x - floating point value
14  *
15  * Output:
16  *   tangent of x
17  *
18  * Description:
19  *   This routine calculates the tangent of x.
20  *
21  *****************************************************************/
22 
23 #include "fdlibm.h"
24 #include "zmath.h"
25 
26 static const float TWO_OVER_PI = 0.6366197723;
27 static const float p[] = { -0.958017723e-1 };
28 static const float q[] = { -0.429135777,
29                             0.971685835e-2 };
30 
31 float
32 _DEFUN (tanf, (float),
33         float x)
34 {
35   float y, f, g, XN, xnum, xden, res;
36   int N;
37 
38   /* Check for special values. */
39   switch (numtestf (x))
40     {
41       case NAN:
42         errno = EDOM;
43         return (x);
44       case INF:
45         errno = EDOM;
46         return (z_notanum_f.f);
47     }
48 
49   y = fabsf (x);
50 
51   /* Check for values that are out of our range. */
52   if (y > 105414357.0)
53     {
54       errno = ERANGE;
55       return (y);
56     }
57 
58   if (x < 0.0)
59     N = (int) (x * TWO_OVER_PI - 0.5);
60   else
61     N = (int) (x * TWO_OVER_PI + 0.5);
62 
63   XN = (float) N;
64 
65   f = x - N * __PI_OVER_TWO;
66 
67   /* Check for values that are too small. */
68   if (-z_rooteps_f < f && f < z_rooteps_f)
69     {
70       xnum = f;
71       xden = 1.0;
72     }
73 
74   /* Calculate the polynomial. */
75   else
76     {
77       g = f * f;
78 
79       xnum = f * (p[0] * g) + f;
80       xden = (q[1] * g + q[0]) * g + 1.0;
81     }
82 
83   /* Check for odd or even values. */
84   if (N & 1)
85     {
86       xnum = -xnum;
87       res = xden / xnum;
88     }
89   else
90     {
91       res = xnum / xden;
92     }
93 
94   return (res);
95 }
96 
97 #ifdef _DOUBLE_IS_32BITS
98 
tan(double x)99 double tan (double x)
100 {
101   return (double) tanf ((float) x);
102 }
103 
104 #endif /* _DOUBLE_IS_32BITS */
105