forked from organicmaps/organicmaps-tmp
[core] greatest common divisor and tests
This commit is contained in:
parent
3f76c76d04
commit
3587e8ccc9
2 changed files with 55 additions and 0 deletions
|
@ -131,3 +131,13 @@ UNIT_TEST(IsIntersect_Intervals)
|
|||
TEST(my::IsIntersect(0, 100, -50, 0), ());
|
||||
TEST(!my::IsIntersect(0, 100, -50, -20), ());
|
||||
}
|
||||
|
||||
UNIT_TEST(GCD_Test)
|
||||
{
|
||||
TEST_EQUAL(my::GCD(6, 3), 3, ());
|
||||
TEST_EQUAL(my::GCD(14, 7), 7, ());
|
||||
TEST_EQUAL(my::GCD(100, 100), 100, ());
|
||||
TEST_EQUAL(my::GCD(7, 3), 1, ());
|
||||
TEST_EQUAL(my::GCD(8, 3), 1, ());
|
||||
TEST_EQUAL(my::GCD(9, 3), 3, ());
|
||||
}
|
||||
|
|
|
@ -139,4 +139,49 @@ inline uint32_t NextPowOf2(uint32_t v)
|
|||
return v + 1;
|
||||
}
|
||||
|
||||
// Greatest Common Divisor
|
||||
inline uint32_t GCD(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t multiplier = 1;
|
||||
uint32_t gcd = 1;
|
||||
while (true)
|
||||
{
|
||||
if (a == 0 || b == 0)
|
||||
{
|
||||
gcd = max(a, b);
|
||||
break;
|
||||
}
|
||||
|
||||
if (a == 1 || b == 1)
|
||||
{
|
||||
gcd = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((a & 0x1) == 0 && (b & 0x1) == 0)
|
||||
{
|
||||
multiplier <<= 1;
|
||||
a >>= 1;
|
||||
b >>= 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((a & 0x1) != 0 && (b & 0x1) != 0)
|
||||
{
|
||||
uint32_t minV = min(a, b);
|
||||
uint32_t maxV = max(a, b);
|
||||
a = (maxV - minV) >> 1;
|
||||
b = minV;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((a & 0x1) != 0)
|
||||
swap(a, b);
|
||||
|
||||
a >>= 1;
|
||||
}
|
||||
|
||||
return multiplier * gcd;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue