s_sin.c revision 22993
172172Sphantom/* @(#)s_sin.c 5.1 93/09/24 */
272172Sphantom/*
388473Sphantom * ====================================================
4118459Smtm * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5123682Sache *
686073Sache * Developed at SunPro, a Sun Microsystems, Inc. business.
7108428Sache * Permission to use, copy, modify, and distribute this
877984Sache * software is freely granted, provided that this notice
977984Sache * is preserved.
1077984Sache * ====================================================
1177984Sache */
1277984Sache
1377984Sache#ifndef lint
1477984Sachestatic char rcsid[] = "$Id$";
15134437Stjr#endif
1677984Sache
1790583Sphantom/* sin(x)
1877984Sache * Return sine function of x.
1987043Sache *
2077984Sache * kernel function:
2177984Sache *	__kernel_sin		... sine function on [-pi/4,pi/4]
22117259Sache *	__kernel_cos		... cose function on [-pi/4,pi/4]
2377984Sache *	__ieee754_rem_pio2	... argument reduction routine
2477984Sache *
2588473Sphantom * Method.
26125208Sache *      Let S,C and T denote the sin, cos and tan respectively on
2788473Sphantom *	[-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
28105965Sache *	in [-pi/4 , +pi/4], and let n = k mod 4.
2977984Sache *	We have
3077984Sache *
3177984Sache *          n        sin(x)      cos(x)        tan(x)
3293885Sphantom *     ----------------------------------------------------------
3377984Sache *	    0	       S	   C		 T
3489077Sache *	    1	       C	  -S		-1/T
3572208Sasmodai *	    2	      -S	  -C		 T
3677984Sache *	    3	      -C	   S		-1/T
3777984Sache *     ----------------------------------------------------------
38105445Sache *
39105445Sache * Special cases:
4077984Sache *      Let trig be any of sin, cos, or tan.
4177984Sache *      trig(+-INF)  is NaN, with signals;
4272565Sache *      trig(NaN)    is that NaN;
43118174Sache *
4472172Sphantom * Accuracy:
45136659Sru *	TRIG(x) returns trig(x) nearly rounded
4676105Sphantom */
4772172Sphantom
4872172Sphantom#include "math.h"
4972172Sphantom#include "math_private.h"
5072172Sphantom
5172172Sphantom#ifdef __STDC__
52136659Sru	double __generic_sin(double x)
53136659Sru#else
5472172Sphantom	double __generic_sin(x)
55136659Sru	double x;
56136659Sru#endif
5772258Swollman{
58136659Sru	double y[2],z=0.0;
59136659Sru	int32_t n, ix;
60136659Sru
61136659Sru    /* High word of x. */
62136659Sru	GET_HIGH_WORD(ix,x);
63136659Sru
64136659Sru    /* |x| ~< pi/4 */
65136659Sru	ix &= 0x7fffffff;
66136659Sru	if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
67136659Sru
68136659Sru    /* sin(Inf or NaN) is NaN */
69136659Sru	else if (ix>=0x7ff00000) return x-x;
70136659Sru
71136659Sru    /* argument reduction needed */
72136659Sru	else {
73136659Sru	    n = __ieee754_rem_pio2(x,y);
74136659Sru	    switch(n&3) {
75136659Sru		case 0: return  __kernel_sin(y[0],y[1],1);
76136659Sru		case 1: return  __kernel_cos(y[0],y[1]);
77136659Sru		case 2: return -__kernel_sin(y[0],y[1],1);
78136659Sru		default:
79136659Sru			return -__kernel_cos(y[0],y[1]);
80136659Sru	    }
81136659Sru	}
82136659Sru}
83136659Sru