CppUnit project page FAQ CppUnit home page

FloatingPoint.h
Go to the documentation of this file.
1 #ifndef CPPUNIT_PORTABILITY_FLOATINGPOINT_H_INCLUDED
2 #define CPPUNIT_PORTABILITY_FLOATINGPOINT_H_INCLUDED
3 
4 #include <cppunit/Portability.h>
5 #include <math.h>
6 #if defined(CPPUNIT_HAVE_IEEEFP_H)
7 #include <ieeefp.h> /* required for isfinite() on Solaris with Sun Studio */
8 #endif
9 
11 
13 // According to IEEE-754 floating point standard,
14 // (see e.g. page 8 of
15 // http://www.cs.berkeley.edu/~wkahan/ieee754status/ieee754.ps)
16 // all comparisons with NaN are false except "x != x", which is true.
17 //
18 // At least Microsoft Visual Studio 6 is known not to implement this test correctly.
19 // It emits the following code to test equality:
20 // fcomp qword ptr [nan]
21 // fnstsw ax // copie fp (floating-point) status register to ax
22 // test ah,40h // test bit 14 of ax (0x4000) => C3 of fp status register
23 // According to the following documentation on the x86 floating point status register,
24 // the C2 bit should be tested to test for NaN value.
25 // http://webster.cs.ucr.edu/AoA/Windows/HTML/RealArithmetic.html#1000117
26 // In Microsoft Visual Studio 2003 & 2005, the test is implemented with:
27 // test ah,44h // Visual Studio 2005 test both C2 & C3...
28 //
29 // To work around this, a NaN is assumed to be detected if no strict ordering is found.
30 inline bool floatingPointIsUnordered( double x )
31 {
32  // x != x will detect a NaN on conformant platform
33  // (2.0 < x && x < 1.0) will detect a NaN on non conformant platform:
34  // => no ordering can be found for x.
35  return (x != x) || (2.0 < x && x < 1.0);
36 }
37 
38 
41 inline int floatingPointIsFinite( double x )
42 {
43 #if defined(CPPUNIT_HAVE_ISFINITE)
44  return isfinite( x );
45 #elif defined(CPPUNIT_HAVE_FINITE)
46  return finite( x );
47 #elif defined(CPPUNIT_HAVE__FINITE)
48  return _finite(x);
49 #else
50  double testInf = x * 0.0; // Produce 0.0 if x is finite, a NaN otherwise.
51  return testInf == 0.0 && !floatingPointIsUnordered(testInf);
52 #endif
53 }
54 
56 
57 #endif // CPPUNIT_PORTABILITY_FLOATINGPOINT_H_INCLUDED

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