/* 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 #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 ); }