]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/ieee754/dbl-64/s_atan.c
Remove ZERO and MZERO macros
[thirdparty/glibc.git] / sysdeps / ieee754 / dbl-64 / s_atan.c
1 /*
2 * IBM Accurate Mathematical Library
3 * written by International Business Machines Corp.
4 * Copyright (C) 2001-2013 Free Software Foundation, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19 /************************************************************************/
20 /* MODULE_NAME: atnat.c */
21 /* */
22 /* FUNCTIONS: uatan */
23 /* atanMp */
24 /* signArctan */
25 /* */
26 /* */
27 /* FILES NEEDED: dla.h endian.h mpa.h mydefs.h atnat.h */
28 /* mpatan.c mpatan2.c mpsqrt.c */
29 /* uatan.tbl */
30 /* */
31 /* An ultimate atan() routine. Given an IEEE double machine number x */
32 /* it computes the correctly rounded (to nearest) value of atan(x). */
33 /* */
34 /* Assumption: Machine arithmetic operations are performed in */
35 /* round to nearest mode of IEEE 754 standard. */
36 /* */
37 /************************************************************************/
38
39 #include <dla.h>
40 #include "mpa.h"
41 #include "MathLib.h"
42 #include "uatan.tbl"
43 #include "atnat.h"
44 #include <math.h>
45
46 void __mpatan (mp_no *, mp_no *, int); /* see definition in mpatan.c */
47 static double atanMp (double, const int[]);
48
49 /* Fix the sign of y and return */
50 static double
51 __signArctan (double x, double y)
52 {
53 return __copysign (y, x);
54 }
55
56
57 /* An ultimate atan() routine. Given an IEEE double machine number x, */
58 /* routine computes the correctly rounded (to nearest) value of atan(x). */
59 double
60 atan (double x)
61 {
62 double cor, s1, ss1, s2, ss2, t1, t2, t3, t7, t8, t9, t10, u, u2, u3,
63 v, vv, w, ww, y, yy, z, zz;
64 #ifndef DLA_FMS
65 double t4, t5, t6;
66 #endif
67 int i, ux, dx;
68 static const int pr[M] = { 6, 8, 10, 32 };
69 number num;
70
71 num.d = x;
72 ux = num.i[HIGH_HALF];
73 dx = num.i[LOW_HALF];
74
75 /* x=NaN */
76 if (((ux & 0x7ff00000) == 0x7ff00000)
77 && (((ux & 0x000fffff) | dx) != 0x00000000))
78 return x + x;
79
80 /* Regular values of x, including denormals +-0 and +-INF */
81 u = (x < 0) ? -x : x;
82 if (u < C)
83 {
84 if (u < B)
85 {
86 if (u < A)
87 return x;
88 else
89 { /* A <= u < B */
90 v = x * x;
91 yy = d11.d + v * d13.d;
92 yy = d9.d + v * yy;
93 yy = d7.d + v * yy;
94 yy = d5.d + v * yy;
95 yy = d3.d + v * yy;
96 yy *= x * v;
97
98 if ((y = x + (yy - U1 * x)) == x + (yy + U1 * x))
99 return y;
100
101 EMULV (x, x, v, vv, t1, t2, t3, t4, t5); /* v+vv=x^2 */
102
103 s1 = f17.d + v * f19.d;
104 s1 = f15.d + v * s1;
105 s1 = f13.d + v * s1;
106 s1 = f11.d + v * s1;
107 s1 *= v;
108
109 ADD2 (f9.d, ff9.d, s1, 0, s2, ss2, t1, t2);
110 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
111 ADD2 (f7.d, ff7.d, s1, ss1, s2, ss2, t1, t2);
112 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
113 ADD2 (f5.d, ff5.d, s1, ss1, s2, ss2, t1, t2);
114 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
115 ADD2 (f3.d, ff3.d, s1, ss1, s2, ss2, t1, t2);
116 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
117 MUL2 (x, 0, s1, ss1, s2, ss2, t1, t2, t3, t4, t5, t6, t7,
118 t8);
119 ADD2 (x, 0, s2, ss2, s1, ss1, t1, t2);
120 if ((y = s1 + (ss1 - U5 * s1)) == s1 + (ss1 + U5 * s1))
121 return y;
122
123 return atanMp (x, pr);
124 }
125 }
126 else
127 { /* B <= u < C */
128 i = (TWO52 + TWO8 * u) - TWO52;
129 i -= 16;
130 z = u - cij[i][0].d;
131 yy = cij[i][5].d + z * cij[i][6].d;
132 yy = cij[i][4].d + z * yy;
133 yy = cij[i][3].d + z * yy;
134 yy = cij[i][2].d + z * yy;
135 yy *= z;
136
137 t1 = cij[i][1].d;
138 if (i < 112)
139 {
140 if (i < 48)
141 u2 = U21; /* u < 1/4 */
142 else
143 u2 = U22;
144 } /* 1/4 <= u < 1/2 */
145 else
146 {
147 if (i < 176)
148 u2 = U23; /* 1/2 <= u < 3/4 */
149 else
150 u2 = U24;
151 } /* 3/4 <= u <= 1 */
152 if ((y = t1 + (yy - u2 * t1)) == t1 + (yy + u2 * t1))
153 return __signArctan (x, y);
154
155 z = u - hij[i][0].d;
156
157 s1 = hij[i][14].d + z * hij[i][15].d;
158 s1 = hij[i][13].d + z * s1;
159 s1 = hij[i][12].d + z * s1;
160 s1 = hij[i][11].d + z * s1;
161 s1 *= z;
162
163 ADD2 (hij[i][9].d, hij[i][10].d, s1, 0, s2, ss2, t1, t2);
164 MUL2 (z, 0, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
165 ADD2 (hij[i][7].d, hij[i][8].d, s1, ss1, s2, ss2, t1, t2);
166 MUL2 (z, 0, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
167 ADD2 (hij[i][5].d, hij[i][6].d, s1, ss1, s2, ss2, t1, t2);
168 MUL2 (z, 0, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
169 ADD2 (hij[i][3].d, hij[i][4].d, s1, ss1, s2, ss2, t1, t2);
170 MUL2 (z, 0, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
171 ADD2 (hij[i][1].d, hij[i][2].d, s1, ss1, s2, ss2, t1, t2);
172 if ((y = s2 + (ss2 - U6 * s2)) == s2 + (ss2 + U6 * s2))
173 return __signArctan (x, y);
174
175 return atanMp (x, pr);
176 }
177 }
178 else
179 {
180 if (u < D)
181 { /* C <= u < D */
182 w = ONE / u;
183 EMULV (w, u, t1, t2, t3, t4, t5, t6, t7);
184 ww = w * ((ONE - t1) - t2);
185 i = (TWO52 + TWO8 * w) - TWO52;
186 i -= 16;
187 z = (w - cij[i][0].d) + ww;
188
189 yy = cij[i][5].d + z * cij[i][6].d;
190 yy = cij[i][4].d + z * yy;
191 yy = cij[i][3].d + z * yy;
192 yy = cij[i][2].d + z * yy;
193 yy = HPI1 - z * yy;
194
195 t1 = HPI - cij[i][1].d;
196 if (i < 112)
197 u3 = U31; /* w < 1/2 */
198 else
199 u3 = U32; /* w >= 1/2 */
200 if ((y = t1 + (yy - u3)) == t1 + (yy + u3))
201 return __signArctan (x, y);
202
203 DIV2 (ONE, 0, u, 0, w, ww, t1, t2, t3, t4, t5, t6, t7, t8, t9,
204 t10);
205 t1 = w - hij[i][0].d;
206 EADD (t1, ww, z, zz);
207
208 s1 = hij[i][14].d + z * hij[i][15].d;
209 s1 = hij[i][13].d + z * s1;
210 s1 = hij[i][12].d + z * s1;
211 s1 = hij[i][11].d + z * s1;
212 s1 *= z;
213
214 ADD2 (hij[i][9].d, hij[i][10].d, s1, 0, s2, ss2, t1, t2);
215 MUL2 (z, zz, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
216 ADD2 (hij[i][7].d, hij[i][8].d, s1, ss1, s2, ss2, t1, t2);
217 MUL2 (z, zz, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
218 ADD2 (hij[i][5].d, hij[i][6].d, s1, ss1, s2, ss2, t1, t2);
219 MUL2 (z, zz, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
220 ADD2 (hij[i][3].d, hij[i][4].d, s1, ss1, s2, ss2, t1, t2);
221 MUL2 (z, zz, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
222 ADD2 (hij[i][1].d, hij[i][2].d, s1, ss1, s2, ss2, t1, t2);
223 SUB2 (HPI, HPI1, s2, ss2, s1, ss1, t1, t2);
224 if ((y = s1 + (ss1 - U7)) == s1 + (ss1 + U7))
225 return __signArctan (x, y);
226
227 return atanMp (x, pr);
228 }
229 else
230 {
231 if (u < E)
232 { /* D <= u < E */
233 w = ONE / u;
234 v = w * w;
235 EMULV (w, u, t1, t2, t3, t4, t5, t6, t7);
236
237 yy = d11.d + v * d13.d;
238 yy = d9.d + v * yy;
239 yy = d7.d + v * yy;
240 yy = d5.d + v * yy;
241 yy = d3.d + v * yy;
242 yy *= w * v;
243
244 ww = w * ((ONE - t1) - t2);
245 ESUB (HPI, w, t3, cor);
246 yy = ((HPI1 + cor) - ww) - yy;
247 if ((y = t3 + (yy - U4)) == t3 + (yy + U4))
248 return __signArctan (x, y);
249
250 DIV2 (ONE, 0, u, 0, w, ww, t1, t2, t3, t4, t5, t6, t7, t8,
251 t9, t10);
252 MUL2 (w, ww, w, ww, v, vv, t1, t2, t3, t4, t5, t6, t7, t8);
253
254 s1 = f17.d + v * f19.d;
255 s1 = f15.d + v * s1;
256 s1 = f13.d + v * s1;
257 s1 = f11.d + v * s1;
258 s1 *= v;
259
260 ADD2 (f9.d, ff9.d, s1, 0, s2, ss2, t1, t2);
261 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
262 ADD2 (f7.d, ff7.d, s1, ss1, s2, ss2, t1, t2);
263 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
264 ADD2 (f5.d, ff5.d, s1, ss1, s2, ss2, t1, t2);
265 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
266 ADD2 (f3.d, ff3.d, s1, ss1, s2, ss2, t1, t2);
267 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
268 MUL2 (w, ww, s1, ss1, s2, ss2, t1, t2, t3, t4, t5, t6, t7, t8);
269 ADD2 (w, ww, s2, ss2, s1, ss1, t1, t2);
270 SUB2 (HPI, HPI1, s1, ss1, s2, ss2, t1, t2);
271
272 if ((y = s2 + (ss2 - U8)) == s2 + (ss2 + U8))
273 return __signArctan (x, y);
274
275 return atanMp (x, pr);
276 }
277 else
278 {
279 /* u >= E */
280 if (x > 0)
281 return HPI;
282 else
283 return MHPI;
284 }
285 }
286 }
287 }
288
289 /* Final stages. Compute atan(x) by multiple precision arithmetic */
290 static double
291 atanMp (double x, const int pr[])
292 {
293 mp_no mpx, mpy, mpy2, mperr, mpt1, mpy1;
294 double y1, y2;
295 int i, p;
296
297 for (i = 0; i < M; i++)
298 {
299 p = pr[i];
300 __dbl_mp (x, &mpx, p);
301 __mpatan (&mpx, &mpy, p);
302 __dbl_mp (u9[i].d, &mpt1, p);
303 __mul (&mpy, &mpt1, &mperr, p);
304 __add (&mpy, &mperr, &mpy1, p);
305 __sub (&mpy, &mperr, &mpy2, p);
306 __mp_dbl (&mpy1, &y1, p);
307 __mp_dbl (&mpy2, &y2, p);
308 if (y1 == y2)
309 return y1;
310 }
311 return y1; /*if impossible to do exact computing */
312 }
313
314 #ifdef NO_LONG_DOUBLE
315 weak_alias (atan, atanl)
316 #endif