CppUnit project page FAQ CppUnit home page

FloatingPoint.h
Go to the documentation of this file.
00001 #ifndef CPPUNIT_PORTABILITY_FLOATINGPOINT_H_INCLUDED
00002 #define CPPUNIT_PORTABILITY_FLOATINGPOINT_H_INCLUDED
00003 
00004 #include <cppunit/Portability.h>
00005 #include <math.h>
00006 #if defined(CPPUNIT_HAVE_IEEEFP_H)
00007 #include <ieeefp.h> /* required for isfinite() on Solaris with Sun Studio */
00008 #endif
00009 
00010 CPPUNIT_NS_BEGIN
00011 
00013 // According to IEEE-754 floating point standard, 
00014 // (see e.g. page 8 of
00015 // http://www.cs.berkeley.edu/~wkahan/ieee754status/ieee754.ps) 
00016 // all comparisons with NaN are false except "x != x", which is true.
00017 //
00018 // At least Microsoft Visual Studio 6 is known not to implement this test correctly.
00019 // It emits the following code to test equality:
00020 //  fcomp       qword ptr [nan]
00021 //  fnstsw      ax                        // copie fp (floating-point) status register to ax
00022 //  test        ah,40h                    // test bit 14 of ax (0x4000) => C3 of fp status register
00023 // According to the following documentation on the x86 floating point status register,
00024 // the C2 bit should be tested to test for NaN value. 
00025 // http://webster.cs.ucr.edu/AoA/Windows/HTML/RealArithmetic.html#1000117
00026 // In Microsoft Visual Studio 2003 & 2005, the test is implemented with:
00027 //  test        ah,44h         // Visual Studio 2005 test both C2 & C3...
00028 //
00029 // To work around this, a NaN is assumed to be detected if no strict ordering is found.
00030 inline bool floatingPointIsUnordered( double x )
00031 {
00032    // x != x will detect a NaN on conformant platform
00033    // (2.0 < x  &&  x < 1.0) will detect a NaN on non conformant platform:
00034    // => no ordering can be found for x.
00035    return  (x != x) ||  (2.0 < x  &&  x < 1.0);
00036 }
00037 
00038 
00041 inline int floatingPointIsFinite( double x )
00042 {
00043 #if defined(CPPUNIT_HAVE_ISFINITE)
00044    return isfinite( x );
00045 #elif defined(CPPUNIT_HAVE_FINITE)
00046    return finite( x );
00047 #elif defined(CPPUNIT_HAVE__FINITE)
00048    return _finite(x);
00049 #else
00050    double testInf = x * 0.0;  // Produce 0.0 if x is finite, a NaN otherwise.
00051    return testInf == 0.0  &&  !floatingPointIsUnordered(testInf);
00052 #endif
00053 }
00054 
00055 CPPUNIT_NS_END
00056 
00057 #endif // CPPUNIT_PORTABILITY_FLOATINGPOINT_H_INCLUDED

SourceForge Logo hosts this site. Send comments to:
CppUnit Developers