2 * IBM Accurate Mathematical Library
3 * written by International Business Machines Corp.
4 * Copyright (C) 2001, 2009, 2011 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, see <http://www.gnu.org/licenses/>.
19 /****************************************************************************/
21 /* MODULE_NAME:usncs.c */
38 /* FILES NEEDED: dla.h endian.h mpa.h mydefs.h usncs.h */
39 /* branred.c sincos32.c dosincos.c mpa.c */
42 /* An ultimate sin and routine. Given an IEEE double machine number x */
43 /* it computes the correctly rounded (to nearest) value of sin(x) or cos(x) */
44 /* Assumption: Machine arithmetic operations are performed in */
45 /* round to nearest mode of IEEE 754 standard. */
47 /****************************************************************************/
55 #include "math_private.h"
65 } __sincostab attribute_hidden
;
68 sn3
= -1.66666666666664880952546298448555E-01,
69 sn5
= 8.33333214285722277379541354343671E-03,
70 cs2
= 4.99999999999999999999950396842453E-01,
71 cs4
= -4.16666666666664434524222570944589E-02,
72 cs6
= 1.38888874007937613028114285595617E-03;
74 void __dubsin(double x
, double dx
, double w
[]);
75 void __docos(double x
, double dx
, double w
[]);
76 double __mpsin(double x
, double dx
);
77 double __mpcos(double x
, double dx
);
78 double __mpsin1(double x
);
79 double __mpcos1(double x
);
80 static double slow(double x
);
81 static double slow1(double x
);
82 static double slow2(double x
);
83 static double sloww(double x
, double dx
, double orig
);
84 static double sloww1(double x
, double dx
, double orig
);
85 static double sloww2(double x
, double dx
, double orig
, int n
);
86 static double bsloww(double x
, double dx
, double orig
, int n
);
87 static double bsloww1(double x
, double dx
, double orig
, int n
);
88 static double bsloww2(double x
, double dx
, double orig
, int n
);
89 int __branred(double x
, double *a
, double *aa
);
90 static double cslow2(double x
);
91 static double csloww(double x
, double dx
, double orig
);
92 static double csloww1(double x
, double dx
, double orig
);
93 static double csloww2(double x
, double dx
, double orig
, int n
);
94 /*******************************************************************/
95 /* An ultimate sin routine. Given an IEEE double machine number x */
96 /* it computes the correctly rounded (to nearest) value of sin(x) */
97 /*******************************************************************/
101 double xx
,res
,t
,cor
,y
,s
,c
,sn
,ssn
,cs
,ccs
,xn
,a
,da
,db
,eps
,xn1
,xn2
;
113 k
= 0x7fffffff&m
; /* no sign */
114 if (k
< 0x3e500000) /* if x->0 =>sin(x)=x */
116 /*---------------------------- 2^-26 < |x|< 0.25 ----------------------*/
117 else if (k
< 0x3fd00000){
120 t
= ((((s5
.x
*xx
+ s4
.x
)*xx
+ s3
.x
)*xx
+ s2
.x
)*xx
+ s1
.x
)*(xx
*x
);
123 return (res
== res
+ 1.07*cor
)? res
: slow(x
);
124 } /* else if (k < 0x3fd00000) */
125 /*---------------------------- 0.25<|x|< 0.855469---------------------- */
126 else if (k
< 0x3feb6000) {
127 u
.x
=(m
>0)?big
.x
+x
:big
.x
-x
;
128 y
=(m
>0)?x
-(u
.x
-big
.x
):x
+(u
.x
-big
.x
);
130 s
= y
+ y
*xx
*(sn3
+xx
*sn5
);
131 c
= xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
133 sn
=(m
>0)?__sincostab
.x
[k
]:-__sincostab
.x
[k
];
134 ssn
=(m
>0)?__sincostab
.x
[k
+1]:-__sincostab
.x
[k
+1];
135 cs
=__sincostab
.x
[k
+2];
136 ccs
=__sincostab
.x
[k
+3];
137 cor
=(ssn
+s
*ccs
-sn
*c
)+cs
*s
;
140 return (res
==res
+1.096*cor
)? res
: slow1(x
);
141 } /* else if (k < 0x3feb6000) */
143 /*----------------------- 0.855469 <|x|<2.426265 ----------------------*/
144 else if (k
< 0x400368fd ) {
146 y
= (m
>0)? hp0
.x
-x
:hp0
.x
+x
;
149 y
= (y
-(u
.x
-big
.x
))+hp1
.x
;
153 y
= (-hp1
.x
) - (y
+(u
.x
-big
.x
));
156 s
= y
+ y
*xx
*(sn3
+xx
*sn5
);
157 c
= xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
160 ssn
=__sincostab
.x
[k
+1];
161 cs
=__sincostab
.x
[k
+2];
162 ccs
=__sincostab
.x
[k
+3];
163 cor
=(ccs
-s
*ssn
-cs
*c
)-sn
*s
;
166 return (res
==res
+1.020*cor
)? ((m
>0)?res
:-res
) : slow2(x
);
167 } /* else if (k < 0x400368fd) */
169 /*-------------------------- 2.426265<|x|< 105414350 ----------------------*/
170 else if (k
< 0x419921FB ) {
171 t
= (x
*hpinv
.x
+ toint
.x
);
174 y
= (x
- xn
*mp1
.x
) - xn
*mp2
.x
;
179 eps
= ABS(x
)*1.2e-30;
181 switch (n
) { /* quarter of unit circle */
185 if (n
) {a
=-a
;da
=-da
;}
188 t
= (((((s5
.x
*xx
+ s4
.x
)*xx
+ s3
.x
)*xx
+ s2
.x
)*xx
+ s1
.x
)*a
- 0.5*da
)*xx
+da
;
191 cor
= (cor
>0)? 1.02*cor
+eps
: 1.02*cor
-eps
;
192 return (res
== res
+ cor
)? res
: sloww(a
,da
,x
);
202 s
= y
+ (db
+y
*xx
*(sn3
+xx
*sn5
));
203 c
= y
*db
+xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
206 ssn
=__sincostab
.x
[k
+1];
207 cs
=__sincostab
.x
[k
+2];
208 ccs
=__sincostab
.x
[k
+3];
209 cor
=(ssn
+s
*ccs
-sn
*c
)+cs
*s
;
212 cor
= (cor
>0)? 1.035*cor
+eps
: 1.035*cor
-eps
;
213 return (res
==res
+cor
)? ((m
)?res
:-res
) : sloww1(a
,da
,x
);
226 ssn
=__sincostab
.x
[k
+1];
227 cs
=__sincostab
.x
[k
+2];
228 ccs
=__sincostab
.x
[k
+3];
229 s
= y
+ y
*xx
*(sn3
+xx
*sn5
);
230 c
= xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
231 cor
=(ccs
-s
*ssn
-cs
*c
)-sn
*s
;
234 cor
= (cor
>0)? 1.025*cor
+eps
: 1.025*cor
-eps
;
235 return (res
==res
+cor
)? ((n
&2)?-res
:res
) : sloww2(a
,da
,x
,n
);
241 } /* else if (k < 0x419921FB ) */
243 /*---------------------105414350 <|x|< 281474976710656 --------------------*/
244 else if (k
< 0x42F00000 ) {
245 t
= (x
*hpinv
.x
+ toint
.x
);
248 xn1
= (xn
+8.0e22
)-8.0e22
;
250 y
= ((((x
- xn1
*mp1
.x
) - xn1
*mp2
.x
)-xn2
*mp1
.x
)-xn2
*mp2
.x
);
255 da
= (da
- xn2
*pp3
.x
) -xn
*pp4
.x
;
264 if (n
) {a
=-a
;da
=-da
;}
267 t
= (((((s5
.x
*xx
+ s4
.x
)*xx
+ s3
.x
)*xx
+ s2
.x
)*xx
+ s1
.x
)*a
- 0.5*da
)*xx
+da
;
270 cor
= (cor
>0)? 1.02*cor
+eps
: 1.02*cor
-eps
;
271 return (res
== res
+ cor
)? res
: bsloww(a
,da
,x
,n
);
274 if (a
>0) {m
=1;t
=a
;db
=da
;}
275 else {m
=0;t
=-a
;db
=-da
;}
279 s
= y
+ (db
+y
*xx
*(sn3
+xx
*sn5
));
280 c
= y
*db
+xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
283 ssn
=__sincostab
.x
[k
+1];
284 cs
=__sincostab
.x
[k
+2];
285 ccs
=__sincostab
.x
[k
+3];
286 cor
=(ssn
+s
*ccs
-sn
*c
)+cs
*s
;
289 cor
= (cor
>0)? 1.035*cor
+eps
: 1.035*cor
-eps
;
290 return (res
==res
+cor
)? ((m
)?res
:-res
) : bsloww1(a
,da
,x
,n
);
303 ssn
=__sincostab
.x
[k
+1];
304 cs
=__sincostab
.x
[k
+2];
305 ccs
=__sincostab
.x
[k
+3];
306 s
= y
+ y
*xx
*(sn3
+xx
*sn5
);
307 c
= xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
308 cor
=(ccs
-s
*ssn
-cs
*c
)-sn
*s
;
311 cor
= (cor
>0)? 1.025*cor
+eps
: 1.025*cor
-eps
;
312 return (res
==res
+cor
)? ((n
&2)?-res
:res
) : bsloww2(a
,da
,x
,n
);
318 } /* else if (k < 0x42F00000 ) */
320 /* -----------------281474976710656 <|x| <2^1024----------------------------*/
321 else if (k
< 0x7ff00000) {
323 n
= __branred(x
,&a
,&da
);
326 if (a
*a
< 0.01588) return bsloww(a
,da
,x
,n
);
327 else return bsloww1(a
,da
,x
,n
);
330 if (a
*a
< 0.01588) return bsloww(-a
,-da
,x
,n
);
331 else return bsloww1(-a
,-da
,x
,n
);
336 return bsloww2(a
,da
,x
,n
);
340 } /* else if (k < 0x7ff00000 ) */
342 /*--------------------- |x| > 2^1024 ----------------------------------*/
344 if (k
== 0x7ff00000 && u
.i
[LOW_HALF
] == 0)
348 return 0; /* unreachable */
352 /*******************************************************************/
353 /* An ultimate cos routine. Given an IEEE double machine number x */
354 /* it computes the correctly rounded (to nearest) value of cos(x) */
355 /*******************************************************************/
361 double y
,xx
,res
,t
,cor
,s
,c
,sn
,ssn
,cs
,ccs
,xn
,a
,da
,db
,eps
,xn1
,xn2
;
369 if (k
< 0x3e400000 ) return 1.0; /* |x|<2^-27 => cos(x)=1 */
371 else if (k
< 0x3feb6000 ) {/* 2^-27 < |x| < 0.855469 */
376 s
= y
+ y
*xx
*(sn3
+xx
*sn5
);
377 c
= xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
380 ssn
=__sincostab
.x
[k
+1];
381 cs
=__sincostab
.x
[k
+2];
382 ccs
=__sincostab
.x
[k
+3];
383 cor
=(ccs
-s
*ssn
-cs
*c
)-sn
*s
;
386 return (res
==res
+1.020*cor
)? res
: cslow2(x
);
388 } /* else if (k < 0x3feb6000) */
390 else if (k
< 0x400368fd ) {/* 0.855469 <|x|<2.426265 */;
396 t
= (((((s5
.x
*xx
+ s4
.x
)*xx
+ s3
.x
)*xx
+ s2
.x
)*xx
+ s1
.x
)*a
- 0.5*da
)*xx
+da
;
399 cor
= (cor
>0)? 1.02*cor
+1.0e-31 : 1.02*cor
-1.0e-31;
400 return (res
== res
+ cor
)? res
: csloww(a
,da
,x
);
403 if (a
>0) {m
=1;t
=a
;db
=da
;}
404 else {m
=0;t
=-a
;db
=-da
;}
408 s
= y
+ (db
+y
*xx
*(sn3
+xx
*sn5
));
409 c
= y
*db
+xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
412 ssn
=__sincostab
.x
[k
+1];
413 cs
=__sincostab
.x
[k
+2];
414 ccs
=__sincostab
.x
[k
+3];
415 cor
=(ssn
+s
*ccs
-sn
*c
)+cs
*s
;
418 cor
= (cor
>0)? 1.035*cor
+1.0e-31 : 1.035*cor
-1.0e-31;
419 return (res
==res
+cor
)? ((m
)?res
:-res
) : csloww1(a
,da
,x
);
422 } /* else if (k < 0x400368fd) */
425 else if (k
< 0x419921FB ) {/* 2.426265<|x|< 105414350 */
426 t
= (x
*hpinv
.x
+ toint
.x
);
429 y
= (x
- xn
*mp1
.x
) - xn
*mp2
.x
;
434 eps
= ABS(x
)*1.2e-30;
440 if (n
== 1) {a
=-a
;da
=-da
;}
442 t
= (((((s5
.x
*xx
+ s4
.x
)*xx
+ s3
.x
)*xx
+ s2
.x
)*xx
+ s1
.x
)*a
- 0.5*da
)*xx
+da
;
445 cor
= (cor
>0)? 1.02*cor
+eps
: 1.02*cor
-eps
;
446 return (res
== res
+ cor
)? res
: csloww(a
,da
,x
);
449 if (a
>0) {m
=1;t
=a
;db
=da
;}
450 else {m
=0;t
=-a
;db
=-da
;}
454 s
= y
+ (db
+y
*xx
*(sn3
+xx
*sn5
));
455 c
= y
*db
+xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
458 ssn
=__sincostab
.x
[k
+1];
459 cs
=__sincostab
.x
[k
+2];
460 ccs
=__sincostab
.x
[k
+3];
461 cor
=(ssn
+s
*ccs
-sn
*c
)+cs
*s
;
464 cor
= (cor
>0)? 1.035*cor
+eps
: 1.035*cor
-eps
;
465 return (res
==res
+cor
)? ((m
)?res
:-res
) : csloww1(a
,da
,x
);
471 if (a
<0) {a
=-a
;da
=-da
;}
477 ssn
=__sincostab
.x
[k
+1];
478 cs
=__sincostab
.x
[k
+2];
479 ccs
=__sincostab
.x
[k
+3];
480 s
= y
+ y
*xx
*(sn3
+xx
*sn5
);
481 c
= xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
482 cor
=(ccs
-s
*ssn
-cs
*c
)-sn
*s
;
485 cor
= (cor
>0)? 1.025*cor
+eps
: 1.025*cor
-eps
;
486 return (res
==res
+cor
)? ((n
)?-res
:res
) : csloww2(a
,da
,x
,n
);
492 } /* else if (k < 0x419921FB ) */
495 else if (k
< 0x42F00000 ) {
496 t
= (x
*hpinv
.x
+ toint
.x
);
499 xn1
= (xn
+8.0e22
)-8.0e22
;
501 y
= ((((x
- xn1
*mp1
.x
) - xn1
*mp2
.x
)-xn2
*mp1
.x
)-xn2
*mp2
.x
);
506 da
= (da
- xn2
*pp3
.x
) -xn
*pp4
.x
;
515 if (n
==1) {a
=-a
;da
=-da
;}
517 t
= (((((s5
.x
*xx
+ s4
.x
)*xx
+ s3
.x
)*xx
+ s2
.x
)*xx
+ s1
.x
)*a
- 0.5*da
)*xx
+da
;
520 cor
= (cor
>0)? 1.02*cor
+eps
: 1.02*cor
-eps
;
521 return (res
== res
+ cor
)? res
: bsloww(a
,da
,x
,n
);
524 if (a
>0) {m
=1;t
=a
;db
=da
;}
525 else {m
=0;t
=-a
;db
=-da
;}
529 s
= y
+ (db
+y
*xx
*(sn3
+xx
*sn5
));
530 c
= y
*db
+xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
533 ssn
=__sincostab
.x
[k
+1];
534 cs
=__sincostab
.x
[k
+2];
535 ccs
=__sincostab
.x
[k
+3];
536 cor
=(ssn
+s
*ccs
-sn
*c
)+cs
*s
;
539 cor
= (cor
>0)? 1.035*cor
+eps
: 1.035*cor
-eps
;
540 return (res
==res
+cor
)? ((m
)?res
:-res
) : bsloww1(a
,da
,x
,n
);
546 if (a
<0) {a
=-a
;da
=-da
;}
552 ssn
=__sincostab
.x
[k
+1];
553 cs
=__sincostab
.x
[k
+2];
554 ccs
=__sincostab
.x
[k
+3];
555 s
= y
+ y
*xx
*(sn3
+xx
*sn5
);
556 c
= xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
557 cor
=(ccs
-s
*ssn
-cs
*c
)-sn
*s
;
560 cor
= (cor
>0)? 1.025*cor
+eps
: 1.025*cor
-eps
;
561 return (res
==res
+cor
)? ((n
)?-res
:res
) : bsloww2(a
,da
,x
,n
);
566 } /* else if (k < 0x42F00000 ) */
568 else if (k
< 0x7ff00000) {/* 281474976710656 <|x| <2^1024 */
570 n
= __branred(x
,&a
,&da
);
573 if (a
*a
< 0.01588) return bsloww(-a
,-da
,x
,n
);
574 else return bsloww1(-a
,-da
,x
,n
);
577 if (a
*a
< 0.01588) return bsloww(a
,da
,x
,n
);
578 else return bsloww1(a
,da
,x
,n
);
583 return bsloww2(a
,da
,x
,n
);
587 } /* else if (k < 0x7ff00000 ) */
593 if (k
== 0x7ff00000 && u
.i
[LOW_HALF
] == 0)
595 return x
/ x
; /* |x| > 2^1024 */
601 /************************************************************************/
602 /* Routine compute sin(x) for 2^-26 < |x|< 0.25 by Taylor with more */
603 /* precision and if still doesn't accurate enough by mpsin or dubsin */
604 /************************************************************************/
609 static const double th2_36
= 206158430208.0; /* 1.5*2**37 */
610 double y
,x1
,x2
,xx
,r
,t
,res
,cor
,w
[2];
611 x1
=(x
+th2_36
)-th2_36
;
616 t
= (((((s5
.x
*xx
+ s4
.x
)*xx
+ s3
.x
)*xx
+ s2
.x
)*xx
+ bb
.x
)*xx
+ 3.0*aa
.x
*x1
*x2
)*x
+aa
.x
*x2
*x2
*x2
;
620 if (res
== res
+ 1.0007*cor
) return res
;
622 __dubsin(ABS(x
),0,w
);
623 if (w
[0] == w
[0]+1.000000001*w
[1]) return (x
>0)?w
[0]:-w
[0];
624 else return (x
>0)?__mpsin(x
,0):-__mpsin(-x
,0);
627 /*******************************************************************************/
628 /* Routine compute sin(x) for 0.25<|x|< 0.855469 by __sincostab.tbl and Taylor */
629 /* and if result still doesn't accurate enough by mpsin or dubsin */
630 /*******************************************************************************/
636 double sn
,ssn
,cs
,ccs
,s
,c
,w
[2],y
,y1
,y2
,c1
,c2
,xx
,cor
,res
;
637 static const double t22
= 6291456.0;
643 s
= y
*xx
*(sn3
+xx
*sn5
);
644 c
= xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
646 sn
=__sincostab
.x
[k
]; /* Data */
647 ssn
=__sincostab
.x
[k
+1]; /* from */
648 cs
=__sincostab
.x
[k
+2]; /* tables */
649 ccs
=__sincostab
.x
[k
+3]; /* __sincostab.tbl */
654 cor
=(ssn
+s
*ccs
+cs
*s
+c2
*y
+c1
*y2
)-sn
*c
;
656 cor
= cor
+((sn
-y
)+c1
*y1
);
659 if (res
== res
+1.0005*cor
) return (x
>0)?res
:-res
;
661 __dubsin(ABS(x
),0,w
);
662 if (w
[0] == w
[0]+1.000000005*w
[1]) return (x
>0)?w
[0]:-w
[0];
663 else return (x
>0)?__mpsin(x
,0):-__mpsin(-x
,0);
666 /**************************************************************************/
667 /* Routine compute sin(x) for 0.855469 <|x|<2.426265 by __sincostab.tbl */
668 /* and if result still doesn't accurate enough by mpsin or dubsin */
669 /**************************************************************************/
674 double sn
,ssn
,cs
,ccs
,s
,c
,w
[2],y
,y1
,y2
,e1
,e2
,xx
,cor
,res
,del
;
675 static const double t22
= 6291456.0;
686 y
= -(y
+(u
.x
-big
.x
));
690 s
= y
*xx
*(sn3
+xx
*sn5
);
691 c
= y
*del
+xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
694 ssn
=__sincostab
.x
[k
+1];
695 cs
=__sincostab
.x
[k
+2];
696 ccs
=__sincostab
.x
[k
+3];
701 cor
=(ccs
-cs
*c
-e1
*y2
-e2
*y
)-sn
*s
;
703 cor
= cor
+((cs
-y
)-e1
*y1
);
706 if (res
== res
+1.0005*cor
) return (x
>0)?res
:-res
;
712 if (w
[0] == w
[0]+1.000000005*w
[1]) return (x
>0)?w
[0]:-w
[0];
713 else return (x
>0)?__mpsin(x
,0):-__mpsin(-x
,0);
716 /***************************************************************************/
717 /* Routine compute sin(x+dx) (Double-Length number) where x is small enough*/
718 /* to use Taylor series around zero and (x+dx) */
719 /* in first or third quarter of unit circle.Routine receive also */
720 /* (right argument) the original value of x for computing error of */
721 /* result.And if result not accurate enough routine calls mpsin1 or dubsin */
722 /***************************************************************************/
726 sloww(double x
,double dx
, double orig
) {
727 static const double th2_36
= 206158430208.0; /* 1.5*2**37 */
728 double y
,x1
,x2
,xx
,r
,t
,res
,cor
,w
[2],a
,da
,xn
;
729 union {int4 i
[2]; double x
;} v
;
731 x1
=(x
+th2_36
)-th2_36
;
736 t
= (((((s5
.x
*xx
+ s4
.x
)*xx
+ s3
.x
)*xx
+ s2
.x
)*xx
+ bb
.x
)*xx
+ 3.0*aa
.x
*x1
*x2
)*x
+aa
.x
*x2
*x2
*x2
+dx
;
740 cor
= (cor
>0)? 1.0005*cor
+ABS(orig
)*3.1e-30 : 1.0005*cor
-ABS(orig
)*3.1e-30;
741 if (res
== res
+ cor
) return res
;
743 (x
>0)? __dubsin(x
,dx
,w
) : __dubsin(-x
,-dx
,w
);
744 cor
= (w
[1]>0)? 1.000000001*w
[1] + ABS(orig
)*1.1e-30 : 1.000000001*w
[1] - ABS(orig
)*1.1e-30;
745 if (w
[0] == w
[0]+cor
) return (x
>0)?w
[0]:-w
[0];
747 t
= (orig
*hpinv
.x
+ toint
.x
);
750 y
= (orig
- xn
*mp1
.x
) - xn
*mp2
.x
;
758 if (n
&2) {a
=-a
; da
=-da
;}
759 (a
>0)? __dubsin(a
,da
,w
) : __dubsin(-a
,-da
,w
);
760 cor
= (w
[1]>0)? 1.000000001*w
[1] + ABS(orig
)*1.1e-40 : 1.000000001*w
[1] - ABS(orig
)*1.1e-40;
761 if (w
[0] == w
[0]+cor
) return (a
>0)?w
[0]:-w
[0];
762 else return __mpsin1(orig
);
766 /***************************************************************************/
767 /* Routine compute sin(x+dx) (Double-Length number) where x in first or */
768 /* third quarter of unit circle.Routine receive also (right argument) the */
769 /* original value of x for computing error of result.And if result not */
770 /* accurate enough routine calls mpsin1 or dubsin */
771 /***************************************************************************/
775 sloww1(double x
, double dx
, double orig
) {
777 double sn
,ssn
,cs
,ccs
,s
,c
,w
[2],y
,y1
,y2
,c1
,c2
,xx
,cor
,res
;
778 static const double t22
= 6291456.0;
785 s
= y
*xx
*(sn3
+xx
*sn5
);
786 c
= xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
789 ssn
=__sincostab
.x
[k
+1];
790 cs
=__sincostab
.x
[k
+2];
791 ccs
=__sincostab
.x
[k
+3];
796 cor
=(ssn
+s
*ccs
+cs
*s
+c2
*y
+c1
*y2
-sn
*y
*dx
)-sn
*c
;
798 cor
= cor
+((sn
-y
)+c1
*y1
);
801 cor
= (cor
>0)? 1.0005*cor
+3.1e-30*ABS(orig
) : 1.0005*cor
-3.1e-30*ABS(orig
);
802 if (res
== res
+ cor
) return (x
>0)?res
:-res
;
804 __dubsin(ABS(x
),dx
,w
);
805 cor
= (w
[1]>0)? 1.000000005*w
[1]+1.1e-30*ABS(orig
) : 1.000000005*w
[1]-1.1e-30*ABS(orig
);
806 if (w
[0] == w
[0]+cor
) return (x
>0)?w
[0]:-w
[0];
807 else return __mpsin1(orig
);
810 /***************************************************************************/
811 /* Routine compute sin(x+dx) (Double-Length number) where x in second or */
812 /* fourth quarter of unit circle.Routine receive also the original value */
813 /* and quarter(n= 1or 3)of x for computing error of result.And if result not*/
814 /* accurate enough routine calls mpsin1 or dubsin */
815 /***************************************************************************/
819 sloww2(double x
, double dx
, double orig
, int n
) {
821 double sn
,ssn
,cs
,ccs
,s
,c
,w
[2],y
,y1
,y2
,e1
,e2
,xx
,cor
,res
;
822 static const double t22
= 6291456.0;
829 s
= y
*xx
*(sn3
+xx
*sn5
);
830 c
= y
*dx
+xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
833 ssn
=__sincostab
.x
[k
+1];
834 cs
=__sincostab
.x
[k
+2];
835 ccs
=__sincostab
.x
[k
+3];
841 cor
=(ccs
-cs
*c
-e1
*y2
-e2
*y
)-sn
*s
;
843 cor
= cor
+((cs
-y
)-e1
*y1
);
846 cor
= (cor
>0)? 1.0005*cor
+3.1e-30*ABS(orig
) : 1.0005*cor
-3.1e-30*ABS(orig
);
847 if (res
== res
+ cor
) return (n
&2)?-res
:res
;
849 __docos(ABS(x
),dx
,w
);
850 cor
= (w
[1]>0)? 1.000000005*w
[1]+1.1e-30*ABS(orig
) : 1.000000005*w
[1]-1.1e-30*ABS(orig
);
851 if (w
[0] == w
[0]+cor
) return (n
&2)?-w
[0]:w
[0];
852 else return __mpsin1(orig
);
855 /***************************************************************************/
856 /* Routine compute sin(x+dx) or cos(x+dx) (Double-Length number) where x */
857 /* is small enough to use Taylor series around zero and (x+dx) */
858 /* in first or third quarter of unit circle.Routine receive also */
859 /* (right argument) the original value of x for computing error of */
860 /* result.And if result not accurate enough routine calls other routines */
861 /***************************************************************************/
865 bsloww(double x
,double dx
, double orig
,int n
) {
866 static const double th2_36
= 206158430208.0; /* 1.5*2**37 */
867 double y
,x1
,x2
,xx
,r
,t
,res
,cor
,w
[2];
870 union {int4 i
[2]; double x
;} v
;
872 x1
=(x
+th2_36
)-th2_36
;
877 t
= (((((s5
.x
*xx
+ s4
.x
)*xx
+ s3
.x
)*xx
+ s2
.x
)*xx
+ bb
.x
)*xx
+ 3.0*aa
.x
*x1
*x2
)*x
+aa
.x
*x2
*x2
*x2
+dx
;
881 cor
= (cor
>0)? 1.0005*cor
+1.1e-24 : 1.0005*cor
-1.1e-24;
882 if (res
== res
+ cor
) return res
;
884 (x
>0)? __dubsin(x
,dx
,w
) : __dubsin(-x
,-dx
,w
);
885 cor
= (w
[1]>0)? 1.000000001*w
[1] + 1.1e-24 : 1.000000001*w
[1] - 1.1e-24;
886 if (w
[0] == w
[0]+cor
) return (x
>0)?w
[0]:-w
[0];
887 else return (n
&1)?__mpcos1(orig
):__mpsin1(orig
);
891 /***************************************************************************/
892 /* Routine compute sin(x+dx) or cos(x+dx) (Double-Length number) where x */
893 /* in first or third quarter of unit circle.Routine receive also */
894 /* (right argument) the original value of x for computing error of result.*/
895 /* And if result not accurate enough routine calls other routines */
896 /***************************************************************************/
900 bsloww1(double x
, double dx
, double orig
,int n
) {
902 double sn
,ssn
,cs
,ccs
,s
,c
,w
[2],y
,y1
,y2
,c1
,c2
,xx
,cor
,res
;
903 static const double t22
= 6291456.0;
910 s
= y
*xx
*(sn3
+xx
*sn5
);
911 c
= xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
914 ssn
=__sincostab
.x
[k
+1];
915 cs
=__sincostab
.x
[k
+2];
916 ccs
=__sincostab
.x
[k
+3];
921 cor
=(ssn
+s
*ccs
+cs
*s
+c2
*y
+c1
*y2
-sn
*y
*dx
)-sn
*c
;
923 cor
= cor
+((sn
-y
)+c1
*y1
);
926 cor
= (cor
>0)? 1.0005*cor
+1.1e-24 : 1.0005*cor
-1.1e-24;
927 if (res
== res
+ cor
) return (x
>0)?res
:-res
;
929 __dubsin(ABS(x
),dx
,w
);
930 cor
= (w
[1]>0)? 1.000000005*w
[1]+1.1e-24: 1.000000005*w
[1]-1.1e-24;
931 if (w
[0] == w
[0]+cor
) return (x
>0)?w
[0]:-w
[0];
932 else return (n
&1)?__mpcos1(orig
):__mpsin1(orig
);
936 /***************************************************************************/
937 /* Routine compute sin(x+dx) or cos(x+dx) (Double-Length number) where x */
938 /* in second or fourth quarter of unit circle.Routine receive also the */
939 /* original value and quarter(n= 1or 3)of x for computing error of result. */
940 /* And if result not accurate enough routine calls other routines */
941 /***************************************************************************/
945 bsloww2(double x
, double dx
, double orig
, int n
) {
947 double sn
,ssn
,cs
,ccs
,s
,c
,w
[2],y
,y1
,y2
,e1
,e2
,xx
,cor
,res
;
948 static const double t22
= 6291456.0;
955 s
= y
*xx
*(sn3
+xx
*sn5
);
956 c
= y
*dx
+xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
959 ssn
=__sincostab
.x
[k
+1];
960 cs
=__sincostab
.x
[k
+2];
961 ccs
=__sincostab
.x
[k
+3];
967 cor
=(ccs
-cs
*c
-e1
*y2
-e2
*y
)-sn
*s
;
969 cor
= cor
+((cs
-y
)-e1
*y1
);
972 cor
= (cor
>0)? 1.0005*cor
+1.1e-24 : 1.0005*cor
-1.1e-24;
973 if (res
== res
+ cor
) return (n
&2)?-res
:res
;
975 __docos(ABS(x
),dx
,w
);
976 cor
= (w
[1]>0)? 1.000000005*w
[1]+1.1e-24 : 1.000000005*w
[1]-1.1e-24;
977 if (w
[0] == w
[0]+cor
) return (n
&2)?-w
[0]:w
[0];
978 else return (n
&1)?__mpsin1(orig
):__mpcos1(orig
);
982 /************************************************************************/
983 /* Routine compute cos(x) for 2^-27 < |x|< 0.25 by Taylor with more */
984 /* precision and if still doesn't accurate enough by mpcos or docos */
985 /************************************************************************/
991 double sn
,ssn
,cs
,ccs
,s
,c
,w
[2],y
,y1
,y2
,e1
,e2
,xx
,cor
,res
;
992 static const double t22
= 6291456.0;
998 s
= y
*xx
*(sn3
+xx
*sn5
);
999 c
= xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
1001 sn
=__sincostab
.x
[k
];
1002 ssn
=__sincostab
.x
[k
+1];
1003 cs
=__sincostab
.x
[k
+2];
1004 ccs
=__sincostab
.x
[k
+3];
1009 cor
=(ccs
-cs
*c
-e1
*y2
-e2
*y
)-sn
*s
;
1011 cor
= cor
+((cs
-y
)-e1
*y1
);
1014 if (res
== res
+1.0005*cor
)
1019 if (w
[0] == w
[0]+1.000000005*w
[1]) return w
[0];
1020 else return __mpcos(x
,0);
1024 /***************************************************************************/
1025 /* Routine compute cos(x+dx) (Double-Length number) where x is small enough*/
1026 /* to use Taylor series around zero and (x+dx) .Routine receive also */
1027 /* (right argument) the original value of x for computing error of */
1028 /* result.And if result not accurate enough routine calls other routines */
1029 /***************************************************************************/
1034 csloww(double x
,double dx
, double orig
) {
1035 static const double th2_36
= 206158430208.0; /* 1.5*2**37 */
1036 double y
,x1
,x2
,xx
,r
,t
,res
,cor
,w
[2],a
,da
,xn
;
1037 union {int4 i
[2]; double x
;} v
;
1039 x1
=(x
+th2_36
)-th2_36
;
1045 t
= (((((s5
.x
*xx
+ s4
.x
)*xx
+ s3
.x
)*xx
+ s2
.x
)*xx
+ bb
.x
)*xx
+ 3.0*aa
.x
*x1
*x2
)*x
+aa
.x
*x2
*x2
*x2
+dx
;
1049 cor
= (cor
>0)? 1.0005*cor
+ABS(orig
)*3.1e-30 : 1.0005*cor
-ABS(orig
)*3.1e-30;
1050 if (res
== res
+ cor
) return res
;
1052 (x
>0)? __dubsin(x
,dx
,w
) : __dubsin(-x
,-dx
,w
);
1053 cor
= (w
[1]>0)? 1.000000001*w
[1] + ABS(orig
)*1.1e-30 : 1.000000001*w
[1] - ABS(orig
)*1.1e-30;
1054 if (w
[0] == w
[0]+cor
) return (x
>0)?w
[0]:-w
[0];
1056 t
= (orig
*hpinv
.x
+ toint
.x
);
1059 y
= (orig
- xn
*mp1
.x
) - xn
*mp2
.x
;
1067 if (n
==1) {a
=-a
; da
=-da
;}
1068 (a
>0)? __dubsin(a
,da
,w
) : __dubsin(-a
,-da
,w
);
1069 cor
= (w
[1]>0)? 1.000000001*w
[1] + ABS(orig
)*1.1e-40 : 1.000000001*w
[1] - ABS(orig
)*1.1e-40;
1070 if (w
[0] == w
[0]+cor
) return (a
>0)?w
[0]:-w
[0];
1071 else return __mpcos1(orig
);
1076 /***************************************************************************/
1077 /* Routine compute sin(x+dx) (Double-Length number) where x in first or */
1078 /* third quarter of unit circle.Routine receive also (right argument) the */
1079 /* original value of x for computing error of result.And if result not */
1080 /* accurate enough routine calls other routines */
1081 /***************************************************************************/
1085 csloww1(double x
, double dx
, double orig
) {
1087 double sn
,ssn
,cs
,ccs
,s
,c
,w
[2],y
,y1
,y2
,c1
,c2
,xx
,cor
,res
;
1088 static const double t22
= 6291456.0;
1095 s
= y
*xx
*(sn3
+xx
*sn5
);
1096 c
= xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
1098 sn
=__sincostab
.x
[k
];
1099 ssn
=__sincostab
.x
[k
+1];
1100 cs
=__sincostab
.x
[k
+2];
1101 ccs
=__sincostab
.x
[k
+3];
1106 cor
=(ssn
+s
*ccs
+cs
*s
+c2
*y
+c1
*y2
-sn
*y
*dx
)-sn
*c
;
1108 cor
= cor
+((sn
-y
)+c1
*y1
);
1111 cor
= (cor
>0)? 1.0005*cor
+3.1e-30*ABS(orig
) : 1.0005*cor
-3.1e-30*ABS(orig
);
1112 if (res
== res
+ cor
) return (x
>0)?res
:-res
;
1114 __dubsin(ABS(x
),dx
,w
);
1115 cor
= (w
[1]>0)? 1.000000005*w
[1]+1.1e-30*ABS(orig
) : 1.000000005*w
[1]-1.1e-30*ABS(orig
);
1116 if (w
[0] == w
[0]+cor
) return (x
>0)?w
[0]:-w
[0];
1117 else return __mpcos1(orig
);
1122 /***************************************************************************/
1123 /* Routine compute sin(x+dx) (Double-Length number) where x in second or */
1124 /* fourth quarter of unit circle.Routine receive also the original value */
1125 /* and quarter(n= 1or 3)of x for computing error of result.And if result not*/
1126 /* accurate enough routine calls other routines */
1127 /***************************************************************************/
1131 csloww2(double x
, double dx
, double orig
, int n
) {
1133 double sn
,ssn
,cs
,ccs
,s
,c
,w
[2],y
,y1
,y2
,e1
,e2
,xx
,cor
,res
;
1134 static const double t22
= 6291456.0;
1141 s
= y
*xx
*(sn3
+xx
*sn5
);
1142 c
= y
*dx
+xx
*(cs2
+xx
*(cs4
+ xx
*cs6
));
1144 sn
=__sincostab
.x
[k
];
1145 ssn
=__sincostab
.x
[k
+1];
1146 cs
=__sincostab
.x
[k
+2];
1147 ccs
=__sincostab
.x
[k
+3];
1153 cor
=(ccs
-cs
*c
-e1
*y2
-e2
*y
)-sn
*s
;
1155 cor
= cor
+((cs
-y
)-e1
*y1
);
1158 cor
= (cor
>0)? 1.0005*cor
+3.1e-30*ABS(orig
) : 1.0005*cor
-3.1e-30*ABS(orig
);
1159 if (res
== res
+ cor
) return (n
)?-res
:res
;
1161 __docos(ABS(x
),dx
,w
);
1162 cor
= (w
[1]>0)? 1.000000005*w
[1]+1.1e-30*ABS(orig
) : 1.000000005*w
[1]-1.1e-30*ABS(orig
);
1163 if (w
[0] == w
[0]+cor
) return (n
)?-w
[0]:w
[0];
1164 else return __mpcos1(orig
);
1169 weak_alias (__cos
, cos
)
1170 # ifdef NO_LONG_DOUBLE
1171 strong_alias (__cos
, __cosl
)
1172 weak_alias (__cos
, cosl
)
1176 weak_alias (__sin
, sin
)
1177 # ifdef NO_LONG_DOUBLE
1178 strong_alias (__sin
, __sinl
)
1179 weak_alias (__sin
, sinl
)