4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
26 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
30 #pragma weak __atanf = atanf
34 * float atanf(float x);
35 * Table look-up algorithm
36 * By K.C. Ng, March 9, 1989
40 * The algorithm is based on atan(x)=atan(y)+atan((x-y)/(1+x*y)).
41 * We use poly1(x) to approximate atan(x) for x in [0,1/8] with
43 * |(atan(x)-poly1(x))/x|<= 2^-115.94 long double
44 * |(atan(x)-poly1(x))/x|<= 2^-58.85 double
45 * |(atan(x)-poly1(x))/x|<= 2^-25.53 float
46 * and use poly2(x) to approximate atan(x) for x in [0,1/65] with
48 * |atan(x)-poly2(x)|<= 2^-122.15 long double
49 * |atan(x)-poly2(x)|<= 2^-64.79 double
50 * |atan(x)-poly2(x)|<= 2^-35.36 float
51 * and use poly3(x) to approximate atan(x) for x in [1/8,7/16] with
52 * error (relative, on for single precision)
53 * |(atan(x)-poly1(x))/x|<= 2^-25.53 float
55 * Here poly1-3 are odd polynomial with the following form:
56 * x + x^3*(a1+x^2*(a2+...))
58 * (0). Purge off Inf and NaN and 0
59 * (1). Reduce x to positive by atan(x) = -atan(-x).
60 * (2). For x <= 1/8, use
61 * (2.1) if x < 2^(-prec/2-2), atan(x) = x with inexact
64 * (3). For x >= 8 then
65 * (3.1) if x >= 2^(prec+2), atan(x) = atan(inf) - pio2lo
66 * (3.2) if x >= 2^(prec/3+2), atan(x) = atan(inf) - 1/x
67 * (3.3) if x > 65, atan(x) = atan(inf) - poly2(1/x)
68 * (3.4) Otherwise, atan(x) = atan(inf) - poly1(1/x)
70 * (4). Now x is in (0.125, 8)
71 * Find y that match x to 4.5 bit after binary (easy).
72 * If iy is the high word of y, then
73 * single : j = (iy - 0x3e000000) >> 19
74 * (single is modified to (iy-0x3f000000)>>19)
75 * double : j = (iy - 0x3fc00000) >> 16
76 * quad : j = (iy - 0x3ffc0000) >> 12
78 * Let s = (x-y)/(1+x*y). Then
79 * atan(x) = atan(y) + poly1(s)
80 * = _TBL_r_atan_hi[j] + (_TBL_r_atan_lo[j] + poly2(s) )
82 * Note. |s| <= 1.5384615385e-02 = 1/65. Maxium occurs at x = 1.03125
88 extern const float _TBL_r_atan_hi
[], _TBL_r_atan_lo
[];
92 p1
= -3.333185951111688247225368498733544672172e-0001F
,
93 p2
= 1.969352894213455405211341983203180636021e-0001F
,
94 q1
= -3.332921964095646819563419704110132937456e-0001F
,
95 a1
= -3.333323465223893614063523351509338934592e-0001F
,
96 a2
= 1.999425625935277805494082274808174062403e-0001F
,
97 a3
= -1.417547090509737780085769846290301788559e-0001F
,
98 a4
= 1.016250813871991983097273733227432685084e-0001F
,
99 a5
= -5.137023693688358515753093811791755221805e-0002F
,
100 pio2hi
= 1.570796371e+0000F
,
101 pio2lo
= -4.371139000e-0008F
;
106 float x
, y
, z
, r
, p
, s
;
107 volatile double dummy
;
112 sign
= ix
& 0x80000000;
116 if (ix
< 0x3e000000) {
117 if (ix
< 0x38800000) { /* if |x| < 2**(-prec/2-2) */
118 dummy
= big
+ x
; /* get inexact flag if x != 0 */
122 if (ix
< 0x3c000000) { /* if |x| < 2**(-prec/4-1) */
123 x
= x
+ (x
* z
) * p1
;
126 x
= x
+ (x
* z
) * (p1
+ z
* p2
);
132 if (ix
>= 0x41000000) {
134 if (ix
< 0x42820000) { /* x < 65 */
137 y
= r
* (one
+ z
* (p1
+ z
* p2
)); /* poly1 */
139 } else if (ix
< 0x44800000) { /* x < 2**(prec/3+2) */
142 y
= r
* (one
+ z
* q1
); /* poly2 */
144 } else if (ix
< 0x4c800000) { /* x < 2**(prec+2) */
145 y
= one
/ x
- pio2lo
;
146 } else if (ix
< 0x7f800000) { /* x < inf */
148 } else { /* x is inf or NaN */
149 if (ix
> 0x7f800000) {
150 return (x
* x
); /* - -> * for Cheetah */
163 /* now x is between 1/8 and 8 */
164 if (ix
< 0x3f000000) { /* between 1/8 and 1/2 */
166 x
= x
+ (x
* z
) * (a1
+ z
* (a2
+ z
* (a3
+ z
* (a4
+
171 iy
= (ix
+ 0x00040000) & 0x7ff80000;
173 j
= (iy
- 0x3f000000) >> 19;
176 p
= x
- y
; /* p=0.0 */
179 s
= (x
- y
) / (one
+ x
* y
);
181 s
= (y
- x
) / (one
+ x
* y
);
183 p
= s
* (one
+ z
* q1
);
186 r
= p
+ _TBL_r_atan_lo
[j
];
187 x
= r
+ _TBL_r_atan_hi
[j
];
189 r
= p
- _TBL_r_atan_lo
[j
];
190 x
= r
- _TBL_r_atan_hi
[j
];