diff --git a/test/test_convert_from_cpp_int.cpp b/test/test_convert_from_cpp_int.cpp new file mode 100644 index 00000000..1ab65d94 --- /dev/null +++ b/test/test_convert_from_cpp_int.cpp @@ -0,0 +1,220 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2012 John Maddock. 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_ + +#ifdef _MSC_VER +# define _SCL_SECURE_NO_WARNINGS +#endif + +#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; + +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_::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_::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_::is_signed && std::numeric_limits::is_signed>()); + } +} + + +template +void test_convert() +{ + test_convert_imp(number_category::type(), number_category::type()); +} + + +int main() +{ + test_convert(); + test_convert(); + + test_convert(); + test_convert(); + test_convert(); + + test_convert(); + test_convert(); + test_convert(); + + test_convert(); + test_convert(); + test_convert(); + +#if defined(HAS_GMP) + test_convert(); + test_convert(); + test_convert(); + + test_convert(); + test_convert(); + test_convert(); + + test_convert(); + test_convert(); + test_convert(); +#endif +#if defined(HAS_MPFR) + test_convert(); + test_convert(); + test_convert(); +#endif +#if defined(HAS_MPFI) + test_convert(); + test_convert(); + test_convert(); +#endif +#ifdef HAS_TOMMATH + test_convert(); + test_convert(); + test_convert(); + + test_convert(); + test_convert(); + test_convert(); +#endif + return boost::report_errors(); +} +