Skip to content

Commit

Permalink
AK: Make ceil_div() handle one argument being negative correctly
Browse files Browse the repository at this point in the history
`ceil_div(-1, 2)` used to return -1.
Now it returns 0, which is the correct ceil(-0.5).

(C++'s division semantics have floor semantics for numbers > 0,
but ceil semantics for numbers < 0.)

This will be important for the JPEG2000 decoder eventually.
  • Loading branch information
nico committed Apr 26, 2024
1 parent 44f073b commit 8bc3158
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
2 changes: 1 addition & 1 deletion AK/StdLibExtras.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ constexpr T ceil_div(T a, U b)
{
static_assert(sizeof(T) == sizeof(U));
T result = a / b;
if ((a % b) != 0)
if ((a % b) != 0 && (a > 0) == (b > 0))
++result;
return result;
}
Expand Down
36 changes: 36 additions & 0 deletions Tests/AK/TestStdLibExtras.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,47 @@ TEST_CASE(ceil_div)
EXPECT_EQ(ceil_div(3, 1), 3);
EXPECT_EQ(ceil_div(4, 1), 4);

EXPECT_EQ(ceil_div(-0, 1), 0);
EXPECT_EQ(ceil_div(-1, 1), -1);
EXPECT_EQ(ceil_div(-2, 1), -2);
EXPECT_EQ(ceil_div(-3, 1), -3);
EXPECT_EQ(ceil_div(-4, 1), -4);

EXPECT_EQ(ceil_div(0, -1), 0);
EXPECT_EQ(ceil_div(1, -1), -1);
EXPECT_EQ(ceil_div(2, -1), -2);
EXPECT_EQ(ceil_div(3, -1), -3);
EXPECT_EQ(ceil_div(4, -1), -4);

EXPECT_EQ(ceil_div(-0, -1), 0);
EXPECT_EQ(ceil_div(-1, -1), 1);
EXPECT_EQ(ceil_div(-2, -1), 2);
EXPECT_EQ(ceil_div(-3, -1), 3);
EXPECT_EQ(ceil_div(-4, -1), 4);

EXPECT_EQ(ceil_div(0, 2), 0);
EXPECT_EQ(ceil_div(1, 2), 1);
EXPECT_EQ(ceil_div(2, 2), 1);
EXPECT_EQ(ceil_div(3, 2), 2);
EXPECT_EQ(ceil_div(4, 2), 2);

EXPECT_EQ(ceil_div(-0, 2), 0);
EXPECT_EQ(ceil_div(-1, 2), 0);
EXPECT_EQ(ceil_div(-2, 2), -1);
EXPECT_EQ(ceil_div(-3, 2), -1);
EXPECT_EQ(ceil_div(-4, 2), -2);

EXPECT_EQ(ceil_div(0, -2), 0);
EXPECT_EQ(ceil_div(1, -2), 0);
EXPECT_EQ(ceil_div(2, -2), -1);
EXPECT_EQ(ceil_div(3, -2), -1);
EXPECT_EQ(ceil_div(4, -2), -2);

EXPECT_EQ(ceil_div(-0, -2), 0);
EXPECT_EQ(ceil_div(-1, -2), 1);
EXPECT_EQ(ceil_div(-2, -2), 1);
EXPECT_EQ(ceil_div(-3, -2), 2);
EXPECT_EQ(ceil_div(-4, -2), 2);
}

TEST_CASE(mix)
Expand Down

0 comments on commit 8bc3158

Please sign in to comment.