mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 03:55:24 +00:00
AK: Add lowest common multiple and greatest common divisor functions
This commit is contained in:
parent
f4bb3a82cf
commit
465b7ebd04
2 changed files with 90 additions and 0 deletions
|
@ -85,4 +85,61 @@ constexpr T reinterpret_as_octal(T decimal)
|
|||
return result;
|
||||
}
|
||||
|
||||
template<Unsigned T>
|
||||
constexpr T gcd(T x, T y)
|
||||
{
|
||||
if (x == 0)
|
||||
return y;
|
||||
if (y == 0)
|
||||
return x;
|
||||
|
||||
int shift = 0;
|
||||
while (((x | y) & 1) == 0) {
|
||||
x >>= 1;
|
||||
y >>= 1;
|
||||
shift++;
|
||||
}
|
||||
|
||||
while (x != y) {
|
||||
if (x & 1) {
|
||||
if (y & 1) {
|
||||
if (x > y)
|
||||
x -= y;
|
||||
else
|
||||
y -= x;
|
||||
} else {
|
||||
y >>= 1;
|
||||
}
|
||||
} else {
|
||||
x >>= 1;
|
||||
if (y & 1) {
|
||||
if (x < y)
|
||||
swap(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return x << shift;
|
||||
}
|
||||
|
||||
template<Signed T>
|
||||
constexpr T gcd(T x, T y)
|
||||
{
|
||||
return gcd(static_cast<MakeUnsigned<T>>(abs(x)), static_cast<MakeUnsigned<T>>(abs(y)));
|
||||
}
|
||||
|
||||
template<Unsigned T>
|
||||
constexpr T lcm(T x, T y)
|
||||
{
|
||||
if (x == 0 || y == 0)
|
||||
return 0;
|
||||
return x / gcd(x, y) * y;
|
||||
}
|
||||
|
||||
template<Signed T>
|
||||
constexpr T lcm(T x, T y)
|
||||
{
|
||||
return lcm(static_cast<MakeUnsigned<T>>(abs(x)), static_cast<MakeUnsigned<T>>(abs(y)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -131,3 +131,36 @@ TEST_CASE(clamp_to)
|
|||
EXPECT_EQ(AK::clamp_to<i64>(-9223372036854775808.0), NumericLimits<i64>::min());
|
||||
EXPECT_EQ(AK::clamp_to<i64>(9223372036854775807.0), NumericLimits<i64>::max());
|
||||
}
|
||||
|
||||
TEST_CASE(gcd)
|
||||
{
|
||||
EXPECT_EQ(AK::gcd(0, 0), 0);
|
||||
EXPECT_EQ(AK::gcd(1, 1), 1);
|
||||
EXPECT_EQ(AK::gcd(0, 2), 2);
|
||||
EXPECT_EQ(AK::gcd(2, 0), 2);
|
||||
EXPECT_EQ(AK::gcd(8, 12), 4);
|
||||
EXPECT_EQ(AK::gcd(17, 23), 1);
|
||||
EXPECT_EQ(AK::gcd(48, 36), 12);
|
||||
EXPECT_EQ(AK::gcd(-8, 12), 4);
|
||||
EXPECT_EQ(AK::gcd(8, -12), 4);
|
||||
EXPECT_EQ(AK::gcd(-8, -12), 4);
|
||||
EXPECT_EQ(AK::gcd(100, 100), 100);
|
||||
EXPECT_EQ(AK::gcd(13, 1), 1);
|
||||
EXPECT_EQ(AK::gcd(-NumericLimits<i32>::max(), NumericLimits<i32>::max()), NumericLimits<i32>::max());
|
||||
}
|
||||
|
||||
TEST_CASE(lcm)
|
||||
{
|
||||
EXPECT_EQ(AK::lcm(0, 0), 0);
|
||||
EXPECT_EQ(AK::lcm(0, 5), 0);
|
||||
EXPECT_EQ(AK::lcm(5, 0), 0);
|
||||
EXPECT_EQ(AK::lcm(1, 1), 1);
|
||||
EXPECT_EQ(AK::lcm(4, 6), 12);
|
||||
EXPECT_EQ(AK::lcm(7, 13), 91);
|
||||
EXPECT_EQ(AK::lcm(12, 18), 36);
|
||||
EXPECT_EQ(AK::lcm(-4, 6), 12);
|
||||
EXPECT_EQ(AK::lcm(4, -6), 12);
|
||||
EXPECT_EQ(AK::lcm(-4, -6), 12);
|
||||
EXPECT_EQ(AK::lcm(10, 10), 10);
|
||||
EXPECT_EQ(AK::lcm(1, 8), 8);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue