/////////////////////////////////////////////////////////////// // Copyright 2017 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 // // Check results of truncated overflow. // #ifdef _MSC_VER #define _SCL_SECURE_NO_WARNINGS #endif #include #include "test.hpp" #include #include 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() { using namespace boost::multiprecision; typedef Number test_type; for (unsigned i = 30; i < std::numeric_limits::digits; ++i) { for (unsigned j = std::numeric_limits::digits - i - 1; j < std::numeric_limits::digits; ++j) { for (unsigned k = 0; k < 10; ++k) { test_type a = static_cast(generate_random(i)); test_type b = static_cast(generate_random(j)); test_type c = static_cast(cpp_int(a) * cpp_int(b)); test_type d = a * b; BOOST_CHECK_EQUAL(c, d); if ((k == 0) && (j == 0)) { for (unsigned s = 1; s < std::numeric_limits::digits; ++s) BOOST_CHECK_EQUAL(a << s, test_type(cpp_int(a) << s)); } } } } } int main() { using namespace boost::multiprecision; test(); test(); // // We also need to test type with "odd" bit counts in order to ensure full code coverage: // test > >(); test > >(); test > >(); test > >(); return boost::report_errors(); }