// (C) Copyright Jeremy Murphy 2015. // Use, modification and distribution are subject to 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) #include #define BOOST_TEST_MAIN #include #include #include #include #include #include #include #include // // Naive implmentation, any fancy versions we create should always agree with this: // template typename boost::enable_if_c::is_signed, T>::type unsigned_abs(T v) { return v < 0 ? -v : v; } template typename boost::disable_if_c::is_signed, T>::type unsigned_abs(T v) { return v; } template T euclid_textbook(T a, T b) { using std::swap; if(a < b) swap(a, b); while(b) { T t = b; b = a % b; a = t; } return unsigned_abs(a); } typedef boost::mpl::list signed_integral_test_types; BOOST_AUTO_TEST_CASE_TEMPLATE(test_zero, T, signed_integral_test_types) { T a = boost::math::gcd(static_cast(2), static_cast(0)); BOOST_CHECK_EQUAL(a, static_cast(2)); a = boost::math::gcd(static_cast(0), static_cast(2)); BOOST_CHECK_EQUAL(a, static_cast(2)); } BOOST_AUTO_TEST_CASE_TEMPLATE(test_signed, T, signed_integral_test_types) { T a = boost::math::gcd(static_cast(-40902), static_cast(-24140)); BOOST_CHECK_EQUAL(a, static_cast(34)); a = boost::math::gcd(static_cast(40902), static_cast(24140)); BOOST_CHECK_EQUAL(a, static_cast(34)); } typedef boost::mpl::list unsigned_integral_test_types; BOOST_AUTO_TEST_CASE_TEMPLATE(test_unsigned, T, unsigned_integral_test_types) { T a = boost::math::gcd(static_cast(40902), static_cast(24140)); BOOST_CHECK_EQUAL(a, static_cast(34)); a = boost::math::gcd(static_cast(1836311903), static_cast(2971215073)); // 46th and 47th Fibonacci numbers. 47th is prime. BOOST_CHECK_EQUAL(a, static_cast(1)); } typedef boost::mpl::list short_signed_integral_test_types; typedef boost::mpl::list short_unsigned_integral_test_types; BOOST_AUTO_TEST_CASE_TEMPLATE(signed_random_test, T, short_signed_integral_test_types) { boost::random::mt19937 gen; boost::uniform_int dist((std::numeric_limits::min)(), (std::numeric_limits::max)()); for(unsigned i = 0; i < 100000; ++i) { T u = dist(gen); T v = dist(gen); BOOST_CHECK_EQUAL(boost::math::gcd(u, v), euclid_textbook(u, v)); } } BOOST_AUTO_TEST_CASE_TEMPLATE(test_random_unsigned, T, short_unsigned_integral_test_types) { boost::random::mt19937 gen; boost::uniform_int dist((std::numeric_limits::min)(), (std::numeric_limits::max)()); for(unsigned i = 0; i < 100000; ++i) { T u = dist(gen); T v = dist(gen); BOOST_CHECK_EQUAL(boost::math::gcd(u, v), euclid_textbook(u, v)); } } BOOST_AUTO_TEST_CASE_TEMPLATE(test_gcd_range, T, unsigned_integral_test_types) { std::vector a; typedef typename std::vector::iterator I; std::pair d; a.push_back(40902); d = boost::math::gcd_range(a.begin(), a.end()); BOOST_CHECK(d == std::make_pair(T(40902), a.end())); a.push_back(24140); d = boost::math::gcd_range(a.begin(), a.end()); BOOST_CHECK(d == std::make_pair(T(34), a.end())); a.push_back(85); d = boost::math::gcd_range(a.begin(), a.end()); BOOST_CHECK(d == std::make_pair(T(17), a.end())); a.push_back(23893); d = boost::math::gcd_range(a.begin(), a.end()); BOOST_CHECK(d == std::make_pair(T(1), a.end())); a.push_back(1024); d = boost::math::gcd_range(a.begin(), a.end()); BOOST_CHECK(d == std::make_pair(T(1), a.end() - 1)); }