From 1c24e65aa9735e8d775cc3d3fec3324d89c59672 Mon Sep 17 00:00:00 2001 From: Clint Banzhaf Date: Sun, 24 Mar 2024 18:38:38 +0100 Subject: [PATCH] Small Improvement on GCD (#77) --- include/CppCore.Test/Math/Util.h | 22 ++++++++++-------- include/CppCore/Math/Util.h | 39 ++++++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/include/CppCore.Test/Math/Util.h b/include/CppCore.Test/Math/Util.h index 507c893d..65b61bec 100644 --- a/include/CppCore.Test/Math/Util.h +++ b/include/CppCore.Test/Math/Util.h @@ -1448,18 +1448,22 @@ namespace CppCore { namespace Test { namespace Math INLINE static bool gcd() { + uint128_t r; + + CppCore::gcd(uint128_t(0), uint128_t(0), r); if (r != 0U) return false; + CppCore::gcd(uint128_t(1), uint128_t(0), r); if (r != 1U) return false; + CppCore::gcd(uint128_t(7), uint128_t(5), r); if (r != 1U) return false; + CppCore::gcd(uint128_t(20), uint128_t(16), r); if (r != 4U) return false; + + CppCore::gcd(uint128_t(CppCore::Primes::MERSENNE128), uint128_t(CppCore::Primes::LARGE128), r); + if (r != 1U) return false; + const uint128_t l1 = uint128_t("2687293461875176346985679234"); const uint128_t l2 = l1 * 3; + CppCore::gcd(l1, l2, r); + if (r != l1) return false; - bool t128 = - CppCore::gcd(uint128_t(0), uint128_t(0)) == 0U && - CppCore::gcd(uint128_t(1), uint128_t(0)) == 1U && - CppCore::gcd(uint128_t(7), uint128_t(5)) == 1U && - CppCore::gcd(uint128_t(20), uint128_t(16)) == 4U && - CppCore::gcd(uint128_t(CppCore::Primes::MERSENNE128), uint128_t(CppCore::Primes::LARGE128)) == 1U && - CppCore::gcd(l1, l2) == l1; - - return t128; + return true; } }; }}} diff --git a/include/CppCore/Math/Util.h b/include/CppCore/Math/Util.h index 540f024a..2ba9fc43 100644 --- a/include/CppCore/Math/Util.h +++ b/include/CppCore/Math/Util.h @@ -3886,20 +3886,39 @@ namespace CppCore /// GCD for any size /// template - INLINE static UINT gcd(const UINT& x, const UINT& y) + INLINE static void gcd(const UINT& x, const UINT& y, UINT& r) { - UINT a, b, r; + UINT b, t; UINT un[2]; + if (CppCore::testzero(x)) - return y; - CppCore::clone(a, x); - CppCore::clone(b, y); - while (!CppCore::testzero(b)) + CppCore::clone(r, y); + + else { - CppCore::umod(r, a, b, un); - CppCore::clone(a, b); - CppCore::clone(b, r); + CppCore::clone(r, x); + CppCore::clone(b, y); + while (!CppCore::testzero(b)) + { + CppCore::umod(t, r, b, un); + CppCore::clone(r, b); + CppCore::clone(b, t); + } } - return a; + } + + /// + /// Specialization for uint32_t + /// + template<> INLINE static void gcd(const uint32_t& x, const uint32_t& y, uint32_t& r) + { + r = CppCore::gcd32(x, y); + } + /// + /// Specialization for uint64_t + /// + template<> INLINE static void gcd(const uint64_t& x, const uint64_t& y, uint64_t& r) + { + r = CppCore::gcd64(x, y); } }