2 * ====================================================
3 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 * Developed at SunPro, a Sun Microsystems, Inc. business.
6 * Permission to use, copy, modify, and distribute this
7 * software is freely granted, provided that this notice
9 * ====================================================
13 Long double expansions are
14 Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
15 and are incorporated herein by permission of the author. The author
16 reserves the right to distribute this material elsewhere under different
17 copying permissions. These modifications are distributed here under
20 This library is free software; you can redistribute it and/or
21 modify it under the terms of the GNU Lesser General Public
22 License as published by the Free Software Foundation; either
23 version 2.1 of the License, or (at your option) any later version.
25 This library is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 Lesser General Public License for more details.
30 You should have received a copy of the GNU Lesser General Public
31 License along with this library; if not, see
32 <http://www.gnu.org/licenses/>. */
36 * acos(x) = pi/2 - asin(x)
37 * acos(-x) = pi/2 + asin(x)
39 * acos(x) = pi/2 - asin(x)
40 * Between .375 and .5 the approximation is
41 * acos(0.4375 + x) = acos(0.4375) + x P(x) / Q(x)
42 * Between .5 and .625 the approximation is
43 * acos(0.5625 + x) = acos(0.5625) + x rS(x) / sS(x)
45 * acos(x) = 2 asin(sqrt((1-x)/2))
46 * computed with an extended precision square root in the leading term.
48 * acos(x) = pi - 2 asin(sqrt((1-|x|)/2))
51 * if x is NaN, return x itself;
52 * if |x|>1, return NaN with invalid signal.
54 * Functions needed: sqrtq.
57 #include "quadmath-imp.h"
59 static const __float128
61 pio2_hi
= 1.5707963267948966192313216916397514420986Q
,
62 pio2_lo
= 4.3359050650618905123985220130216759843812E-35Q
,
64 /* acos(0.5625 + x) = acos(0.5625) + x rS(x) / sS(x)
65 -0.0625 <= x <= 0.0625
66 peak relative error 3.3e-35 */
68 rS0
= 5.619049346208901520945464704848780243887E0Q
,
69 rS1
= -4.460504162777731472539175700169871920352E1Q
,
70 rS2
= 1.317669505315409261479577040530751477488E2Q
,
71 rS3
= -1.626532582423661989632442410808596009227E2Q
,
72 rS4
= 3.144806644195158614904369445440583873264E1Q
,
73 rS5
= 9.806674443470740708765165604769099559553E1Q
,
74 rS6
= -5.708468492052010816555762842394927806920E1Q
,
75 rS7
= -1.396540499232262112248553357962639431922E1Q
,
76 rS8
= 1.126243289311910363001762058295832610344E1Q
,
77 rS9
= 4.956179821329901954211277873774472383512E-1Q
,
78 rS10
= -3.313227657082367169241333738391762525780E-1Q
,
80 sS0
= -4.645814742084009935700221277307007679325E0Q
,
81 sS1
= 3.879074822457694323970438316317961918430E1Q
,
82 sS2
= -1.221986588013474694623973554726201001066E2Q
,
83 sS3
= 1.658821150347718105012079876756201905822E2Q
,
84 sS4
= -4.804379630977558197953176474426239748977E1Q
,
85 sS5
= -1.004296417397316948114344573811562952793E2Q
,
86 sS6
= 7.530281592861320234941101403870010111138E1Q
,
87 sS7
= 1.270735595411673647119592092304357226607E1Q
,
88 sS8
= -1.815144839646376500705105967064792930282E1Q
,
89 sS9
= -7.821597334910963922204235247786840828217E-2Q
,
90 /* 1.000000000000000000000000000000000000000E0 */
92 acosr5625
= 9.7338991014954640492751132535550279812151E-1Q
,
93 pimacosr5625
= 2.1682027434402468335351320579240000860757E0Q
,
95 /* acos(0.4375 + x) = acos(0.4375) + x rS(x) / sS(x)
96 -0.0625 <= x <= 0.0625
97 peak relative error 2.1e-35 */
99 P0
= 2.177690192235413635229046633751390484892E0Q
,
100 P1
= -2.848698225706605746657192566166142909573E1Q
,
101 P2
= 1.040076477655245590871244795403659880304E2Q
,
102 P3
= -1.400087608918906358323551402881238180553E2Q
,
103 P4
= 2.221047917671449176051896400503615543757E1Q
,
104 P5
= 9.643714856395587663736110523917499638702E1Q
,
105 P6
= -5.158406639829833829027457284942389079196E1Q
,
106 P7
= -1.578651828337585944715290382181219741813E1Q
,
107 P8
= 1.093632715903802870546857764647931045906E1Q
,
108 P9
= 5.448925479898460003048760932274085300103E-1Q
,
109 P10
= -3.315886001095605268470690485170092986337E-1Q
,
110 Q0
= -1.958219113487162405143608843774587557016E0Q
,
111 Q1
= 2.614577866876185080678907676023269360520E1Q
,
112 Q2
= -9.990858606464150981009763389881793660938E1Q
,
113 Q3
= 1.443958741356995763628660823395334281596E2Q
,
114 Q4
= -3.206441012484232867657763518369723873129E1Q
,
115 Q5
= -1.048560885341833443564920145642588991492E2Q
,
116 Q6
= 6.745883931909770880159915641984874746358E1Q
,
117 Q7
= 1.806809656342804436118449982647641392951E1Q
,
118 Q8
= -1.770150690652438294290020775359580915464E1Q
,
119 Q9
= -5.659156469628629327045433069052560211164E-1Q
,
120 /* 1.000000000000000000000000000000000000000E0 */
122 acosr4375
= 1.1179797320499710475919903296900511518755E0Q
,
123 pimacosr4375
= 2.0236129215398221908706530535894517323217E0Q
,
125 /* asin(x) = x + x^3 pS(x^2) / qS(x^2)
127 peak relative error 1.9e-35 */
128 pS0
= -8.358099012470680544198472400254596543711E2Q
,
129 pS1
= 3.674973957689619490312782828051860366493E3Q
,
130 pS2
= -6.730729094812979665807581609853656623219E3Q
,
131 pS3
= 6.643843795209060298375552684423454077633E3Q
,
132 pS4
= -3.817341990928606692235481812252049415993E3Q
,
133 pS5
= 1.284635388402653715636722822195716476156E3Q
,
134 pS6
= -2.410736125231549204856567737329112037867E2Q
,
135 pS7
= 2.219191969382402856557594215833622156220E1Q
,
136 pS8
= -7.249056260830627156600112195061001036533E-1Q
,
137 pS9
= 1.055923570937755300061509030361395604448E-3Q
,
139 qS0
= -5.014859407482408326519083440151745519205E3Q
,
140 qS1
= 2.430653047950480068881028451580393430537E4Q
,
141 qS2
= -4.997904737193653607449250593976069726962E4Q
,
142 qS3
= 5.675712336110456923807959930107347511086E4Q
,
143 qS4
= -3.881523118339661268482937768522572588022E4Q
,
144 qS5
= 1.634202194895541569749717032234510811216E4Q
,
145 qS6
= -4.151452662440709301601820849901296953752E3Q
,
146 qS7
= 5.956050864057192019085175976175695342168E2Q
,
147 qS8
= -4.175375777334867025769346564600396877176E1Q
;
148 /* 1.000000000000000000000000000000000000000E0 */
153 __float128 z
, r
, w
, p
, q
, s
, t
, f2
;
159 ix
= sign
& 0x7fffffff;
160 u
.words32
.w0
= ix
; /* |x| */
161 if (ix
>= 0x3fff0000) /* |x| >= 1 */
164 && (u
.words32
.w1
| u
.words32
.w2
| u
.words32
.w3
) == 0)
166 if ((sign
& 0x80000000) == 0)
167 return 0.0; /* acos(1) = 0 */
169 return (2.0 * pio2_hi
) + (2.0 * pio2_lo
); /* acos(-1)= pi */
171 return (x
- x
) / (x
- x
); /* acos(|x| > 1) is NaN */
173 else if (ix
< 0x3ffe0000) /* |x| < 0.5 */
175 if (ix
< 0x3f8e0000) /* |x| < 2**-113 */
176 return pio2_hi
+ pio2_lo
;
177 if (ix
< 0x3ffde000) /* |x| < .4375 */
202 z
= pio2_hi
- (r
- pio2_lo
);
205 /* .4375 <= |x| < .5 */
206 t
= u
.value
- 0.4375Q
;
207 p
= ((((((((((P10
* t
231 if (sign
& 0x80000000)
232 r
= pimacosr4375
- r
;
237 else if (ix
< 0x3ffe4000) /* |x| < 0.625 */
239 t
= u
.value
- 0.5625Q
;
240 p
= ((((((((((rS10
* t
263 if (sign
& 0x80000000)
264 r
= pimacosr5625
- p
/ q
;
266 r
= acosr5625
+ p
/ q
;
271 z
= (one
- u
.value
) * 0.5;
273 /* Compute an extended precision square root from
274 the Newton iteration s -> 0.5 * (s + z / s).
275 The change w from s to the improved value is
276 w = 0.5 * (s + z / s) - s = (s^2 + z)/2s - s = (z - s^2)/2s.
277 Express s = f1 + f2 where f1 * f1 is exactly representable.
278 w = (z - s^2)/2s = (z - f1^2 - 2 f1 f2 - f2^2)/2s .
279 s + w has extended precision. */
284 w
= z
- u
.value
* u
.value
;
285 w
= w
- 2.0 * u
.value
* f2
;
309 r
= s
+ (w
+ s
* p
/ q
);
311 if (sign
& 0x80000000)
312 w
= pio2_hi
+ (pio2_lo
- r
);