AK: Make ceil_div() handle one argument being negative correctly

`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.
This commit is contained in:
Nico Weber 2024-04-26 17:57:35 -04:00 committed by Andreas Kling
parent f2ebad11a8
commit 88d0702763
Notes: sideshowbarker 2024-07-17 02:38:39 +09:00
2 changed files with 37 additions and 1 deletions

View file

@ -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;
}

View file

@ -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)