s_tan.c revision 2117
1178476Sjb/* @(#)s_tan.c 5.1 93/09/24 */
2178476Sjb/*
3178476Sjb * ====================================================
4178476Sjb * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5178476Sjb *
6178476Sjb * Developed at SunPro, a Sun Microsystems, Inc. business.
7178476Sjb * Permission to use, copy, modify, and distribute this
8178476Sjb * software is freely granted, provided that this notice
9178476Sjb * is preserved.
10178476Sjb * ====================================================
11178476Sjb */
12178476Sjb
13178476Sjb#ifndef lint
14178476Sjbstatic char rcsid[] = "$Id: s_tan.c,v 1.5 1994/08/18 23:10:19 jtc Exp $";
15178476Sjb#endif
16178476Sjb
17178476Sjb/* tan(x)
18178476Sjb * Return tangent function of x.
19178476Sjb *
20178476Sjb * kernel function:
21178476Sjb *	__kernel_tan		... tangent function on [-pi/4,pi/4]
22178476Sjb *	__ieee754_rem_pio2	... argument reduction routine
23178476Sjb *
24178476Sjb * Method.
25178476Sjb *      Let S,C and T denote the sin, cos and tan respectively on
26178476Sjb *	[-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
27178476Sjb *	in [-pi/4 , +pi/4], and let n = k mod 4.
28178476Sjb *	We have
29178476Sjb *
30178476Sjb *          n        sin(x)      cos(x)        tan(x)
31178476Sjb *     ----------------------------------------------------------
32178476Sjb *	    0	       S	   C		 T
33178476Sjb *	    1	       C	  -S		-1/T
34178476Sjb *	    2	      -S	  -C		 T
35178476Sjb *	    3	      -C	   S		-1/T
36178476Sjb *     ----------------------------------------------------------
37178476Sjb *
38178476Sjb * Special cases:
39178476Sjb *      Let trig be any of sin, cos, or tan.
40178476Sjb *      trig(+-INF)  is NaN, with signals;
41178476Sjb *      trig(NaN)    is that NaN;
42178476Sjb *
43178476Sjb * Accuracy:
44178476Sjb *	TRIG(x) returns trig(x) nearly rounded
45178476Sjb */
46178476Sjb
47178476Sjb#include "math.h"
48178476Sjb#include "math_private.h"
49178476Sjb
50178476Sjb#ifdef __STDC__
51178476Sjb	double tan(double x)
52178476Sjb#else
53178476Sjb	double tan(x)
54178476Sjb	double x;
55178476Sjb#endif
56178476Sjb{
57178476Sjb	double y[2],z=0.0;
58178476Sjb	int32_t n, ix;
59178476Sjb
60178476Sjb    /* High word of x. */
61178476Sjb	GET_HIGH_WORD(ix,x);
62178476Sjb
63178476Sjb    /* |x| ~< pi/4 */
64178476Sjb	ix &= 0x7fffffff;
65178476Sjb	if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1);
66178476Sjb
67178476Sjb    /* tan(Inf or NaN) is NaN */
68178476Sjb	else if (ix>=0x7ff00000) return x-x;		/* NaN */
69178476Sjb
70178476Sjb    /* argument reduction needed */
71178476Sjb	else {
72178476Sjb	    n = __ieee754_rem_pio2(x,y);
73178476Sjb	    return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /*   1 -- n even
74178476Sjb							-1 -- n odd */
75178476Sjb	}
76178476Sjb}
77178476Sjb