xref: /original-bsd/lib/libm/common/tan.c (revision c3e32dec)
1 /*
2  * Copyright (c) 1987, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)tan.c	8.1 (Berkeley) 06/04/93";
10 #endif /* not lint */
11 
12 #include "trig.h"
13 double
14 tan(x)
15 double x;
16 {
17 	double a,z,ss,cc,c;
18 	int k;
19 
20 	if(!finite(x))		/* tan(NaN) and tan(INF) must be NaN */
21 		return x-x;
22 	x = drem(x,PI);			/* reduce x into [-PI/2, PI/2] */
23 	a = copysign(x,one);		/* ... = abs(x) */
24 	if (a >= PIo4) {
25 		k = 1;
26 		x = copysign(PIo2-a,x);
27 	}
28 	else {
29 		k = 0;
30 		if (a < small) {
31 			big+a;
32 			return x;
33 		}
34 	}
35 	z = x*x;
36 	cc = cos__C(z);
37 	ss = sin__S(z);
38 	z *= half;			/* Next get c = cos(x) accurately */
39 	c = (z >= thresh ? half-((z-half)-cc) : one-(z-cc));
40 	if (k == 0)
41 		return x+(x*(z-(cc-ss)))/c;	/* ... sin/cos */
42 #ifdef national
43 	else if (x == zero)
44 		return copysign(fmax,x);	/* no inf on 32k */
45 #endif	/* national */
46 	else
47 		return c/(x+x*ss);		/* ... cos/sin */
48 }
49