/* tanl.c
*
* Circular tangent, long double precision
*
*
*
* SYNOPSIS:
*
* long double x, y, tanl();
*
* y = tanl( x );
*
*
*
* DESCRIPTION:
*
* Returns the circular tangent of the radian argument x.
*
* Range reduction is modulo pi/4. A rational function
* x + x**3 P(x**2)/Q(x**2)
* is employed in the basic interval [0, pi/4].
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE +-1.07e9 30000 1.9e-19 4.8e-20
*
* ERROR MESSAGES:
*
* message condition value returned
* tan total loss x > 2^39 0.0
*
*/
/* cotl.c
*
* Circular cotangent, long double precision
*
*
*
* SYNOPSIS:
*
* long double x, y, cotl();
*
* y = cotl( x );
*
*
*
* DESCRIPTION:
*
* Returns the circular cotangent of the radian argument x.
*
* Range reduction is modulo pi/4. A rational function
* x + x**3 P(x**2)/Q(x**2)
* is employed in the basic interval [0, pi/4].
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE +-1.07e9 30000 1.9e-19 5.1e-20
*
*
* ERROR MESSAGES:
*
* message condition value returned
* cot total loss x > 2^39 0.0
* cot singularity x = 0 INFINITYL
*
*/
/*
Cephes Math Library Release 2.7: May, 1998
Copyright 1984, 1990, 1998 by Stephen L. Moshier
*/
#include "mconf.h"
#ifdef UNK
static long double P[] = {
-1.3093693918138377764608E4L,
1.1535166483858741613983E6L,
-1.7956525197648487798769E7L,
};
static long double Q[] = {
/* 1.0000000000000000000000E0L,*/
1.3681296347069295467845E4L,
-1.3208923444021096744731E6L,
2.5008380182335791583922E7L,
-5.3869575592945462988123E7L,
};
static long double DP1 = 7.853981554508209228515625E-1L;
static long double DP2 = 7.946627356147928367136046290398E-9L;
static long double DP3 = 3.061616997868382943065164830688E-17L;
#endif
#ifdef IBMPC
static short P[] = {
0xbc1c,0x79f9,0xc692,0xcc96,0xc00c, XPD
0xe5b1,0xe4ee,0x652f,0x8ccf,0x4013, XPD
0xaf9a,0x4c8b,0x5699,0x88ff,0xc017, XPD
};
static short Q[] = {
/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
0x8ed4,0x9b2b,0x2f75,0xd5c5,0x400c, XPD
0xadcd,0x55e4,0xe2c1,0xa13d,0xc013, XPD
0x7adf,0x56c7,0x7e17,0xbecc,0x4017, XPD
0x86f6,0xf2d1,0x01e5,0xcd7f,0xc018, XPD
};
static short P1[] = {0x0000,0x0000,0xda80,0xc90f,0x3ffe, XPD};
static short P2[] = {0x0000,0x0000,0xa300,0x8885,0x3fe4, XPD};
static short P3[] = {0x3707,0xa2e0,0x3198,0x8d31,0x3fc8, XPD};
#define DP1 *(long double *)P1
#define DP2 *(long double *)P2
#define DP3 *(long double *)P3
#endif
#ifdef MIEEE
static long P[] = {
0xc00c0000,0xcc96c692,0x79f9bc1c,
0x40130000,0x8ccf652f,0xe4eee5b1,
0xc0170000,0x88ff5699,0x4c8baf9a,
};
static long Q[] = {
/*0x3fff0000,0x80000000,0x00000000,*/
0x400c0000,0xd5c52f75,0x9b2b8ed4,
0xc0130000,0xa13de2c1,0x55e4adcd,
0x40170000,0xbecc7e17,0x56c77adf,
0xc0180000,0xcd7f01e5,0xf2d186f6,
};
static long P1[] = {0x3ffe0000,0xc90fda80,0x00000000};
static long P2[] = {0x3fe40000,0x8885a300,0x00000000};
static long P3[] = {0x3fc80000,0x8d313198,0xa2e03707};
#define DP1 *(long double *)P1
#define DP2 *(long double *)P2
#define DP3 *(long double *)P3
#endif
static long double lossth = 5.49755813888e11L; /* 2^39 */
extern long double PIO4L;
extern long double MAXNUML;
#ifdef ANSIPROT
extern long double polevll ( long double, void *, int );
extern long double p1evll ( long double, void *, int );
extern long double floorl ( long double );
extern long double ldexpl ( long double, int );
extern int isnanl ( long double );
extern int isfinitel ( long double );
static long double tancotl( long double, int );
#else
long double polevll(), p1evll(), floorl(), ldexpl(), isnanl(), isfinitel();
static long double tancotl();
#endif
#ifdef INFINITIES
extern long double INFINITYL;
#endif
#ifdef NANS
extern long double NANL;
#endif
long double tanl(x)
long double x;
{
#ifdef NANS
if( isnanl(x) )
return(x);
#endif
#ifdef MINUSZERO
if( x == 0.0L )
return(x);
#endif
#ifdef NANS
if( !isfinitel(x) )
{
mtherr( "tanl", DOMAIN );
return(NANL);
}
#endif
return( tancotl(x,0) );
}
long double cotl(x)
long double x;
{
if( x == 0.0L )
{
mtherr( "cotl", SING );
#ifdef INFINITIES
return( INFINITYL );
#else
return( MAXNUML );
#endif
}
return( tancotl(x,1) );
}
static long double tancotl( xx, cotflg )
long double xx;
int cotflg;
{
long double x, y, z, zz;
int j, sign;
/* make argument positive but save the sign */
if( xx < 0.0L )
{
x = -xx;
sign = -1;
}
else
{
x = xx;
sign = 1;
}
if( x > lossth )
{
if( cotflg )
mtherr( "cotl", TLOSS );
else
mtherr( "tanl", TLOSS );
return(0.0L);
}
/* compute x mod PIO4 */
y = floorl( x/PIO4L );
/* strip high bits of integer part */
z = ldexpl( y, -4 );
z = floorl(z); /* integer part of y/16 */
z = y - ldexpl( z, 4 ); /* y - 16 * (y/16) */
/* integer and fractional part modulo one octant */
j = z;
/* map zeros and singularities to origin */
if( j & 1 )
{
j += 1;
y += 1.0L;
}
z = ((x - y * DP1) - y * DP2) - y * DP3;
zz = z * z;
if( zz > 1.0e-20L )
y = z + z * (zz * polevll( zz, P, 2 )/p1evll(zz, Q, 4));
else
y = z;
if( j & 2 )
{
if( cotflg )
y = -y;
else
y = -1.0L/y;
}
else
{
if( cotflg )
y = 1.0L/y;
}
if( sign < 0 )
y = -y;
return( y );
}
syntax highlighted by Code2HTML, v. 0.9.1