/////////////////////////////////////////////////////////////////////////////// // Copyright 2021 Fahad Syed. // Copyright 2021 Christopher Kormanyos. // Copyright 2021 Janek Kozicki. // 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) // // Constructor tests for cpp_double_float<> // cd /mnt/c/Users/User/Documents/Ks/PC_Software/Test // g++ -O3 -Wall -march=native -std=c++11 -I/mnt/c/MyGitRepos/BoostGSoC21_multiprecision/include -I/mnt/c/boost/boost_1_76_0 test.cpp -o test_double_float.exe #include #include #ifdef BOOST_MATH_USE_FLOAT128 #include #endif #include #include #include #include #include #include #include namespace test_cpp_double_constructors { namespace detail { template constexpr T max(T a, T b) { return ((a > b) ? a : b); } } template ::value, bool>::type = true> FloatingPointType uniform_real() { static std::random_device rd; static std::mt19937 gen(rd()); static boost::random::uniform_real_distribution dis(0.0, 1.0); return dis(gen); } template ::value, bool>::type = true> NumericType uniform_integral_number() { NumericType out = 0; for (int i = 0; i < int(sizeof(NumericType)); ++i) out = (out << 8) + static_cast(std::round(256.0 * uniform_real())); return out; } template ::value, bool>::type = true> NumericType get_rand() { return uniform_integral_number(); } template ::value, bool>::type = true> FloatingPointType get_rand() { return uniform_real(); } template boost::multiprecision::backends::cpp_double_float get_rand() { using float_type = typename FloatingPointType::float_type; return boost::multiprecision::backends::cpp_double_float(uniform_real()) * boost::multiprecision::backends::cpp_double_float(uniform_real()); } template ::value || boost::multiprecision::backends::detail::is_floating_point_or_float128::value>::type const* = nullptr> ConstructionType construct_from(ArithmeticType f) { return ConstructionType(f); } template ::value || boost::multiprecision::backends::detail::is_floating_point_or_float128::value)>::type const* = nullptr> ConstructionType construct_from(DoubleFloatType f) { static_assert(std::is_same< boost::multiprecision::backends::cpp_double_float , typename std::decay::type>::value, "Only double float should come here"); return ConstructionType(f.first()) + ConstructionType(f.second()); } template int test_constructor() { using double_float_t = boost::multiprecision::backends::cpp_double_float; using control_float_type = boost::multiprecision::number::digits10, std::numeric_limits::digits10) * 2 + 1>, boost::multiprecision::et_off>; std::cout << "Testing constructor for "; std::cout.width(30); std::cout << typeid(NumericType).name() << "... "; int i; for (i = 0; i < 10000; ++i) { NumericType n = get_rand(); double_float_t d(n); typename double_float_t::rep_type rep(d.rep()); double_float_t::normalize_pair(rep); // Check if representation of the cpp_double_float is not normalized if (rep != d.rep()) { std::cerr << "[FAILED]\nabnormal representation for " << typeid(NumericType).name() << " = " << n << " (cpp_double_float<" << typeid(FloatingPointType).name() << "> = " << d.get_raw_str() << ")" << std::endl; return -1; } const control_float_type MaxError = boost::multiprecision::ldexp(control_float_type(1), -std::numeric_limits::digits); control_float_type n_prime = construct_from(n); control_float_type d_prime = construct_from(d); using boost::multiprecision::fabs; if (fabs(1- fabs(n_prime / d_prime)) > MaxError) { std::cerr << "[FAILED] exceeded acceptable error (n = " << n << ")" << std::endl; return -1; } } std::cout << "ok (" << i << " cases tested)" << std::endl; return 0; } // Test compilation, constructors, basic operatory template int test_constructors() { using double_float_t = boost::multiprecision::backends::cpp_double_float; double_float_t a, b; std::cout << "Testing cpp_double_float< " << typeid(FloatingPointType).name() << " >...\n===" << std::endl; int e = 0; e += test_constructor(); e += test_constructor(); e += test_constructor(); e += test_constructor(); e += test_constructor(); e += test_constructor(); e += test_constructor(); e += test_constructor(); e += test_constructor(); e += test_constructor(); e += test_constructor(); #ifdef BOOST_MATH_USE_FLOAT128 e += test_constructor(); #endif e += test_constructor>(); e += test_constructor>(); e += test_constructor>(); #ifdef BOOST_MATH_USE_FLOAT128 e += test_constructor>(); #endif if (e == 0) std::cout << "PASSED all tests"; else std::cout << "FAILED some test(s)"; std::cout << std::endl << std::endl; return e; } } // namespace test_cpp_double_constructors int main() { int e = 0; e += test_cpp_double_constructors::test_constructors(); e += test_cpp_double_constructors::test_constructors(); e += test_cpp_double_constructors::test_constructors(); #ifdef BOOST_MATH_USE_FLOAT128 e += test_cpp_double_constructors::test_constructors(); #endif return e; }