/////////////////////////////////////////////////////////////// // Copyright 2012 John Maddock. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt #ifdef _MSC_VER #define _SCL_SECURE_NO_WARNINGS #endif #if defined(HAS_GMP) #include #include #include #include "test.hpp" #if defined(HAS_GMP) #include #endif #if defined(HAS_MPFR) #include #endif #if defined(HAS_MPFI) #include #endif #ifdef HAS_TOMMATH #include #endif #ifdef HAS_FLOAT128 #include #endif #include #include using namespace boost::multiprecision; #ifdef BOOST_MSVC #pragma warning(disable : 4127) #endif template T generate_random() { typedef int e_type; static boost::random::mt19937 gen; T val = gen(); T prev_val = -1; while (val != prev_val) { val *= (gen.max)(); prev_val = val; val += gen(); } e_type e; val = frexp(val, &e); static boost::random::uniform_int_distribution ui(-20, 20); return ldexp(val, ui(gen)); } template void test_convert_neg_int(From from, const boost::mpl::true_&) { from = -from; To t3(from); To t4 = from.template convert_to(); BOOST_CHECK_EQUAL(From(trunc(from)), From(t3)); BOOST_CHECK_EQUAL(From(trunc(from)), From(t4)); } template void test_convert_neg_int(From const&, const boost::mpl::false_&) { } template void test_convert_imp(boost::mpl::int_ const&, boost::mpl::int_ const&) { for (unsigned i = 0; i < 100; ++i) { From from = generate_random(); To t1(from); To t2 = from.template convert_to(); BOOST_CHECK_EQUAL(From(trunc(from)), From(t1)); BOOST_CHECK_EQUAL(From(trunc(from)), From(t2)); test_convert_neg_int(from, boost::mpl::bool_ < std::numeric_limits::is_signed && std::numeric_limits::is_signed > ()); } } template void test_convert_neg_rat(From from, const boost::mpl::true_&) { from = -from; To t3(from); To t4 = from.template convert_to(); From tol = std::numeric_limits::epsilon(); BOOST_CHECK_CLOSE_FRACTION(From(t3), from, tol); BOOST_CHECK_CLOSE_FRACTION(From(t4), from, tol); } template void test_convert_rat_int(From const&, const boost::mpl::false_&) { } template void test_convert_imp(boost::mpl::int_ const&, boost::mpl::int_ const&) { for (unsigned i = 0; i < 100; ++i) { From from = generate_random(); To t1(from); To t2 = from.template convert_to(); From tol = std::numeric_limits::epsilon(); BOOST_CHECK_CLOSE_FRACTION(From(t1), from, tol); BOOST_CHECK_CLOSE_FRACTION(From(t2), from, tol); test_convert_neg_rat(from, boost::mpl::bool_ < std::numeric_limits::is_signed && std::numeric_limits::is_signed > ()); } } template void test_convert_neg_float(From from, const boost::mpl::true_&) { from = -from; To t3(from); To t4 = from.template convert_to(); To answer(from.str()); To tol = (std::max)(std::numeric_limits::epsilon(), To(std::numeric_limits::epsilon())) * 2; BOOST_CHECK_CLOSE_FRACTION(t3, answer, tol); BOOST_CHECK_CLOSE_FRACTION(t4, answer, tol); } template void test_convert_neg_float(From const&, const boost::mpl::false_&) { } template void test_convert_imp(boost::mpl::int_ const&, boost::mpl::int_ const&) { for (unsigned i = 0; i < 100; ++i) { From from = generate_random(); To t1(from); To t2 = from.template convert_to(); To answer(from.str()); To tol = (std::max)(std::numeric_limits::epsilon(), To(std::numeric_limits::epsilon())) * 2; BOOST_CHECK_CLOSE_FRACTION(t1, answer, tol); BOOST_CHECK_CLOSE_FRACTION(t2, answer, tol); test_convert_neg_float(from, boost::mpl::bool_ < std::numeric_limits::is_signed && std::numeric_limits::is_signed > ()); } } template void test_convert() { test_convert_imp(typename number_category::type(), typename number_category::type()); } int main() { test_convert(); test_convert(); test_convert(); test_convert(); test_convert(); test_convert(); test_convert(); #if defined(HAS_MPFR) test_convert(); #endif #if defined(HAS_MPFI) test_convert(); #endif #ifdef HAS_TOMMATH test_convert(); test_convert(); #endif #ifdef HAS_FLOAT128 test_convert(); #endif return boost::report_errors(); } #else int main() { return 0; } #endif