mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-16 09:01:59 -05: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));
|
||
|
}
|