Skip to content

Commit

Permalink
[numeric] Introduce divideRoundUp() for integer division with rounding
Browse files Browse the repository at this point in the history
  • Loading branch information
p12tic committed Oct 2, 2022
1 parent 3d8ec2a commit 392a66b
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/aliceVision/numeric/numeric.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,20 @@ void SplitRange(const T range_start, const T range_end, const int nb_split,
}
}

template<class T>
T divideRoundUp(T x, T y)
{
static_assert(std::is_integral<T>::value, "divideRoundUp only works with integer arguments");
auto xPos = x >= 0;
auto yPos = y >= 0;
if (xPos == yPos) {
return x / y + ((x % y) != 0 ? 1 : 0);
} else {
// negative result, rounds towards zero anywaya
return x / y;
}
}

/**
* This function initializes the global state of random number generators that e.g. our tests
* depend on. This makes it possible to have exactly reproducible program runtime behavior
Expand Down
61 changes: 61 additions & 0 deletions src/aliceVision/numeric/numeric_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,64 @@ BOOST_AUTO_TEST_CASE(Numeric_MeanAndVarianceAlongRows) {
BOOST_CHECK_SMALL(0.25-variance(0), 1e-8);
BOOST_CHECK_SMALL(1.25-variance(1), 1e-8);
}

BOOST_AUTO_TEST_CASE(Numeric_divideRoundUp)
{
BOOST_CHECK_EQUAL(divideRoundUp(0, 1), 0);
BOOST_CHECK_EQUAL(divideRoundUp(1, 1), 1);
BOOST_CHECK_EQUAL(divideRoundUp(2, 1), 2);
BOOST_CHECK_EQUAL(divideRoundUp(0, 2), 0);
BOOST_CHECK_EQUAL(divideRoundUp(1, 2), 1);
BOOST_CHECK_EQUAL(divideRoundUp(2, 2), 1);
BOOST_CHECK_EQUAL(divideRoundUp(3, 2), 2);
BOOST_CHECK_EQUAL(divideRoundUp(4, 2), 2);
BOOST_CHECK_EQUAL(divideRoundUp(999, 1000), 1);
BOOST_CHECK_EQUAL(divideRoundUp(1000, 1000), 1);
BOOST_CHECK_EQUAL(divideRoundUp(1001, 1000), 2);
BOOST_CHECK_EQUAL(divideRoundUp(1000999, 1000), 1001);
BOOST_CHECK_EQUAL(divideRoundUp(1001000, 1000), 1001);
BOOST_CHECK_EQUAL(divideRoundUp(1001001, 1000), 1002);

BOOST_CHECK_EQUAL(divideRoundUp(-1, 1), -1);
BOOST_CHECK_EQUAL(divideRoundUp(-2, 1), -2);
BOOST_CHECK_EQUAL(divideRoundUp(-0, 2), 0);
BOOST_CHECK_EQUAL(divideRoundUp(-1, 2), 0);
BOOST_CHECK_EQUAL(divideRoundUp(-2, 2), -1);
BOOST_CHECK_EQUAL(divideRoundUp(-3, 2), -1);
BOOST_CHECK_EQUAL(divideRoundUp(-4, 2), -2);
BOOST_CHECK_EQUAL(divideRoundUp(-999, 1000), 0);
BOOST_CHECK_EQUAL(divideRoundUp(-1000, 1000), -1);
BOOST_CHECK_EQUAL(divideRoundUp(-1001, 1000), -1);
BOOST_CHECK_EQUAL(divideRoundUp(-1000999, 1000), -1000);
BOOST_CHECK_EQUAL(divideRoundUp(-1001000, 1000), -1001);
BOOST_CHECK_EQUAL(divideRoundUp(-1001001, 1000), -1001);

BOOST_CHECK_EQUAL(divideRoundUp(0, -1), 0);
BOOST_CHECK_EQUAL(divideRoundUp(1, -1), -1);
BOOST_CHECK_EQUAL(divideRoundUp(2, -1), -2);
BOOST_CHECK_EQUAL(divideRoundUp(0, -2), 0);
BOOST_CHECK_EQUAL(divideRoundUp(1, -2), 0);
BOOST_CHECK_EQUAL(divideRoundUp(2, -2), -1);
BOOST_CHECK_EQUAL(divideRoundUp(3, -2), -1);
BOOST_CHECK_EQUAL(divideRoundUp(4, -2), -2);
BOOST_CHECK_EQUAL(divideRoundUp(999, -1000), 0);
BOOST_CHECK_EQUAL(divideRoundUp(1000, -1000), -1);
BOOST_CHECK_EQUAL(divideRoundUp(1001, -1000), -1);
BOOST_CHECK_EQUAL(divideRoundUp(1000999, -1000), -1000);
BOOST_CHECK_EQUAL(divideRoundUp(1001000, -1000), -1001);
BOOST_CHECK_EQUAL(divideRoundUp(1001001, -1000), -1001);

BOOST_CHECK_EQUAL(divideRoundUp(-1, -1), 1);
BOOST_CHECK_EQUAL(divideRoundUp(-2, -1), 2);
BOOST_CHECK_EQUAL(divideRoundUp(0, -2), 0);
BOOST_CHECK_EQUAL(divideRoundUp(-1, -2), 1);
BOOST_CHECK_EQUAL(divideRoundUp(-2, -2), 1);
BOOST_CHECK_EQUAL(divideRoundUp(-3, -2), 2);
BOOST_CHECK_EQUAL(divideRoundUp(-4, -2), 2);
BOOST_CHECK_EQUAL(divideRoundUp(-999, -1000), 1);
BOOST_CHECK_EQUAL(divideRoundUp(-1000, -1000), 1);
BOOST_CHECK_EQUAL(divideRoundUp(-1001, -1000), 2);
BOOST_CHECK_EQUAL(divideRoundUp(-1000999, -1000), 1001);
BOOST_CHECK_EQUAL(divideRoundUp(-1001000, -1000), 1001);
BOOST_CHECK_EQUAL(divideRoundUp(-1001001, -1000), 1002);
}

0 comments on commit 392a66b

Please sign in to comment.