123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- /* 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 <math.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 );
- }
|