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 Thu Nov 20 11:49:51 2008 for RTAI API by doxygen 1.3.8