]>
Commit | Line | Data |
---|---|---|
f7eac6eb | 1 | /* |
e4d82761 | 2 | * IBM Accurate Mathematical Library |
aeb25823 | 3 | * written by International Business Machines Corp. |
dff8da6b | 4 | * Copyright (C) 2001-2024 Free Software Foundation, Inc. |
f7eac6eb | 5 | * |
e4d82761 UD |
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 | |
cc7375ce | 8 | * the Free Software Foundation; either version 2.1 of the License, or |
e4d82761 | 9 | * (at your option) any later version. |
f7eac6eb | 10 | * |
e4d82761 UD |
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 | |
c6c6dd48 | 14 | * GNU Lesser General Public License for more details. |
f7eac6eb | 15 | * |
e4d82761 | 16 | * You should have received a copy of the GNU Lesser General Public License |
5a82c748 | 17 | * along with this program; if not, see <https://www.gnu.org/licenses/>. |
f7eac6eb | 18 | */ |
e4d82761 UD |
19 | /************************************************************************/ |
20 | /* MODULE_NAME: atnat.c */ | |
21 | /* */ | |
22 | /* FUNCTIONS: uatan */ | |
e4d82761 UD |
23 | /* signArctan */ |
24 | /* */ | |
e898cd15 | 25 | /* FILES NEEDED: dla.h endian.h mydefs.h atnat.h */ |
e4d82761 UD |
26 | /* uatan.tbl */ |
27 | /* */ | |
e4d82761 | 28 | /************************************************************************/ |
f7eac6eb | 29 | |
c8b3296b | 30 | #include <dla.h> |
e898cd15 | 31 | #include "mydefs.h" |
e4d82761 UD |
32 | #include "uatan.tbl" |
33 | #include "atnat.h" | |
ae63c7eb | 34 | #include <fenv.h> |
4629c866 | 35 | #include <float.h> |
38722448 | 36 | #include <libm-alias-double.h> |
1ed0291c | 37 | #include <math.h> |
70e2ba33 | 38 | #include <fenv_private.h> |
8f5b00d3 | 39 | #include <math-underflow.h> |
e4d82761 | 40 | |
e898cd15 | 41 | #define TWO52 0x1.0p52 |
af968f62 UD |
42 | |
43 | /* Fix the sign of y and return */ | |
d26dd3eb SP |
44 | static double |
45 | __signArctan (double x, double y) | |
46 | { | |
81dca813 | 47 | return copysign (y, x); |
af968f62 UD |
48 | } |
49 | ||
e898cd15 | 50 | /* atan with max ULP of ~0.523 based on random sampling. */ |
d26dd3eb | 51 | double |
527cd19c | 52 | __atan (double x) |
d26dd3eb | 53 | { |
e898cd15 WD |
54 | double cor, t1, t2, t3, u, |
55 | v, w, ww, y, yy, z; | |
d26dd3eb | 56 | int i, ux, dx; |
e898cd15 | 57 | mynumber num; |
e4d82761 | 58 | |
d26dd3eb SP |
59 | num.d = x; |
60 | ux = num.i[HIGH_HALF]; | |
61 | dx = num.i[LOW_HALF]; | |
e4d82761 UD |
62 | |
63 | /* x=NaN */ | |
d26dd3eb SP |
64 | if (((ux & 0x7ff00000) == 0x7ff00000) |
65 | && (((ux & 0x000fffff) | dx) != 0x00000000)) | |
66 | return x + x; | |
e4d82761 UD |
67 | |
68 | /* Regular values of x, including denormals +-0 and +-INF */ | |
ae63c7eb | 69 | SET_RESTORE_ROUND (FE_TONEAREST); |
a64d7e0e | 70 | u = (x < 0) ? -x : x; |
d26dd3eb SP |
71 | if (u < C) |
72 | { | |
73 | if (u < B) | |
74 | { | |
75 | if (u < A) | |
4629c866 | 76 | { |
d96164c3 | 77 | math_check_force_underflow_nonneg (u); |
4629c866 JM |
78 | return x; |
79 | } | |
d26dd3eb SP |
80 | else |
81 | { /* A <= u < B */ | |
82 | v = x * x; | |
83 | yy = d11.d + v * d13.d; | |
84 | yy = d9.d + v * yy; | |
85 | yy = d7.d + v * yy; | |
86 | yy = d5.d + v * yy; | |
87 | yy = d3.d + v * yy; | |
88 | yy *= x * v; | |
89 | ||
e898cd15 WD |
90 | y = x + yy; |
91 | /* Max ULP is 0.511. */ | |
92 | return y; | |
d26dd3eb SP |
93 | } |
94 | } | |
95 | else | |
96 | { /* B <= u < C */ | |
e898cd15 | 97 | i = (TWO52 + 256 * u) - TWO52; |
d26dd3eb SP |
98 | i -= 16; |
99 | z = u - cij[i][0].d; | |
100 | yy = cij[i][5].d + z * cij[i][6].d; | |
101 | yy = cij[i][4].d + z * yy; | |
102 | yy = cij[i][3].d + z * yy; | |
103 | yy = cij[i][2].d + z * yy; | |
104 | yy *= z; | |
105 | ||
106 | t1 = cij[i][1].d; | |
e898cd15 WD |
107 | y = t1 + yy; |
108 | /* Max ULP is 0.56. */ | |
109 | return __signArctan (x, y); | |
d26dd3eb | 110 | } |
e4d82761 | 111 | } |
d26dd3eb SP |
112 | else |
113 | { | |
114 | if (u < D) | |
115 | { /* C <= u < D */ | |
c2d94018 | 116 | w = 1 / u; |
e93c2643 | 117 | EMULV (w, u, t1, t2); |
c2d94018 | 118 | ww = w * ((1 - t1) - t2); |
e898cd15 | 119 | i = (TWO52 + 256 * w) - TWO52; |
d26dd3eb SP |
120 | i -= 16; |
121 | z = (w - cij[i][0].d) + ww; | |
122 | ||
123 | yy = cij[i][5].d + z * cij[i][6].d; | |
124 | yy = cij[i][4].d + z * yy; | |
125 | yy = cij[i][3].d + z * yy; | |
126 | yy = cij[i][2].d + z * yy; | |
c5d5d574 | 127 | yy = HPI1 - z * yy; |
f7eac6eb | 128 | |
d26dd3eb | 129 | t1 = HPI - cij[i][1].d; |
e898cd15 WD |
130 | y = t1 + yy; |
131 | /* Max ULP is 0.503. */ | |
132 | return __signArctan (x, y); | |
d26dd3eb SP |
133 | } |
134 | else | |
135 | { | |
136 | if (u < E) | |
c5d5d574 | 137 | { /* D <= u < E */ |
c2d94018 | 138 | w = 1 / u; |
d26dd3eb | 139 | v = w * w; |
e93c2643 | 140 | EMULV (w, u, t1, t2); |
d26dd3eb SP |
141 | |
142 | yy = d11.d + v * d13.d; | |
143 | yy = d9.d + v * yy; | |
144 | yy = d7.d + v * yy; | |
145 | yy = d5.d + v * yy; | |
146 | yy = d3.d + v * yy; | |
147 | yy *= w * v; | |
148 | ||
c2d94018 | 149 | ww = w * ((1 - t1) - t2); |
d26dd3eb SP |
150 | ESUB (HPI, w, t3, cor); |
151 | yy = ((HPI1 + cor) - ww) - yy; | |
e898cd15 WD |
152 | y = t3 + yy; |
153 | /* Max ULP is 0.5003. */ | |
154 | return __signArctan (x, y); | |
d26dd3eb SP |
155 | } |
156 | else | |
157 | { | |
158 | /* u >= E */ | |
159 | if (x > 0) | |
160 | return HPI; | |
161 | else | |
162 | return MHPI; | |
163 | } | |
164 | } | |
165 | } | |
f7eac6eb | 166 | } |
e4d82761 | 167 | |
527cd19c | 168 | #ifndef __atan |
38722448 | 169 | libm_alias_double (__atan, atan) |
cccda09f | 170 | #endif |