summaryrefslogtreecommitdiff
path: root/include/cppunit/portability
diff options
context:
space:
mode:
authorBaptiste Lepilleur <gaiacrtn@free.fr>2007-02-24 20:13:04 +0000
committerBaptiste Lepilleur <gaiacrtn@free.fr>2007-02-24 20:13:04 +0000
commit0d30a2aec28085cfb9fe359c321c289609b884ca (patch)
treed5848b1cb981a9fa5ba351b5eb01e4a0e06e1cf8 /include/cppunit/portability
parent3ca9c5d071cb8162c89fd514a6116ee6b450d763 (diff)
downloadcppunit-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.h50
-rw-r--r--include/cppunit/portability/Makefile.am11
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