From eff60d491104f648b6d7a1f7fbde95ea10cce88e Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 13 Oct 2007 17:47:57 +0000 Subject: [PATCH] Separate the long double hash tests from the test for other float types. On some platforms the standard library has poor support for long doubles causing long doubles to fail when the others pass. So this makes it clearer that the problem is only for long doubles. [SVN r39979] --- hash/test/Jamfile.v2 | 1 + hash/test/hash_float_test.cpp | 197 +-------------------------- hash/test/hash_float_test.hpp | 200 ++++++++++++++++++++++++++++ hash/test/hash_long_double_test.cpp | 17 +++ 4 files changed, 219 insertions(+), 196 deletions(-) create mode 100644 hash/test/hash_float_test.hpp create mode 100644 hash/test/hash_long_double_test.cpp diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index 62b4a75..55789a8 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -20,6 +20,7 @@ test-suite functional/hash [ run hash_pointer_test.cpp ] [ run hash_function_pointer_test.cpp ] [ run hash_float_test.cpp : : : always_show_run_output ] + [ run hash_long_double_test.cpp : : : always_show_run_output ] [ run hash_string_test.cpp ] [ run hash_range_test.cpp ] [ run hash_custom_test.cpp ] diff --git a/hash/test/hash_float_test.cpp b/hash/test/hash_float_test.cpp index 7c9dfbc..6ceda4b 100644 --- a/hash/test/hash_float_test.cpp +++ b/hash/test/hash_float_test.cpp @@ -3,200 +3,7 @@ // Distributed under 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 "./config.hpp" - -#ifdef TEST_STD_INCLUDES -# include -#else -# include -#endif - -#include - -#include -#include - -#include - -template -void float_tests(char const* name, T* = 0) -{ - std::cerr<<"\n" - <<"Testing " BOOST_STRINGIZE(HASH_NAMESPACE) "::hash<"<\n" - <<"\n" - <<"std::numeric_limits::digits = " - <::digits<<"\n" - <<"std::numeric_limits::digits = " - <::digits<<"\n" - <<"std::numeric_limits::digits = " - <::digits<<"\n" - <<"\n" - ; - - HASH_NAMESPACE::hash x1; - - T zero = 0; - T minus_zero = (T) -1 * zero; - - BOOST_TEST(zero == minus_zero); - BOOST_TEST(x1(zero) == x1(minus_zero)); - - BOOST_TEST(x1(zero) == HASH_NAMESPACE::hash_value(zero)); - BOOST_TEST(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero)); - - using namespace std; - -// Doing anything with infinity causes borland to crash. -#if defined(__BORLANDC__) - std::cerr<<"Not running infinity checks on Borland, as it causes it to crash.\n"; -#else - if(std::numeric_limits::has_infinity) { - T infinity = -log(zero); - T infinity2 = (T) 1. / zero; - T infinity3 = (T) -1. / minus_zero; - T infinity4 = std::numeric_limits::infinity(); - - T minus_infinity = log(zero); - T minus_infinity2 = (T) -1. / zero; - T minus_infinity3 = (T) 1. / minus_zero; - - BOOST_TEST(x1(infinity) == HASH_NAMESPACE::hash_value(infinity)); - BOOST_TEST(x1(minus_infinity) - == HASH_NAMESPACE::hash_value(minus_infinity)); - - if(infinity == infinity2) - BOOST_TEST(x1(infinity) == x1(infinity2)); - if(infinity == infinity3) - BOOST_TEST(x1(infinity) == x1(infinity3)); - if(infinity == infinity4) - BOOST_TEST(x1(infinity) == x1(infinity4)); - - if(minus_infinity == minus_infinity2) - BOOST_TEST(x1(minus_infinity) == x1(minus_infinity2)); - if(minus_infinity == minus_infinity3) - BOOST_TEST(x1(minus_infinity) == x1(minus_infinity3)); - - BOOST_TEST(infinity != minus_infinity); - - if(x1(infinity) == x1(minus_infinity)) { - std::cerr<<"x1(infinity) == x1(-infinity) == "<::has_denorm) { - if(x1(std::numeric_limits::denorm_min()) == x1(infinity)) { - std::cerr<<"x1(denorm_min) == x1(infinity) == "<::denorm_min()) == x1(minus_infinity)) { - std::cerr<<"x1(denorm_min) == x1(-infinity) == "<::has_quiet_NaN) { - if(x1(std::numeric_limits::quiet_NaN()) == x1(infinity)) { - std::cerr<<"x1(quiet_NaN) == x1(infinity) == "<::quiet_NaN()) == x1(minus_infinity)) { - std::cerr<<"x1(quiet_NaN) == x1(-infinity) == "<::max)(); - T half_max = max / 2; - T quarter_max = max / 4; - T three_quarter_max = max - quarter_max; - - BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max)); - BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max)); - BOOST_TEST(x1(quarter_max) == HASH_NAMESPACE::hash_value(quarter_max)); - BOOST_TEST(x1(three_quarter_max) == HASH_NAMESPACE::hash_value(three_quarter_max)); - - // The '!=' tests could legitimately fail, but with my hash it indicates a bug. - BOOST_TEST(x1(max) == x1(max)); - BOOST_TEST(x1(max) != x1(quarter_max)); - BOOST_TEST(x1(max) != x1(half_max)); - BOOST_TEST(x1(max) != x1(three_quarter_max)); - BOOST_TEST(x1(quarter_max) == x1(quarter_max)); - BOOST_TEST(x1(quarter_max) != x1(half_max)); - BOOST_TEST(x1(quarter_max) != x1(three_quarter_max)); - BOOST_TEST(x1(half_max) == x1(half_max)); - BOOST_TEST(x1(half_max) != x1(three_quarter_max)); - BOOST_TEST(x1(three_quarter_max) == x1(three_quarter_max)); - -// Intel with gcc stdlib sometimes segfaults on calls to asin and acos. -#if !((defined(__INTEL_COMPILER) || defined(__ICL) || \ - defined(__ICC) || defined(__ECC)) && \ - (defined(__GLIBCPP__) || defined(__GLIBCXX__))) - T v1 = asin((T) 1); - T v2 = acos((T) 0); - if(v1 == v2) - BOOST_TEST(x1(v1) == x1(v2)); - BOOST_TEST(x1(v1) == HASH_NAMESPACE::hash_value(v1)); - BOOST_TEST(x1(v2) == HASH_NAMESPACE::hash_value(v2)); -#endif - - BOOST_TEST(x1(std::numeric_limits::epsilon()) == - HASH_NAMESPACE::hash_value(std::numeric_limits::epsilon())); - - BOOST_TEST(std::numeric_limits::epsilon() != (T) 0); - if(x1(std::numeric_limits::epsilon()) == x1((T) 0)) - std::cerr<<"x1(epsilon) == x1(0) == "<::epsilon() != (T) 0); - if(x1(-std::numeric_limits::epsilon()) == x1((T) 0)) - std::cerr<<"x1(-epsilon) == x1(0) == "<::epsilon() != (T) 1); - if(x1((T) 1 + std::numeric_limits::epsilon()) == x1((T) 1)) - std::cerr<<"x1(1 + epsilon) == x1(1) == "<::epsilon() != (T) 1); - if(x1((T) 1 - std::numeric_limits::epsilon()) == x1((T) 1)) - std::cerr<<"x1(1 - epsilon) == x1(1) == "<::epsilon() != (T) -1); - if(x1((T) -1 + std::numeric_limits::epsilon()) == x1((T) -1)) - std::cerr<<"x1(-1 + epsilon) == x1(-1) == "<::epsilon() != (T) -1); - if(x1((T) -1 - std::numeric_limits::epsilon()) == x1((T) -1)) - std::cerr<<"x1(-1 - epsilon) == x1(-1) == "<::has_denorm) { - if(x1(std::numeric_limits::denorm_min()) == x1(zero)) { - std::cerr<<"x1(denorm_min) == x1(zero) == "<::denorm_min()) != - HASH_NAMESPACE::hash_value(std::numeric_limits::denorm_min())) - { - std::cerr<<"x1(std::numeric_limits::denorm_min()) = " - << x1(std::numeric_limits::denorm_min()) - << "\nhash_value(std::numeric_limits::denorm_min()) = " - << HASH_NAMESPACE::hash_value( - std::numeric_limits::denorm_min()) - << "\nx1(0) = "<::has_quiet_NaN) { - if(x1(std::numeric_limits::quiet_NaN()) == x1(1.0)) { - std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<::quiet_NaN()) == - HASH_NAMESPACE::hash_value(std::numeric_limits::quiet_NaN())); - } -#endif -} +#include "hash_float_test.hpp" int main() { @@ -206,8 +13,6 @@ int main() float_tests("float", (float*) 0); float_tests("double", (double*) 0); - float_tests("long double", (long double*) 0); return boost::report_errors(); } - diff --git a/hash/test/hash_float_test.hpp b/hash/test/hash_float_test.hpp new file mode 100644 index 0000000..4c0a431 --- /dev/null +++ b/hash/test/hash_float_test.hpp @@ -0,0 +1,200 @@ + +// Copyright 2005-2007 Daniel James. +// Distributed under 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 "./config.hpp" + +#ifdef TEST_STD_INCLUDES +# include +#else +# include +#endif + +#include + +#include +#include + +#include + +template +void float_tests(char const* name, T* = 0) +{ + std::cerr<<"\n" + <<"Testing " BOOST_STRINGIZE(HASH_NAMESPACE) "::hash<"<\n" + <<"\n" + <<"std::numeric_limits::digits = " + <::digits<<"\n" + <<"std::numeric_limits::digits = " + <::digits<<"\n" + <<"std::numeric_limits::digits = " + <::digits<<"\n" + <<"\n" + ; + + HASH_NAMESPACE::hash x1; + + T zero = 0; + T minus_zero = (T) -1 * zero; + + BOOST_TEST(zero == minus_zero); + BOOST_TEST(x1(zero) == x1(minus_zero)); + + BOOST_TEST(x1(zero) == HASH_NAMESPACE::hash_value(zero)); + BOOST_TEST(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero)); + + using namespace std; + +// Doing anything with infinity causes borland to crash. +#if defined(__BORLANDC__) + std::cerr<<"Not running infinity checks on Borland, as it causes it to crash.\n"; +#else + if(std::numeric_limits::has_infinity) { + T infinity = -log(zero); + T infinity2 = (T) 1. / zero; + T infinity3 = (T) -1. / minus_zero; + T infinity4 = std::numeric_limits::infinity(); + + T minus_infinity = log(zero); + T minus_infinity2 = (T) -1. / zero; + T minus_infinity3 = (T) 1. / minus_zero; + + BOOST_TEST(x1(infinity) == HASH_NAMESPACE::hash_value(infinity)); + BOOST_TEST(x1(minus_infinity) + == HASH_NAMESPACE::hash_value(minus_infinity)); + + if(infinity == infinity2) + BOOST_TEST(x1(infinity) == x1(infinity2)); + if(infinity == infinity3) + BOOST_TEST(x1(infinity) == x1(infinity3)); + if(infinity == infinity4) + BOOST_TEST(x1(infinity) == x1(infinity4)); + + if(minus_infinity == minus_infinity2) + BOOST_TEST(x1(minus_infinity) == x1(minus_infinity2)); + if(minus_infinity == minus_infinity3) + BOOST_TEST(x1(minus_infinity) == x1(minus_infinity3)); + + BOOST_TEST(infinity != minus_infinity); + + if(x1(infinity) == x1(minus_infinity)) { + std::cerr<<"x1(infinity) == x1(-infinity) == "<::has_denorm) { + if(x1(std::numeric_limits::denorm_min()) == x1(infinity)) { + std::cerr<<"x1(denorm_min) == x1(infinity) == "<::denorm_min()) == x1(minus_infinity)) { + std::cerr<<"x1(denorm_min) == x1(-infinity) == "<::has_quiet_NaN) { + if(x1(std::numeric_limits::quiet_NaN()) == x1(infinity)) { + std::cerr<<"x1(quiet_NaN) == x1(infinity) == "<::quiet_NaN()) == x1(minus_infinity)) { + std::cerr<<"x1(quiet_NaN) == x1(-infinity) == "<::max)(); + T half_max = max / 2; + T quarter_max = max / 4; + T three_quarter_max = max - quarter_max; + + BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max)); + BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max)); + BOOST_TEST(x1(quarter_max) == HASH_NAMESPACE::hash_value(quarter_max)); + BOOST_TEST(x1(three_quarter_max) == HASH_NAMESPACE::hash_value(three_quarter_max)); + + // The '!=' tests could legitimately fail, but with my hash it indicates a bug. + BOOST_TEST(x1(max) == x1(max)); + BOOST_TEST(x1(max) != x1(quarter_max)); + BOOST_TEST(x1(max) != x1(half_max)); + BOOST_TEST(x1(max) != x1(three_quarter_max)); + BOOST_TEST(x1(quarter_max) == x1(quarter_max)); + BOOST_TEST(x1(quarter_max) != x1(half_max)); + BOOST_TEST(x1(quarter_max) != x1(three_quarter_max)); + BOOST_TEST(x1(half_max) == x1(half_max)); + BOOST_TEST(x1(half_max) != x1(three_quarter_max)); + BOOST_TEST(x1(three_quarter_max) == x1(three_quarter_max)); + +// Intel with gcc stdlib sometimes segfaults on calls to asin and acos. +#if !((defined(__INTEL_COMPILER) || defined(__ICL) || \ + defined(__ICC) || defined(__ECC)) && \ + (defined(__GLIBCPP__) || defined(__GLIBCXX__))) + T v1 = asin((T) 1); + T v2 = acos((T) 0); + if(v1 == v2) + BOOST_TEST(x1(v1) == x1(v2)); + BOOST_TEST(x1(v1) == HASH_NAMESPACE::hash_value(v1)); + BOOST_TEST(x1(v2) == HASH_NAMESPACE::hash_value(v2)); +#endif + + BOOST_TEST(x1(std::numeric_limits::epsilon()) == + HASH_NAMESPACE::hash_value(std::numeric_limits::epsilon())); + + BOOST_TEST(std::numeric_limits::epsilon() != (T) 0); + if(x1(std::numeric_limits::epsilon()) == x1((T) 0)) + std::cerr<<"x1(epsilon) == x1(0) == "<::epsilon() != (T) 0); + if(x1(-std::numeric_limits::epsilon()) == x1((T) 0)) + std::cerr<<"x1(-epsilon) == x1(0) == "<::epsilon() != (T) 1); + if(x1((T) 1 + std::numeric_limits::epsilon()) == x1((T) 1)) + std::cerr<<"x1(1 + epsilon) == x1(1) == "<::epsilon() != (T) 1); + if(x1((T) 1 - std::numeric_limits::epsilon()) == x1((T) 1)) + std::cerr<<"x1(1 - epsilon) == x1(1) == "<::epsilon() != (T) -1); + if(x1((T) -1 + std::numeric_limits::epsilon()) == x1((T) -1)) + std::cerr<<"x1(-1 + epsilon) == x1(-1) == "<::epsilon() != (T) -1); + if(x1((T) -1 - std::numeric_limits::epsilon()) == x1((T) -1)) + std::cerr<<"x1(-1 - epsilon) == x1(-1) == "<::has_denorm) { + if(x1(std::numeric_limits::denorm_min()) == x1(zero)) { + std::cerr<<"x1(denorm_min) == x1(zero) == "<::denorm_min()) != + HASH_NAMESPACE::hash_value(std::numeric_limits::denorm_min())) + { + std::cerr<<"x1(std::numeric_limits::denorm_min()) = " + << x1(std::numeric_limits::denorm_min()) + << "\nhash_value(std::numeric_limits::denorm_min()) = " + << HASH_NAMESPACE::hash_value( + std::numeric_limits::denorm_min()) + << "\nx1(0) = "<::has_quiet_NaN) { + if(x1(std::numeric_limits::quiet_NaN()) == x1(1.0)) { + std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<::quiet_NaN()) == + HASH_NAMESPACE::hash_value(std::numeric_limits::quiet_NaN())); + } +#endif +} + diff --git a/hash/test/hash_long_double_test.cpp b/hash/test/hash_long_double_test.cpp new file mode 100644 index 0000000..1c3aa74 --- /dev/null +++ b/hash/test/hash_long_double_test.cpp @@ -0,0 +1,17 @@ + +// Copyright 2005-2007 Daniel James. +// Distributed under 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 "hash_float_test.hpp" + +int main() +{ + std::cerr<<"Compiler: "<