/////////////////////////////////////////////////////////////// // 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_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(unsigned bits_wanted) { static boost::random::mt19937 gen; typedef boost::random::mt19937::result_type random_type; T max_val; unsigned digits; if (std::numeric_limits::is_bounded && (bits_wanted == (unsigned)std::numeric_limits::digits)) { max_val = (std::numeric_limits::max)(); digits = std::numeric_limits::digits; } else { max_val = T(1) << bits_wanted; digits = bits_wanted; } unsigned bits_per_r_val = std::numeric_limits::digits - 1; while ((random_type(1) << bits_per_r_val) > (gen.max)()) --bits_per_r_val; unsigned terms_needed = digits / bits_per_r_val + 1; T val = 0; for (unsigned i = 0; i < terms_needed; ++i) { val *= (gen.max)(); val += gen(); } val %= max_val; return val; } 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.str(), t3.str()); BOOST_CHECK_EQUAL(from.str(), t4.str()); } 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&) { int bits_wanted = (std::min)((std::min)(std::numeric_limits::digits, std::numeric_limits::digits), 2000); for (unsigned i = 0; i < 100; ++i) { From from = generate_random(bits_wanted); To t1(from); To t2 = from.template convert_to(); BOOST_CHECK_EQUAL(from.str(), t1.str()); BOOST_CHECK_EQUAL(from.str(), t2.str()); 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(); BOOST_CHECK_EQUAL(from.str(), numerator(t3).str()); BOOST_CHECK_EQUAL(from.str(), numerator(t4).str()); } template void test_convert_neg_rat(From const&, const boost::mpl::false_&) { } template void test_convert_imp(boost::mpl::int_ const&, boost::mpl::int_ const&) { int bits_wanted = (std::min)((std::min)(std::numeric_limits::digits, std::numeric_limits::digits), 2000); for (unsigned i = 0; i < 100; ++i) { From from = generate_random(bits_wanted); To t1(from); To t2 = from.template convert_to(); BOOST_CHECK_EQUAL(from.str(), numerator(t1).str()); BOOST_CHECK_EQUAL(from.str(), numerator(t2).str()); 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 check(from.str() + ".0"); BOOST_CHECK_EQUAL(t3, check); BOOST_CHECK_EQUAL(t4, check); } 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&) { int bits_wanted = (std::min)((std::min)(std::numeric_limits::digits, std::numeric_limits::digits), 2000); for (unsigned i = 0; i < 100; ++i) { From from = generate_random(bits_wanted); To t1(from); To t2 = from.template convert_to(); To check(from.str() + ".0"); BOOST_CHECK_EQUAL(t1, check); BOOST_CHECK_EQUAL(t2, check); 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(); 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