mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-25 18:10:21 -04:00 
			
		
		
		
	
		
			
	
	
		
			126 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			126 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|  | //  (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 <boost/config.hpp>
 | ||
|  | #define BOOST_TEST_MAIN
 | ||
|  | #include <boost/array.hpp>
 | ||
|  | #include <boost/math/common_factor_rt.hpp>
 | ||
|  | #include <boost/mpl/list.hpp>
 | ||
|  | #include <boost/test/test_case_template.hpp>
 | ||
|  | #include <boost/test/unit_test.hpp>
 | ||
|  | #include <boost/multiprecision/cpp_int.hpp>
 | ||
|  | #include <utility>
 | ||
|  | #include <boost/random.hpp>
 | ||
|  | 
 | ||
|  | //
 | ||
|  | // Naive implmentation, any fancy versions we create should always agree with this:
 | ||
|  | //
 | ||
|  | template <class T> | ||
|  | typename boost::enable_if_c<std::numeric_limits<T>::is_signed, T>::type unsigned_abs(T v) { return v < 0 ? -v : v; } | ||
|  | template <class T> | ||
|  | typename boost::disable_if_c<std::numeric_limits<T>::is_signed, T>::type unsigned_abs(T v) { return v; } | ||
|  | 
 | ||
|  | template <class T> | ||
|  | 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<boost::int32_t | ||
|  | #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1500)
 | ||
|  |    , boost::int64_t, boost::multiprecision::cpp_int | ||
|  | #endif
 | ||
|  | > signed_integral_test_types; | ||
|  | 
 | ||
|  | BOOST_AUTO_TEST_CASE_TEMPLATE(test_zero, T, signed_integral_test_types) | ||
|  | { | ||
|  |     T a = boost::math::gcd(static_cast<T>(2), static_cast<T>(0)); | ||
|  |     BOOST_CHECK_EQUAL(a, static_cast<T>(2)); | ||
|  |     a = boost::math::gcd(static_cast<T>(0), static_cast<T>(2)); | ||
|  |     BOOST_CHECK_EQUAL(a, static_cast<T>(2)); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | BOOST_AUTO_TEST_CASE_TEMPLATE(test_signed, T, signed_integral_test_types) | ||
|  | { | ||
|  |     T a = boost::math::gcd(static_cast<T>(-40902), static_cast<T>(-24140)); | ||
|  |     BOOST_CHECK_EQUAL(a, static_cast<T>(34)); | ||
|  |     a = boost::math::gcd(static_cast<T>(40902), static_cast<T>(24140)); | ||
|  |     BOOST_CHECK_EQUAL(a, static_cast<T>(34)); | ||
|  | } | ||
|  | 
 | ||
|  | typedef boost::mpl::list<boost::uint32_t | ||
|  | #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1500)
 | ||
|  |    , boost::uint64_t, boost::multiprecision::uint256_t | ||
|  | #endif
 | ||
|  | > unsigned_integral_test_types; | ||
|  | 
 | ||
|  | BOOST_AUTO_TEST_CASE_TEMPLATE(test_unsigned, T, unsigned_integral_test_types) | ||
|  | { | ||
|  |     T a = boost::math::gcd(static_cast<T>(40902), static_cast<T>(24140)); | ||
|  |     BOOST_CHECK_EQUAL(a, static_cast<T>(34)); | ||
|  |     a = boost::math::gcd(static_cast<T>(1836311903), static_cast<T>(2971215073)); // 46th and 47th Fibonacci numbers. 47th is prime.
 | ||
|  |     BOOST_CHECK_EQUAL(a, static_cast<T>(1)); | ||
|  | } | ||
|  | 
 | ||
|  | typedef boost::mpl::list<boost::int32_t, boost::int64_t> short_signed_integral_test_types; | ||
|  | typedef boost::mpl::list<boost::uint32_t, boost::uint64_t> 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<T> dist((std::numeric_limits<T>::min)(), (std::numeric_limits<T>::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<T> dist((std::numeric_limits<T>::min)(), (std::numeric_limits<T>::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<T> a; | ||
|  |     typedef typename std::vector<T>::iterator I; | ||
|  |     std::pair<T, I> 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)); | ||
|  | } |