140 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
| 
 | |
| /* @(#)z_tan.c 1.0 98/08/13 */
 | |
| /******************************************************************
 | |
|  * The following routines are coded directly from the algorithms
 | |
|  * and coefficients given in "Software Manual for the Elementary
 | |
|  * Functions" by William J. Cody, Jr. and William Waite, Prentice
 | |
|  * Hall, 1980.
 | |
|  ******************************************************************/
 | |
| 
 | |
| /*
 | |
| FUNCTION
 | |
|         <<tan>>, <<tanf>>---tangent
 | |
| 
 | |
| INDEX
 | |
| tan
 | |
| INDEX
 | |
| tanf
 | |
| 
 | |
| ANSI_SYNOPSIS
 | |
|         #include <math.h>
 | |
|         double tan(double <[x]>);
 | |
|         float tanf(float <[x]>);
 | |
| 
 | |
| TRAD_SYNOPSIS
 | |
|         #include <math.h>
 | |
|         double tan(<[x]>)
 | |
|         double <[x]>;
 | |
| 
 | |
|         float tanf(<[x]>)
 | |
|         float <[x]>;
 | |
| 
 | |
| 
 | |
| DESCRIPTION
 | |
| <<tan>> computes the tangent of the argument <[x]>.
 | |
| Angles are specified in radians.
 | |
| 
 | |
| <<tanf>> is identical, save that it takes and returns <<float>> values.
 | |
| 
 | |
| RETURNS
 | |
| The tangent of <[x]> is returned.
 | |
| 
 | |
| PORTABILITY
 | |
| <<tan>> is ANSI. <<tanf>> is an extension.
 | |
| */
 | |
| 
 | |
| /******************************************************************
 | |
|  * Tangent
 | |
|  *
 | |
|  * Input:
 | |
|  *   x - floating point value
 | |
|  *
 | |
|  * Output:
 | |
|  *   tangent of x
 | |
|  *
 | |
|  * Description:
 | |
|  *   This routine calculates the tangent of x.
 | |
|  *
 | |
|  *****************************************************************/
 | |
| 
 | |
| #include "fdlibm.h"
 | |
| #include "zmath.h"
 | |
| 
 | |
| #ifndef _DOUBLE_IS_32BITS
 | |
| 
 | |
| static const double TWO_OVER_PI = 0.63661977236758134308;
 | |
| static const double p[] = { -0.13338350006421960681,
 | |
|                              0.34248878235890589960e-2,
 | |
|                             -0.17861707342254426711e-4 };
 | |
| static const double q[] = { -0.46671683339755294240,
 | |
|                              0.25663832289440112864e-1,
 | |
|                             -0.31181531907010027307e-3,
 | |
|                              0.49819433993786512270e-6 };
 | |
| 
 | |
| double
 | |
| _DEFUN (tan, (double),
 | |
|         double x)
 | |
| {
 | |
|   double y, f, g, XN, xnum, xden, res;
 | |
|   int N;
 | |
| 
 | |
|   /* Check for special values. */
 | |
|   switch (numtest (x))
 | |
|     {
 | |
|       case NAN:
 | |
|         errno = EDOM;
 | |
|         return (x);
 | |
|       case INF:
 | |
|         errno = EDOM;
 | |
|         return (z_notanum.d);
 | |
|     }
 | |
| 
 | |
|   y = fabs (x);
 | |
| 
 | |
|   /* Check for values that are out of our range. */
 | |
|   if (y > 105414357.0)
 | |
|     {
 | |
|       errno = ERANGE;
 | |
|       return (y);
 | |
|     }
 | |
| 
 | |
|   if (x < 0.0)
 | |
|     N = (int) (x * TWO_OVER_PI - 0.5);
 | |
|   else
 | |
|     N = (int) (x * TWO_OVER_PI + 0.5);
 | |
| 
 | |
|   XN = (double) N;
 | |
| 
 | |
|   f = x - N * __PI_OVER_TWO;
 | |
| 
 | |
|   /* Check for values that are too small. */
 | |
|   if (-z_rooteps < f && f < z_rooteps)
 | |
|     {
 | |
|       xnum = f;
 | |
|       xden = 1.0;
 | |
|     }
 | |
| 
 | |
|   /* Calculate the polynomial. */ 
 | |
|   else
 | |
|     { 
 | |
|       g = f * f;
 | |
| 
 | |
|       xnum = f * ((p[2] * g + p[1]) * g + p[0]) * g + f;
 | |
|       xden = (((q[3] * g + q[2]) * g + q[1]) * g + q[0]) * g + 1.0;
 | |
|     }
 | |
| 
 | |
|   if (N & 1)
 | |
|     {
 | |
|       xnum = -xnum;
 | |
|       res = xden / xnum;
 | |
|     } 
 | |
|   else
 | |
|     {
 | |
|       res = xnum / xden;
 | |
|     }
 | |
| 
 | |
|   return (res);
 | |
| }
 | |
| 
 | |
| #endif /* _DOUBLE_IS_32BITS */
 |