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