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 __cacosl = cacosl
32 #include "libm.h" /* acosl/atanl/fabsl/isinfl/log1pl/logl/sqrtl */
33 #include "complex_wrapper.h"
34 #include "longdouble.h"
37 static const long double
43 ln2
= 6.931471805599453094172321214581765680755e-0001L,
44 Foursqrtu
= 7.3344154702193886624856495681939326638255e-2466L, /* 2**-8189 */
46 E
= 5.4210108624275221700372640043497085571289e-20L, /* 2**-64 */
47 pi
= 3.141592653589793238295968524909085317631252110004425048828125L,
48 pi_l
= 1.666748583704175665659172893706807721468195923078e-19L,
49 pi_2
= 1.5707963267948966191479842624545426588156260L,
50 pi_2_l
= 8.3337429185208783282958644685340386073409796e-20L,
51 pi_4
= 0.78539816339744830957399213122727132940781302750110626220703125L,
52 pi_4_l
= 4.166871459260439164147932234267019303670489807695410e-20L,
53 pi3_4
= 2.35619449019234492872197639368181398822343908250331878662109375L,
54 pi3_4_l
= 1.250061437778131749244379670280105791101146942308e-19L;
56 E
= 9.6296497219361792652798897129246365926905e-35L, /* 2**-113 */
57 pi
= 3.1415926535897932384626433832795027974790680981372955730045043318L,
58 pi_l
= 8.6718101301237810247970440260433519687623233462565303417759356862e-35L,
59 pi_2
= 1.5707963267948966192313216916397513987395340L,
60 pi_2_l
= 4.3359050650618905123985220130216759843811616e-35L,
61 pi_4
= 0.785398163397448309615660845819875699369767024534323893251126L,
62 pi_4_l
= 2.167952532530945256199261006510837992190580836564132585443e-35L,
63 pi3_4
= 2.35619449019234492884698253745962709810930107360297167975337824L,
64 pi3_4_l
= 6.503857597592835768597783019532513976571742509692397756331e-35L;
69 static const int ip1
= 0x40400000; /* 2**65 */
71 static const int ip1
= 0x40710000; /* 2**114 */
76 long double x
, y
, t
, R
, S
, A
, Am1
, B
, y2
, xm1
, xp1
, Apx
;
89 if (y
== zero
|| (iy
>= 0x7fff0000)) {
90 LD_RE(ans
) = pi_2
+ pi_2_l
;
96 /* |y| is inf or NaN */
97 if (iy
>= 0x7fff0000) {
98 if (isinfl(y
)) { /* cacos(x + i inf) = pi/2 - i inf */
100 if (ix
< 0x7fff0000) {
101 LD_RE(ans
) = pi_2
+ pi_2_l
;
102 } else if (isinfl(x
)) {
104 LD_RE(ans
) = pi_4
+ pi_4_l
;
106 LD_RE(ans
) = pi3_4
+ pi3_4_l
;
110 } else { /* cacos(x + i NaN) = NaN + i NaN */
113 LD_IM(ans
) = -fabsl(x
);
122 if (ix
>= 0x7fff0000) { /* x is inf or NaN */
123 if (isinfl(x
)) { /* x is INF */
124 LD_IM(ans
) = -fabsl(x
);
125 if (iy
>= 0x7fff0000) {
128 /* cacos(inf + i inf) = pi/4 - i inf */
129 /* cacos(-inf+ i inf) =3pi/4 - i inf */
132 LD_RE(ans
) = pi_4
+ pi_4_l
;
134 LD_RE(ans
) = pi3_4
+ pi3_4_l
;
137 /* cacos(inf + i NaN) = NaN - i inf */
142 /* cacos(inf + iy ) = 0 - i inf */
143 /* cacos(-inf+ iy ) = pi - i inf */
148 LD_RE(ans
) = pi
+ pi_l
;
150 } else { /* x is NaN */
153 * cacos(NaN + i inf) = NaN - i inf
154 * cacos(NaN + i y ) = NaN + i NaN
155 * cacos(NaN + i NaN) = NaN + i NaN
159 if (iy
>= 0x7fff0000) {
166 LD_IM(ans
) = -LD_IM(ans
);
170 if (y
== zero
) { /* region 1: y=0 */
171 if (ix
< 0x3fff0000) { /* |x| < 1 */
172 LD_RE(ans
) = acosl(x
);
177 if (ix
>= ip1
) /* i386 ? 2**65 : 2**114 */
178 LD_IM(ans
) = ln2
+ logl(x
);
179 else if (ix
>= 0x3fff8000) /* x > Acrossover */
180 LD_IM(ans
) = logl(x
+ sqrtl((x
- one
) * (x
+
184 LD_IM(ans
) = log1pl(xm1
+ sqrtl(xm1
* (x
+
188 } else if (y
<= E
* fabsl(fabsl(x
) - one
)) {
189 /* region 2: y < tiny*||x|-1| */
190 if (ix
< 0x3fff0000) { /* x < 1 */
191 LD_RE(ans
) = acosl(x
);
193 LD_IM(ans
) = y
/ sqrtl((one
+ x
) * (one
- x
));
194 } else if (ix
>= ip1
) { /* i386 ? 2**65 : 2**114 */
198 if (ix
>= ip1
+ 0x00040000)
199 LD_RE(ans
) = pi
+ pi_l
;
205 LD_IM(ans
) = ln2
+ logl(fabsl(x
));
208 t
= sqrtl((x
- one
) * (x
+ one
));
209 LD_RE(ans
) = (hx
>= 0)? y
/ t
: pi
- (y
/ t
- pi_l
);
210 if (ix
>= 0x3fff8000) /* x > Acrossover */
211 LD_IM(ans
) = logl(x
+ t
);
213 LD_IM(ans
) = log1pl(t
- (one
- x
));
215 } else if (y
< Foursqrtu
) { /* region 3 */
217 LD_RE(ans
) = (hx
>= 0)? t
: pi
+ pi_l
;
219 } else if (E
* y
- one
>= fabsl(x
)) { /* region 4 */
220 LD_RE(ans
) = pi_2
+ pi_2_l
;
221 LD_IM(ans
) = ln2
+ logl(y
);
222 } else if (ix
>= 0x5ffb0000 || iy
>= 0x5ffb0000) {
223 /* region 5: x+1 and y are both (>= sqrt(max)/8) i.e. 2**8188 */
225 LD_RE(ans
) = atan2l(y
, x
);
226 LD_IM(ans
) = ln2
+ logl(y
) + half
* log1pl(t
* t
);
227 } else if (fabsl(x
) < Foursqrtu
) {
228 /* region 6: x is very small, < 4sqrt(min) */
229 LD_RE(ans
) = pi_2
+ pi_2_l
;
230 A
= sqrtl(one
+ y
* y
);
231 if (iy
>= 0x3fff8000) /* if y > Acrossover */
232 LD_IM(ans
) = logl(y
+ A
);
234 LD_IM(ans
) = half
* log1pl((y
+ y
) * (y
+ A
));
235 } else { /* safe region */
240 R
= sqrtl(xp1
* xp1
+ y2
);
241 S
= sqrtl(xm1
* xm1
+ y2
);
246 LD_RE(ans
) = (hx
>= 0)? acosl(B
) : acosl(-B
);
247 else { /* use atan and an accurate approx to a-x */
250 LD_RE(ans
) = atan2l(sqrtl(half
* Apx
* (y2
/
251 (R
+ xp1
) + (S
- xm1
))), x
);
253 LD_RE(ans
) = atan2l((y
* sqrtl(half
* (Apx
/
254 (R
+ xp1
) + Apx
/ (S
+ xm1
)))), x
);
256 if (A
<= Acrossover
) {
257 /* use log1p and an accurate approx to A-1 */
259 Am1
= half
* (y2
/ (R
+ xp1
) + y2
/ (S
- xm1
));
261 Am1
= half
* (y2
/ (R
+ xp1
) + (S
+ xm1
));
262 LD_IM(ans
) = log1pl(Am1
+ sqrtl(Am1
* (A
+ one
)));
264 LD_IM(ans
) = logl(A
+ sqrtl(A
* A
- one
));
269 LD_IM(ans
) = -LD_IM(ans
);