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