How to Ensure That a Division of Integers Is Always Rounded Up

How can I ensure that a division of integers is always rounded up?

UPDATE: This question was the subject of my blog in January 2013. Thanks for the great question!


Getting integer arithmetic correct is hard. As has been demonstrated amply thus far, the moment you try to do a "clever" trick, odds are good that you've made a mistake. And when a flaw is found, changing the code to fix the flaw without considering whether the fix breaks something else is not a good problem-solving technique. So far we've had I think five different incorrect integer arithmetic solutions to this completely not-particularly-difficult problem posted.

The right way to approach integer arithmetic problems -- that is, the way that increases the likelihood of getting the answer right the first time - is to approach the problem carefully, solve it one step at a time, and use good engineering principles in doing so.

Start by reading the specification for what you're trying to replace. The specification for integer division clearly states:

  1. The division rounds the result towards zero

  2. The result is zero or positive when the two operands have the same sign and zero or negative when the two operands have opposite signs

  3. If the left operand is the smallest representable int and the right operand is –1, an overflow occurs. [...] it is implementation-defined as to whether [an ArithmeticException] is thrown or the overflow goes unreported with the resulting value being that of the left operand.

  4. If the value of the right operand is zero, a System.DivideByZeroException is thrown.

What we want is an integer division function which computes the quotient but rounds the result always upwards, not always towards zero.

So write a specification for that function. Our function int DivRoundUp(int dividend, int divisor) must have behaviour defined for every possible input. That undefined behaviour is deeply worrying, so let's eliminate it. We'll say that our operation has this specification:

  1. operation throws if divisor is zero

  2. operation throws if dividend is int.minval and divisor is -1

  3. if there is no remainder -- division is 'even' -- then the return value is the integral quotient

  4. Otherwise it returns the smallest integer that is greater than the quotient, that is, it always rounds up.

Now we have a specification, so we know we can come up with a testable design. Suppose we add an additional design criterion that the problem be solved solely with integer arithmetic, rather than computing the quotient as a double, since the "double" solution has been explicitly rejected in the problem statement.

So what must we compute? Clearly, to meet our spec while remaining solely in integer arithmetic, we need to know three facts. First, what was the integer quotient? Second, was the division free of remainder? And third, if not, was the integer quotient computed by rounding up or down?

Now that we have a specification and a design, we can start writing code.

public static int DivRoundUp(int dividend, int divisor)
{
if (divisor == 0 ) throw ...
if (divisor == -1 && dividend == Int32.MinValue) throw ...
int roundedTowardsZeroQuotient = dividend / divisor;
bool dividedEvenly = (dividend % divisor) == 0;
if (dividedEvenly)
return roundedTowardsZeroQuotient;

// At this point we know that divisor was not zero
// (because we would have thrown) and we know that
// dividend was not zero (because there would have been no remainder)
// Therefore both are non-zero. Either they are of the same sign,
// or opposite signs. If they're of opposite sign then we rounded
// UP towards zero so we're done. If they're of the same sign then
// we rounded DOWN towards zero, so we need to add one.

bool wasRoundedDown = ((divisor > 0) == (dividend > 0));
if (wasRoundedDown)
return roundedTowardsZeroQuotient + 1;
else
return roundedTowardsZeroQuotient;
}

Is this clever? No. Beautiful? No. Short? No. Correct according to the specification? I believe so, but I have not fully tested it. It looks pretty good though.

We're professionals here; use good engineering practices. Research your tools, specify the desired behaviour, consider error cases first, and write the code to emphasize its obvious correctness. And when you find a bug, consider whether your algorithm is deeply flawed to begin with before you just randomly start swapping the directions of comparisons around and break stuff that already works.

How to round up the result of integer division?

Found an elegant solution:

int pageCount = (records + recordsPerPage - 1) / recordsPerPage;

Source: Number Conversion, Roland Backhouse, 2001

Rounding integer division (instead of truncating)


int a = 59.0f / 4.0f + 0.5f;

This only works when assigning to an int as it discards anything after the '.'

Edit:
This solution will only work in the simplest of cases. A more robust solution would be:

unsigned int round_closest(unsigned int dividend, unsigned int divisor)
{
return (dividend + (divisor / 2)) / divisor;
}

Dividing two integers and rounding up result to nearest integer

Since a and b are integers, a/b will use integer division, and only return the "whole" part of the result. Instead, you should multiply a by 100.0 (note the .0, which makes it a double literal!) to use floating-point division, and then ceil the result, and truncate it to an int:

c = (int) Math.ceil(100.0 * a / b);

How to round up integer division and have int result in Java?

To round up an integer division you can use

import static java.lang.Math.abs;

public static long roundUp(long num, long divisor) {
int sign = (num > 0 ? 1 : -1) * (divisor > 0 ? 1 : -1);
return sign * (abs(num) + abs(divisor) - 1) / abs(divisor);
}

or if both numbers are positive

public static long roundUp(long num, long divisor) {
return (num + divisor - 1) / divisor;
}

What is the right way to round dividing to integers?

Since all the integers in your example are positive, I'll assume that you are not interested in the case where one or both operands are negative or zero.

Math.Round works on floating-point numbers. That is not necessary here.

Dividing two integers gives an integer result. It always rounds down. You want something like this:

int Divide(int numerator, int denominator) {
return (numerator + denominator - 1) / denominator;
}

For example,for 1/4, we get (1 + 4 - 1) / 4 = 4 / 4 = 1, and for 8/4 we get (8 + 4 - 1) / 4 = 11 / 4 = 2.

There's a very slight possibility of overflow here, so if the numerator is always greater than zero, it's better to use:

int Divide(int numerator, int denominator) {
return 1 + (numerator - 1) / denominator;
}

how to always round up to the next integer


Math.Ceiling((double)list.Count() / 10);


Related Topics



Leave a reply



Submit