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