s_tan.c revision 218509
1194084Sedwin/* @(#)s_tan.c 5.1 93/09/24 */ 2194084Sedwin/* 3194084Sedwin * ==================================================== 4194084Sedwin * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 5194084Sedwin * 6194084Sedwin * Developed at SunPro, a Sun Microsystems, Inc. business. 7194084Sedwin * Permission to use, copy, modify, and distribute this 8194084Sedwin * software is freely granted, provided that this notice 9194084Sedwin * is preserved. 10194084Sedwin * ==================================================== 11194084Sedwin */ 12194084Sedwin 13194084Sedwin#include <sys/cdefs.h> 14194084Sedwin__FBSDID("$FreeBSD: head/lib/msun/src/s_tan.c 218509 2011-02-10 07:37:50Z das $"); 15194084Sedwin 16194084Sedwin/* tan(x) 17194084Sedwin * Return tangent function of x. 18194084Sedwin * 19194084Sedwin * kernel function: 20194084Sedwin * __kernel_tan ... tangent function on [-pi/4,pi/4] 21194084Sedwin * __ieee754_rem_pio2 ... argument reduction routine 22194084Sedwin * 23194084Sedwin * Method. 24194084Sedwin * Let S,C and T denote the sin, cos and tan respectively on 25194084Sedwin * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 26194084Sedwin * in [-pi/4 , +pi/4], and let n = k mod 4. 27194084Sedwin * We have 28194084Sedwin * 29194084Sedwin * n sin(x) cos(x) tan(x) 30194084Sedwin * ---------------------------------------------------------- 31194084Sedwin * 0 S C T 32194084Sedwin * 1 C -S -1/T 33270114Sse * 2 -S -C T 34270114Sse * 3 -C S -1/T 35270114Sse * ---------------------------------------------------------- 36270114Sse * 37194084Sedwin * Special cases: 38194084Sedwin * Let trig be any of sin, cos, or tan. 39194084Sedwin * trig(+-INF) is NaN, with signals; 40194084Sedwin * trig(NaN) is that NaN; 41194084Sedwin * 42194084Sedwin * Accuracy: 43270114Sse * TRIG(x) returns trig(x) nearly rounded 44194084Sedwin */ 45194084Sedwin 46194084Sedwin#include <float.h> 47194084Sedwin 48194084Sedwin#include "math.h" 49270114Sse#define INLINE_REM_PIO2 50194084Sedwin#include "math_private.h" 51194084Sedwin#include "e_rem_pio2.c" 52194084Sedwin 53194084Sedwindouble 54194084Sedwintan(double x) 55194084Sedwin{ 56194084Sedwin double y[2],z=0.0; 57270114Sse int32_t n, ix; 58270114Sse 59194084Sedwin /* High word of x. */ 60194084Sedwin GET_HIGH_WORD(ix,x); 61194084Sedwin 62270114Sse /* |x| ~< pi/4 */ 63194084Sedwin ix &= 0x7fffffff; 64194084Sedwin if(ix <= 0x3fe921fb) { 65194084Sedwin if(ix<0x3e400000) /* x < 2**-27 */ 66194084Sedwin if((int)x==0) return x; /* generate inexact */ 67194084Sedwin return __kernel_tan(x,z,1); 68194084Sedwin } 69194084Sedwin 70270114Sse /* tan(Inf or NaN) is NaN */ 71270114Sse else if (ix>=0x7ff00000) return x-x; /* NaN */ 72270114Sse 73194084Sedwin /* argument reduction needed */ 74194084Sedwin else { 75194084Sedwin n = __ieee754_rem_pio2(x,y); 76194084Sedwin return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even 77194084Sedwin -1 -- n odd */ 78194084Sedwin } 79194084Sedwin} 80194084Sedwin 81194084Sedwin#if (LDBL_MANT_DIG == 53) 82194084Sedwin__weak_reference(tan, tanl); 83194084Sedwin#endif 84194084Sedwin