CppUnit project page | FAQ | CppUnit home page

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# 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
    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