130 lines
2.6 KiB
C
130 lines
2.6 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
|
|
|
|
SYNOPSIS
|
|
#include <math.h>
|
|
double tan(double <[x]>);
|
|
float tanf(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
|
|
tan (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 */
|