1/*
2 * IBM Accurate Mathematical Library
3 * written by International Business Machines Corp.
4 * Copyright (C) 2001-2024 Free Software Foundation, Inc.
5 *
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.
10 *
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.
15 *
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/>.
18 */
19/******************************************************************/
20/* MODULE_NAME:uasncs.c */
21/* */
22/* FUNCTIONS: uasin */
23/* uacos */
24/* FILES NEEDED: dla.h endian.h mydefs.h usncs.h */
25/* sincos.tbl asincos.tbl powtwo.tbl root.tbl */
26/* */
27/******************************************************************/
28#include "endian.h"
29#include "mydefs.h"
30#include "asincos.tbl"
31#include "root.tbl"
32#include "powtwo.tbl"
33#include "uasncs.h"
34#include <float.h>
35#include <math.h>
36#include <math_private.h>
37#include <math-underflow.h>
38#include <libm-alias-finite.h>
39
40#ifndef SECTION
41# define SECTION
42#endif
43
44/* asin with max ULP of ~0.516 based on random sampling. */
45double
46SECTION
47__ieee754_asin(double x){
48 double x2,xx,res1,p,t,res,r,cor,cc,y,c,z;
49 mynumber u,v;
50 int4 k,m,n;
51
52 u.x = x;
53 m = u.i[HIGH_HALF];
54 k = 0x7fffffff&m; /* no sign */
55
56 if (k < 0x3e500000)
57 {
58 math_check_force_underflow (x);
59 return x; /* for x->0 => sin(x)=x */
60 }
61 /*----------------------2^-26 <= |x| < 2^ -3 -----------------*/
62 else
63 if (k < 0x3fc00000) {
64 x2 = x*x;
65 t = (((((f6*x2 + f5)*x2 + f4)*x2 + f3)*x2 + f2)*x2 + f1)*(x2*x);
66 res = x+t; /* res=arcsin(x) according to Taylor series */
67 /* Max ULP is 0.513. */
68 return res;
69 }
70 /*---------------------0.125 <= |x| < 0.5 -----------------------------*/
71 else if (k < 0x3fe00000) {
72 if (k<0x3fd00000) n = 11*((k&0x000fffff)>>15);
73 else n = 11*((k&0x000fffff)>>14)+352;
74 if (m>0) xx = x - asncs.x[n];
75 else xx = -x - asncs.x[n];
76 t = asncs.x[n+1]*xx;
77 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+xx*(asncs.x[n+5]
78 +xx*asncs.x[n+6]))))+asncs.x[n+7];
79 t+=p;
80 res =asncs.x[n+8] +t;
81 /* Max ULP is 0.524. */
82 return (m>0)?res:-res;
83 } /* else if (k < 0x3fe00000) */
84 /*-------------------- 0.5 <= |x| < 0.75 -----------------------------*/
85 else
86 if (k < 0x3fe80000) {
87 n = 1056+((k&0x000fe000)>>11)*3;
88 if (m>0) xx = x - asncs.x[n];
89 else xx = -x - asncs.x[n];
90 t = asncs.x[n+1]*xx;
91 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+xx*(asncs.x[n+5]
92 +xx*(asncs.x[n+6]+xx*asncs.x[n+7])))))+asncs.x[n+8];
93 t+=p;
94 res =asncs.x[n+9] +t;
95 /* Max ULP is 0.505. */
96 return (m>0)?res:-res;
97 } /* else if (k < 0x3fe80000) */
98 /*--------------------- 0.75 <= |x|< 0.921875 ----------------------*/
99 else
100 if (k < 0x3fed8000) {
101 n = 992+((k&0x000fe000)>>13)*13;
102 if (m>0) xx = x - asncs.x[n];
103 else xx = -x - asncs.x[n];
104 t = asncs.x[n+1]*xx;
105 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+xx*(asncs.x[n+5]
106 +xx*(asncs.x[n+6]+xx*(asncs.x[n+7]+xx*asncs.x[n+8]))))))+asncs.x[n+9];
107 t+=p;
108 res =asncs.x[n+10] +t;
109 /* Max ULP is 0.505. */
110 return (m>0)?res:-res;
111 } /* else if (k < 0x3fed8000) */
112 /*-------------------0.921875 <= |x| < 0.953125 ------------------------*/
113 else
114 if (k < 0x3fee8000) {
115 n = 884+((k&0x000fe000)>>13)*14;
116 if (m>0) xx = x - asncs.x[n];
117 else xx = -x - asncs.x[n];
118 t = asncs.x[n+1]*xx;
119 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
120 xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
121 +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+
122 xx*asncs.x[n+9])))))))+asncs.x[n+10];
123 t+=p;
124 res =asncs.x[n+11] +t;
125 /* Max ULP is 0.505. */
126 return (m>0)?res:-res;
127 } /* else if (k < 0x3fee8000) */
128
129 /*--------------------0.953125 <= |x| < 0.96875 ------------------------*/
130 else
131 if (k < 0x3fef0000) {
132 n = 768+((k&0x000fe000)>>13)*15;
133 if (m>0) xx = x - asncs.x[n];
134 else xx = -x - asncs.x[n];
135 t = asncs.x[n+1]*xx;
136 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
137 xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
138 +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+
139 xx*(asncs.x[n+9]+xx*asncs.x[n+10]))))))))+asncs.x[n+11];
140 t+=p;
141 res =asncs.x[n+12] +t;
142 /* Max ULP is 0.505. */
143 return (m>0)?res:-res;
144 } /* else if (k < 0x3fef0000) */
145 /*--------------------0.96875 <= |x| < 1 --------------------------------*/
146 else
147 if (k<0x3ff00000) {
148 z = 0.5*((m>0)?(1.0-x):(1.0+x));
149 v.x=z;
150 k=v.i[HIGH_HALF];
151 t=inroot[(k&0x001fffff)>>14]*powtwo[511-(k>>21)];
152 r=1.0-t*t*z;
153 t = t*(rt0+r*(rt1+r*(rt2+r*rt3)));
154 c=t*z;
155 t=c*(1.5-0.5*t*c);
156 y=(c+t24)-t24;
157 cc = (z-y*y)/(t+y);
158 p=(((((f6*z+f5)*z+f4)*z+f3)*z+f2)*z+f1)*z;
159 cor = (hp1.x - 2.0*cc)-2.0*(y+cc)*p;
160 res1 = hp0.x - 2.0*y;
161 res =res1 + cor;
162 /* Max ULP is 0.5015. */
163 return (m>0)?res:-res;
164 } /* else if (k < 0x3ff00000) */
165 /*---------------------------- |x|>=1 -------------------------------*/
166 else if (k==0x3ff00000 && u.i[LOW_HALF]==0) return (m>0)?hp0.x:-hp0.x;
167 else
168 return (x - x) / (x - x);
169}
170#ifndef __ieee754_asin
171libm_alias_finite (__ieee754_asin, __asin)
172#endif
173
174/*******************************************************************/
175/* */
176/* End of arcsine, below is arccosine */
177/* */
178/*******************************************************************/
179
180/* acos with max ULP of ~0.523 based on random sampling. */
181double
182SECTION
183__ieee754_acos(double x)
184{
185 double x2,xx,res1,p,t,res,r,cor,cc,y,c,z;
186 mynumber u,v;
187 int4 k,m,n;
188 u.x = x;
189 m = u.i[HIGH_HALF];
190 k = 0x7fffffff&m;
191 /*------------------- |x|<2.77556*10^-17 ----------------------*/
192 if (k < 0x3c880000) return hp0.x;
193
194 /*----------------- 2.77556*10^-17 <= |x| < 2^-3 --------------*/
195 else
196 if (k < 0x3fc00000) {
197 x2 = x*x;
198 t = (((((f6*x2 + f5)*x2 + f4)*x2 + f3)*x2 + f2)*x2 + f1)*(x2*x);
199 r=hp0.x-x;
200 cor=(((hp0.x-r)-x)+hp1.x)-t;
201 res = r+cor;
202 /* Max ULP is 0.502. */
203 return res;
204 } /* else if (k < 0x3fc00000) */
205 /*---------------------- 0.125 <= |x| < 0.5 --------------------*/
206 else
207 if (k < 0x3fe00000) {
208 if (k<0x3fd00000) n = 11*((k&0x000fffff)>>15);
209 else n = 11*((k&0x000fffff)>>14)+352;
210 if (m>0) xx = x - asncs.x[n];
211 else xx = -x - asncs.x[n];
212 t = asncs.x[n+1]*xx;
213 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
214 xx*(asncs.x[n+5]+xx*asncs.x[n+6]))))+asncs.x[n+7];
215 t+=p;
216 y = (m>0)?(hp0.x-asncs.x[n+8]):(hp0.x+asncs.x[n+8]);
217 t = (m>0)?(hp1.x-t):(hp1.x+t);
218 res = y+t;
219 /* Max ULP is 0.51. */
220 return res;
221 } /* else if (k < 0x3fe00000) */
222
223 /*--------------------------- 0.5 <= |x| < 0.75 ---------------------*/
224 else
225 if (k < 0x3fe80000) {
226 n = 1056+((k&0x000fe000)>>11)*3;
227 if (m>0) {xx = x - asncs.x[n]; }
228 else {xx = -x - asncs.x[n]; }
229 t = asncs.x[n+1]*xx;
230 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
231 xx*(asncs.x[n+5]+xx*(asncs.x[n+6]+
232 xx*asncs.x[n+7])))))+asncs.x[n+8];
233 t+=p;
234 y = (m>0)?(hp0.x-asncs.x[n+9]):(hp0.x+asncs.x[n+9]);
235 t = (m>0)?(hp1.x-t):(hp1.x+t);
236 res = y+t;
237 /* Max ULP is 0.523 based on random sampling. */
238 return res;
239 } /* else if (k < 0x3fe80000) */
240
241/*------------------------- 0.75 <= |x| < 0.921875 -------------*/
242 else
243 if (k < 0x3fed8000) {
244 n = 992+((k&0x000fe000)>>13)*13;
245 if (m>0) {xx = x - asncs.x[n]; }
246 else {xx = -x - asncs.x[n]; }
247 t = asncs.x[n+1]*xx;
248 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
249 xx*(asncs.x[n+5]+xx*(asncs.x[n+6]+xx*(asncs.x[n+7]+
250 xx*asncs.x[n+8]))))))+asncs.x[n+9];
251 t+=p;
252 y = (m>0)?(hp0.x-asncs.x[n+10]):(hp0.x+asncs.x[n+10]);
253 t = (m>0)?(hp1.x-t):(hp1.x+t);
254 res = y+t;
255 /* Max ULP is 0.523 based on random sampling. */
256 return res;
257 } /* else if (k < 0x3fed8000) */
258
259/*-------------------0.921875 <= |x| < 0.953125 ------------------*/
260 else
261 if (k < 0x3fee8000) {
262 n = 884+((k&0x000fe000)>>13)*14;
263 if (m>0) {xx = x - asncs.x[n]; }
264 else {xx = -x - asncs.x[n]; }
265 t = asncs.x[n+1]*xx;
266 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
267 xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
268 +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+
269 xx*asncs.x[n+9])))))))+asncs.x[n+10];
270 t+=p;
271 y = (m>0)?(hp0.x-asncs.x[n+11]):(hp0.x+asncs.x[n+11]);
272 t = (m>0)?(hp1.x-t):(hp1.x+t);
273 res = y+t;
274 /* Max ULP is 0.523 based on random sampling. */
275 return res;
276 } /* else if (k < 0x3fee8000) */
277
278 /*--------------------0.953125 <= |x| < 0.96875 ----------------*/
279 else
280 if (k < 0x3fef0000) {
281 n = 768+((k&0x000fe000)>>13)*15;
282 if (m>0) {xx = x - asncs.x[n]; }
283 else {xx = -x - asncs.x[n]; }
284 t = asncs.x[n+1]*xx;
285 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
286 xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
287 +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+xx*(asncs.x[n+9]+
288 xx*asncs.x[n+10]))))))))+asncs.x[n+11];
289 t+=p;
290 y = (m>0)?(hp0.x-asncs.x[n+12]):(hp0.x+asncs.x[n+12]);
291 t = (m>0)?(hp1.x-t):(hp1.x+t);
292 res = y+t;
293 /* Max ULP is 0.523 based on random sampling. */
294 return res;
295 } /* else if (k < 0x3fef0000) */
296 /*-----------------0.96875 <= |x| < 1 ---------------------------*/
297
298 else
299 if (k<0x3ff00000) {
300 z = 0.5*((m>0)?(1.0-x):(1.0+x));
301 v.x=z;
302 k=v.i[HIGH_HALF];
303 t=inroot[(k&0x001fffff)>>14]*powtwo[511-(k>>21)];
304 r=1.0-t*t*z;
305 t = t*(rt0+r*(rt1+r*(rt2+r*rt3)));
306 c=t*z;
307 t=c*(1.5-0.5*t*c);
308 y = (t27*c+c)-t27*c;
309 cc = (z-y*y)/(t+y);
310 p=(((((f6*z+f5)*z+f4)*z+f3)*z+f2)*z+f1)*z;
311 if (m<0) {
312 cor = (hp1.x - cc)-(y+cc)*p;
313 res1 = hp0.x - y;
314 res =res1 + cor;
315 /* Max ULP is 0.501. */
316 return (res+res);
317 }
318 else {
319 cor = cc+p*(y+cc);
320 res = y + cor;
321 /* Max ULP is 0.515. */
322 return (res+res);
323 }
324 } /* else if (k < 0x3ff00000) */
325
326 /*---------------------------- |x|>=1 -----------------------*/
327 else
328 if (k==0x3ff00000 && u.i[LOW_HALF]==0) return (m>0)?0:2.0*hp0.x;
329 else
330 return (x - x) / (x - x);
331}
332#ifndef __ieee754_acos
333libm_alias_finite (__ieee754_acos, __acos)
334#endif
335

source code of glibc/sysdeps/ieee754/dbl-64/e_asin.c