base/math/fpmacros.c

Go to the documentation of this file.
00001 /***********************************************************************
00002 **  File:  fpmacros.c
00003 **   
00004 **  Contains:  C source code for implementations of floating-point
00005 **             functions which involve float format numbers, as
00006 **             defined in header <fp.h>.  In particular, this file
00007 **             contains implementations of functions
00008 **              __fpclassify(d,f), __isnormal(d,f), __isfinite(d,f),
00009 **             __isnan(d,f), and __signbit(d,f).  This file targets
00010 **             PowerPC platforms.
00011 **            
00012 **  Written by:   Robert A. Murley, Ali Sazegari
00013 **   
00014 **  Copyright:   c 2001 by Apple Computer, Inc., all rights reserved
00015 **   
00016 **  Change History (most recent first):
00017 **
00018 **     07 Jul 01   ram      First created from fpfloatfunc.c, fp.c,
00019 **                          classify.c and sign.c in MathLib v3 Mac OS9.
00020 **            
00021 ***********************************************************************/
00022 
00023 #include     "fpP.h"
00024 
00025 #define SIGN_MASK 0x80000000
00026 #define NSIGN_MASK 0x7fffffff
00027 #define FEXP_MASK 0x7f800000
00028 #define FFRAC_MASK 0x007fffff
00029 
00030 /***********************************************************************
00031    long int __fpclassifyf(float x) returns the classification code of the
00032    argument x, as defined in <fp.h>.
00033    
00034    Exceptions:  INVALID signaled if x is a signaling NaN; in this case,
00035                 the FP_QNAN code is returned.
00036    
00037    Calls:  none
00038 ***********************************************************************/
00039 
00040 long int __fpclassifyf ( float x )
00041 {
00042    unsigned long int iexp;
00043    
00044    union {
00045       unsigned long int lval;
00046       float fval;
00047    } z;
00048    
00049    z.fval = x;
00050    iexp = z.lval & FEXP_MASK;                 /* isolate float exponent */ 
00051    
00052    if (iexp == FEXP_MASK) {                   /* NaN or INF case */
00053       if ((z.lval & 0x007fffff) == 0)
00054          return (long int) FP_INFINITE;
00055       else if ((z.lval & 0x00400000) != 0)
00056          return (long int) FP_QNAN;
00057       else
00058          return (long int) FP_SNAN;
00059    }
00060    
00061    if (iexp != 0)                             /* normal float */
00062       return (long int) FP_NORMAL;
00063       
00064    if (x == 0.0)
00065       return (long int) FP_ZERO;             /* zero */
00066    else
00067       return (long int) FP_SUBNORMAL;        /* must be subnormal */
00068 }
00069    
00070 
00071 /***********************************************************************
00072       Function __fpclassify,                                                 
00073       Implementation of classify of a double number for the PowerPC.          
00074                                                                               
00075    Exceptions:  INVALID signaled if x is a signaling NaN; in this case,
00076                 the FP_QNAN code is returned.
00077    
00078    Calls:  none
00079 ***********************************************************************/
00080 
00081 long int __fpclassify ( double arg )
00082 {
00083     register unsigned long int exponent;
00084       union
00085             {
00086             dHexParts hex;
00087             double dbl;
00088             } x;
00089       
00090     x.dbl = arg;
00091     
00092     exponent = x.hex.high & dExpMask;
00093     if ( exponent == dExpMask )
00094         {
00095         if ( ( ( x.hex.high & dHighMan ) | x.hex.low ) == 0 )
00096             return (long int) FP_INFINITE;
00097         else
00098                 return ( x.hex.high & 0x00080000 ) ? FP_QNAN : FP_SNAN; 
00099         }
00100     else if ( exponent != 0)
00101         return (long int) FP_NORMAL;
00102     else {
00103         if ( arg == 0.0 )
00104             return (long int) FP_ZERO;
00105         else
00106             return (long int) FP_SUBNORMAL;
00107         }
00108 }
00109 
00110 
00111 /***********************************************************************
00112    long int __isnormalf(float x) returns nonzero if and only if x is a
00113    normalized float number and zero otherwise.
00114    
00115    Exceptions:  INVALID is raised if x is a signaling NaN; in this case,
00116                 zero is returned.
00117    
00118    Calls:  none
00119 ***********************************************************************/
00120 
00121 long int __isnormalf ( float x )
00122 {
00123    unsigned long int iexp;
00124    union {
00125       unsigned long int lval;
00126       float fval;
00127    } z;
00128    
00129    z.fval = x;
00130    iexp = z.lval & FEXP_MASK;                 /* isolate float exponent */
00131    return ((iexp != FEXP_MASK) && (iexp != 0));
00132 }
00133    
00134 
00135 long int __isnorma ( double x )
00136 {
00137     return ( __fpclassify ( x ) == FP_NORMAL ); 
00138 }
00139 
00140 
00141 /***********************************************************************
00142    long int __isfinitef(float x) returns nonzero if and only if x is a
00143    finite (normal, subnormal, or zero) float number and zero otherwise.
00144    
00145    Exceptions:  INVALID is raised if x is a signaling NaN; in this case,
00146                 zero is returned.
00147    
00148    Calls:  none
00149 ***********************************************************************/
00150 
00151 long int __isfinitef ( float x )
00152 {   
00153    union {
00154       unsigned long int lval;
00155       float fval;
00156    } z;
00157    
00158    z.fval = x;
00159    return ((z.lval & FEXP_MASK) != FEXP_MASK);
00160 }
00161    
00162 long int __isfinite ( double x )
00163 {
00164     return ( __fpclassify ( x ) >= FP_ZERO ); 
00165 }
00166 
00167 
00168 
00169 /***********************************************************************
00170    long int __isnanf(float x) returns nonzero if and only if x is a
00171    NaN and zero otherwise.
00172    
00173    Exceptions:  INVALID is raised if x is a signaling NaN; in this case,
00174                 nonzero is returned.
00175    
00176    Calls:  none
00177 ***********************************************************************/
00178 
00179 long int __isnanf ( float x )
00180 {   
00181    union {
00182       unsigned long int lval;
00183       float fval;
00184    } z;
00185    
00186    z.fval = x;
00187    return (((z.lval&FEXP_MASK) == FEXP_MASK) && ((z.lval&FFRAC_MASK) != 0));
00188 }
00189 
00190 long int __isnan ( double x )
00191 {
00192     long int class = __fpclassify(x);
00193     return ( ( class == FP_SNAN ) || ( class == FP_QNAN ) ); 
00194 }
00195 
00196 
00197 /***********************************************************************
00198    long int __signbitf(float x) returns nonzero if and only if the sign
00199    bit of x is set and zero otherwise.
00200    
00201    Exceptions:  INVALID is raised if x is a signaling NaN.
00202    
00203    Calls:  none
00204 ***********************************************************************/
00205 
00206 long int __signbitf ( float x )
00207 {   
00208    union {
00209       unsigned long int lval;
00210       float fval;
00211    } z;
00212    
00213    z.fval = x;
00214    return ((z.lval & SIGN_MASK) != 0);
00215 }
00216 
00217 
00218 /***********************************************************************
00219       Function sign of a double.                                              
00220       Implementation of sign bit for the PowerPC.                             
00221    
00222    Calls:  none
00223 ***********************************************************************/
00224 
00225 long int __signbit ( double arg )
00226 {
00227       union
00228             {
00229             dHexParts hex;
00230             double dbl;
00231             } x;
00232       long int sign;
00233 
00234       x.dbl = arg;
00235       sign = ( ( x.hex.high & dSgnMask ) == dSgnMask ) ? 1 : 0;
00236       return sign;
00237 }
00238 
00239 

Generated on Tue Feb 2 17:46:05 2010 for RTAI API by  doxygen 1.4.7