]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/msun/src/s_sincosf.c
sqlite3: Vendor import of sqlite3 3.44.0
[FreeBSD/FreeBSD.git] / lib / msun / src / s_sincosf.c
1 /*-
2  * ====================================================
3  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
4  *
5  * Developed at SunPro, a Sun Microsystems, Inc. business.
6  * Permission to use, copy, modify, and distribute this
7  * software is freely granted, provided that this notice
8  * is preserved.
9  * ====================================================
10  */
11
12 /* s_sincosf.c -- float version of s_sincos.c.
13  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
14  * Optimized by Bruce D. Evans.
15  * Merged s_sinf.c and s_cosf.c by Steven G. Kargl.
16  */
17
18 #include <sys/cdefs.h>
19 #include <float.h>
20
21 #include "math.h"
22 #define INLINE_REM_PIO2F
23 #include "math_private.h"
24 #include "e_rem_pio2f.c"
25 #include "k_sincosf.h"
26
27 /* Small multiples of pi/2 rounded to double precision. */
28 static const double
29 p1pio2 = 1*M_PI_2,                      /* 0x3FF921FB, 0x54442D18 */
30 p2pio2 = 2*M_PI_2,                      /* 0x400921FB, 0x54442D18 */
31 p3pio2 = 3*M_PI_2,                      /* 0x4012D97C, 0x7F3321D2 */
32 p4pio2 = 4*M_PI_2;                      /* 0x401921FB, 0x54442D18 */
33
34 void
35 sincosf(float x, float *sn, float *cs)
36 {
37         float c, s;
38         double y;
39         int32_t n, hx, ix;
40
41         GET_FLOAT_WORD(hx, x);
42         ix = hx & 0x7fffffff;
43
44         if (ix <= 0x3f490fda) {         /* |x| ~<= pi/4 */
45                 if (ix < 0x39800000) {  /* |x| < 2**-12 */
46                         if ((int)x == 0) {
47                                 *sn = x;        /* x with inexact if x != 0 */
48                                 *cs = 1;
49                                 return;
50                         }
51                 }
52                 __kernel_sincosdf(x, sn, cs);
53                 return;
54         }
55
56         if (ix <= 0x407b53d1) {         /* |x| ~<= 5*pi/4 */
57                 if (ix <= 0x4016cbe3) { /* |x| ~<= 3pi/4 */
58                         if (hx > 0) {
59                                 __kernel_sincosdf(x - p1pio2, cs, sn);
60                                 *cs = -*cs;
61                         } else {
62                                 __kernel_sincosdf(x + p1pio2, cs, sn);
63                                 *sn = -*sn;
64                         }
65                 } else {
66                         if (hx > 0)
67                                 __kernel_sincosdf(x - p2pio2, sn, cs);
68                         else
69                                 __kernel_sincosdf(x + p2pio2, sn, cs);
70                         *sn = -*sn;
71                         *cs = -*cs;
72                 }
73                 return;
74         }
75
76         if (ix <= 0x40e231d5) {         /* |x| ~<= 9*pi/4 */
77                 if (ix <= 0x40afeddf) { /* |x| ~<= 7*pi/4 */
78                         if (hx > 0) {
79                                 __kernel_sincosdf(x - p3pio2, cs, sn);
80                                 *sn = -*sn;
81                         } else {
82                                 __kernel_sincosdf(x + p3pio2, cs, sn);
83                                 *cs = -*cs;
84                         }
85                 } else {
86                         if (hx > 0)
87                                 __kernel_sincosdf(x - p4pio2, sn, cs);
88                         else
89                                 __kernel_sincosdf(x + p4pio2, sn, cs);
90                 }
91                 return;
92         }
93
94         /* If x = Inf or NaN, then sin(x) = NaN and cos(x) = NaN. */
95         if (ix >= 0x7f800000) {
96                 *sn = x - x;
97                 *cs = x - x;
98                 return;
99         }
100
101         /* Argument reduction. */
102         n = __ieee754_rem_pio2f(x, &y);
103         __kernel_sincosdf(y, &s, &c);
104
105         switch(n & 3) {
106         case 0:
107                 *sn = s;
108                 *cs = c;
109                 break;
110         case 1:
111                 *sn = c;
112                 *cs = -s;
113                 break;
114         case 2:
115                 *sn = -s;
116                 *cs = -c;
117                 break;
118         default:
119                 *sn = -c;
120                 *cs = s;
121         }
122 }
123
124