| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 | /*							atanl.c * *	Inverse circular tangent, long double precision *      (arctangent) * * * * SYNOPSIS: * * long double x, y, atanl(); * * y = atanl( 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 *    IEEE      -10, 10    150000       1.3e-19     3.0e-20 * *//*							atan2l() * *	Quadrant correct inverse circular tangent, *	long double precision * * * * SYNOPSIS: * * long double x, y, z, atan2l(); * * z = atan2l( 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     60000       1.7e-19     3.2e-20 * See atan.c. * *//*							atan.c *//*Cephes Math Library Release 2.7:  May, 1998Copyright 1984, 1990, 1998 by Stephen L. Moshier*/#include <math.h>#ifdef UNKstatic long double P[] = {-8.6863818178092187535440E-1L,-1.4683508633175792446076E1L,-6.3976888655834347413154E1L,-9.9988763777265819915721E1L,-5.0894116899623603312185E1L,};static long double Q[] = {/* 1.00000000000000000000E0L,*/ 2.2981886733594175366172E1L, 1.4399096122250781605352E2L, 3.6144079386152023162701E2L, 3.9157570175111990631099E2L, 1.5268235069887081006606E2L,};/* tan( 3*pi/8 ) */static long double T3P8 =  2.41421356237309504880169L;/* tan( pi/8 ) */static long double TP8 =  4.1421356237309504880169e-1L;#endif#ifdef IBMPCstatic unsigned short P[] = {0x8ece,0xce53,0x1266,0xde5f,0xbffe, XPD0x07e6,0xa061,0xa6bf,0xeaef,0xc002, XPD0x53ee,0xf291,0x557f,0xffe8,0xc004, XPD0xf9d6,0xeda6,0x3f3e,0xc7fa,0xc005, XPD0xb6c3,0x6abc,0x9361,0xcb93,0xc004, XPD};static unsigned short Q[] = {/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/0x54d4,0x894e,0xe76e,0xb7da,0x4003, XPD0x76b9,0x7a46,0xafa2,0x8ffd,0x4006, XPD0xe3a9,0xe9c0,0x6bee,0xb4b8,0x4007, XPD0xabc1,0x50a7,0xb098,0xc3c9,0x4007, XPD0x891c,0x100d,0xae89,0x98ae,0x4006, XPD};/* tan( 3*pi/8 ) = 2.41421356237309504880 */static unsigned short T3P8A[] = {0x3242,0xfcef,0x7999,0x9a82,0x4000, XPD};#define T3P8 *(long double *)T3P8A/* tan( pi/8 ) = 0.41421356237309504880 */static unsigned short TP8A[] = {0x9211,0xe779,0xcccf,0xd413,0x3ffd, XPD};#define TP8 *(long double *)TP8A#endif#ifdef MIEEEstatic unsigned long P[] = {0xbffe0000,0xde5f1266,0xce538ece,0xc0020000,0xeaefa6bf,0xa06107e6,0xc0040000,0xffe8557f,0xf29153ee,0xc0050000,0xc7fa3f3e,0xeda6f9d6,0xc0040000,0xcb939361,0x6abcb6c3,};static unsigned long Q[] = {/*0x3fff0000,0x80000000,0x00000000,*/0x40030000,0xb7dae76e,0x894e54d4,0x40060000,0x8ffdafa2,0x7a4676b9,0x40070000,0xb4b86bee,0xe9c0e3a9,0x40070000,0xc3c9b098,0x50a7abc1,0x40060000,0x98aeae89,0x100d891c,};/* tan( 3*pi/8 ) = 2.41421356237309504880 */static long T3P8A[] = {0x40000000,0x9a827999,0xfcef3242};#define T3P8 *(long double *)T3P8A/* tan( pi/8 ) = 0.41421356237309504880 */static long TP8A[] = {0x3ffd0000,0xd413cccf,0xe7799211};#define TP8 *(long double *)TP8A#endif#ifdef ANSIPROTextern long double polevll ( long double, void *, int );extern long double p1evll ( long double, void *, int );extern long double fabsl ( long double );extern int signbitl ( long double );extern int isnanl ( long double );long double atanl ( long double );#elselong double polevll(), p1evll(), fabsl(), signbitl(), isnanl();long double atanl();#endif#ifdef INFINITIESextern long double INFINITYL;#endif#ifdef NANSextern long double NANL;#endif#ifdef MINUSZEROextern long double NEGZEROL;#endiflong double atanl(x)long double x;{extern long double PIO2L, PIO4L;long double y, z;short sign;#ifdef MINUSZEROif( x == 0.0L )	return(x);#endif#ifdef INFINITIESif( x == INFINITYL )	return( PIO2L );if( x == -INFINITYL )	return( -PIO2L );#endif/* make argument positive and save the sign */sign = 1;if( x < 0.0L )	{	sign = -1;	x = -x;	}/* range reduction */if( x > T3P8 )	{	y = PIO2L;	x = -( 1.0L/x );	}else if( x > TP8 )	{	y = PIO4L;	x = (x-1.0L)/(x+1.0L);	}else	y = 0.0L;/* rational form in x**2 */z = x * x;y = y + ( polevll( z, P, 4 ) / p1evll( z, Q, 5 ) ) * z * x + x;if( sign < 0 )	y = -y;return(y);}/*							atan2	*/extern long double PIL, PIO2L, MAXNUML;#if ANSIClong double atan2l( y, x )#elselong double atan2l( x, y )#endiflong double x, y;{long double z, w;short code;code = 0;if( x < 0.0L )	code = 2;if( y < 0.0L )	code |= 1;#ifdef NANSif( isnanl(x) )	return(x);if( isnanl(y) )	return(y);#endif#ifdef MINUSZEROif( y == 0.0L )	{	if( signbitl(y) )		{		if( x > 0.0L )			z = y;		else if( x < 0.0L )			z = -PIL;		else			{			if( signbitl(x) )				z = -PIL;			else				z = y;			}		}	else /* y is +0 */		{		if( x == 0.0L )			{			if( signbitl(x) )				z = PIL;			else				z = 0.0L;			}		else if( x > 0.0L )			z = 0.0L;		else			z = PIL;		}	return z;	}if( x == 0.0L )	{	if( y > 0.0L )		z = PIO2L;	else		z = -PIO2L;	return z;	}#endif /* MINUSZERO */#ifdef INFINITIESif( x == INFINITYL )	{	if( y == INFINITYL )		z = 0.25L * PIL;	else if( y == -INFINITYL )		z = -0.25L * PIL;	else if( y < 0.0L )		z = NEGZEROL;	else		z = 0.0L;	return z;	}if( x == -INFINITYL )	{	if( y == INFINITYL )		z = 0.75L * PIL;	else if( y == -INFINITYL )		z = -0.75L * PIL;	else if( y >= 0.0L )		z = PIL;	else		z = -PIL;	return z;	}if( y == INFINITYL )	return( PIO2L );if( y == -INFINITYL )	return( -PIO2L );#endif /* INFINITIES */#ifdef INFINITIESif( x == 0.0L )#elseif( fabsl(x) <= (fabsl(y) / MAXNUML) )#endif	{	if( code & 1 )		{#if ANSIC		return( -PIO2L );#else		return( 3.0L*PIO2L );#endif		}	if( y == 0.0L )		return( 0.0L );	return( PIO2L );	}if( y == 0.0L )	{	if( code & 2 )		return( PIL );	return( 0.0L );	}switch( code )	{	default:#if ANSIC	case 0:	case 1: w = 0.0L; break;	case 2: w = PIL; break;	case 3: w = -PIL; break;#else	case 0: w = 0.0L; break;	case 1: w = 2.0L * PIL; break;	case 2:	case 3: w = PIL; break;#endif	}z = w + atanl( y/x );#ifdef MINUSZEROif( z == 0.0L && y < 0.0L )	z = NEGZEROL;#endifreturn( z );}
 |