s_sin.c revision 22993
167754Smsmith/* @(#)s_sin.c 5.1 93/09/24 */
267754Smsmith/*
367754Smsmith * ====================================================
467754Smsmith * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
571867Smsmith *
667754Smsmith * Developed at SunPro, a Sun Microsystems, Inc. business.
767754Smsmith * Permission to use, copy, modify, and distribute this
867754Smsmith * software is freely granted, provided that this notice
967754Smsmith * is preserved.
1067754Smsmith * ====================================================
1167754Smsmith */
1267754Smsmith
1371867Smsmith#ifndef lint
1470243Smsmithstatic char rcsid[] = "$Id$";
1567754Smsmith#endif
1667754Smsmith
1767754Smsmith/* sin(x)
1867754Smsmith * Return sine function of x.
1967754Smsmith *
2067754Smsmith * kernel function:
2167754Smsmith *	__kernel_sin		... sine function on [-pi/4,pi/4]
2267754Smsmith *	__kernel_cos		... cose function on [-pi/4,pi/4]
2367754Smsmith *	__ieee754_rem_pio2	... argument reduction routine
2467754Smsmith *
2567754Smsmith * Method.
2667754Smsmith *      Let S,C and T denote the sin, cos and tan respectively on
2767754Smsmith *	[-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
2867754Smsmith *	in [-pi/4 , +pi/4], and let n = k mod 4.
2967754Smsmith *	We have
3067754Smsmith *
3167754Smsmith *          n        sin(x)      cos(x)        tan(x)
3267754Smsmith *     ----------------------------------------------------------
3367754Smsmith *	    0	       S	   C		 T
3467754Smsmith *	    1	       C	  -S		-1/T
3567754Smsmith *	    2	      -S	  -C		 T
3667754Smsmith *	    3	      -C	   S		-1/T
3767754Smsmith *     ----------------------------------------------------------
3867754Smsmith *
3967754Smsmith * Special cases:
4067754Smsmith *      Let trig be any of sin, cos, or tan.
4167754Smsmith *      trig(+-INF)  is NaN, with signals;
4267754Smsmith *      trig(NaN)    is that NaN;
4367754Smsmith *
4467754Smsmith * Accuracy:
4567754Smsmith *	TRIG(x) returns trig(x) nearly rounded
4667754Smsmith */
4767754Smsmith
4867754Smsmith#include "math.h"
4967754Smsmith#include "math_private.h"
5067754Smsmith
5167754Smsmith#ifdef __STDC__
5267754Smsmith	double __generic_sin(double x)
5367754Smsmith#else
5467754Smsmith	double __generic_sin(x)
5567754Smsmith	double x;
5667754Smsmith#endif
5767754Smsmith{
5867754Smsmith	double y[2],z=0.0;
5967754Smsmith	int32_t n, ix;
6067754Smsmith
6167754Smsmith    /* High word of x. */
6267754Smsmith	GET_HIGH_WORD(ix,x);
6367754Smsmith
6467754Smsmith    /* |x| ~< pi/4 */
6567754Smsmith	ix &= 0x7fffffff;
6667754Smsmith	if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
6767754Smsmith
6867754Smsmith    /* sin(Inf or NaN) is NaN */
6967754Smsmith	else if (ix>=0x7ff00000) return x-x;
7067754Smsmith
7167754Smsmith    /* argument reduction needed */
7267754Smsmith	else {
7367754Smsmith	    n = __ieee754_rem_pio2(x,y);
7467754Smsmith	    switch(n&3) {
7567754Smsmith		case 0: return  __kernel_sin(y[0],y[1],1);
7667754Smsmith		case 1: return  __kernel_cos(y[0],y[1]);
7767754Smsmith		case 2: return -__kernel_sin(y[0],y[1],1);
7867754Smsmith		default:
7967754Smsmith			return -__kernel_cos(y[0],y[1]);
8067754Smsmith	    }
8167754Smsmith	}
8267754Smsmith}
8367754Smsmith