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  * s_sin.c and s_cos.c merged by Steven G. Kargl.  Descriptions of the
12  * algorithms are contained in the original files.
13  */
14 
15 #include <float.h>
16 #include "math.h"
17 
18 #include "math_private.h"
19 #include "k_sincos.h"
20 
21 void
22 sincos(double x, double *sn, double *cs)
23 {
24 	double y[2];
25 	int32_t n, ix;
26 
27 	/* High word of x. */
28 	GET_HIGH_WORD(ix, x);
29 
30 	/* |x| ~< pi/4 */
31 	ix &= 0x7fffffff;
32 	if (ix <= 0x3fe921fb) {
33 		if (ix < 0x3e400000) {		/* |x| < 2**-27 */
34 			if ((int)x == 0) {	/* Generate inexact. */
35 				*sn = x;
36 				*cs = 1;
37 				return;
38 			}
39 		}
40 		__kernel_sincos(x, 0, 0, sn, cs);
41 		return;
42 	}
43 
44 	/* If x = Inf or NaN, then sin(x) = NaN and cos(x) = NaN. */
45 	if (ix >= 0x7ff00000) {
46 		*sn = x - x;
47 		*cs = x - x;
48 		return;
49 	}
50 
51 	/* Argument reduction. */
52 	n = __ieee754_rem_pio2(x, y);
53 
54 	switch(n & 3) {
55 	case 0:
56 		__kernel_sincos(y[0], y[1], 1, sn, cs);
57 		break;
58 	case 1:
59 		__kernel_sincos(y[0], y[1], 1, cs, sn);
60 		*cs = -*cs;
61 		break;
62 	case 2:
63 		__kernel_sincos(y[0], y[1], 1, sn, cs);
64 		*sn = -*sn;
65 		*cs = -*cs;
66 		break;
67 	default:
68 		__kernel_sincos(y[0], y[1], 1, cs, sn);
69 		*sn = -*sn;
70 	}
71 }
72