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