2.9
[glibc/nacl-glibc.git] / sysdeps / ieee754 / dbl-64 / e_asin.c
blobce5d227b71e7031d30d747c145ef03d124674895
1 /*
2 * IBM Accurate Mathematical Library
3 * written by International Business Machines Corp.
4 * Copyright (C) 2001 Free Software Foundation
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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 /******************************************************************/
21 /* MODULE_NAME:uasncs.c */
22 /* */
23 /* FUNCTIONS: uasin */
24 /* uacos */
25 /* FILES NEEDED: dla.h endian.h mpa.h mydefs.h usncs.h */
26 /* doasin.c sincos32.c dosincos.c mpa.c */
27 /* sincos.tbl asincos.tbl powtwo.tbl root.tbl */
28 /* */
29 /* Ultimate asin/acos routines. Given an IEEE double machine */
30 /* number x, compute the correctly rounded value of */
31 /* arcsin(x)or arccos(x) according to the function called. */
32 /* Assumption: Machine arithmetic operations are performed in */
33 /* round to nearest mode of IEEE 754 standard. */
34 /* */
35 /******************************************************************/
36 #include "endian.h"
37 #include "mydefs.h"
38 #include "asincos.tbl"
39 #include "root.tbl"
40 #include "powtwo.tbl"
41 #include "MathLib.h"
42 #include "uasncs.h"
43 #include "math_private.h"
45 void __doasin(double x, double dx, double w[]);
46 void __dubsin(double x, double dx, double v[]);
47 void __dubcos(double x, double dx, double v[]);
48 void __docos(double x, double dx, double v[]);
49 double __sin32(double x, double res, double res1);
50 double __cos32(double x, double res, double res1);
52 /***************************************************************************/
53 /* An ultimate asin routine. Given an IEEE double machine number x */
54 /* it computes the correctly rounded (to nearest) value of arcsin(x) */
55 /***************************************************************************/
56 double __ieee754_asin(double x){
57 double x1,x2,xx,s1,s2,res1,p,t,res,r,cor,cc,y,c,z,w[2];
58 mynumber u,v;
59 int4 k,m,n;
60 #if 0
61 int4 nn;
62 #endif
64 u.x = x;
65 m = u.i[HIGH_HALF];
66 k = 0x7fffffff&m; /* no sign */
68 if (k < 0x3e500000) return x; /* for x->0 => sin(x)=x */
69 /*----------------------2^-26 <= |x| < 2^ -3 -----------------*/
70 else
71 if (k < 0x3fc00000) {
72 x2 = x*x;
73 t = (((((f6*x2 + f5)*x2 + f4)*x2 + f3)*x2 + f2)*x2 + f1)*(x2*x);
74 res = x+t; /* res=arcsin(x) according to Taylor series */
75 cor = (x-res)+t;
76 if (res == res+1.025*cor) return res;
77 else {
78 x1 = x+big;
79 xx = x*x;
80 x1 -= big;
81 x2 = x - x1;
82 p = x1*x1*x1;
83 s1 = a1.x*p;
84 s2 = ((((((c7*xx + c6)*xx + c5)*xx + c4)*xx + c3)*xx + c2)*xx*xx*x +
85 ((a1.x+a2.x)*x2*x2+ 0.5*x1*x)*x2) + a2.x*p;
86 res1 = x+s1;
87 s2 = ((x-res1)+s1)+s2;
88 res = res1+s2;
89 cor = (res1-res)+s2;
90 if (res == res+1.00014*cor) return res;
91 else {
92 __doasin(x,0,w);
93 if (w[0]==(w[0]+1.00000001*w[1])) return w[0];
94 else {
95 y=ABS(x);
96 res=ABS(w[0]);
97 res1=ABS(w[0]+1.1*w[1]);
98 return (m>0)?__sin32(y,res,res1):-__sin32(y,res,res1);
103 /*---------------------0.125 <= |x| < 0.5 -----------------------------*/
104 else if (k < 0x3fe00000) {
105 if (k<0x3fd00000) n = 11*((k&0x000fffff)>>15);
106 else n = 11*((k&0x000fffff)>>14)+352;
107 if (m>0) xx = x - asncs.x[n];
108 else xx = -x - asncs.x[n];
109 t = asncs.x[n+1]*xx;
110 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+xx*(asncs.x[n+5]
111 +xx*asncs.x[n+6]))))+asncs.x[n+7];
112 t+=p;
113 res =asncs.x[n+8] +t;
114 cor = (asncs.x[n+8]-res)+t;
115 if (res == res+1.05*cor) return (m>0)?res:-res;
116 else {
117 r=asncs.x[n+8]+xx*asncs.x[n+9];
118 t=((asncs.x[n+8]-r)+xx*asncs.x[n+9])+(p+xx*asncs.x[n+10]);
119 res = r+t;
120 cor = (r-res)+t;
121 if (res == res+1.0005*cor) return (m>0)?res:-res;
122 else {
123 res1=res+1.1*cor;
124 z=0.5*(res1-res);
125 __dubsin(res,z,w);
126 z=(w[0]-ABS(x))+w[1];
127 if (z>1.0e-27) return (m>0)?min(res,res1):-min(res,res1);
128 else if (z<-1.0e-27) return (m>0)?max(res,res1):-max(res,res1);
129 else {
130 y=ABS(x);
131 return (m>0)?__sin32(y,res,res1):-__sin32(y,res,res1);
135 } /* else if (k < 0x3fe00000) */
136 /*-------------------- 0.5 <= |x| < 0.75 -----------------------------*/
137 else
138 if (k < 0x3fe80000) {
139 n = 1056+((k&0x000fe000)>>11)*3;
140 if (m>0) xx = x - asncs.x[n];
141 else xx = -x - asncs.x[n];
142 t = asncs.x[n+1]*xx;
143 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+xx*(asncs.x[n+5]
144 +xx*(asncs.x[n+6]+xx*asncs.x[n+7])))))+asncs.x[n+8];
145 t+=p;
146 res =asncs.x[n+9] +t;
147 cor = (asncs.x[n+9]-res)+t;
148 if (res == res+1.01*cor) return (m>0)?res:-res;
149 else {
150 r=asncs.x[n+9]+xx*asncs.x[n+10];
151 t=((asncs.x[n+9]-r)+xx*asncs.x[n+10])+(p+xx*asncs.x[n+11]);
152 res = r+t;
153 cor = (r-res)+t;
154 if (res == res+1.0005*cor) return (m>0)?res:-res;
155 else {
156 res1=res+1.1*cor;
157 z=0.5*(res1-res);
158 __dubsin(res,z,w);
159 z=(w[0]-ABS(x))+w[1];
160 if (z>1.0e-27) return (m>0)?min(res,res1):-min(res,res1);
161 else if (z<-1.0e-27) return (m>0)?max(res,res1):-max(res,res1);
162 else {
163 y=ABS(x);
164 return (m>0)?__sin32(y,res,res1):-__sin32(y,res,res1);
168 } /* else if (k < 0x3fe80000) */
169 /*--------------------- 0.75 <= |x|< 0.921875 ----------------------*/
170 else
171 if (k < 0x3fed8000) {
172 n = 992+((k&0x000fe000)>>13)*13;
173 if (m>0) xx = x - asncs.x[n];
174 else xx = -x - asncs.x[n];
175 t = asncs.x[n+1]*xx;
176 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+xx*(asncs.x[n+5]
177 +xx*(asncs.x[n+6]+xx*(asncs.x[n+7]+xx*asncs.x[n+8]))))))+asncs.x[n+9];
178 t+=p;
179 res =asncs.x[n+10] +t;
180 cor = (asncs.x[n+10]-res)+t;
181 if (res == res+1.01*cor) return (m>0)?res:-res;
182 else {
183 r=asncs.x[n+10]+xx*asncs.x[n+11];
184 t=((asncs.x[n+10]-r)+xx*asncs.x[n+11])+(p+xx*asncs.x[n+12]);
185 res = r+t;
186 cor = (r-res)+t;
187 if (res == res+1.0008*cor) return (m>0)?res:-res;
188 else {
189 res1=res+1.1*cor;
190 z=0.5*(res1-res);
191 y=hp0.x-res;
192 z=((hp0.x-y)-res)+(hp1.x-z);
193 __dubcos(y,z,w);
194 z=(w[0]-ABS(x))+w[1];
195 if (z>1.0e-27) return (m>0)?min(res,res1):-min(res,res1);
196 else if (z<-1.0e-27) return (m>0)?max(res,res1):-max(res,res1);
197 else {
198 y=ABS(x);
199 return (m>0)?__sin32(y,res,res1):-__sin32(y,res,res1);
203 } /* else if (k < 0x3fed8000) */
204 /*-------------------0.921875 <= |x| < 0.953125 ------------------------*/
205 else
206 if (k < 0x3fee8000) {
207 n = 884+((k&0x000fe000)>>13)*14;
208 if (m>0) xx = x - asncs.x[n];
209 else xx = -x - asncs.x[n];
210 t = asncs.x[n+1]*xx;
211 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
212 xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
213 +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+
214 xx*asncs.x[n+9])))))))+asncs.x[n+10];
215 t+=p;
216 res =asncs.x[n+11] +t;
217 cor = (asncs.x[n+11]-res)+t;
218 if (res == res+1.01*cor) return (m>0)?res:-res;
219 else {
220 r=asncs.x[n+11]+xx*asncs.x[n+12];
221 t=((asncs.x[n+11]-r)+xx*asncs.x[n+12])+(p+xx*asncs.x[n+13]);
222 res = r+t;
223 cor = (r-res)+t;
224 if (res == res+1.0007*cor) return (m>0)?res:-res;
225 else {
226 res1=res+1.1*cor;
227 z=0.5*(res1-res);
228 y=(hp0.x-res)-z;
229 z=y+hp1.x;
230 y=(y-z)+hp1.x;
231 __dubcos(z,y,w);
232 z=(w[0]-ABS(x))+w[1];
233 if (z>1.0e-27) return (m>0)?min(res,res1):-min(res,res1);
234 else if (z<-1.0e-27) return (m>0)?max(res,res1):-max(res,res1);
235 else {
236 y=ABS(x);
237 return (m>0)?__sin32(y,res,res1):-__sin32(y,res,res1);
241 } /* else if (k < 0x3fee8000) */
243 /*--------------------0.953125 <= |x| < 0.96875 ------------------------*/
244 else
245 if (k < 0x3fef0000) {
246 n = 768+((k&0x000fe000)>>13)*15;
247 if (m>0) xx = x - asncs.x[n];
248 else xx = -x - asncs.x[n];
249 t = asncs.x[n+1]*xx;
250 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
251 xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
252 +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+
253 xx*(asncs.x[n+9]+xx*asncs.x[n+10]))))))))+asncs.x[n+11];
254 t+=p;
255 res =asncs.x[n+12] +t;
256 cor = (asncs.x[n+12]-res)+t;
257 if (res == res+1.01*cor) return (m>0)?res:-res;
258 else {
259 r=asncs.x[n+12]+xx*asncs.x[n+13];
260 t=((asncs.x[n+12]-r)+xx*asncs.x[n+13])+(p+xx*asncs.x[n+14]);
261 res = r+t;
262 cor = (r-res)+t;
263 if (res == res+1.0007*cor) return (m>0)?res:-res;
264 else {
265 res1=res+1.1*cor;
266 z=0.5*(res1-res);
267 y=(hp0.x-res)-z;
268 z=y+hp1.x;
269 y=(y-z)+hp1.x;
270 __dubcos(z,y,w);
271 z=(w[0]-ABS(x))+w[1];
272 if (z>1.0e-27) return (m>0)?min(res,res1):-min(res,res1);
273 else if (z<-1.0e-27) return (m>0)?max(res,res1):-max(res,res1);
274 else {
275 y=ABS(x);
276 return (m>0)?__sin32(y,res,res1):-__sin32(y,res,res1);
280 } /* else if (k < 0x3fef0000) */
281 /*--------------------0.96875 <= |x| < 1 --------------------------------*/
282 else
283 if (k<0x3ff00000) {
284 z = 0.5*((m>0)?(1.0-x):(1.0+x));
285 v.x=z;
286 k=v.i[HIGH_HALF];
287 t=inroot[(k&0x001fffff)>>14]*powtwo[511-(k>>21)];
288 r=1.0-t*t*z;
289 t = t*(rt0+r*(rt1+r*(rt2+r*rt3)));
290 c=t*z;
291 t=c*(1.5-0.5*t*c);
292 y=(c+t24)-t24;
293 cc = (z-y*y)/(t+y);
294 p=(((((f6*z+f5)*z+f4)*z+f3)*z+f2)*z+f1)*z;
295 cor = (hp1.x - 2.0*cc)-2.0*(y+cc)*p;
296 res1 = hp0.x - 2.0*y;
297 res =res1 + cor;
298 if (res == res+1.003*((res1-res)+cor)) return (m>0)?res:-res;
299 else {
300 c=y+cc;
301 cc=(y-c)+cc;
302 __doasin(c,cc,w);
303 res1=hp0.x-2.0*w[0];
304 cor=((hp0.x-res1)-2.0*w[0])+(hp1.x-2.0*w[1]);
305 res = res1+cor;
306 cor = (res1-res)+cor;
307 if (res==(res+1.0000001*cor)) return (m>0)?res:-res;
308 else {
309 y=ABS(x);
310 res1=res+1.1*cor;
311 return (m>0)?__sin32(y,res,res1):-__sin32(y,res,res1);
314 } /* else if (k < 0x3ff00000) */
315 /*---------------------------- |x|>=1 -------------------------------*/
316 else if (k==0x3ff00000 && u.i[LOW_HALF]==0) return (m>0)?hp0.x:-hp0.x;
317 else
318 if (k>0x7ff00000 || (k == 0x7ff00000 && u.i[LOW_HALF] != 0)) return x;
319 else {
320 u.i[HIGH_HALF]=0x7ff00000;
321 v.i[HIGH_HALF]=0x7ff00000;
322 u.i[LOW_HALF]=0;
323 v.i[LOW_HALF]=0;
324 return u.x/v.x; /* NaN */
328 /*******************************************************************/
329 /* */
330 /* End of arcsine, below is arccosine */
331 /* */
332 /*******************************************************************/
334 double __ieee754_acos(double x)
336 double x1,x2,xx,s1,s2,res1,p,t,res,r,cor,cc,y,c,z,w[2],eps;
337 #if 0
338 double fc;
339 #endif
340 mynumber u,v;
341 int4 k,m,n;
342 #if 0
343 int4 nn;
344 #endif
345 u.x = x;
346 m = u.i[HIGH_HALF];
347 k = 0x7fffffff&m;
348 /*------------------- |x|<2.77556*10^-17 ----------------------*/
349 if (k < 0x3c880000) return hp0.x;
351 /*----------------- 2.77556*10^-17 <= |x| < 2^-3 --------------*/
352 else
353 if (k < 0x3fc00000) {
354 x2 = x*x;
355 t = (((((f6*x2 + f5)*x2 + f4)*x2 + f3)*x2 + f2)*x2 + f1)*(x2*x);
356 r=hp0.x-x;
357 cor=(((hp0.x-r)-x)+hp1.x)-t;
358 res = r+cor;
359 cor = (r-res)+cor;
360 if (res == res+1.004*cor) return res;
361 else {
362 x1 = x+big;
363 xx = x*x;
364 x1 -= big;
365 x2 = x - x1;
366 p = x1*x1*x1;
367 s1 = a1.x*p;
368 s2 = ((((((c7*xx + c6)*xx + c5)*xx + c4)*xx + c3)*xx + c2)*xx*xx*x +
369 ((a1.x+a2.x)*x2*x2+ 0.5*x1*x)*x2) + a2.x*p;
370 res1 = x+s1;
371 s2 = ((x-res1)+s1)+s2;
372 r=hp0.x-res1;
373 cor=(((hp0.x-r)-res1)+hp1.x)-s2;
374 res = r+cor;
375 cor = (r-res)+cor;
376 if (res == res+1.00004*cor) return res;
377 else {
378 __doasin(x,0,w);
379 r=hp0.x-w[0];
380 cor=((hp0.x-r)-w[0])+(hp1.x-w[1]);
381 res=r+cor;
382 cor=(r-res)+cor;
383 if (res ==(res +1.00000001*cor)) return res;
384 else {
385 res1=res+1.1*cor;
386 return __cos32(x,res,res1);
390 } /* else if (k < 0x3fc00000) */
391 /*---------------------- 0.125 <= |x| < 0.5 --------------------*/
392 else
393 if (k < 0x3fe00000) {
394 if (k<0x3fd00000) n = 11*((k&0x000fffff)>>15);
395 else n = 11*((k&0x000fffff)>>14)+352;
396 if (m>0) xx = x - asncs.x[n];
397 else xx = -x - asncs.x[n];
398 t = asncs.x[n+1]*xx;
399 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
400 xx*(asncs.x[n+5]+xx*asncs.x[n+6]))))+asncs.x[n+7];
401 t+=p;
402 y = (m>0)?(hp0.x-asncs.x[n+8]):(hp0.x+asncs.x[n+8]);
403 t = (m>0)?(hp1.x-t):(hp1.x+t);
404 res = y+t;
405 if (res == res+1.02*((y-res)+t)) return res;
406 else {
407 r=asncs.x[n+8]+xx*asncs.x[n+9];
408 t=((asncs.x[n+8]-r)+xx*asncs.x[n+9])+(p+xx*asncs.x[n+10]);
409 if (m>0)
410 {p = hp0.x-r; t = (((hp0.x-p)-r)-t)+hp1.x; }
411 else
412 {p = hp0.x+r; t = ((hp0.x-p)+r)+(hp1.x+t); }
413 res = p+t;
414 cor = (p-res)+t;
415 if (res == (res+1.0002*cor)) return res;
416 else {
417 res1=res+1.1*cor;
418 z=0.5*(res1-res);
419 __docos(res,z,w);
420 z=(w[0]-x)+w[1];
421 if (z>1.0e-27) return max(res,res1);
422 else if (z<-1.0e-27) return min(res,res1);
423 else return __cos32(x,res,res1);
426 } /* else if (k < 0x3fe00000) */
428 /*--------------------------- 0.5 <= |x| < 0.75 ---------------------*/
429 else
430 if (k < 0x3fe80000) {
431 n = 1056+((k&0x000fe000)>>11)*3;
432 if (m>0) {xx = x - asncs.x[n]; eps=1.04; }
433 else {xx = -x - asncs.x[n]; eps=1.02; }
434 t = asncs.x[n+1]*xx;
435 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
436 xx*(asncs.x[n+5]+xx*(asncs.x[n+6]+
437 xx*asncs.x[n+7])))))+asncs.x[n+8];
438 t+=p;
439 y = (m>0)?(hp0.x-asncs.x[n+9]):(hp0.x+asncs.x[n+9]);
440 t = (m>0)?(hp1.x-t):(hp1.x+t);
441 res = y+t;
442 if (res == res+eps*((y-res)+t)) return res;
443 else {
444 r=asncs.x[n+9]+xx*asncs.x[n+10];
445 t=((asncs.x[n+9]-r)+xx*asncs.x[n+10])+(p+xx*asncs.x[n+11]);
446 if (m>0) {p = hp0.x-r; t = (((hp0.x-p)-r)-t)+hp1.x; eps=1.0004; }
447 else {p = hp0.x+r; t = ((hp0.x-p)+r)+(hp1.x+t); eps=1.0002; }
448 res = p+t;
449 cor = (p-res)+t;
450 if (res == (res+eps*cor)) return res;
451 else {
452 res1=res+1.1*cor;
453 z=0.5*(res1-res);
454 __docos(res,z,w);
455 z=(w[0]-x)+w[1];
456 if (z>1.0e-27) return max(res,res1);
457 else if (z<-1.0e-27) return min(res,res1);
458 else return __cos32(x,res,res1);
461 } /* else if (k < 0x3fe80000) */
463 /*------------------------- 0.75 <= |x| < 0.921875 -------------*/
464 else
465 if (k < 0x3fed8000) {
466 n = 992+((k&0x000fe000)>>13)*13;
467 if (m>0) {xx = x - asncs.x[n]; eps = 1.04; }
468 else {xx = -x - asncs.x[n]; eps = 1.01; }
469 t = asncs.x[n+1]*xx;
470 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
471 xx*(asncs.x[n+5]+xx*(asncs.x[n+6]+xx*(asncs.x[n+7]+
472 xx*asncs.x[n+8]))))))+asncs.x[n+9];
473 t+=p;
474 y = (m>0)?(hp0.x-asncs.x[n+10]):(hp0.x+asncs.x[n+10]);
475 t = (m>0)?(hp1.x-t):(hp1.x+t);
476 res = y+t;
477 if (res == res+eps*((y-res)+t)) return res;
478 else {
479 r=asncs.x[n+10]+xx*asncs.x[n+11];
480 t=((asncs.x[n+10]-r)+xx*asncs.x[n+11])+(p+xx*asncs.x[n+12]);
481 if (m>0) {p = hp0.x-r; t = (((hp0.x-p)-r)-t)+hp1.x; eps=1.0032; }
482 else {p = hp0.x+r; t = ((hp0.x-p)+r)+(hp1.x+t); eps=1.0008; }
483 res = p+t;
484 cor = (p-res)+t;
485 if (res == (res+eps*cor)) return res;
486 else {
487 res1=res+1.1*cor;
488 z=0.5*(res1-res);
489 __docos(res,z,w);
490 z=(w[0]-x)+w[1];
491 if (z>1.0e-27) return max(res,res1);
492 else if (z<-1.0e-27) return min(res,res1);
493 else return __cos32(x,res,res1);
496 } /* else if (k < 0x3fed8000) */
498 /*-------------------0.921875 <= |x| < 0.953125 ------------------*/
499 else
500 if (k < 0x3fee8000) {
501 n = 884+((k&0x000fe000)>>13)*14;
502 if (m>0) {xx = x - asncs.x[n]; eps=1.04; }
503 else {xx = -x - asncs.x[n]; eps =1.005; }
504 t = asncs.x[n+1]*xx;
505 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
506 xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
507 +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+
508 xx*asncs.x[n+9])))))))+asncs.x[n+10];
509 t+=p;
510 y = (m>0)?(hp0.x-asncs.x[n+11]):(hp0.x+asncs.x[n+11]);
511 t = (m>0)?(hp1.x-t):(hp1.x+t);
512 res = y+t;
513 if (res == res+eps*((y-res)+t)) return res;
514 else {
515 r=asncs.x[n+11]+xx*asncs.x[n+12];
516 t=((asncs.x[n+11]-r)+xx*asncs.x[n+12])+(p+xx*asncs.x[n+13]);
517 if (m>0) {p = hp0.x-r; t = (((hp0.x-p)-r)-t)+hp1.x; eps=1.0030; }
518 else {p = hp0.x+r; t = ((hp0.x-p)+r)+(hp1.x+t); eps=1.0005; }
519 res = p+t;
520 cor = (p-res)+t;
521 if (res == (res+eps*cor)) return res;
522 else {
523 res1=res+1.1*cor;
524 z=0.5*(res1-res);
525 __docos(res,z,w);
526 z=(w[0]-x)+w[1];
527 if (z>1.0e-27) return max(res,res1);
528 else if (z<-1.0e-27) return min(res,res1);
529 else return __cos32(x,res,res1);
532 } /* else if (k < 0x3fee8000) */
534 /*--------------------0.953125 <= |x| < 0.96875 ----------------*/
535 else
536 if (k < 0x3fef0000) {
537 n = 768+((k&0x000fe000)>>13)*15;
538 if (m>0) {xx = x - asncs.x[n]; eps=1.04; }
539 else {xx = -x - asncs.x[n]; eps=1.005;}
540 t = asncs.x[n+1]*xx;
541 p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
542 xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
543 +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+xx*(asncs.x[n+9]+
544 xx*asncs.x[n+10]))))))))+asncs.x[n+11];
545 t+=p;
546 y = (m>0)?(hp0.x-asncs.x[n+12]):(hp0.x+asncs.x[n+12]);
547 t = (m>0)?(hp1.x-t):(hp1.x+t);
548 res = y+t;
549 if (res == res+eps*((y-res)+t)) return res;
550 else {
551 r=asncs.x[n+12]+xx*asncs.x[n+13];
552 t=((asncs.x[n+12]-r)+xx*asncs.x[n+13])+(p+xx*asncs.x[n+14]);
553 if (m>0) {p = hp0.x-r; t = (((hp0.x-p)-r)-t)+hp1.x; eps=1.0030; }
554 else {p = hp0.x+r; t = ((hp0.x-p)+r)+(hp1.x+t); eps=1.0005; }
555 res = p+t;
556 cor = (p-res)+t;
557 if (res == (res+eps*cor)) return res;
558 else {
559 res1=res+1.1*cor;
560 z=0.5*(res1-res);
561 __docos(res,z,w);
562 z=(w[0]-x)+w[1];
563 if (z>1.0e-27) return max(res,res1);
564 else if (z<-1.0e-27) return min(res,res1);
565 else return __cos32(x,res,res1);
568 } /* else if (k < 0x3fef0000) */
569 /*-----------------0.96875 <= |x| < 1 ---------------------------*/
571 else
572 if (k<0x3ff00000) {
573 z = 0.5*((m>0)?(1.0-x):(1.0+x));
574 v.x=z;
575 k=v.i[HIGH_HALF];
576 t=inroot[(k&0x001fffff)>>14]*powtwo[511-(k>>21)];
577 r=1.0-t*t*z;
578 t = t*(rt0+r*(rt1+r*(rt2+r*rt3)));
579 c=t*z;
580 t=c*(1.5-0.5*t*c);
581 y = (t27*c+c)-t27*c;
582 cc = (z-y*y)/(t+y);
583 p=(((((f6*z+f5)*z+f4)*z+f3)*z+f2)*z+f1)*z;
584 if (m<0) {
585 cor = (hp1.x - cc)-(y+cc)*p;
586 res1 = hp0.x - y;
587 res =res1 + cor;
588 if (res == res+1.002*((res1-res)+cor)) return (res+res);
589 else {
590 c=y+cc;
591 cc=(y-c)+cc;
592 __doasin(c,cc,w);
593 res1=hp0.x-w[0];
594 cor=((hp0.x-res1)-w[0])+(hp1.x-w[1]);
595 res = res1+cor;
596 cor = (res1-res)+cor;
597 if (res==(res+1.000001*cor)) return (res+res);
598 else {
599 res=res+res;
600 res1=res+1.2*cor;
601 return __cos32(x,res,res1);
605 else {
606 cor = cc+p*(y+cc);
607 res = y + cor;
608 if (res == res+1.03*((y-res)+cor)) return (res+res);
609 else {
610 c=y+cc;
611 cc=(y-c)+cc;
612 __doasin(c,cc,w);
613 res = w[0];
614 cor=w[1];
615 if (res==(res+1.000001*cor)) return (res+res);
616 else {
617 res=res+res;
618 res1=res+1.2*cor;
619 return __cos32(x,res,res1);
623 } /* else if (k < 0x3ff00000) */
625 /*---------------------------- |x|>=1 -----------------------*/
626 else
627 if (k==0x3ff00000 && u.i[LOW_HALF]==0) return (m>0)?0:2.0*hp0.x;
628 else
629 if (k>0x7ff00000 || (k == 0x7ff00000 && u.i[LOW_HALF] != 0)) return x;
630 else {
631 u.i[HIGH_HALF]=0x7ff00000;
632 v.i[HIGH_HALF]=0x7ff00000;
633 u.i[LOW_HALF]=0;
634 v.i[LOW_HALF]=0;
635 return u.x/v.x;