summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/math/test/test_classify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/math/test/test_classify.cpp')
-rw-r--r--src/boost/libs/math/test/test_classify.cpp313
1 files changed, 313 insertions, 0 deletions
diff --git a/src/boost/libs/math/test/test_classify.cpp b/src/boost/libs/math/test/test_classify.cpp
new file mode 100644
index 00000000..52d2b2d7
--- /dev/null
+++ b/src/boost/libs/math/test/test_classify.cpp
@@ -0,0 +1,313 @@
+// Copyright John Maddock 2006.
+// Copyright Paul A. Bristow 2007
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <pch.hpp>
+
+#include <cmath>
+#include <math.h>
+#include <boost/limits.hpp>
+#include <boost/math/concepts/real_concept.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+#include <iostream>
+#include <iomanip>
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4127 4146) // conditional expression is constant
+#endif
+
+const char* method_name(const boost::math::detail::native_tag&)
+{
+ return "Native";
+}
+
+const char* method_name(const boost::math::detail::generic_tag<true>&)
+{
+ return "Generic (with numeric limits)";
+}
+
+const char* method_name(const boost::math::detail::generic_tag<false>&)
+{
+ return "Generic (without numeric limits)";
+}
+
+const char* method_name(const boost::math::detail::ieee_tag&)
+{
+ return "IEEE std";
+}
+
+const char* method_name(const boost::math::detail::ieee_copy_all_bits_tag&)
+{
+ return "IEEE std, copy all bits";
+}
+
+const char* method_name(const boost::math::detail::ieee_copy_leading_bits_tag&)
+{
+ return "IEEE std, copy leading bits";
+}
+
+template <class T>
+void test_classify(T t, const char* type)
+{
+ std::cout << "Testing type " << type << std::endl;
+
+ typedef typename boost::math::detail::fp_traits<T>::type traits;
+ typedef typename traits::method method;
+
+ std::cout << "Evaluation method = " << method_name(method()) << std::endl;
+
+ t = 2;
+ T u = 2;
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_NORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_NORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), true);
+ if(std::numeric_limits<T>::is_specialized)
+ {
+ t = (std::numeric_limits<T>::max)();
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_NORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_NORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), true);
+ t = (std::numeric_limits<T>::min)();
+ if(t != 0)
+ {
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_NORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), true);
+ if(!std::numeric_limits<T>::is_integer)
+ {
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_NORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ }
+ }
+ }
+ if(std::numeric_limits<T>::has_denorm)
+ {
+ t = (std::numeric_limits<T>::min)();
+ t /= 2;
+ if(t != 0)
+ {
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_SUBNORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_SUBNORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ }
+ t = std::numeric_limits<T>::denorm_min();
+ if((t != 0) && (t < (std::numeric_limits<T>::min)()))
+ {
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_SUBNORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_SUBNORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ }
+ }
+ else
+ {
+ std::cout << "Denormalised forms not tested" << std::endl;
+ }
+ t = 0;
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_ZERO);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_ZERO);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ t /= -u; // create minus zero if it exists
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_ZERO);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_ZERO);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ // infinity:
+ if(std::numeric_limits<T>::has_infinity)
+ {
+ // At least one std::numeric_limits<T>::infinity)() returns zero
+ // (Compaq true64 cxx), hence the check.
+ t = (std::numeric_limits<T>::infinity)();
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_INFINITE);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_INFINITE);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+#if !defined(__BORLANDC__) && !(defined(__DECCXX) && !defined(_IEEE_FP))
+ // divide by zero on Borland triggers a C++ exception :-(
+ // divide by zero on Compaq CXX triggers a C style signal :-(
+ t = 2;
+ u = 0;
+ t /= u;
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_INFINITE);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_INFINITE);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ t = -2;
+ t /= u;
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_INFINITE);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_INFINITE);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+#else
+ std::cout << "Infinities from divide by zero not tested" << std::endl;
+#endif
+ }
+ else
+ {
+ std::cout << "Infinity not tested" << std::endl;
+ }
+#ifndef __BORLANDC__
+ // NaN's:
+ // Note that Borland throws an exception if we even try to obtain a Nan
+ // by calling std::numeric_limits<T>::quiet_NaN() !!!!!!!
+ if(std::numeric_limits<T>::has_quiet_NaN)
+ {
+ t = std::numeric_limits<T>::quiet_NaN();
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_NAN);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_NAN);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ }
+ else
+ {
+ std::cout << "Quiet NaN's not tested" << std::endl;
+ }
+ if(std::numeric_limits<T>::has_signaling_NaN)
+ {
+ t = std::numeric_limits<T>::signaling_NaN();
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_NAN);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_NAN);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ }
+ else
+ {
+ std::cout << "Signaling NaN's not tested" << std::endl;
+ }
+#endif
+}
+
+BOOST_AUTO_TEST_CASE( test_main )
+{
+ BOOST_MATH_CONTROL_FP;
+ // start by printing some information:
+#ifdef isnan
+ std::cout << "Platform has isnan macro." << std::endl;
+#endif
+#ifdef fpclassify
+ std::cout << "Platform has fpclassify macro." << std::endl;
+#endif
+#ifdef BOOST_HAS_FPCLASSIFY
+ std::cout << "Platform has FP_NORMAL macro." << std::endl;
+#endif
+ std::cout << "FP_ZERO: " << (int)FP_ZERO << std::endl;
+ std::cout << "FP_NORMAL: " << (int)FP_NORMAL << std::endl;
+ std::cout << "FP_INFINITE: " << (int)FP_INFINITE << std::endl;
+ std::cout << "FP_NAN: " << (int)FP_NAN << std::endl;
+ std::cout << "FP_SUBNORMAL: " << (int)FP_SUBNORMAL << std::endl;
+
+ // then run the tests:
+ test_classify(float(0), "float");
+ test_classify(double(0), "double");
+ // long double support for fpclassify is considered "core" so we always test it
+ // even when long double support is turned off via BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+ test_classify((long double)(0), "long double");
+ test_classify((boost::math::concepts::real_concept)(0), "real_concept");
+
+ // We should test with integer types as well:
+ test_classify(int(0), "int");
+ test_classify(unsigned(0), "unsigned");
+}
+
+/*
+Autorun "i:\Boost-sandbox\math_toolkit\libs\math\test\MSVC80\debug\test_classify.exe"
+Running 1 test case...
+FP_ZERO: 0
+FP_NORMAL: 1
+FP_INFINITE: 2
+FP_NAN: 3
+FP_SUBNORMAL: 4
+Testing type float
+Testing type double
+Testing type long double
+Testing type real_concept
+Denormalised forms not tested
+Infinity not tested
+Quiet NaN's not tested
+Signaling NaN's not tested
+Test suite "Test Program" passed with:
+ 79 assertions out of 79 passed
+ 1 test case out of 1 passed
+ Test case "test_main_caller( argc, argv )" passed with:
+ 79 assertions out of 79 passed
+
+*/