CppUnit project page | FAQ | CppUnit home page |
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
|
hosts this site. |
Send comments to: CppUnit Developers |