2 * IBM Accurate Mathematical Library
3 * written by International Business Machines Corp.
4 * Copyright (C) 2001-2023 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 <https://www.gnu.org/licenses/>.
19 /************************************************************************/
20 /* MODULE_NAME: atnat.c */
22 /* FUNCTIONS: uatan */
25 /* FILES NEEDED: dla.h endian.h mydefs.h atnat.h */
28 /************************************************************************/
36 #include <libm-alias-double.h>
38 #include <fenv_private.h>
39 #include <math-underflow.h>
41 #define TWO52 0x1.0p52
43 /* Fix the sign of y and return */
45 __signArctan (double x
, double y
)
47 return copysign (y
, x
);
50 /* atan with max ULP of ~0.523 based on random sampling. */
54 double cor
, t1
, t2
, t3
, u
,
60 ux
= num
.i
[HIGH_HALF
];
64 if (((ux
& 0x7ff00000) == 0x7ff00000)
65 && (((ux
& 0x000fffff) | dx
) != 0x00000000))
68 /* Regular values of x, including denormals +-0 and +-INF */
69 SET_RESTORE_ROUND (FE_TONEAREST
);
77 math_check_force_underflow_nonneg (u
);
83 yy
= d11
.d
+ v
* d13
.d
;
91 /* Max ULP is 0.511. */
97 i
= (TWO52
+ 256 * u
) - TWO52
;
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
;
108 /* Max ULP is 0.56. */
109 return __signArctan (x
, y
);
117 EMULV (w
, u
, t1
, t2
);
118 ww
= w
* ((1 - t1
) - t2
);
119 i
= (TWO52
+ 256 * w
) - TWO52
;
121 z
= (w
- cij
[i
][0].d
) + ww
;
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
;
129 t1
= HPI
- cij
[i
][1].d
;
131 /* Max ULP is 0.503. */
132 return __signArctan (x
, y
);
140 EMULV (w
, u
, t1
, t2
);
142 yy
= d11
.d
+ v
* d13
.d
;
149 ww
= w
* ((1 - t1
) - t2
);
150 ESUB (HPI
, w
, t3
, cor
);
151 yy
= ((HPI1
+ cor
) - ww
) - yy
;
153 /* Max ULP is 0.5003. */
154 return __signArctan (x
, y
);
169 libm_alias_double (__atan
, atan
)