1*c9945492SAndroid Build Coastguard Worker /* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */
2*c9945492SAndroid Build Coastguard Worker /*
3*c9945492SAndroid Build Coastguard Worker * ====================================================
4*c9945492SAndroid Build Coastguard Worker * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5*c9945492SAndroid Build Coastguard Worker *
6*c9945492SAndroid Build Coastguard Worker * Developed at SunPro, a Sun Microsystems, Inc. business.
7*c9945492SAndroid Build Coastguard Worker * Permission to use, copy, modify, and distribute this
8*c9945492SAndroid Build Coastguard Worker * software is freely granted, provided that this notice
9*c9945492SAndroid Build Coastguard Worker * is preserved.
10*c9945492SAndroid Build Coastguard Worker * ====================================================
11*c9945492SAndroid Build Coastguard Worker */
12*c9945492SAndroid Build Coastguard Worker
13*c9945492SAndroid Build Coastguard Worker #define _GNU_SOURCE
14*c9945492SAndroid Build Coastguard Worker #include "libm.h"
15*c9945492SAndroid Build Coastguard Worker
sincos(double x,double * sin,double * cos)16*c9945492SAndroid Build Coastguard Worker void sincos(double x, double *sin, double *cos)
17*c9945492SAndroid Build Coastguard Worker {
18*c9945492SAndroid Build Coastguard Worker double y[2], s, c;
19*c9945492SAndroid Build Coastguard Worker uint32_t ix;
20*c9945492SAndroid Build Coastguard Worker unsigned n;
21*c9945492SAndroid Build Coastguard Worker
22*c9945492SAndroid Build Coastguard Worker GET_HIGH_WORD(ix, x);
23*c9945492SAndroid Build Coastguard Worker ix &= 0x7fffffff;
24*c9945492SAndroid Build Coastguard Worker
25*c9945492SAndroid Build Coastguard Worker /* |x| ~< pi/4 */
26*c9945492SAndroid Build Coastguard Worker if (ix <= 0x3fe921fb) {
27*c9945492SAndroid Build Coastguard Worker /* if |x| < 2**-27 * sqrt(2) */
28*c9945492SAndroid Build Coastguard Worker if (ix < 0x3e46a09e) {
29*c9945492SAndroid Build Coastguard Worker /* raise inexact if x!=0 and underflow if subnormal */
30*c9945492SAndroid Build Coastguard Worker FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
31*c9945492SAndroid Build Coastguard Worker *sin = x;
32*c9945492SAndroid Build Coastguard Worker *cos = 1.0;
33*c9945492SAndroid Build Coastguard Worker return;
34*c9945492SAndroid Build Coastguard Worker }
35*c9945492SAndroid Build Coastguard Worker *sin = __sin(x, 0.0, 0);
36*c9945492SAndroid Build Coastguard Worker *cos = __cos(x, 0.0);
37*c9945492SAndroid Build Coastguard Worker return;
38*c9945492SAndroid Build Coastguard Worker }
39*c9945492SAndroid Build Coastguard Worker
40*c9945492SAndroid Build Coastguard Worker /* sincos(Inf or NaN) is NaN */
41*c9945492SAndroid Build Coastguard Worker if (ix >= 0x7ff00000) {
42*c9945492SAndroid Build Coastguard Worker *sin = *cos = x - x;
43*c9945492SAndroid Build Coastguard Worker return;
44*c9945492SAndroid Build Coastguard Worker }
45*c9945492SAndroid Build Coastguard Worker
46*c9945492SAndroid Build Coastguard Worker /* argument reduction needed */
47*c9945492SAndroid Build Coastguard Worker n = __rem_pio2(x, y);
48*c9945492SAndroid Build Coastguard Worker s = __sin(y[0], y[1], 1);
49*c9945492SAndroid Build Coastguard Worker c = __cos(y[0], y[1]);
50*c9945492SAndroid Build Coastguard Worker switch (n&3) {
51*c9945492SAndroid Build Coastguard Worker case 0:
52*c9945492SAndroid Build Coastguard Worker *sin = s;
53*c9945492SAndroid Build Coastguard Worker *cos = c;
54*c9945492SAndroid Build Coastguard Worker break;
55*c9945492SAndroid Build Coastguard Worker case 1:
56*c9945492SAndroid Build Coastguard Worker *sin = c;
57*c9945492SAndroid Build Coastguard Worker *cos = -s;
58*c9945492SAndroid Build Coastguard Worker break;
59*c9945492SAndroid Build Coastguard Worker case 2:
60*c9945492SAndroid Build Coastguard Worker *sin = -s;
61*c9945492SAndroid Build Coastguard Worker *cos = -c;
62*c9945492SAndroid Build Coastguard Worker break;
63*c9945492SAndroid Build Coastguard Worker case 3:
64*c9945492SAndroid Build Coastguard Worker default:
65*c9945492SAndroid Build Coastguard Worker *sin = -c;
66*c9945492SAndroid Build Coastguard Worker *cos = s;
67*c9945492SAndroid Build Coastguard Worker break;
68*c9945492SAndroid Build Coastguard Worker }
69*c9945492SAndroid Build Coastguard Worker }
70