d632fe6f3be0d321498e0d5c8e6fefcbe71858f4
[musl] / src / math / sincosl.c
1 #define _GNU_SOURCE
2 #include "libm.h"
3
4 #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
5 void sincosl(long double x, long double *sin, long double *cos)
6 {
7         sincos(x, (double *)sin, (double *)cos);
8 }
9 #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
10 void sincosl(long double x, long double *sin, long double *cos)
11 {
12         union IEEEl2bits u;
13         int n;
14         long double y[2], s, c;
15
16         u.e = x;
17         u.bits.sign = 0;
18
19         /* x = +-0 or subnormal */
20         if (!u.bits.exp) {
21                 *sin = x;
22                 *cos = 1.0;
23                 return;
24         }
25
26         /* x = nan or inf */
27         if (u.bits.exp == 0x7fff) {
28                 *sin = *cos = x - x;
29                 return;
30         }
31
32         /* |x| < pi/4 */
33         if (u.e < M_PI_4) {
34                 *sin = __sinl(x, 0, 0);
35                 *cos = __cosl(x, 0);
36                 return;
37         }
38
39         n = __rem_pio2l(x, y);
40         s = __sinl(y[0], y[1], 1);
41         c = __cosl(y[0], y[1]);
42         switch (n & 3) {
43         case 0:
44                 *sin = s;
45                 *cos = c;
46                 break;
47         case 1:
48                 *sin = c;
49                 *cos = -s;
50                 break;
51         case 2:
52                 *sin = -s;
53                 *cos = -c;
54                 break;
55         case 3:
56         default:
57                 *sin = -c;
58                 *cos = s;
59                 break;
60         }
61 }
62 #endif