| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 | /*************************************************************************  File:  fpmacros.c****  Contains:  C source code for implementations of floating-point**             functions which involve float format numbers, as**             defined in header <fp.h>.  In particular, this file**             contains implementations of functions**              __fpclassify(d,f), __isnormal(d,f), __isfinite(d,f),**             __isnan(d,f), and __signbit(d,f).  This file targets**             PowerPC platforms.****  Written by:   Robert A. Murley, Ali Sazegari****  Copyright:   c 2001 by Apple Computer, Inc., all rights reserved****  Change History (most recent first):****     07 Jul 01   ram      First created from fpfloatfunc.c, fp.c,**				classify.c and sign.c in MathLib v3 Mac OS9.*************************************************************************/#include     <features.h>#include     <sys/types.h>#include     <math.h>#include     "fp_private.h"#define SIGN_MASK 0x80000000#define NSIGN_MASK 0x7fffffff#define FEXP_MASK 0x7f800000#define FFRAC_MASK 0x007fffff/***********************************************************************   int __fpclassifyf(float x) returns the classification code of the   argument x, as defined in <fp.h>.   Exceptions:  INVALID signaled if x is a signaling NaN; in this case,                the FP_QNAN code is returned.   Calls:  none***********************************************************************/libm_hidden_proto(__fpclassifyf)int __fpclassifyf ( float x ){   unsigned int iexp;   union {      u_int32_t lval;      float fval;   } z;   z.fval = x;   iexp = z.lval & FEXP_MASK;                 /* isolate float exponent */   if (iexp == FEXP_MASK) {                   /* NaN or INF case */      if ((z.lval & 0x007fffff) == 0)         return FP_INFINITE;	return FP_NAN;   }   if (iexp != 0)                             /* normal float */      return FP_NORMAL;   if (x == 0.0)      return FP_ZERO;             /* zero */   else      return FP_SUBNORMAL;        /* must be subnormal */}libm_hidden_def(__fpclassifyf)/***********************************************************************      Function __fpclassify,      Implementation of classify of a double number for the PowerPC.   Exceptions:  INVALID signaled if x is a signaling NaN; in this case,                the FP_QNAN code is returned.   Calls:  none***********************************************************************/libm_hidden_proto(__fpclassify)int __fpclassify ( double arg ){	register unsigned int exponent;      union            {            dHexParts hex;            double dbl;            } x;	x.dbl = arg;	exponent = x.hex.high & dExpMask;	if ( exponent == dExpMask )		{		if ( ( ( x.hex.high & dHighMan ) | x.hex.low ) == 0 )			return FP_INFINITE;		else            	return FP_NAN;		}	else if ( exponent != 0)		return FP_NORMAL;	else {		if ( arg == 0.0 )			return FP_ZERO;		else			return FP_SUBNORMAL;		}}libm_hidden_def(__fpclassify)/***********************************************************************   int __isnormalf(float x) returns nonzero if and only if x is a   normalized float number and zero otherwise.   Exceptions:  INVALID is raised if x is a signaling NaN; in this case,                zero is returned.   Calls:  none***********************************************************************/int __isnormalf ( float x );int __isnormalf ( float x ){   unsigned int iexp;   union {      u_int32_t lval;      float fval;   } z;   z.fval = x;   iexp = z.lval & FEXP_MASK;                 /* isolate float exponent */   return ((iexp != FEXP_MASK) && (iexp != 0));}int __isnormal ( double x );int __isnormal ( double x ){	return ( __fpclassify ( x ) == FP_NORMAL );}/***********************************************************************   int __isfinitef(float x) returns nonzero if and only if x is a   finite (normal, subnormal, or zero) float number and zero otherwise.   Exceptions:  INVALID is raised if x is a signaling NaN; in this case,                zero is returned.   Calls:  none***********************************************************************/int __finitef ( float x ){   union {      u_int32_t lval;      float fval;   } z;   z.fval = x;   return ((z.lval & FEXP_MASK) != FEXP_MASK);}strong_alias(__finitef,finitef)#if 0 /* use __finite in s_finite.c */int __finite ( double x ){	return ( __fpclassify ( x ) >= FP_ZERO );}strong_alias(__finite,finite)#endif/***********************************************************************   int __signbitf(float x) returns nonzero if and only if the sign   bit of x is set and zero otherwise.   Exceptions:  INVALID is raised if x is a signaling NaN.   Calls:  none***********************************************************************/libm_hidden_proto(__signbitf)int __signbitf ( float x ){   union {      u_int32_t lval;      float fval;   } z;   z.fval = x;   return ((z.lval & SIGN_MASK) != 0);}libm_hidden_def(__signbitf)/***********************************************************************      Function sign of a double.      Implementation of sign bit for the PowerPC.   Calls:  none***********************************************************************/libm_hidden_proto(__signbit)int __signbit ( double arg ){      union            {            dHexParts hex;            double dbl;            } x;      int sign;      x.dbl = arg;      sign = ( ( x.hex.high & dSgnMask ) == dSgnMask ) ? 1 : 0;      return sign;}libm_hidden_def(__signbit)/************************************************************************ int __isinff(float x) returns -1 if value represents  negative*	infinity,  1  if value represents positive infinity,*	and 0 otherwise.** Calls:  __signbit* +***********************************************************************/int __isinff ( float x ){    int class = __fpclassifyf(x);    if ( class == FP_INFINITE ) {	return ( (__signbitf(x)) ? -1 : 1);    }    return 0;}strong_alias(__isinff,isinff)int __isinf ( double x ){    int class = __fpclassify(x);    if ( class == FP_INFINITE ) {	return ( (__signbit(x)) ? -1 : 1);    }    return 0;}strong_alias(__isinf,isinf)#if 0int __isinfl ( long double x ){    int class = __fpclassify(x);    if ( class == FP_INFINITE ) {	return ( (__signbit(x)) ? -1 : 1);    }    return 0;}strong_alias(__isinfl,isinfl)#endif/***********************************************************************   int __isnanf(float x) returns nonzero if and only if x is a   NaN and zero otherwise.   Exceptions:  INVALID is raised if x is a signaling NaN; in this case,                nonzero is returned.   Calls:  none***********************************************************************/int __isnanf ( float x ){   union {      u_int32_t lval;      float fval;   } z;   z.fval = x;   return (((z.lval&FEXP_MASK) == FEXP_MASK) && ((z.lval&FFRAC_MASK) != 0));}strong_alias(__isnanf,isnanf)libm_hidden_proto(__isnan)int __isnan ( double x ){	int class = __fpclassify(x);	return ( class == FP_NAN );}libm_hidden_def(__isnan)strong_alias(__isnan,isnan)#if 0int __isnanl ( long double x ){	int class = __fpclassify(x);	return ( class == FP_NAN );}strong_alias(__isnanl,isnanl)#endif
 |