From 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 20:24:20 +0200 Subject: Adding upstream version 14.2.21. Signed-off-by: Daniel Baumann --- src/boost/libs/math/test/test_classify.cpp | 313 +++++++++++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 src/boost/libs/math/test/test_classify.cpp (limited to 'src/boost/libs/math/test/test_classify.cpp') 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 + +#include +#include +#include +#include +#include +#define BOOST_TEST_MAIN +#include +#include +#include + +#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&) +{ + return "Generic (with numeric limits)"; +} + +const char* method_name(const boost::math::detail::generic_tag&) +{ + 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 +void test_classify(T t, const char* type) +{ + std::cout << "Testing type " << type << std::endl; + + typedef typename boost::math::detail::fp_traits::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::is_specialized) + { + t = (std::numeric_limits::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::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::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::has_denorm) + { + t = (std::numeric_limits::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::denorm_min(); + if((t != 0) && (t < (std::numeric_limits::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::has_infinity) + { + // At least one std::numeric_limits::infinity)() returns zero + // (Compaq true64 cxx), hence the check. + t = (std::numeric_limits::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::quiet_NaN() !!!!!!! + if(std::numeric_limits::has_quiet_NaN) + { + t = std::numeric_limits::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::has_signaling_NaN) + { + t = std::numeric_limits::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 + +*/ -- cgit v1.2.3