Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libm / mathfp / s_atangent.c
blob02675b522573cda1b97968ed452d6198ec3a54a9
2 /* @(#)z_atangent.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 ******************************************************************/
11 FUNCTION
12 <<atan>>, <<atanf>>, <<atan2>>, <<atan2f>>, <<atangent>>, <<atangentf>>---arc tangent
14 INDEX
15 atan2
16 INDEX
17 atan2f
18 INDEX
19 atan
20 INDEX
21 atanf
23 SYNOPSIS
24 #include <math.h>
25 double atan(double <[x]>);
26 float atan(float <[x]>);
27 double atan2(double <[y]>,double <[x]>);
28 float atan2f(float <[y]>,float <[x]>);
30 DESCRIPTION
32 <<atan2>> computes the inverse tangent (arc tangent) of y / x.
34 <<atan2f>> is identical to <<atan2>>, save that it operates on <<floats>>.
36 <<atan>> computes the inverse tangent (arc tangent) of the input value.
38 <<atanf>> is identical to <<atan>>, save that it operates on <<floats>>.
40 RETURNS
41 @ifnottex
42 <<atan>> returns a value in radians, in the range of -pi/2 to pi/2.
43 <<atan2>> returns a value in radians, in the range of -pi/2 to pi/2.
44 @end ifnottex
45 @tex
46 <<atan>> returns a value in radians, in the range of $-\pi/2$ to $\pi/2$.
47 <<atan2>> returns a value in radians, in the range of $-\pi/2$ to $\pi/2$.
48 @end tex
50 PORTABILITY
51 <<atan>> is ANSI C. <<atanf>> is an extension.
52 <<atan2>> is ANSI C. <<atan2f>> is an extension.
56 /******************************************************************
57 * Arctangent
59 * Input:
60 * x - floating point value
62 * Output:
63 * arctangent of x
65 * Description:
66 * This routine calculates arctangents.
68 *****************************************************************/
69 #include <float.h>
70 #include "fdlibm.h"
71 #include "zmath.h"
73 #ifndef _DOUBLE_IS_32BITS
75 static const double ROOT3 = 1.73205080756887729353;
76 static const double a[] = { 0.0, 0.52359877559829887308, 1.57079632679489661923,
77 1.04719755119659774615 };
78 static const double q[] = { 0.41066306682575781263e+2,
79 0.86157349597130242515e+2,
80 0.59578436142597344465e+2,
81 0.15024001160028576121e+2 };
82 static const double p[] = { -0.13688768894191926929e+2,
83 -0.20505855195861651981e+2,
84 -0.84946240351320683534e+1,
85 -0.83758299368150059274 };
87 double
88 atangent (double x,
89 double v,
90 double u,
91 int arctan2)
93 double f, g, R, P, Q, A, res;
94 int N;
95 int branch = 0;
96 int expv, expu;
98 /* Preparation for calculating arctan2. */
99 if (arctan2)
101 if (u == 0.0)
102 if (v == 0.0)
104 errno = ERANGE;
105 return (z_notanum.d);
107 else
109 branch = 1;
110 res = __PI_OVER_TWO;
113 if (!branch)
115 int e;
116 /* Get the exponent values of the inputs. */
117 g = frexp (v, &expv);
118 g = frexp (u, &expu);
120 /* See if a divide will overflow. */
121 e = expv - expu;
122 if (e > DBL_MAX_EXP)
124 branch = 1;
125 res = __PI_OVER_TWO;
128 /* Also check for underflow. */
129 else if (e < DBL_MIN_EXP)
131 branch = 2;
132 res = 0.0;
137 if (!branch)
139 if (arctan2)
140 f = fabs (v / u);
141 else
142 f = fabs (x);
144 if (f > 1.0)
146 f = 1.0 / f;
147 N = 2;
149 else
150 N = 0;
152 if (f > (2.0 - ROOT3))
154 A = ROOT3 - 1.0;
155 f = (((A * f - 0.5) - 0.5) + f) / (ROOT3 + f);
156 N++;
159 /* Check for values that are too small. */
160 if (-z_rooteps < f && f < z_rooteps)
161 res = f;
163 /* Calculate the Taylor series. */
164 else
166 g = f * f;
167 P = (((p[3] * g + p[2]) * g + p[1]) * g + p[0]) * g;
168 Q = (((g + q[3]) * g + q[2]) * g + q[1]) * g + q[0];
169 R = P / Q;
171 res = f + f * R;
174 if (N > 1)
175 res = -res;
177 res += a[N];
180 if (arctan2)
182 if (u < 0.0)
183 res = __PI - res;
184 if (v < 0.0)
185 res = -res;
187 else if (x < 0.0)
189 res = -res;
192 return (res);
195 #endif /* _DOUBLE_IS_32BITS */