167754Smsmith/* @(#)s_sin.c 5.1 93/09/24 */
267754Smsmith/*
367754Smsmith * ====================================================
467754Smsmith * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
567754Smsmith *
667754Smsmith * Developed at SunPro, a Sun Microsystems, Inc. business.
767754Smsmith * Permission to use, copy, modify, and distribute this
8217365Sjkim * software is freely granted, provided that this notice
9217365Sjkim * is preserved.
1070243Smsmith * ====================================================
1167754Smsmith */
12217365Sjkim
13217365Sjkim#include <sys/cdefs.h>
14217365Sjkim__FBSDID("$FreeBSD: releng/10.3/lib/msun/src/s_sin.c 218509 2011-02-10 07:37:50Z das $");
15217365Sjkim
16217365Sjkim/* sin(x)
17217365Sjkim * Return sine function of x.
18217365Sjkim *
19217365Sjkim * kernel function:
20217365Sjkim *	__kernel_sin		... sine function on [-pi/4,pi/4]
21217365Sjkim *	__kernel_cos		... cose function on [-pi/4,pi/4]
22217365Sjkim *	__ieee754_rem_pio2	... argument reduction routine
23217365Sjkim *
24217365Sjkim * Method.
25217365Sjkim *      Let S,C and T denote the sin, cos and tan respectively on
2667754Smsmith *	[-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
27217365Sjkim *	in [-pi/4 , +pi/4], and let n = k mod 4.
28217365Sjkim *	We have
29217365Sjkim *
3067754Smsmith *          n        sin(x)      cos(x)        tan(x)
31217365Sjkim *     ----------------------------------------------------------
32217365Sjkim *	    0	       S	   C		 T
33217365Sjkim *	    1	       C	  -S		-1/T
34217365Sjkim *	    2	      -S	  -C		 T
35217365Sjkim *	    3	      -C	   S		-1/T
36217365Sjkim *     ----------------------------------------------------------
37217365Sjkim *
38217365Sjkim * Special cases:
39217365Sjkim *      Let trig be any of sin, cos, or tan.
40217365Sjkim *      trig(+-INF)  is NaN, with signals;
41217365Sjkim *      trig(NaN)    is that NaN;
42217365Sjkim *
43217365Sjkim * Accuracy:
4467754Smsmith *	TRIG(x) returns trig(x) nearly rounded
4567754Smsmith */
4667754Smsmith
4767754Smsmith#include <float.h>
48193341Sjkim
49193341Sjkim#include "math.h"
50193341Sjkim#define INLINE_REM_PIO2
5167754Smsmith#include "math_private.h"
5267754Smsmith#include "e_rem_pio2.c"
5377424Smsmith
5491116Smsmithdouble
5567754Smsmithsin(double x)
5667754Smsmith{
5767754Smsmith	double y[2],z=0.0;
5867754Smsmith	int32_t n, ix;
5967754Smsmith
6067754Smsmith    /* High word of x. */
61151937Sjkim	GET_HIGH_WORD(ix,x);
6267754Smsmith
6367754Smsmith    /* |x| ~< pi/4 */
6467754Smsmith	ix &= 0x7fffffff;
6567754Smsmith	if(ix <= 0x3fe921fb) {
6667754Smsmith	    if(ix<0x3e500000)			/* |x| < 2**-26 */
6767754Smsmith	       {if((int)x==0) return x;}	/* generate inexact */
6867754Smsmith	    return __kernel_sin(x,z,0);
6967754Smsmith	}
7067754Smsmith
7167754Smsmith    /* sin(Inf or NaN) is NaN */
7267754Smsmith	else if (ix>=0x7ff00000) return x-x;
7367754Smsmith
7467754Smsmith    /* argument reduction needed */
7591116Smsmith	else {
7667754Smsmith	    n = __ieee754_rem_pio2(x,y);
7767754Smsmith	    switch(n&3) {
7867754Smsmith		case 0: return  __kernel_sin(y[0],y[1],1);
7967754Smsmith		case 1: return  __kernel_cos(y[0],y[1]);
8067754Smsmith		case 2: return -__kernel_sin(y[0],y[1],1);
8167754Smsmith		default:
8267754Smsmith			return -__kernel_cos(y[0],y[1]);
8367754Smsmith	    }
8467754Smsmith	}
8567754Smsmith}
8667754Smsmith
8767754Smsmith#if (LDBL_MANT_DIG == 53)
8867754Smsmith__weak_reference(sin, sinl);
8967754Smsmith#endif
9067754Smsmith