xref: /minix3/lib/libm/src/s_tan.c (revision 2fe8fb192fe7e8720e3e7a77f928da545e872a6a)
1*2fe8fb19SBen Gras /* @(#)s_tan.c 5.1 93/09/24 */
2*2fe8fb19SBen Gras /*
3*2fe8fb19SBen Gras  * ====================================================
4*2fe8fb19SBen Gras  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5*2fe8fb19SBen Gras  *
6*2fe8fb19SBen Gras  * Developed at SunPro, a Sun Microsystems, Inc. business.
7*2fe8fb19SBen Gras  * Permission to use, copy, modify, and distribute this
8*2fe8fb19SBen Gras  * software is freely granted, provided that this notice
9*2fe8fb19SBen Gras  * is preserved.
10*2fe8fb19SBen Gras  * ====================================================
11*2fe8fb19SBen Gras  */
12*2fe8fb19SBen Gras 
13*2fe8fb19SBen Gras #include <sys/cdefs.h>
14*2fe8fb19SBen Gras #if defined(LIBM_SCCS) && !defined(lint)
15*2fe8fb19SBen Gras __RCSID("$NetBSD: s_tan.c,v 1.10 2002/05/26 22:01:58 wiz Exp $");
16*2fe8fb19SBen Gras #endif
17*2fe8fb19SBen Gras 
18*2fe8fb19SBen Gras /* tan(x)
19*2fe8fb19SBen Gras  * Return tangent function of x.
20*2fe8fb19SBen Gras  *
21*2fe8fb19SBen Gras  * kernel function:
22*2fe8fb19SBen Gras  *	__kernel_tan		... tangent function on [-pi/4,pi/4]
23*2fe8fb19SBen Gras  *	__ieee754_rem_pio2	... argument reduction routine
24*2fe8fb19SBen Gras  *
25*2fe8fb19SBen Gras  * Method.
26*2fe8fb19SBen Gras  *      Let S,C and T denote the sin, cos and tan respectively on
27*2fe8fb19SBen Gras  *	[-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
28*2fe8fb19SBen Gras  *	in [-pi/4 , +pi/4], and let n = k mod 4.
29*2fe8fb19SBen Gras  *	We have
30*2fe8fb19SBen Gras  *
31*2fe8fb19SBen Gras  *          n        sin(x)      cos(x)        tan(x)
32*2fe8fb19SBen Gras  *     ----------------------------------------------------------
33*2fe8fb19SBen Gras  *	    0	       S	   C		 T
34*2fe8fb19SBen Gras  *	    1	       C	  -S		-1/T
35*2fe8fb19SBen Gras  *	    2	      -S	  -C		 T
36*2fe8fb19SBen Gras  *	    3	      -C	   S		-1/T
37*2fe8fb19SBen Gras  *     ----------------------------------------------------------
38*2fe8fb19SBen Gras  *
39*2fe8fb19SBen Gras  * Special cases:
40*2fe8fb19SBen Gras  *      Let trig be any of sin, cos, or tan.
41*2fe8fb19SBen Gras  *      trig(+-INF)  is NaN, with signals;
42*2fe8fb19SBen Gras  *      trig(NaN)    is that NaN;
43*2fe8fb19SBen Gras  *
44*2fe8fb19SBen Gras  * Accuracy:
45*2fe8fb19SBen Gras  *	TRIG(x) returns trig(x) nearly rounded
46*2fe8fb19SBen Gras  */
47*2fe8fb19SBen Gras 
48*2fe8fb19SBen Gras #include "math.h"
49*2fe8fb19SBen Gras #include "math_private.h"
50*2fe8fb19SBen Gras 
51*2fe8fb19SBen Gras double
tan(double x)52*2fe8fb19SBen Gras tan(double x)
53*2fe8fb19SBen Gras {
54*2fe8fb19SBen Gras 	double y[2],z=0.0;
55*2fe8fb19SBen Gras 	int32_t n, ix;
56*2fe8fb19SBen Gras 
57*2fe8fb19SBen Gras     /* High word of x. */
58*2fe8fb19SBen Gras 	GET_HIGH_WORD(ix,x);
59*2fe8fb19SBen Gras 
60*2fe8fb19SBen Gras     /* |x| ~< pi/4 */
61*2fe8fb19SBen Gras 	ix &= 0x7fffffff;
62*2fe8fb19SBen Gras 	if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1);
63*2fe8fb19SBen Gras 
64*2fe8fb19SBen Gras     /* tan(Inf or NaN) is NaN */
65*2fe8fb19SBen Gras 	else if (ix>=0x7ff00000) return x-x;		/* NaN */
66*2fe8fb19SBen Gras 
67*2fe8fb19SBen Gras     /* argument reduction needed */
68*2fe8fb19SBen Gras 	else {
69*2fe8fb19SBen Gras 	    n = __ieee754_rem_pio2(x,y);
70*2fe8fb19SBen Gras 	    return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /*   1 -- n even
71*2fe8fb19SBen Gras 							-1 -- n odd */
72*2fe8fb19SBen Gras 	}
73*2fe8fb19SBen Gras }
74