diff options
| author | Baptiste Lepilleur <gaiacrtn@free.fr> | 2007-02-24 20:13:04 +0000 |
|---|---|---|
| committer | Baptiste Lepilleur <gaiacrtn@free.fr> | 2007-02-24 20:13:04 +0000 |
| commit | 0d30a2aec28085cfb9fe359c321c289609b884ca (patch) | |
| tree | d5848b1cb981a9fa5ba351b5eb01e4a0e06e1cf8 /include/cppunit/portability | |
| parent | 3ca9c5d071cb8162c89fd514a6116ee6b450d763 (diff) | |
| download | cppunit-0d30a2aec28085cfb9fe359c321c289609b884ca.tar.gz | |
Src/cppunit/TestAssert.
src/cppunit/TestAssert.cpp (assertDoubleEquals): Moved finite & NaN
tests to include/cppunit/portability/FloatingPoint.h. Changed
implementation assertDoubleEquals to explicitly test for NaN
in case of non-finite values to force equality failure in the
presence of NaN. Previous implementation failed on Microsoft
Visual Studio 6 (on this platform: NaN == NaN).
* examples/cppunittest/TestAssertTest.cpp: Add more unit tests to
test the portable floating-point primitive. Added missing
include <limits>.
* include/cppunit/portability/Makefile.am:
* include/cppunit/portability/FloatingPoint.h: Added file. Extracted
isfinite() from TestAssert.cpp.
* include/cppunit/config-evc4:
* include/cppunit/config-msvc6: Added support for _finite().
Diffstat (limited to 'include/cppunit/portability')
| -rw-r--r-- | include/cppunit/portability/FloatingPoint.h | 50 | ||||
| -rw-r--r-- | include/cppunit/portability/Makefile.am | 11 |
2 files changed, 56 insertions, 5 deletions
diff --git a/include/cppunit/portability/FloatingPoint.h b/include/cppunit/portability/FloatingPoint.h new file mode 100644 index 0000000..fa3095e --- /dev/null +++ b/include/cppunit/portability/FloatingPoint.h @@ -0,0 +1,50 @@ +#ifndef CPPUNIT_PORTABILITY_FLOATINGPOINT_H_INCLUDED +#define CPPUNIT_PORTABILITY_FLOATINGPOINT_H_INCLUDED + +#include <math.h> + +CPPUNIT_NS_BEGIN + +/// \brief Tests if a floating-point is a NaN. +// According to IEEE-754 floating point standard, NaN comparison should always +// be 'false'. +// At least Microsoft Visual Studio 6 is known not to implement this test correctly. +// It emits the following code to test equality: +// fcomp qword ptr [nan] +// fnstsw ax // copie fp (floating-point) status register to ax +// test ah,40h // test bit 14 of ax (0x4000) => C3 of fp status register +// According to the following documentation on the x86 floating point status register, +// the C2 bit should be tested to test for NaN value. +// http://webster.cs.ucr.edu/AoA/Windows/HTML/RealArithmetic.html#1000117 +// In Microsoft Visual Studio 2003 & 2005, the test is implemented with: +// test ah,44h // Visual Studio 2005 test both C2 & C3... +// +// To work around this, a NaN is assumed to be detected if no strict ordering is found. +inline bool floatingPointIsUnordered( double x ) +{ + // x != x will detect a NaN on conformant platform + // (2.0 < x && x < 1.0) will detect a NaN on non conformant platform: + // => no ordering can be found for x. + return (x != x) || (2.0 < x && x < 1.0); +} + + +/// \brief Tests if a floating-point is finite. +/// @return \c true if x is neither a NaN, nor +inf, nor -inf, \c false otherwise. +inline bool floatingPointIsFinite( double x ) +{ +#if defined(CPPUNIT_HAVE_ISFINITE) + return (bool)isfinite( x ); +#elif defined(CPPUNIT_HAVE_FINITE) + return (bool)finite( x ); +#elif defined(CPPUNIT_HAVE__FINITE) + return _finite(x); +#else + double testInf = x * 0.0; // Produce 0.0 if x is finite, a NaN otherwise. + return testInf == 0.0 && !floatingPointIsUnordered(testInf); +#endif +} + +CPPUNIT_NS_END + +#endif // CPPUNIT_PORTABILITY_FLOATINGPOINT_H_INCLUDED diff --git a/include/cppunit/portability/Makefile.am b/include/cppunit/portability/Makefile.am index 3c578e3..2caeb32 100644 --- a/include/cppunit/portability/Makefile.am +++ b/include/cppunit/portability/Makefile.am @@ -1,9 +1,10 @@ libcppunitincludedir = $(includedir)/cppunit/portability libcppunitinclude_HEADERS = \ - CppUnitDeque.h \ - CppUnitMap.h \ - CppUnitSet.h \ - CppUnitStack.h \ + CppUnitDeque.h \ + CppUnitMap.h \ + CppUnitSet.h \ + CppUnitStack.h \ CppUnitVector.h \ - Stream.h + FloatingPoint.h \ + Stream.h |
