Skip to content

Commit

Permalink
Small Improvement on GCD (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
cyberjunk committed Mar 24, 2024
1 parent 9decbfe commit 1c24e65
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 19 deletions.
22 changes: 13 additions & 9 deletions include/CppCore.Test/Math/Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
};
}}}
Expand Down
39 changes: 29 additions & 10 deletions include/CppCore/Math/Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -3886,20 +3886,39 @@ namespace CppCore
/// GCD for any size
/// </summary>
template<typename UINT>
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<UINT>(a, x);
CppCore::clone<UINT>(b, y);
while (!CppCore::testzero(b))
CppCore::clone(r, y);

else
{
CppCore::umod<UINT, UINT>(r, a, b, un);
CppCore::clone<UINT>(a, b);
CppCore::clone<UINT>(b, r);
CppCore::clone(r, x);
CppCore::clone(b, y);
while (!CppCore::testzero(b))
{
CppCore::umod<UINT, UINT>(t, r, b, un);
CppCore::clone(r, b);
CppCore::clone(b, t);
}
}
return a;
}

/// <summary>
/// Specialization for uint32_t
/// </summary>
template<> INLINE static void gcd(const uint32_t& x, const uint32_t& y, uint32_t& r)
{
r = CppCore::gcd32(x, y);
}
/// <summary>
/// Specialization for uint64_t
/// </summary>
template<> INLINE static void gcd(const uint64_t& x, const uint64_t& y, uint64_t& r)
{
r = CppCore::gcd64(x, y);
}
}

0 comments on commit 1c24e65

Please sign in to comment.