CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/FWCore/Utilities/interface/math.h

Go to the documentation of this file.
00001 #ifndef FWCore_Utilities_math_h
00002 #define FWCore_Utilities_math_h
00003 
00004 #include <cmath>
00005 #include <sys/types.h>
00006 #include "math_private.h"
00007 
00008 namespace edm 
00009 {
00010 
00011   namespace detail
00012   {
00013     inline bool isnan(float x)
00014     {
00015       u_int32_t wx;
00016       
00017       GET_FLOAT_WORD (wx, x);
00018       wx &= 0x7fffffff;
00019       return (bool)(wx > 0x7f800000);
00020     }
00021     
00022     inline bool isnan(double x)
00023     {
00024       u_int32_t hx, lx;
00025       
00026       EXTRACT_WORDS (hx, lx, x);
00027       lx |= hx & 0xfffff;
00028       hx &= 0x7ff00000;
00029       return (bool)(hx == 0x7ff00000) && (lx != 0);
00030     }
00031     
00032     inline bool isnan(long double x)
00033     {
00034       u_int32_t ex, hx, lx;
00035       
00036       GET_LDOUBLE_WORDS (ex, hx, lx, x);
00037       ex &= 0x7fff;
00038       return (bool)((ex == 0x7fff) && ((hx & 0x7fffffff) | lx));
00039     }
00040   }
00041 
00042 
00043   template <class FP> inline bool asm_isnan(FP x)
00044   {
00045     // I do not know of a preprocessor symbol used to identify the
00046     // presence of an x87 floating-point processor.
00047 #if defined(__i386__)||defined(__x86_64)
00048     u_int16_t flags;
00049     __asm__("fxam\n\t"
00050             "fstsw %%ax"
00051             : "=a" (flags) /* output */
00052             : "t"  (x)     /* input */
00053             :              /* clobbered */
00054             );
00055     return (flags & 0x4500)==0x0100;
00056 #else
00057     #error No asm_isnan for this architecture.
00058 #endif    
00059   }
00060 
00061   template <class FP> inline bool equal_isnan(FP x)
00062     {
00063       return x !=x;
00064     }
00065 
00066   // Here are the public functions, chosen by best timing on Intel
00067   // Pentium 4.  Other architectures are likely to have different
00068   // orderings.
00069   inline bool isnan(float f) { return detail::isnan(f); }
00070 
00071   inline bool isnan(double d) { return equal_isnan(d); }
00072 
00073   inline bool isnan(long double q) { return detail::isnan(q); }
00074 
00075 } // namespace edm
00076 
00077 #endif