Category : C Source Code
Archive   : CEPHES22.ZIP
Filename : ATAN.C

 
Output of file : ATAN.C contained in archive : CEPHES22.ZIP
/* atan.c
*
* Inverse circular tangent
* (arctangent)
*
*
*
* SYNOPSIS:
*
* double x, y, atan();
*
* y = atan( x );
*
*
*
* DESCRIPTION:
*
* Returns radian angle between -pi/2 and +pi/2 whose tangent
* is x.
*
* Range reduction is from four intervals into the interval
* from zero to tan( pi/8 ). The approximant uses a rational
* function of degree 3/4 of the form x + x**3 P(x)/Q(x).
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* DEC 0, 10 9500 2.8e-17 8.6e-18
* DEC 0,MAXNUM 9500 4.2e-17 4.3e-18
* IEEE -10, 10 30000 3.1e-16 7.9e-17
*
*/
/* atan2()
*
* Quadrant correct inverse circular tangent
*
*
*
* SYNOPSIS:
*
* double x, y, z, atan2();
*
* z = atan2( y, x );
*
*
*
* DESCRIPTION:
*
* Returns radian angle whose tangent is y/x.
* Define compile time symbol ANSIC = 1 for ANSI standard,
* range -PI < z <= +PI, args (y,x); else ANSIC = 0 for range
* 0 to 2PI, args (x,y).
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE -10, 10 30000 3.6e-16 7.1e-17
* See atan.c.
*
*/

/* atan.c */


/*
Cephes Math Library Release 2.1: January, 1989
Copyright 1984, 1987, 1989 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/


#include "mconf.h"

#ifdef UNK
static double P[] = {
-8.40980878064499716001E-1,
-8.83860837023772394279E0,
-2.18476213081316705724E1,
-1.48307050340438946993E1
};
static double Q[] = {
/* 1.00000000000000000000E0,*/
1.54974124675307267552E1,
6.27906555762653017263E1,
9.22381329856214406485E1,
4.44921151021319438465E1,
};

/* tan( 3*pi/8 ) */
static double T3P8 = 2.41421356237309504880;

/* tan( pi/8 ) */
static double TP8 = 0.41421356237309504880;
#endif

#ifdef DEC
static short P[] = {
0140127,0045205,0153731,0030027,
0141015,0065360,0116105,0025210,
0141256,0143755,0127056,0105716,
0141155,0045221,0056235,0072437
};
static short Q[] = {
/*0040200,0000000,0000000,0000000,*/
0041167,0172546,0143212,0126224,
0041573,0024641,0116611,0153210,
0041670,0074754,0110422,0127624,
0041461,0173755,0002566,0014374
};

/* tan( 3*pi/8 ) = 2.41421356237309504880 */
static short T3P8A[] = {040432,0101171,0114774,0167462,};
#define T3P8 *(double *)T3P8A

/* tan( pi/8 ) = 0.41421356237309504880 */
static short TP8A[] = {037724,011714,0147747,074622,};
#define TP8 *(double *)TP8A
#endif

#ifdef IBMPC
static short P[] = {
0x2603,0xbafb,0xe950,0xbfea,
0xa551,0x1388,0xad5e,0xc021,
0xd17a,0xb5c5,0xd8fd,0xc035,
0xaea4,0x2b93,0xa952,0xc02d
};
static short Q[] = {
/*0x0000,0x0000,0x0000,0x3ff0,*/
0x5592,0xd8d1,0xfeac,0x402e,
0x3ad1,0x33b1,0x6534,0x404f,
0x55f2,0x9222,0x0f3d,0x4057,
0xc31f,0xa0ae,0x3efd,0x4046
};

/* tan( 3*pi/8 ) = 2.41421356237309504880 */
static short T3P8A[] = {0x9de6,0x333f,0x504f,0x4003};
#define T3P8 *(double *)T3P8A

/* tan( pi/8 ) = 0.41421356237309504880 */
static short TP8A[] = {0xef32,0x99fc,0x8279,0x3fda};
#define TP8 *(double *)TP8A
#endif

#ifdef MIEEE
static short P[] = {
0xbfea,0xe950,0xbafb,0x2603,
0xc021,0xad5e,0x1388,0xa551,
0xc035,0xd8fd,0xb5c5,0xd17a,
0xc02d,0xa952,0x2b93,0xaea4
};
static short Q[] = {
0x402e,0xfeac,0xd8d1,0x5592,
0x404f,0x6534,0x33b1,0x3ad1,
0x4057,0x0f3d,0x9222,0x55f2,
0x4046,0x3efd,0xa0ae,0xc31f,
};

/* tan( 3*pi/8 ) = 2.41421356237309504880 */
static short T3P8A[] = {
0x4003,0x504f,0x333f,0x9de6
};
#define T3P8 *(double *)T3P8A

/* tan( pi/8 ) = 0.41421356237309504880 */
static short TP8A[] = {
0x3fda,0x8279,0x99fc,0xef32
};
#define TP8 *(double *)TP8A
#endif


double atan(x)
double x;
{
extern double PIO2, PIO4;
double y,z,p,q;
double polevl(), p1evl();
short sign;

/* make argument positive and save the sign */
sign = 1;
if( x < 0.0 )
{
sign = -1;
x = -x;
}

/* range reduction */
if( x > T3P8 )
{
y = PIO2;
x = -( 1.0/x );
}

else if( x > TP8 )
{
y = PIO4;
x = (x-1.0)/(x+1.0);
}
else
y = 0.0;

/* rational form in x**2 */
z = x * x;
y = y + ( polevl( z, P, 3 ) / p1evl( z, Q, 4 ) ) * z * x + x;

if( sign < 0 )
y = -y;

return(y);
}

/* atan2 */


extern double PI, PIO2;

#if ANSIC
double atan2( y, x )
#else
double atan2( x, y )
#endif
double x, y;
{
double z, w;
short code;
double atan();


code = 0;

if( x < 0.0 )
code = 2;
if( y < 0.0 )
code |= 1;

if( x == 0.0 )
{
if( code & 1 )
{
#if ANSIC
return( -PIO2 );
#else
return( 3.0*PIO2 );
#endif
}
if( y == 0.0 )
return( 0.0 );
return( PIO2 );
}

if( y == 0.0 )
{
if( code & 2 )
return( PI );
return( 0.0 );
}


switch( code )
{
#if ANSIC
case 0:
case 1: w = 0.0; break;
case 2: w = PI; break;
case 3: w = -PI; break;
#else
case 0: w = 0.0; break;
case 1: w = 2.0 * PI; break;
case 2:
case 3: w = PI; break;
#endif
}

z = atan( y/x );

return( w + z );
}


  3 Responses to “Category : C Source Code
Archive   : CEPHES22.ZIP
Filename : ATAN.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/