Update copyright notices with scripts/update-copyrights
[glibc.git] / sysdeps / ieee754 / dbl-64 / s_atan.c
blob0aa145cade5f359fa47fbfe5509c13f95b78c882
1 /*
2 * IBM Accurate Mathematical Library
3 * written by International Business Machines Corp.
4 * Copyright (C) 2001-2014 Free Software Foundation, Inc.
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.
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.
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/>.
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 /************************************************************************/
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 #include <stap-probe.h>
47 void __mpatan (mp_no *, mp_no *, int); /* see definition in mpatan.c */
48 static double atanMp (double, const int[]);
50 /* Fix the sign of y and return */
51 static double
52 __signArctan (double x, double y)
54 return __copysign (y, x);
58 /* An ultimate atan() routine. Given an IEEE double machine number x, */
59 /* routine computes the correctly rounded (to nearest) value of atan(x). */
60 double
61 atan (double x)
63 double cor, s1, ss1, s2, ss2, t1, t2, t3, t7, t8, t9, t10, u, u2, u3,
64 v, vv, w, ww, y, yy, z, zz;
65 #ifndef DLA_FMS
66 double t4, t5, t6;
67 #endif
68 int i, ux, dx;
69 static const int pr[M] = { 6, 8, 10, 32 };
70 number num;
72 num.d = x;
73 ux = num.i[HIGH_HALF];
74 dx = num.i[LOW_HALF];
76 /* x=NaN */
77 if (((ux & 0x7ff00000) == 0x7ff00000)
78 && (((ux & 0x000fffff) | dx) != 0x00000000))
79 return x + x;
81 /* Regular values of x, including denormals +-0 and +-INF */
82 u = (x < 0) ? -x : x;
83 if (u < C)
85 if (u < B)
87 if (u < A)
88 return x;
89 else
90 { /* A <= u < B */
91 v = x * x;
92 yy = d11.d + v * d13.d;
93 yy = d9.d + v * yy;
94 yy = d7.d + v * yy;
95 yy = d5.d + v * yy;
96 yy = d3.d + v * yy;
97 yy *= x * v;
99 if ((y = x + (yy - U1 * x)) == x + (yy + U1 * x))
100 return y;
102 EMULV (x, x, v, vv, t1, t2, t3, t4, t5); /* v+vv=x^2 */
104 s1 = f17.d + v * f19.d;
105 s1 = f15.d + v * s1;
106 s1 = f13.d + v * s1;
107 s1 = f11.d + v * s1;
108 s1 *= v;
110 ADD2 (f9.d, ff9.d, s1, 0, s2, ss2, t1, t2);
111 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
112 ADD2 (f7.d, ff7.d, s1, ss1, s2, ss2, t1, t2);
113 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
114 ADD2 (f5.d, ff5.d, s1, ss1, s2, ss2, t1, t2);
115 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
116 ADD2 (f3.d, ff3.d, s1, ss1, s2, ss2, t1, t2);
117 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
118 MUL2 (x, 0, s1, ss1, s2, ss2, t1, t2, t3, t4, t5, t6, t7,
119 t8);
120 ADD2 (x, 0, s2, ss2, s1, ss1, t1, t2);
121 if ((y = s1 + (ss1 - U5 * s1)) == s1 + (ss1 + U5 * s1))
122 return y;
124 return atanMp (x, pr);
127 else
128 { /* B <= u < C */
129 i = (TWO52 + TWO8 * u) - TWO52;
130 i -= 16;
131 z = u - cij[i][0].d;
132 yy = cij[i][5].d + z * cij[i][6].d;
133 yy = cij[i][4].d + z * yy;
134 yy = cij[i][3].d + z * yy;
135 yy = cij[i][2].d + z * yy;
136 yy *= z;
138 t1 = cij[i][1].d;
139 if (i < 112)
141 if (i < 48)
142 u2 = U21; /* u < 1/4 */
143 else
144 u2 = U22;
145 } /* 1/4 <= u < 1/2 */
146 else
148 if (i < 176)
149 u2 = U23; /* 1/2 <= u < 3/4 */
150 else
151 u2 = U24;
152 } /* 3/4 <= u <= 1 */
153 if ((y = t1 + (yy - u2 * t1)) == t1 + (yy + u2 * t1))
154 return __signArctan (x, y);
156 z = u - hij[i][0].d;
158 s1 = hij[i][14].d + z * hij[i][15].d;
159 s1 = hij[i][13].d + z * s1;
160 s1 = hij[i][12].d + z * s1;
161 s1 = hij[i][11].d + z * s1;
162 s1 *= z;
164 ADD2 (hij[i][9].d, hij[i][10].d, s1, 0, s2, ss2, t1, t2);
165 MUL2 (z, 0, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
166 ADD2 (hij[i][7].d, hij[i][8].d, s1, ss1, s2, ss2, t1, t2);
167 MUL2 (z, 0, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
168 ADD2 (hij[i][5].d, hij[i][6].d, s1, ss1, s2, ss2, t1, t2);
169 MUL2 (z, 0, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
170 ADD2 (hij[i][3].d, hij[i][4].d, s1, ss1, s2, ss2, t1, t2);
171 MUL2 (z, 0, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
172 ADD2 (hij[i][1].d, hij[i][2].d, s1, ss1, s2, ss2, t1, t2);
173 if ((y = s2 + (ss2 - U6 * s2)) == s2 + (ss2 + U6 * s2))
174 return __signArctan (x, y);
176 return atanMp (x, pr);
179 else
181 if (u < D)
182 { /* C <= u < D */
183 w = 1 / u;
184 EMULV (w, u, t1, t2, t3, t4, t5, t6, t7);
185 ww = w * ((1 - t1) - t2);
186 i = (TWO52 + TWO8 * w) - TWO52;
187 i -= 16;
188 z = (w - cij[i][0].d) + ww;
190 yy = cij[i][5].d + z * cij[i][6].d;
191 yy = cij[i][4].d + z * yy;
192 yy = cij[i][3].d + z * yy;
193 yy = cij[i][2].d + z * yy;
194 yy = HPI1 - z * yy;
196 t1 = HPI - cij[i][1].d;
197 if (i < 112)
198 u3 = U31; /* w < 1/2 */
199 else
200 u3 = U32; /* w >= 1/2 */
201 if ((y = t1 + (yy - u3)) == t1 + (yy + u3))
202 return __signArctan (x, y);
204 DIV2 (1, 0, u, 0, w, ww, t1, t2, t3, t4, t5, t6, t7, t8, t9,
205 t10);
206 t1 = w - hij[i][0].d;
207 EADD (t1, ww, z, zz);
209 s1 = hij[i][14].d + z * hij[i][15].d;
210 s1 = hij[i][13].d + z * s1;
211 s1 = hij[i][12].d + z * s1;
212 s1 = hij[i][11].d + z * s1;
213 s1 *= z;
215 ADD2 (hij[i][9].d, hij[i][10].d, s1, 0, s2, ss2, t1, t2);
216 MUL2 (z, zz, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
217 ADD2 (hij[i][7].d, hij[i][8].d, s1, ss1, s2, ss2, t1, t2);
218 MUL2 (z, zz, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
219 ADD2 (hij[i][5].d, hij[i][6].d, s1, ss1, s2, ss2, t1, t2);
220 MUL2 (z, zz, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
221 ADD2 (hij[i][3].d, hij[i][4].d, s1, ss1, s2, ss2, t1, t2);
222 MUL2 (z, zz, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
223 ADD2 (hij[i][1].d, hij[i][2].d, s1, ss1, s2, ss2, t1, t2);
224 SUB2 (HPI, HPI1, s2, ss2, s1, ss1, t1, t2);
225 if ((y = s1 + (ss1 - U7)) == s1 + (ss1 + U7))
226 return __signArctan (x, y);
228 return atanMp (x, pr);
230 else
232 if (u < E)
233 { /* D <= u < E */
234 w = 1 / u;
235 v = w * w;
236 EMULV (w, u, t1, t2, t3, t4, t5, t6, t7);
238 yy = d11.d + v * d13.d;
239 yy = d9.d + v * yy;
240 yy = d7.d + v * yy;
241 yy = d5.d + v * yy;
242 yy = d3.d + v * yy;
243 yy *= w * v;
245 ww = w * ((1 - t1) - t2);
246 ESUB (HPI, w, t3, cor);
247 yy = ((HPI1 + cor) - ww) - yy;
248 if ((y = t3 + (yy - U4)) == t3 + (yy + U4))
249 return __signArctan (x, y);
251 DIV2 (1, 0, u, 0, w, ww, t1, t2, t3, t4, t5, t6, t7, t8,
252 t9, t10);
253 MUL2 (w, ww, w, ww, v, vv, t1, t2, t3, t4, t5, t6, t7, t8);
255 s1 = f17.d + v * f19.d;
256 s1 = f15.d + v * s1;
257 s1 = f13.d + v * s1;
258 s1 = f11.d + v * s1;
259 s1 *= v;
261 ADD2 (f9.d, ff9.d, s1, 0, s2, ss2, t1, t2);
262 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
263 ADD2 (f7.d, ff7.d, s1, ss1, s2, ss2, t1, t2);
264 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
265 ADD2 (f5.d, ff5.d, s1, ss1, s2, ss2, t1, t2);
266 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
267 ADD2 (f3.d, ff3.d, s1, ss1, s2, ss2, t1, t2);
268 MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8);
269 MUL2 (w, ww, s1, ss1, s2, ss2, t1, t2, t3, t4, t5, t6, t7, t8);
270 ADD2 (w, ww, s2, ss2, s1, ss1, t1, t2);
271 SUB2 (HPI, HPI1, s1, ss1, s2, ss2, t1, t2);
273 if ((y = s2 + (ss2 - U8)) == s2 + (ss2 + U8))
274 return __signArctan (x, y);
276 return atanMp (x, pr);
278 else
280 /* u >= E */
281 if (x > 0)
282 return HPI;
283 else
284 return MHPI;
290 /* Final stages. Compute atan(x) by multiple precision arithmetic */
291 static double
292 atanMp (double x, const int pr[])
294 mp_no mpx, mpy, mpy2, mperr, mpt1, mpy1;
295 double y1, y2;
296 int i, p;
298 for (i = 0; i < M; i++)
300 p = pr[i];
301 __dbl_mp (x, &mpx, p);
302 __mpatan (&mpx, &mpy, p);
303 __dbl_mp (u9[i].d, &mpt1, p);
304 __mul (&mpy, &mpt1, &mperr, p);
305 __add (&mpy, &mperr, &mpy1, p);
306 __sub (&mpy, &mperr, &mpy2, p);
307 __mp_dbl (&mpy1, &y1, p);
308 __mp_dbl (&mpy2, &y2, p);
309 if (y1 == y2)
311 LIBC_PROBE (slowatan, 3, &p, &x, &y1);
312 return y1;
315 LIBC_PROBE (slowatan_inexact, 3, &p, &x, &y1);
316 return y1; /*if impossible to do exact computing */
319 #ifdef NO_LONG_DOUBLE
320 weak_alias (atan, atanl)
321 #endif