2 * IBM Accurate Mathematical Library
3 * written by International Business Machines Corp.
4 * Copyright (C) 2001-2013 Free Software Foundation, Inc.
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>
66 } __sincostab attribute_hidden
;
69 sn3
= -1.66666666666664880952546298448555E-01,
70 sn5
= 8.33333214285722277379541354343671E-03,
71 cs2
= 4.99999999999999999999950396842453E-01,
72 cs4
= -4.16666666666664434524222570944589E-02,
73 cs6
= 1.38888874007937613028114285595617E-03;
75 void __dubsin (double x
, double dx
, double w
[]);
76 void __docos (double x
, double dx
, double w
[]);
77 double __mpsin (double x
, double dx
);
78 double __mpcos (double x
, double dx
);
79 double __mpsin1 (double x
);
80 double __mpcos1 (double x
);
81 static double slow (double x
);
82 static double slow1 (double x
);
83 static double slow2 (double x
);
84 static double sloww (double x
, double dx
, double orig
);
85 static double sloww1 (double x
, double dx
, double orig
);
86 static double sloww2 (double x
, double dx
, double orig
, int n
);
87 static double bsloww (double x
, double dx
, double orig
, int n
);
88 static double bsloww1 (double x
, double dx
, double orig
, int n
);
89 static double bsloww2 (double x
, double dx
, double orig
, int n
);
90 int __branred (double x
, double *a
, double *aa
);
91 static double cslow2 (double x
);
92 static double csloww (double x
, double dx
, double orig
);
93 static double csloww1 (double x
, double dx
, double orig
);
94 static double csloww2 (double x
, double dx
, double orig
, int n
);
96 /*******************************************************************/
97 /* An ultimate sin routine. Given an IEEE double machine number x */
98 /* it computes the correctly rounded (to nearest) value of sin(x) */
99 /*******************************************************************/
104 double xx
, res
, t
, cor
, y
, s
, c
, sn
, ssn
, cs
, ccs
, xn
, a
, da
, db
, eps
, xn1
,
110 SET_RESTORE_ROUND_53BIT (FE_TONEAREST
);
114 k
= 0x7fffffff & m
; /* no sign */
115 if (k
< 0x3e500000) /* if x->0 =>sin(x)=x */
120 /*---------------------------- 2^-26 < |x|< 0.25 ----------------------*/
121 else if (k
< 0x3fd00000)
125 t
= (((((s5
.x
* xx
+ s4
.x
) * xx
+ s3
.x
) * xx
+ s2
.x
) * xx
+ s1
.x
)
129 retval
= (res
== res
+ 1.07 * cor
) ? res
: slow (x
);
131 } /* else if (k < 0x3fd00000) */
132 /*---------------------------- 0.25<|x|< 0.855469---------------------- */
133 else if (k
< 0x3feb6000)
135 u
.x
= (m
> 0) ? big
.x
+ x
: big
.x
- x
;
136 y
= (m
> 0) ? x
- (u
.x
- big
.x
) : x
+ (u
.x
- big
.x
);
138 s
= y
+ y
* xx
* (sn3
+ xx
* sn5
);
139 c
= xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
140 k
= u
.i
[LOW_HALF
] << 2;
141 sn
= (m
> 0) ? __sincostab
.x
[k
] : -__sincostab
.x
[k
];
142 ssn
= (m
> 0) ? __sincostab
.x
[k
+ 1] : -__sincostab
.x
[k
+ 1];
143 cs
= __sincostab
.x
[k
+ 2];
144 ccs
= __sincostab
.x
[k
+ 3];
145 cor
= (ssn
+ s
* ccs
- sn
* c
) + cs
* s
;
147 cor
= (sn
- res
) + cor
;
148 retval
= (res
== res
+ 1.096 * cor
) ? res
: slow1 (x
);
150 } /* else if (k < 0x3feb6000) */
152 /*----------------------- 0.855469 <|x|<2.426265 ----------------------*/
153 else if (k
< 0x400368fd)
156 y
= (m
> 0) ? hp0
.x
- x
: hp0
.x
+ x
;
160 y
= (y
- (u
.x
- big
.x
)) + hp1
.x
;
165 y
= (-hp1
.x
) - (y
+ (u
.x
- big
.x
));
168 s
= y
+ y
* xx
* (sn3
+ xx
* sn5
);
169 c
= xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
170 k
= u
.i
[LOW_HALF
] << 2;
171 sn
= __sincostab
.x
[k
];
172 ssn
= __sincostab
.x
[k
+ 1];
173 cs
= __sincostab
.x
[k
+ 2];
174 ccs
= __sincostab
.x
[k
+ 3];
175 cor
= (ccs
- s
* ssn
- cs
* c
) - sn
* s
;
177 cor
= (cs
- res
) + cor
;
178 retval
= (res
== res
+ 1.020 * cor
) ? ((m
> 0) ? res
: -res
) : slow2 (x
);
180 } /* else if (k < 0x400368fd) */
182 /*-------------------------- 2.426265<|x|< 105414350 ----------------------*/
183 else if (k
< 0x419921FB)
185 t
= (x
* hpinv
.x
+ toint
.x
);
188 y
= (x
- xn
* mp1
.x
) - xn
* mp2
.x
;
189 n
= v
.i
[LOW_HALF
] & 3;
193 eps
= ABS (x
) * 1.2e-30;
196 { /* quarter of unit circle */
208 t
= (((((s5
.x
* xx
+ s4
.x
) * xx
+ s3
.x
) * xx
+ s2
.x
) * xx
209 + s1
.x
) * a
- 0.5 * da
) * xx
+ da
;
212 cor
= (cor
> 0) ? 1.02 * cor
+ eps
: 1.02 * cor
- eps
;
213 retval
= (res
== res
+ cor
) ? res
: sloww (a
, da
, x
);
231 y
= t
- (u
.x
- big
.x
);
233 s
= y
+ (db
+ y
* xx
* (sn3
+ xx
* sn5
));
234 c
= y
* db
+ xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
235 k
= u
.i
[LOW_HALF
] << 2;
236 sn
= __sincostab
.x
[k
];
237 ssn
= __sincostab
.x
[k
+ 1];
238 cs
= __sincostab
.x
[k
+ 2];
239 ccs
= __sincostab
.x
[k
+ 3];
240 cor
= (ssn
+ s
* ccs
- sn
* c
) + cs
* s
;
242 cor
= (sn
- res
) + cor
;
243 cor
= (cor
> 0) ? 1.035 * cor
+ eps
: 1.035 * cor
- eps
;
244 retval
= ((res
== res
+ cor
) ? ((m
) ? res
: -res
)
245 : sloww1 (a
, da
, x
));
258 y
= a
- (u
.x
- big
.x
) + da
;
260 k
= u
.i
[LOW_HALF
] << 2;
261 sn
= __sincostab
.x
[k
];
262 ssn
= __sincostab
.x
[k
+ 1];
263 cs
= __sincostab
.x
[k
+ 2];
264 ccs
= __sincostab
.x
[k
+ 3];
265 s
= y
+ y
* xx
* (sn3
+ xx
* sn5
);
266 c
= xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
267 cor
= (ccs
- s
* ssn
- cs
* c
) - sn
* s
;
269 cor
= (cs
- res
) + cor
;
270 cor
= (cor
> 0) ? 1.025 * cor
+ eps
: 1.025 * cor
- eps
;
271 retval
= ((res
== res
+ cor
) ? ((n
& 2) ? -res
: res
)
272 : sloww2 (a
, da
, x
, n
));
278 } /* else if (k < 0x419921FB ) */
280 /*---------------------105414350 <|x|< 281474976710656 --------------------*/
281 else if (k
< 0x42F00000)
283 t
= (x
* hpinv
.x
+ toint
.x
);
286 xn1
= (xn
+ 8.0e22
) - 8.0e22
;
288 y
= ((((x
- xn1
* mp1
.x
) - xn1
* mp2
.x
) - xn2
* mp1
.x
) - xn2
* mp2
.x
);
289 n
= v
.i
[LOW_HALF
] & 3;
293 da
= (da
- xn2
* pp3
.x
) - xn
* pp4
.x
;
311 t
= (((((s5
.x
* xx
+ s4
.x
) * xx
+ s3
.x
) * xx
+ s2
.x
) * xx
312 + s1
.x
) * a
- 0.5 * da
) * xx
+ da
;
315 cor
= (cor
> 0) ? 1.02 * cor
+ eps
: 1.02 * cor
- eps
;
316 retval
= (res
== res
+ cor
) ? res
: bsloww (a
, da
, x
, n
);
334 y
= t
- (u
.x
- big
.x
);
336 s
= y
+ (db
+ y
* xx
* (sn3
+ xx
* sn5
));
337 c
= y
* db
+ xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
338 k
= u
.i
[LOW_HALF
] << 2;
339 sn
= __sincostab
.x
[k
];
340 ssn
= __sincostab
.x
[k
+ 1];
341 cs
= __sincostab
.x
[k
+ 2];
342 ccs
= __sincostab
.x
[k
+ 3];
343 cor
= (ssn
+ s
* ccs
- sn
* c
) + cs
* s
;
345 cor
= (sn
- res
) + cor
;
346 cor
= (cor
> 0) ? 1.035 * cor
+ eps
: 1.035 * cor
- eps
;
347 retval
= ((res
== res
+ cor
) ? ((m
) ? res
: -res
)
348 : bsloww1 (a
, da
, x
, n
));
361 y
= a
- (u
.x
- big
.x
) + da
;
363 k
= u
.i
[LOW_HALF
] << 2;
364 sn
= __sincostab
.x
[k
];
365 ssn
= __sincostab
.x
[k
+ 1];
366 cs
= __sincostab
.x
[k
+ 2];
367 ccs
= __sincostab
.x
[k
+ 3];
368 s
= y
+ y
* xx
* (sn3
+ xx
* sn5
);
369 c
= xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
370 cor
= (ccs
- s
* ssn
- cs
* c
) - sn
* s
;
372 cor
= (cs
- res
) + cor
;
373 cor
= (cor
> 0) ? 1.025 * cor
+ eps
: 1.025 * cor
- eps
;
374 retval
= ((res
== res
+ cor
) ? ((n
& 2) ? -res
: res
)
375 : bsloww2 (a
, da
, x
, n
));
380 } /* else if (k < 0x42F00000 ) */
382 /* -----------------281474976710656 <|x| <2^1024----------------------------*/
383 else if (k
< 0x7ff00000)
385 n
= __branred (x
, &a
, &da
);
390 retval
= bsloww (a
, da
, x
, n
);
392 retval
= bsloww1 (a
, da
, x
, n
);
397 retval
= bsloww (-a
, -da
, x
, n
);
399 retval
= bsloww1 (-a
, -da
, x
, n
);
405 retval
= bsloww2 (a
, da
, x
, n
);
409 } /* else if (k < 0x7ff00000 ) */
411 /*--------------------- |x| > 2^1024 ----------------------------------*/
414 if (k
== 0x7ff00000 && u
.i
[LOW_HALF
] == 0)
425 /*******************************************************************/
426 /* An ultimate cos routine. Given an IEEE double machine number x */
427 /* it computes the correctly rounded (to nearest) value of cos(x) */
428 /*******************************************************************/
434 double y
, xx
, res
, t
, cor
, s
, c
, sn
, ssn
, cs
, ccs
, xn
, a
, da
, db
, eps
, xn1
,
441 SET_RESTORE_ROUND_53BIT (FE_TONEAREST
);
451 } /* |x|<2^-27 => cos(x)=1 */
453 else if (k
< 0x3feb6000)
454 { /* 2^-27 < |x| < 0.855469 */
457 y
= y
- (u
.x
- big
.x
);
459 s
= y
+ y
* xx
* (sn3
+ xx
* sn5
);
460 c
= xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
461 k
= u
.i
[LOW_HALF
] << 2;
462 sn
= __sincostab
.x
[k
];
463 ssn
= __sincostab
.x
[k
+ 1];
464 cs
= __sincostab
.x
[k
+ 2];
465 ccs
= __sincostab
.x
[k
+ 3];
466 cor
= (ccs
- s
* ssn
- cs
* c
) - sn
* s
;
468 cor
= (cs
- res
) + cor
;
469 retval
= (res
== res
+ 1.020 * cor
) ? res
: cslow2 (x
);
471 } /* else if (k < 0x3feb6000) */
473 else if (k
< 0x400368fd)
474 { /* 0.855469 <|x|<2.426265 */ ;
477 da
= (y
- a
) + hp1
.x
;
481 t
= (((((s5
.x
* xx
+ s4
.x
) * xx
+ s3
.x
) * xx
+ s2
.x
) * xx
+ s1
.x
)
482 * a
- 0.5 * da
) * xx
+ da
;
485 cor
= (cor
> 0) ? 1.02 * cor
+ 1.0e-31 : 1.02 * cor
- 1.0e-31;
486 retval
= (res
== res
+ cor
) ? res
: csloww (a
, da
, x
);
504 y
= t
- (u
.x
- big
.x
);
506 s
= y
+ (db
+ y
* xx
* (sn3
+ xx
* sn5
));
507 c
= y
* db
+ xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
508 k
= u
.i
[LOW_HALF
] << 2;
509 sn
= __sincostab
.x
[k
];
510 ssn
= __sincostab
.x
[k
+ 1];
511 cs
= __sincostab
.x
[k
+ 2];
512 ccs
= __sincostab
.x
[k
+ 3];
513 cor
= (ssn
+ s
* ccs
- sn
* c
) + cs
* s
;
515 cor
= (sn
- res
) + cor
;
516 cor
= (cor
> 0) ? 1.035 * cor
+ 1.0e-31 : 1.035 * cor
- 1.0e-31;
517 retval
= ((res
== res
+ cor
) ? ((m
) ? res
: -res
)
518 : csloww1 (a
, da
, x
));
522 } /* else if (k < 0x400368fd) */
525 else if (k
< 0x419921FB)
526 { /* 2.426265<|x|< 105414350 */
527 t
= (x
* hpinv
.x
+ toint
.x
);
530 y
= (x
- xn
* mp1
.x
) - xn
* mp2
.x
;
531 n
= v
.i
[LOW_HALF
] & 3;
535 eps
= ABS (x
) * 1.2e-30;
549 t
= (((((s5
.x
* xx
+ s4
.x
) * xx
+ s3
.x
) * xx
+ s2
.x
) * xx
550 + s1
.x
) * a
- 0.5 * da
) * xx
+ da
;
553 cor
= (cor
> 0) ? 1.02 * cor
+ eps
: 1.02 * cor
- eps
;
554 retval
= (res
== res
+ cor
) ? res
: csloww (a
, da
, x
);
572 y
= t
- (u
.x
- big
.x
);
574 s
= y
+ (db
+ y
* xx
* (sn3
+ xx
* sn5
));
575 c
= y
* db
+ xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
576 k
= u
.i
[LOW_HALF
] << 2;
577 sn
= __sincostab
.x
[k
];
578 ssn
= __sincostab
.x
[k
+ 1];
579 cs
= __sincostab
.x
[k
+ 2];
580 ccs
= __sincostab
.x
[k
+ 3];
581 cor
= (ssn
+ s
* ccs
- sn
* c
) + cs
* s
;
583 cor
= (sn
- res
) + cor
;
584 cor
= (cor
> 0) ? 1.035 * cor
+ eps
: 1.035 * cor
- eps
;
585 retval
= ((res
== res
+ cor
) ? ((m
) ? res
: -res
)
586 : csloww1 (a
, da
, x
));
599 y
= a
- (u
.x
- big
.x
) + da
;
601 k
= u
.i
[LOW_HALF
] << 2;
602 sn
= __sincostab
.x
[k
];
603 ssn
= __sincostab
.x
[k
+ 1];
604 cs
= __sincostab
.x
[k
+ 2];
605 ccs
= __sincostab
.x
[k
+ 3];
606 s
= y
+ y
* xx
* (sn3
+ xx
* sn5
);
607 c
= xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
608 cor
= (ccs
- s
* ssn
- cs
* c
) - sn
* s
;
610 cor
= (cs
- res
) + cor
;
611 cor
= (cor
> 0) ? 1.025 * cor
+ eps
: 1.025 * cor
- eps
;
612 retval
= ((res
== res
+ cor
) ? ((n
) ? -res
: res
)
613 : csloww2 (a
, da
, x
, n
));
618 } /* else if (k < 0x419921FB ) */
620 else if (k
< 0x42F00000)
622 t
= (x
* hpinv
.x
+ toint
.x
);
625 xn1
= (xn
+ 8.0e22
) - 8.0e22
;
627 y
= ((((x
- xn1
* mp1
.x
) - xn1
* mp2
.x
) - xn2
* mp1
.x
) - xn2
* mp2
.x
);
628 n
= v
.i
[LOW_HALF
] & 3;
632 da
= (da
- xn2
* pp3
.x
) - xn
* pp4
.x
;
649 t
= (((((s5
.x
* xx
+ s4
.x
) * xx
+ s3
.x
) * xx
+ s2
.x
) * xx
650 + s1
.x
) * a
- 0.5 * da
) * xx
+ da
;
653 cor
= (cor
> 0) ? 1.02 * cor
+ eps
: 1.02 * cor
- eps
;
654 retval
= (res
== res
+ cor
) ? res
: bsloww (a
, da
, x
, n
);
672 y
= t
- (u
.x
- big
.x
);
674 s
= y
+ (db
+ y
* xx
* (sn3
+ xx
* sn5
));
675 c
= y
* db
+ xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
676 k
= u
.i
[LOW_HALF
] << 2;
677 sn
= __sincostab
.x
[k
];
678 ssn
= __sincostab
.x
[k
+ 1];
679 cs
= __sincostab
.x
[k
+ 2];
680 ccs
= __sincostab
.x
[k
+ 3];
681 cor
= (ssn
+ s
* ccs
- sn
* c
) + cs
* s
;
683 cor
= (sn
- res
) + cor
;
684 cor
= (cor
> 0) ? 1.035 * cor
+ eps
: 1.035 * cor
- eps
;
685 retval
= ((res
== res
+ cor
) ? ((m
) ? res
: -res
)
686 : bsloww1 (a
, da
, x
, n
));
699 y
= a
- (u
.x
- big
.x
) + da
;
701 k
= u
.i
[LOW_HALF
] << 2;
702 sn
= __sincostab
.x
[k
];
703 ssn
= __sincostab
.x
[k
+ 1];
704 cs
= __sincostab
.x
[k
+ 2];
705 ccs
= __sincostab
.x
[k
+ 3];
706 s
= y
+ y
* xx
* (sn3
+ xx
* sn5
);
707 c
= xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
708 cor
= (ccs
- s
* ssn
- cs
* c
) - sn
* s
;
710 cor
= (cs
- res
) + cor
;
711 cor
= (cor
> 0) ? 1.025 * cor
+ eps
: 1.025 * cor
- eps
;
712 retval
= ((res
== res
+ cor
) ? ((n
) ? -res
: res
)
713 : bsloww2 (a
, da
, x
, n
));
717 } /* else if (k < 0x42F00000 ) */
719 else if (k
< 0x7ff00000)
720 { /* 281474976710656 <|x| <2^1024 */
722 n
= __branred (x
, &a
, &da
);
727 retval
= bsloww (-a
, -da
, x
, n
);
729 retval
= bsloww1 (-a
, -da
, x
, n
);
734 retval
= bsloww (a
, da
, x
, n
);
736 retval
= bsloww1 (a
, da
, x
, n
);
742 retval
= bsloww2 (a
, da
, x
, n
);
746 } /* else if (k < 0x7ff00000 ) */
750 if (k
== 0x7ff00000 && u
.i
[LOW_HALF
] == 0)
752 retval
= x
/ x
; /* |x| > 2^1024 */
760 /************************************************************************/
761 /* Routine compute sin(x) for 2^-26 < |x|< 0.25 by Taylor with more */
762 /* precision and if still doesn't accurate enough by mpsin or dubsin */
763 /************************************************************************/
769 static const double th2_36
= 206158430208.0; /* 1.5*2**37 */
770 double y
, x1
, x2
, xx
, r
, t
, res
, cor
, w
[2];
771 x1
= (x
+ th2_36
) - th2_36
;
772 y
= aa
.x
* x1
* x1
* x1
;
776 t
= (((((s5
.x
* xx
+ s4
.x
) * xx
+ s3
.x
) * xx
+ s2
.x
) * xx
+ bb
.x
) * xx
777 + 3.0 * aa
.x
* x1
* x2
) * x
+ aa
.x
* x2
* x2
* x2
;
778 t
= ((x
- r
) + y
) + t
;
781 if (res
== res
+ 1.0007 * cor
)
785 __dubsin (ABS (x
), 0, w
);
786 if (w
[0] == w
[0] + 1.000000001 * w
[1])
787 return (x
> 0) ? w
[0] : -w
[0];
789 return (x
> 0) ? __mpsin (x
, 0) : -__mpsin (-x
, 0);
793 /*******************************************************************************/
794 /* Routine compute sin(x) for 0.25<|x|< 0.855469 by __sincostab.tbl and Taylor */
795 /* and if result still doesn't accurate enough by mpsin or dubsin */
796 /*******************************************************************************/
803 double sn
, ssn
, cs
, ccs
, s
, c
, w
[2], y
, y1
, y2
, c1
, c2
, xx
, cor
, res
;
804 static const double t22
= 6291456.0;
808 y
= y
- (u
.x
- big
.x
);
810 s
= y
* xx
* (sn3
+ xx
* sn5
);
811 c
= xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
812 k
= u
.i
[LOW_HALF
] << 2;
813 sn
= __sincostab
.x
[k
]; /* Data */
814 ssn
= __sincostab
.x
[k
+ 1]; /* from */
815 cs
= __sincostab
.x
[k
+ 2]; /* tables */
816 ccs
= __sincostab
.x
[k
+ 3]; /* __sincostab.tbl */
817 y1
= (y
+ t22
) - t22
;
819 c1
= (cs
+ t22
) - t22
;
820 c2
= (cs
- c1
) + ccs
;
821 cor
= (ssn
+ s
* ccs
+ cs
* s
+ c2
* y
+ c1
* y2
) - sn
* c
;
823 cor
= cor
+ ((sn
- y
) + c1
* y1
);
825 cor
= (y
- res
) + cor
;
826 if (res
== res
+ 1.0005 * cor
)
827 return (x
> 0) ? res
: -res
;
830 __dubsin (ABS (x
), 0, w
);
831 if (w
[0] == w
[0] + 1.000000005 * w
[1])
832 return (x
> 0) ? w
[0] : -w
[0];
834 return (x
> 0) ? __mpsin (x
, 0) : -__mpsin (-x
, 0);
838 /**************************************************************************/
839 /* Routine compute sin(x) for 0.855469 <|x|<2.426265 by __sincostab.tbl */
840 /* and if result still doesn't accurate enough by mpsin or dubsin */
841 /**************************************************************************/
847 double sn
, ssn
, cs
, ccs
, s
, c
, w
[2], y
, y1
, y2
, e1
, e2
, xx
, cor
, res
, del
;
848 static const double t22
= 6291456.0;
855 y
= y
- (u
.x
- big
.x
);
861 y
= -(y
+ (u
.x
- big
.x
));
865 s
= y
* xx
* (sn3
+ xx
* sn5
);
866 c
= y
* del
+ xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
867 k
= u
.i
[LOW_HALF
] << 2;
868 sn
= __sincostab
.x
[k
];
869 ssn
= __sincostab
.x
[k
+ 1];
870 cs
= __sincostab
.x
[k
+ 2];
871 ccs
= __sincostab
.x
[k
+ 3];
872 y1
= (y
+ t22
) - t22
;
874 e1
= (sn
+ t22
) - t22
;
875 e2
= (sn
- e1
) + ssn
;
876 cor
= (ccs
- cs
* c
- e1
* y2
- e2
* y
) - sn
* s
;
878 cor
= cor
+ ((cs
- y
) - e1
* y1
);
880 cor
= (y
- res
) + cor
;
881 if (res
== res
+ 1.0005 * cor
)
882 return (x
> 0) ? res
: -res
;
887 y2
= (y
- y1
) - hp1
.x
;
889 if (w
[0] == w
[0] + 1.000000005 * w
[1])
890 return (x
> 0) ? w
[0] : -w
[0];
892 return (x
> 0) ? __mpsin (x
, 0) : -__mpsin (-x
, 0);
896 /***************************************************************************/
897 /* Routine compute sin(x+dx) (Double-Length number) where x is small enough*/
898 /* to use Taylor series around zero and (x+dx) */
899 /* in first or third quarter of unit circle.Routine receive also */
900 /* (right argument) the original value of x for computing error of */
901 /* result.And if result not accurate enough routine calls mpsin1 or dubsin */
902 /***************************************************************************/
906 sloww (double x
, double dx
, double orig
)
908 static const double th2_36
= 206158430208.0; /* 1.5*2**37 */
909 double y
, x1
, x2
, xx
, r
, t
, res
, cor
, w
[2], a
, da
, xn
;
916 x1
= (x
+ th2_36
) - th2_36
;
917 y
= aa
.x
* x1
* x1
* x1
;
921 t
= (((((s5
.x
* xx
+ s4
.x
) * xx
+ s3
.x
) * xx
+ s2
.x
) * xx
+ bb
.x
) * xx
922 + 3.0 * aa
.x
* x1
* x2
) * x
+ aa
.x
* x2
* x2
* x2
+ dx
;
923 t
= ((x
- r
) + y
) + t
;
928 0) ? 1.0005 * cor
+ ABS (orig
) * 3.1e-30 : 1.0005 * cor
-
929 ABS (orig
) * 3.1e-30;
930 if (res
== res
+ cor
)
934 (x
> 0) ? __dubsin (x
, dx
, w
) : __dubsin (-x
, -dx
, w
);
936 cor
= 1.000000001 * w
[1] + ABS (orig
) * 1.1e-30;
938 cor
= 1.000000001 * w
[1] - ABS (orig
) * 1.1e-30;
940 if (w
[0] == w
[0] + cor
)
941 return (x
> 0) ? w
[0] : -w
[0];
944 t
= (orig
* hpinv
.x
+ toint
.x
);
947 y
= (orig
- xn
* mp1
.x
) - xn
* mp2
.x
;
948 n
= v
.i
[LOW_HALF
] & 3;
954 da
= ((t
- a
) - y
) + da
;
960 (a
> 0) ? __dubsin (a
, da
, w
) : __dubsin (-a
, -da
, w
);
962 cor
= 1.000000001 * w
[1] + ABS (orig
) * 1.1e-40;
964 cor
= 1.000000001 * w
[1] - ABS (orig
) * 1.1e-40;
966 if (w
[0] == w
[0] + cor
)
967 return (a
> 0) ? w
[0] : -w
[0];
969 return __mpsin1 (orig
);
974 /***************************************************************************/
975 /* Routine compute sin(x+dx) (Double-Length number) where x in first or */
976 /* third quarter of unit circle.Routine receive also (right argument) the */
977 /* original value of x for computing error of result.And if result not */
978 /* accurate enough routine calls mpsin1 or dubsin */
979 /***************************************************************************/
983 sloww1 (double x
, double dx
, double orig
)
986 double sn
, ssn
, cs
, ccs
, s
, c
, w
[2], y
, y1
, y2
, c1
, c2
, xx
, cor
, res
;
987 static const double t22
= 6291456.0;
992 y
= y
- (u
.x
- big
.x
);
993 dx
= (x
> 0) ? dx
: -dx
;
995 s
= y
* xx
* (sn3
+ xx
* sn5
);
996 c
= xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
997 k
= u
.i
[LOW_HALF
] << 2;
998 sn
= __sincostab
.x
[k
];
999 ssn
= __sincostab
.x
[k
+ 1];
1000 cs
= __sincostab
.x
[k
+ 2];
1001 ccs
= __sincostab
.x
[k
+ 3];
1002 y1
= (y
+ t22
) - t22
;
1004 c1
= (cs
+ t22
) - t22
;
1005 c2
= (cs
- c1
) + ccs
;
1006 cor
= (ssn
+ s
* ccs
+ cs
* s
+ c2
* y
+ c1
* y2
- sn
* y
* dx
) - sn
* c
;
1008 cor
= cor
+ ((sn
- y
) + c1
* y1
);
1010 cor
= (y
- res
) + cor
;
1013 cor
= 1.0005 * cor
+ 3.1e-30 * ABS (orig
);
1015 cor
= 1.0005 * cor
- 3.1e-30 * ABS (orig
);
1017 if (res
== res
+ cor
)
1018 return (x
> 0) ? res
: -res
;
1021 __dubsin (ABS (x
), dx
, w
);
1024 cor
= 1.000000005 * w
[1] + 1.1e-30 * ABS (orig
);
1026 cor
= 1.000000005 * w
[1] - 1.1e-30 * ABS (orig
);
1028 if (w
[0] == w
[0] + cor
)
1029 return (x
> 0) ? w
[0] : -w
[0];
1031 return __mpsin1 (orig
);
1035 /***************************************************************************/
1036 /* Routine compute sin(x+dx) (Double-Length number) where x in second or */
1037 /* fourth quarter of unit circle.Routine receive also the original value */
1038 /* and quarter(n= 1or 3)of x for computing error of result.And if result not*/
1039 /* accurate enough routine calls mpsin1 or dubsin */
1040 /***************************************************************************/
1044 sloww2 (double x
, double dx
, double orig
, int n
)
1047 double sn
, ssn
, cs
, ccs
, s
, c
, w
[2], y
, y1
, y2
, e1
, e2
, xx
, cor
, res
;
1048 static const double t22
= 6291456.0;
1053 y
= y
- (u
.x
- big
.x
);
1054 dx
= (x
> 0) ? dx
: -dx
;
1056 s
= y
* xx
* (sn3
+ xx
* sn5
);
1057 c
= y
* dx
+ xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
1058 k
= u
.i
[LOW_HALF
] << 2;
1059 sn
= __sincostab
.x
[k
];
1060 ssn
= __sincostab
.x
[k
+ 1];
1061 cs
= __sincostab
.x
[k
+ 2];
1062 ccs
= __sincostab
.x
[k
+ 3];
1064 y1
= (y
+ t22
) - t22
;
1066 e1
= (sn
+ t22
) - t22
;
1067 e2
= (sn
- e1
) + ssn
;
1068 cor
= (ccs
- cs
* c
- e1
* y2
- e2
* y
) - sn
* s
;
1070 cor
= cor
+ ((cs
- y
) - e1
* y1
);
1072 cor
= (y
- res
) + cor
;
1075 cor
= 1.0005 * cor
+ 3.1e-30 * ABS (orig
);
1077 cor
= 1.0005 * cor
- 3.1e-30 * ABS (orig
);
1079 if (res
== res
+ cor
)
1080 return (n
& 2) ? -res
: res
;
1083 __docos (ABS (x
), dx
, w
);
1086 cor
= 1.000000005 * w
[1] + 1.1e-30 * ABS (orig
);
1088 cor
= 1.000000005 * w
[1] - 1.1e-30 * ABS (orig
);
1090 if (w
[0] == w
[0] + cor
)
1091 return (n
& 2) ? -w
[0] : w
[0];
1093 return __mpsin1 (orig
);
1097 /***************************************************************************/
1098 /* Routine compute sin(x+dx) or cos(x+dx) (Double-Length number) where x */
1099 /* is small enough to use Taylor series around zero and (x+dx) */
1100 /* in first or third quarter of unit circle.Routine receive also */
1101 /* (right argument) the original value of x for computing error of */
1102 /* result.And if result not accurate enough routine calls other routines */
1103 /***************************************************************************/
1107 bsloww (double x
, double dx
, double orig
, int n
)
1109 static const double th2_36
= 206158430208.0; /* 1.5*2**37 */
1110 double y
, x1
, x2
, xx
, r
, t
, res
, cor
, w
[2];
1112 x1
= (x
+ th2_36
) - th2_36
;
1113 y
= aa
.x
* x1
* x1
* x1
;
1117 t
= (((((s5
.x
* xx
+ s4
.x
) * xx
+ s3
.x
) * xx
+ s2
.x
) * xx
+ bb
.x
) * xx
1118 + 3.0 * aa
.x
* x1
* x2
) * x
+ aa
.x
* x2
* x2
* x2
+ dx
;
1119 t
= ((x
- r
) + y
) + t
;
1121 cor
= (r
- res
) + t
;
1122 cor
= (cor
> 0) ? 1.0005 * cor
+ 1.1e-24 : 1.0005 * cor
- 1.1e-24;
1123 if (res
== res
+ cor
)
1127 (x
> 0) ? __dubsin (x
, dx
, w
) : __dubsin (-x
, -dx
, w
);
1129 cor
= 1.000000001 * w
[1] + 1.1e-24;
1131 cor
= 1.000000001 * w
[1] - 1.1e-24;
1132 if (w
[0] == w
[0] + cor
)
1133 return (x
> 0) ? w
[0] : -w
[0];
1135 return (n
& 1) ? __mpcos1 (orig
) : __mpsin1 (orig
);
1139 /***************************************************************************/
1140 /* Routine compute sin(x+dx) or cos(x+dx) (Double-Length number) where x */
1141 /* in first or third quarter of unit circle.Routine receive also */
1142 /* (right argument) the original value of x for computing error of result.*/
1143 /* And if result not accurate enough routine calls other routines */
1144 /***************************************************************************/
1148 bsloww1 (double x
, double dx
, double orig
, int n
)
1151 double sn
, ssn
, cs
, ccs
, s
, c
, w
[2], y
, y1
, y2
, c1
, c2
, xx
, cor
, res
;
1152 static const double t22
= 6291456.0;
1157 y
= y
- (u
.x
- big
.x
);
1158 dx
= (x
> 0) ? dx
: -dx
;
1160 s
= y
* xx
* (sn3
+ xx
* sn5
);
1161 c
= xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
1162 k
= u
.i
[LOW_HALF
] << 2;
1163 sn
= __sincostab
.x
[k
];
1164 ssn
= __sincostab
.x
[k
+ 1];
1165 cs
= __sincostab
.x
[k
+ 2];
1166 ccs
= __sincostab
.x
[k
+ 3];
1167 y1
= (y
+ t22
) - t22
;
1169 c1
= (cs
+ t22
) - t22
;
1170 c2
= (cs
- c1
) + ccs
;
1171 cor
= (ssn
+ s
* ccs
+ cs
* s
+ c2
* y
+ c1
* y2
- sn
* y
* dx
) - sn
* c
;
1173 cor
= cor
+ ((sn
- y
) + c1
* y1
);
1175 cor
= (y
- res
) + cor
;
1176 cor
= (cor
> 0) ? 1.0005 * cor
+ 1.1e-24 : 1.0005 * cor
- 1.1e-24;
1177 if (res
== res
+ cor
)
1178 return (x
> 0) ? res
: -res
;
1181 __dubsin (ABS (x
), dx
, w
);
1184 cor
= 1.000000005 * w
[1] + 1.1e-24;
1186 cor
= 1.000000005 * w
[1] - 1.1e-24;
1188 if (w
[0] == w
[0] + cor
)
1189 return (x
> 0) ? w
[0] : -w
[0];
1191 return (n
& 1) ? __mpcos1 (orig
) : __mpsin1 (orig
);
1195 /***************************************************************************/
1196 /* Routine compute sin(x+dx) or cos(x+dx) (Double-Length number) where x */
1197 /* in second or fourth quarter of unit circle.Routine receive also the */
1198 /* original value and quarter(n= 1or 3)of x for computing error of result. */
1199 /* And if result not accurate enough routine calls other routines */
1200 /***************************************************************************/
1204 bsloww2 (double x
, double dx
, double orig
, int n
)
1207 double sn
, ssn
, cs
, ccs
, s
, c
, w
[2], y
, y1
, y2
, e1
, e2
, xx
, cor
, res
;
1208 static const double t22
= 6291456.0;
1213 y
= y
- (u
.x
- big
.x
);
1214 dx
= (x
> 0) ? dx
: -dx
;
1216 s
= y
* xx
* (sn3
+ xx
* sn5
);
1217 c
= y
* dx
+ xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
1218 k
= u
.i
[LOW_HALF
] << 2;
1219 sn
= __sincostab
.x
[k
];
1220 ssn
= __sincostab
.x
[k
+ 1];
1221 cs
= __sincostab
.x
[k
+ 2];
1222 ccs
= __sincostab
.x
[k
+ 3];
1224 y1
= (y
+ t22
) - t22
;
1226 e1
= (sn
+ t22
) - t22
;
1227 e2
= (sn
- e1
) + ssn
;
1228 cor
= (ccs
- cs
* c
- e1
* y2
- e2
* y
) - sn
* s
;
1230 cor
= cor
+ ((cs
- y
) - e1
* y1
);
1232 cor
= (y
- res
) + cor
;
1233 cor
= (cor
> 0) ? 1.0005 * cor
+ 1.1e-24 : 1.0005 * cor
- 1.1e-24;
1234 if (res
== res
+ cor
)
1235 return (n
& 2) ? -res
: res
;
1238 __docos (ABS (x
), dx
, w
);
1241 cor
= 1.000000005 * w
[1] + 1.1e-24;
1243 cor
= 1.000000005 * w
[1] - 1.1e-24;
1245 if (w
[0] == w
[0] + cor
)
1246 return (n
& 2) ? -w
[0] : w
[0];
1248 return (n
& 1) ? __mpsin1 (orig
) : __mpcos1 (orig
);
1252 /************************************************************************/
1253 /* Routine compute cos(x) for 2^-27 < |x|< 0.25 by Taylor with more */
1254 /* precision and if still doesn't accurate enough by mpcos or docos */
1255 /************************************************************************/
1262 double sn
, ssn
, cs
, ccs
, s
, c
, w
[2], y
, y1
, y2
, e1
, e2
, xx
, cor
, res
;
1263 static const double t22
= 6291456.0;
1268 y
= y
- (u
.x
- big
.x
);
1270 s
= y
* xx
* (sn3
+ xx
* sn5
);
1271 c
= xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
1272 k
= u
.i
[LOW_HALF
] << 2;
1273 sn
= __sincostab
.x
[k
];
1274 ssn
= __sincostab
.x
[k
+ 1];
1275 cs
= __sincostab
.x
[k
+ 2];
1276 ccs
= __sincostab
.x
[k
+ 3];
1277 y1
= (y
+ t22
) - t22
;
1279 e1
= (sn
+ t22
) - t22
;
1280 e2
= (sn
- e1
) + ssn
;
1281 cor
= (ccs
- cs
* c
- e1
* y2
- e2
* y
) - sn
* s
;
1283 cor
= cor
+ ((cs
- y
) - e1
* y1
);
1285 cor
= (y
- res
) + cor
;
1286 if (res
== res
+ 1.0005 * cor
)
1292 if (w
[0] == w
[0] + 1.000000005 * w
[1])
1295 return __mpcos (x
, 0);
1299 /***************************************************************************/
1300 /* Routine compute cos(x+dx) (Double-Length number) where x is small enough*/
1301 /* to use Taylor series around zero and (x+dx) .Routine receive also */
1302 /* (right argument) the original value of x for computing error of */
1303 /* result.And if result not accurate enough routine calls other routines */
1304 /***************************************************************************/
1309 csloww (double x
, double dx
, double orig
)
1311 static const double th2_36
= 206158430208.0; /* 1.5*2**37 */
1312 double y
, x1
, x2
, xx
, r
, t
, res
, cor
, w
[2], a
, da
, xn
;
1320 x1
= (x
+ th2_36
) - th2_36
;
1321 y
= aa
.x
* x1
* x1
* x1
;
1326 t
= (((((s5
.x
* xx
+ s4
.x
) * xx
+ s3
.x
) * xx
+ s2
.x
) * xx
+ bb
.x
) * xx
1327 + 3.0 * aa
.x
* x1
* x2
) * x
+ aa
.x
* x2
* x2
* x2
+ dx
;
1328 t
= ((x
- r
) + y
) + t
;
1330 cor
= (r
- res
) + t
;
1333 cor
= 1.0005 * cor
+ ABS (orig
) * 3.1e-30;
1335 cor
= 1.0005 * cor
- ABS (orig
) * 3.1e-30;
1337 if (res
== res
+ cor
)
1341 (x
> 0) ? __dubsin (x
, dx
, w
) : __dubsin (-x
, -dx
, w
);
1344 cor
= 1.000000001 * w
[1] + ABS (orig
) * 1.1e-30;
1346 cor
= 1.000000001 * w
[1] - ABS (orig
) * 1.1e-30;
1348 if (w
[0] == w
[0] + cor
)
1349 return (x
> 0) ? w
[0] : -w
[0];
1352 t
= (orig
* hpinv
.x
+ toint
.x
);
1355 y
= (orig
- xn
* mp1
.x
) - xn
* mp2
.x
;
1356 n
= v
.i
[LOW_HALF
] & 3;
1362 da
= ((t
- a
) - y
) + da
;
1368 (a
> 0) ? __dubsin (a
, da
, w
) : __dubsin (-a
, -da
, w
);
1371 cor
= 1.000000001 * w
[1] + ABS (orig
) * 1.1e-40;
1373 cor
= 1.000000001 * w
[1] - ABS (orig
) * 1.1e-40;
1375 if (w
[0] == w
[0] + cor
)
1376 return (a
> 0) ? w
[0] : -w
[0];
1378 return __mpcos1 (orig
);
1383 /***************************************************************************/
1384 /* Routine compute sin(x+dx) (Double-Length number) where x in first or */
1385 /* third quarter of unit circle.Routine receive also (right argument) the */
1386 /* original value of x for computing error of result.And if result not */
1387 /* accurate enough routine calls other routines */
1388 /***************************************************************************/
1392 csloww1 (double x
, double dx
, double orig
)
1395 double sn
, ssn
, cs
, ccs
, s
, c
, w
[2], y
, y1
, y2
, c1
, c2
, xx
, cor
, res
;
1396 static const double t22
= 6291456.0;
1401 y
= y
- (u
.x
- big
.x
);
1402 dx
= (x
> 0) ? dx
: -dx
;
1404 s
= y
* xx
* (sn3
+ xx
* sn5
);
1405 c
= xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
1406 k
= u
.i
[LOW_HALF
] << 2;
1407 sn
= __sincostab
.x
[k
];
1408 ssn
= __sincostab
.x
[k
+ 1];
1409 cs
= __sincostab
.x
[k
+ 2];
1410 ccs
= __sincostab
.x
[k
+ 3];
1411 y1
= (y
+ t22
) - t22
;
1413 c1
= (cs
+ t22
) - t22
;
1414 c2
= (cs
- c1
) + ccs
;
1415 cor
= (ssn
+ s
* ccs
+ cs
* s
+ c2
* y
+ c1
* y2
- sn
* y
* dx
) - sn
* c
;
1417 cor
= cor
+ ((sn
- y
) + c1
* y1
);
1419 cor
= (y
- res
) + cor
;
1422 cor
= 1.0005 * cor
+ 3.1e-30 * ABS (orig
);
1424 cor
= 1.0005 * cor
- 3.1e-30 * ABS (orig
);
1426 if (res
== res
+ cor
)
1427 return (x
> 0) ? res
: -res
;
1430 __dubsin (ABS (x
), dx
, w
);
1432 cor
= 1.000000005 * w
[1] + 1.1e-30 * ABS (orig
);
1434 cor
= 1.000000005 * w
[1] - 1.1e-30 * ABS (orig
);
1435 if (w
[0] == w
[0] + cor
)
1436 return (x
> 0) ? w
[0] : -w
[0];
1438 return __mpcos1 (orig
);
1443 /***************************************************************************/
1444 /* Routine compute sin(x+dx) (Double-Length number) where x in second or */
1445 /* fourth quarter of unit circle.Routine receive also the original value */
1446 /* and quarter(n= 1or 3)of x for computing error of result.And if result not*/
1447 /* accurate enough routine calls other routines */
1448 /***************************************************************************/
1452 csloww2 (double x
, double dx
, double orig
, int n
)
1455 double sn
, ssn
, cs
, ccs
, s
, c
, w
[2], y
, y1
, y2
, e1
, e2
, xx
, cor
, res
;
1456 static const double t22
= 6291456.0;
1461 y
= y
- (u
.x
- big
.x
);
1462 dx
= (x
> 0) ? dx
: -dx
;
1464 s
= y
* xx
* (sn3
+ xx
* sn5
);
1465 c
= y
* dx
+ xx
* (cs2
+ xx
* (cs4
+ xx
* cs6
));
1466 k
= u
.i
[LOW_HALF
] << 2;
1467 sn
= __sincostab
.x
[k
];
1468 ssn
= __sincostab
.x
[k
+ 1];
1469 cs
= __sincostab
.x
[k
+ 2];
1470 ccs
= __sincostab
.x
[k
+ 3];
1472 y1
= (y
+ t22
) - t22
;
1474 e1
= (sn
+ t22
) - t22
;
1475 e2
= (sn
- e1
) + ssn
;
1476 cor
= (ccs
- cs
* c
- e1
* y2
- e2
* y
) - sn
* s
;
1478 cor
= cor
+ ((cs
- y
) - e1
* y1
);
1480 cor
= (y
- res
) + cor
;
1483 cor
= 1.0005 * cor
+ 3.1e-30 * ABS (orig
);
1485 cor
= 1.0005 * cor
- 3.1e-30 * ABS (orig
);
1487 if (res
== res
+ cor
)
1488 return (n
) ? -res
: res
;
1491 __docos (ABS (x
), dx
, w
);
1493 cor
= 1.000000005 * w
[1] + 1.1e-30 * ABS (orig
);
1495 cor
= 1.000000005 * w
[1] - 1.1e-30 * ABS (orig
);
1496 if (w
[0] == w
[0] + cor
)
1497 return (n
) ? -w
[0] : w
[0];
1499 return __mpcos1 (orig
);
1504 weak_alias (__cos
, cos
)
1505 # ifdef NO_LONG_DOUBLE
1506 strong_alias (__cos
, __cosl
)
1507 weak_alias (__cos
, cosl
)
1511 weak_alias (__sin
, sin
)
1512 # ifdef NO_LONG_DOUBLE
1513 strong_alias (__sin
, __sinl
)
1514 weak_alias (__sin
, sinl
)