| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 | /*							ceil() *							floor() *							frexp() *							ldexp() *							signbit() *							isnan() *							isfinite() * *	Floating point numeric utilities * * * * SYNOPSIS: * * double ceil(), floor(), frexp(), ldexp(); * int signbit(), isnan(), isfinite(); * double x, y; * int expnt, n; * * y = floor(x); * y = ceil(x); * y = frexp( x, &expnt ); * y = ldexp( x, n ); * n = signbit(x); * n = isnan(x); * n = isfinite(x); * * * * DESCRIPTION: * * All four routines return a double precision floating point * result. * * floor() returns the largest integer less than or equal to x. * It truncates toward minus infinity. * * ceil() returns the smallest integer greater than or equal * to x.  It truncates toward plus infinity. * * frexp() extracts the exponent from x.  It returns an integer * power of two to expnt and the significand between 0.5 and 1 * to y.  Thus  x = y * 2**expn. * * ldexp() multiplies x by 2**n. * * signbit(x) returns 1 if the sign bit of x is 1, else 0. * * These functions are part of the standard C run time library * for many but not all C compilers.  The ones supplied are * written in C for either DEC or IEEE arithmetic.  They should * be used only if your compiler library does not already have * them. * * The IEEE versions assume that denormal numbers are implemented * in the arithmetic.  Some modifications will be required if * the arithmetic has abrupt rather than gradual underflow. *//*Cephes Math Library Release 2.8:  June, 2000Copyright 1984, 1995, 2000 by Stephen L. Moshier*/#include <math.h>#ifdef UNK/* ceil(), floor(), frexp(), ldexp() may need to be rewritten. */#undef UNK#if BIGENDIAN#define MIEEE 1#else#define IBMPC 1#endif#endif#ifdef DEC#define EXPMSK 0x807f#define MEXP 255#define NBITS 56#endif#ifdef IBMPC#define EXPMSK 0x800f#define MEXP 0x7ff#define NBITS 53#endif#ifdef MIEEE#define EXPMSK 0x800f#define MEXP 0x7ff#define NBITS 53#endifextern double MAXNUM, NEGZERO;#ifdef ANSIPROTdouble floor ( double );int isnan ( double );int isfinite ( double );double ldexp ( double, int );#elsedouble floor();int isnan(), isfinite();double ldexp();#endifdouble ceil(x)double x;{double y;#ifdef UNKmtherr( "ceil", DOMAIN );return(0.0);#endif#ifdef NANSif( isnan(x) )	return( x );#endif#ifdef INFINITIESif(!isfinite(x))	return(x);#endify = floor(x);if( y < x )	y += 1.0;#ifdef MINUSZEROif( y == 0.0 && x < 0.0 )	return( NEGZERO );#endifreturn(y);}/* Bit clearing masks: */static unsigned short bmask[] = {0xffff,0xfffe,0xfffc,0xfff8,0xfff0,0xffe0,0xffc0,0xff80,0xff00,0xfe00,0xfc00,0xf800,0xf000,0xe000,0xc000,0x8000,0x0000,};double floor(x)double x;{union	{	double y;	unsigned short sh[4];	} u;unsigned short *p;int e;#ifdef UNKmtherr( "floor", DOMAIN );return(0.0);#endif#ifdef NANSif( isnan(x) )	return( x );#endif#ifdef INFINITIESif(!isfinite(x))	return(x);#endif#ifdef MINUSZEROif(x == 0.0L)	return(x);#endifu.y = x;/* find the exponent (power of 2) */#ifdef DECp = (unsigned short *)&u.sh[0];e = (( *p  >> 7) & 0377) - 0201;p += 3;#endif#ifdef IBMPCp = (unsigned short *)&u.sh[3];e = (( *p >> 4) & 0x7ff) - 0x3ff;p -= 3;#endif#ifdef MIEEEp = (unsigned short *)&u.sh[0];e = (( *p >> 4) & 0x7ff) - 0x3ff;p += 3;#endifif( e < 0 )	{	if( u.y < 0.0 )		return( -1.0 );	else		return( 0.0 );	}e = (NBITS -1) - e;/* clean out 16 bits at a time */while( e >= 16 )	{#ifdef IBMPC	*p++ = 0;#endif#ifdef DEC	*p-- = 0;#endif#ifdef MIEEE	*p-- = 0;#endif	e -= 16;	}/* clear the remaining bits */if( e > 0 )	*p &= bmask[e];if( (x < 0) && (u.y != x) )	u.y -= 1.0;return(u.y);}double frexp( x, pw2 )double x;int *pw2;{union	{	double y;	unsigned short sh[4];	} u;int i;#ifdef DENORMALint k;#endifshort *q;u.y = x;#ifdef UNKmtherr( "frexp", DOMAIN );return(0.0);#endif#ifdef IBMPCq = (short *)&u.sh[3];#endif#ifdef DECq = (short *)&u.sh[0];#endif#ifdef MIEEEq = (short *)&u.sh[0];#endif/* find the exponent (power of 2) */#ifdef DECi  = ( *q >> 7) & 0377;if( i == 0 )	{	*pw2 = 0;	return(0.0);	}i -= 0200;*pw2 = i;*q &= 0x807f;	/* strip all exponent bits */*q |= 040000;	/* mantissa between 0.5 and 1 */return(u.y);#endif#ifdef IBMPCi  = ( *q >> 4) & 0x7ff;if( i != 0 )	goto ieeedon;#endif#ifdef MIEEEi  =  *q >> 4;i &= 0x7ff;if( i != 0 )	goto ieeedon;#ifdef DENORMAL#else*pw2 = 0;return(0.0);#endif#endif#ifndef DEC/* Number is denormal or zero */#ifdef DENORMALif( u.y == 0.0 )	{	*pw2 = 0;	return( 0.0 );	}/* Handle denormal number. */do	{	u.y *= 2.0;	i -= 1;	k  = ( *q >> 4) & 0x7ff;	}while( k == 0 );i = i + k;#endif /* DENORMAL */ieeedon:i -= 0x3fe;*pw2 = i;*q &= 0x800f;*q |= 0x3fe0;return( u.y );#endif}double ldexp( x, pw2 )double x;int pw2;{union	{	double y;	unsigned short sh[4];	} u;short *q;int e;#ifdef UNKmtherr( "ldexp", DOMAIN );return(0.0);#endifu.y = x;#ifdef DECq = (short *)&u.sh[0];e  = ( *q >> 7) & 0377;if( e == 0 )	return(0.0);#else#ifdef IBMPCq = (short *)&u.sh[3];#endif#ifdef MIEEEq = (short *)&u.sh[0];#endifwhile( (e = (*q & 0x7ff0) >> 4) == 0 )	{	if( u.y == 0.0 )		{		return( 0.0 );		}/* Input is denormal. */	if( pw2 > 0 )		{		u.y *= 2.0;		pw2 -= 1;		}	if( pw2 < 0 )		{		if( pw2 < -53 )			return(0.0);		u.y /= 2.0;		pw2 += 1;		}	if( pw2 == 0 )		return(u.y);	}#endif /* not DEC */e += pw2;/* Handle overflow */#ifdef DECif( e > MEXP )	return( MAXNUM );#elseif( e >= MEXP )	return( 2.0*MAXNUM );#endif/* Handle denormalized results */if( e < 1 )	{#ifdef DENORMAL	if( e < -53 )		return(0.0);	*q &= 0x800f;	*q |= 0x10;	/* For denormals, significant bits may be lost even	   when dividing by 2.  Construct 2^-(1-e) so the result	   is obtained with only one multiplication.  */	u.y *= ldexp(1.0, e-1);	return(u.y);#else	return(0.0);#endif	}else	{#ifdef DEC	*q &= 0x807f;	/* strip all exponent bits */	*q |= (e & 0xff) << 7;#else	*q &= 0x800f;	*q |= (e & 0x7ff) << 4;#endif	return(u.y);	}}
 |