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