s_tan.c revision 117912
1169691Skan/* @(#)s_tan.c 5.1 93/09/24 */ 2169691Skan/* 3169691Skan * ==================================================== 4169691Skan * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 5169691Skan * 6169691Skan * Developed at SunPro, a Sun Microsystems, Inc. business. 7169691Skan * Permission to use, copy, modify, and distribute this 8169691Skan * software is freely granted, provided that this notice 9169691Skan * is preserved. 10169691Skan * ==================================================== 11169691Skan */ 12169691Skan 13169691Skan#ifndef lint 14169691Skanstatic char rcsid[] = "$FreeBSD: head/lib/msun/src/s_tan.c 117912 2003-07-23 04:53:47Z peter $"; 15169691Skan#endif 16169691Skan 17169691Skan/* tan(x) 18169691Skan * Return tangent function of x. 19169691Skan * 20169691Skan * kernel function: 21169691Skan * __kernel_tan ... tangent function on [-pi/4,pi/4] 22169691Skan * __ieee754_rem_pio2 ... argument reduction routine 23169691Skan * 24169691Skan * Method. 25169691Skan * Let S,C and T denote the sin, cos and tan respectively on 26169691Skan * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 27169691Skan * in [-pi/4 , +pi/4], and let n = k mod 4. 28169691Skan * We have 29169691Skan * 30169691Skan * n sin(x) cos(x) tan(x) 31169691Skan * ---------------------------------------------------------- 32169691Skan * 0 S C T 33169691Skan * 1 C -S -1/T 34169691Skan * 2 -S -C T 35169691Skan * 3 -C S -1/T 36169691Skan * ---------------------------------------------------------- 37169691Skan * 38169691Skan * Special cases: 39169691Skan * Let trig be any of sin, cos, or tan. 40169691Skan * trig(+-INF) is NaN, with signals; 41169691Skan * trig(NaN) is that NaN; 42169691Skan * 43169691Skan * Accuracy: 44169691Skan * TRIG(x) returns trig(x) nearly rounded 45169691Skan */ 46169691Skan 47169691Skan#include "math.h" 48169691Skan#include "math_private.h" 49169691Skan 50169691Skandouble 51169691Skantan(double x) 52169691Skan{ 53169691Skan double y[2],z=0.0; 54169691Skan int32_t n, ix; 55169691Skan 56169691Skan /* High word of x. */ 57169691Skan GET_HIGH_WORD(ix,x); 58169691Skan 59169691Skan /* |x| ~< pi/4 */ 60169691Skan ix &= 0x7fffffff; 61169691Skan if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1); 62169691Skan 63169691Skan /* tan(Inf or NaN) is NaN */ 64169691Skan else if (ix>=0x7ff00000) return x-x; /* NaN */ 65169691Skan 66169691Skan /* argument reduction needed */ 67169691Skan else { 68169691Skan n = __ieee754_rem_pio2(x,y); 69169691Skan return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even 70169691Skan -1 -- n odd */ 71169691Skan } 72169691Skan} 73169691Skan