mirror of
https://github.com/SerenityOS/serenity
synced 2026-04-25 17:15:42 +02:00
Everywhere: Use AK::mod() more, and add a test
The tests show that mod(a, b) takes on the sign of b while a % b takes on the sign of a. As b is usually a positive constant, mod() is useful when you want a guaranteed positive result. mod() matches the semantics of % in Python. Also, mod(a, b) == mod(a, abs(b)) modulo b, while a % b != abs(a) % b modulo b. So mod() makes it easier to get a guaranteed-positive result even if the sign of b is unknown. No behavior change.
This commit is contained in:
@@ -128,6 +128,30 @@ TEST_CASE(mix)
|
||||
EXPECT_APPROXIMATE(mix(b, a, 1.0), 1.0);
|
||||
}
|
||||
|
||||
TEST_CASE(mod)
|
||||
{
|
||||
EXPECT_EQ(mod(5, 3), 2);
|
||||
EXPECT_EQ(mod(-5, 3), 1);
|
||||
EXPECT_EQ(-5 % 3, -2);
|
||||
EXPECT_EQ(mod(5, -3), -1);
|
||||
EXPECT_EQ(5 % -3, 2);
|
||||
EXPECT_EQ(mod(-5, -3), -2);
|
||||
EXPECT_EQ(-5 % -3, -2);
|
||||
|
||||
EXPECT_EQ(mod(4, 2), 0);
|
||||
EXPECT_EQ(mod(-4, 2), 0);
|
||||
EXPECT_EQ(mod(4, -2), 0);
|
||||
EXPECT_EQ(mod(-4, -2), 0);
|
||||
|
||||
EXPECT_EQ(mod(1, 1), 0);
|
||||
EXPECT_EQ(mod(-1, 1), 0);
|
||||
EXPECT_EQ(mod(1, -1), 0);
|
||||
EXPECT_EQ(mod(-1, -1), 0);
|
||||
|
||||
EXPECT_EQ(mod(0, 5), 0);
|
||||
EXPECT_EQ(mod(0, -5), 0);
|
||||
}
|
||||
|
||||
TEST_CASE(swap)
|
||||
{
|
||||
int i = 4;
|
||||
|
||||
@@ -119,11 +119,6 @@ static inline BigAllocator (&big_allocators())[1]
|
||||
// chunk. It has no bearing on the rest of the allocator, especially for
|
||||
// regular malloc.
|
||||
|
||||
static inline unsigned long modulo(long a, long b)
|
||||
{
|
||||
return (b + (a % b)) % b;
|
||||
}
|
||||
|
||||
struct EuclideanResult {
|
||||
long x;
|
||||
long y;
|
||||
@@ -160,12 +155,12 @@ static inline bool block_has_aligned_chunk(long align, long bytes_per_chunk, lon
|
||||
|
||||
// Solve the linear congruence n*bytes_per_chunk = -sizeof(ChunkedBlock) (mod align).
|
||||
auto [x, y, gcd] = extended_euclid(bytes_per_chunk % align, align);
|
||||
long constant = modulo(-sizeof(ChunkedBlock), align);
|
||||
long constant = mod(-sizeof(ChunkedBlock), align);
|
||||
if (constant % gcd != 0)
|
||||
// No solution. Chunk size is probably a multiple of align.
|
||||
return false;
|
||||
|
||||
long n = modulo(x * (constant / gcd), align);
|
||||
long n = mod(x * (constant / gcd), align);
|
||||
if (x < 0)
|
||||
n = (n + align / gcd) % align;
|
||||
|
||||
|
||||
@@ -157,10 +157,6 @@ static struct tm* time_to_tm(struct tm* tm, time_t t, StringView time_zone)
|
||||
tm->tm_wday = day_of_week(year, month, tm->tm_mday);
|
||||
tm->tm_mon = month - 1;
|
||||
|
||||
auto mod = [](i64 a, i64 b) {
|
||||
return (a % b + b) % b;
|
||||
};
|
||||
|
||||
t = mod(t, __seconds_per_day);
|
||||
|
||||
VERIFY(t >= 0);
|
||||
|
||||
@@ -108,8 +108,7 @@ public:
|
||||
auto current_loc = loc + m_start_offset;
|
||||
auto gradient_len = static_cast<i64>(m_gradient_line_colors.size());
|
||||
if (m_repeat_mode == RepeatMode::Repeat) {
|
||||
auto color_loc = current_loc % gradient_len;
|
||||
return color_loc < 0 ? gradient_len + color_loc : color_loc;
|
||||
return mod(current_loc, gradient_len);
|
||||
} else if (m_repeat_mode == RepeatMode::Reflect) {
|
||||
auto color_loc = AK::abs(current_loc % gradient_len);
|
||||
auto repeats = current_loc / gradient_len;
|
||||
|
||||
@@ -259,9 +259,6 @@ inline void _1D_EXTR(Transformation transformation, IDWTOutput& a, int start, in
|
||||
// (F-4)
|
||||
// PSE is short for "Period Symmetric Extension".
|
||||
auto PSE = [](int i, int i0, int i1) {
|
||||
auto mod = [](int a, int b) {
|
||||
return (a % b + b) % b;
|
||||
};
|
||||
return i0 + min(mod(i - i0, 2 * (i1 - i0 - 1)), 2 * (i1 - i0 - 1) - mod(i - i0, 2 * (i1 - i0 - 1)));
|
||||
};
|
||||
|
||||
|
||||
@@ -301,7 +301,7 @@ auto modulo(T x, U y)
|
||||
auto r = fmod(x, y);
|
||||
return r < 0 ? r + y : r;
|
||||
} else {
|
||||
return ((x % y) + y) % y;
|
||||
return AK::mod(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -112,9 +112,7 @@ void WindowSwitcher::on_key_event(KeyEvent const& event)
|
||||
if (!event.shift()) {
|
||||
new_selected_index = (m_selected_index + 1) % static_cast<int>(m_windows.size());
|
||||
} else {
|
||||
new_selected_index = (m_selected_index - 1) % static_cast<int>(m_windows.size());
|
||||
if (new_selected_index < 0)
|
||||
new_selected_index = static_cast<int>(m_windows.size()) - 1;
|
||||
new_selected_index = mod(m_selected_index - 1, static_cast<int>(m_windows.size()));
|
||||
}
|
||||
VERIFY(new_selected_index < static_cast<int>(m_windows.size()));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user