1570af302Sopenharmony_ci/* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */
2570af302Sopenharmony_ci/*
3570af302Sopenharmony_ci * ====================================================
4570af302Sopenharmony_ci * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5570af302Sopenharmony_ci *
6570af302Sopenharmony_ci * Developed at SunPro, a Sun Microsystems, Inc. business.
7570af302Sopenharmony_ci * Permission to use, copy, modify, and distribute this
8570af302Sopenharmony_ci * software is freely granted, provided that this notice
9570af302Sopenharmony_ci * is preserved.
10570af302Sopenharmony_ci * ====================================================
11570af302Sopenharmony_ci */
12570af302Sopenharmony_ci/* sin(x)
13570af302Sopenharmony_ci * Return sine function of x.
14570af302Sopenharmony_ci *
15570af302Sopenharmony_ci * kernel function:
16570af302Sopenharmony_ci *      __sin            ... sine function on [-pi/4,pi/4]
17570af302Sopenharmony_ci *      __cos            ... cose function on [-pi/4,pi/4]
18570af302Sopenharmony_ci *      __rem_pio2       ... argument reduction routine
19570af302Sopenharmony_ci *
20570af302Sopenharmony_ci * Method.
21570af302Sopenharmony_ci *      Let S,C and T denote the sin, cos and tan respectively on
22570af302Sopenharmony_ci *      [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
23570af302Sopenharmony_ci *      in [-pi/4 , +pi/4], and let n = k mod 4.
24570af302Sopenharmony_ci *      We have
25570af302Sopenharmony_ci *
26570af302Sopenharmony_ci *          n        sin(x)      cos(x)        tan(x)
27570af302Sopenharmony_ci *     ----------------------------------------------------------
28570af302Sopenharmony_ci *          0          S           C             T
29570af302Sopenharmony_ci *          1          C          -S            -1/T
30570af302Sopenharmony_ci *          2         -S          -C             T
31570af302Sopenharmony_ci *          3         -C           S            -1/T
32570af302Sopenharmony_ci *     ----------------------------------------------------------
33570af302Sopenharmony_ci *
34570af302Sopenharmony_ci * Special cases:
35570af302Sopenharmony_ci *      Let trig be any of sin, cos, or tan.
36570af302Sopenharmony_ci *      trig(+-INF)  is NaN, with signals;
37570af302Sopenharmony_ci *      trig(NaN)    is that NaN;
38570af302Sopenharmony_ci *
39570af302Sopenharmony_ci * Accuracy:
40570af302Sopenharmony_ci *      TRIG(x) returns trig(x) nearly rounded
41570af302Sopenharmony_ci */
42570af302Sopenharmony_ci
43570af302Sopenharmony_ci#include "libm.h"
44570af302Sopenharmony_ci
45570af302Sopenharmony_cidouble sin(double x)
46570af302Sopenharmony_ci{
47570af302Sopenharmony_ci	double y[2];
48570af302Sopenharmony_ci	uint32_t ix;
49570af302Sopenharmony_ci	unsigned n;
50570af302Sopenharmony_ci
51570af302Sopenharmony_ci	/* High word of x. */
52570af302Sopenharmony_ci	GET_HIGH_WORD(ix, x);
53570af302Sopenharmony_ci	ix &= 0x7fffffff;
54570af302Sopenharmony_ci
55570af302Sopenharmony_ci	/* |x| ~< pi/4 */
56570af302Sopenharmony_ci	if (ix <= 0x3fe921fb) {
57570af302Sopenharmony_ci		if (ix < 0x3e500000) {  /* |x| < 2**-26 */
58570af302Sopenharmony_ci			/* raise inexact if x != 0 and underflow if subnormal*/
59570af302Sopenharmony_ci			FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
60570af302Sopenharmony_ci			return x;
61570af302Sopenharmony_ci		}
62570af302Sopenharmony_ci		return __sin(x, 0.0, 0);
63570af302Sopenharmony_ci	}
64570af302Sopenharmony_ci
65570af302Sopenharmony_ci	/* sin(Inf or NaN) is NaN */
66570af302Sopenharmony_ci	if (ix >= 0x7ff00000)
67570af302Sopenharmony_ci		return x - x;
68570af302Sopenharmony_ci
69570af302Sopenharmony_ci	/* argument reduction needed */
70570af302Sopenharmony_ci	n = __rem_pio2(x, y);
71570af302Sopenharmony_ci	switch (n&3) {
72570af302Sopenharmony_ci	case 0: return  __sin(y[0], y[1], 1);
73570af302Sopenharmony_ci	case 1: return  __cos(y[0], y[1]);
74570af302Sopenharmony_ci	case 2: return -__sin(y[0], y[1], 1);
75570af302Sopenharmony_ci	default:
76570af302Sopenharmony_ci		return -__cos(y[0], y[1]);
77570af302Sopenharmony_ci	}
78570af302Sopenharmony_ci}
79