This other day I came across an interesting line of code in the Linux kernel. So, there are two integers n and d. As a programmer, how do you divide them and apply a ceiling function(rounding up) on the result of the division? The most direct approach, would be a function like this:

int div_and_ceil(int n, int d)

{

if(n%d == 0)

return (n/d);

else

return (n/d + 1);

} /* Remember that n and d are integers and n/d in the context of C code will always give an integer result */

But, what we have in the kernel source code for this, is the following macro defined in /include/linux/kernel.h:

#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))

It is important here that n and d be integers or this formula fails. Before you read further, I would encourage you to give a thought on how this formula works. Turns out this is a simple mathematical logic employed combining the division and the ceiling operations.

Let us break down the operation. What does ceiling on a number give? When the number has a non-zero decimal part, you get the next integer; otherwise you get the same number.

Doing a division of n by d would give a non-zero decimal result when the dividend n is not an integer multiple of the divisor d; in other words, the remainder is non-zero.

For example,

Illustrating the relationships between the ceiling function, the remainder and the quotient.

So, a ceiling on the result of integer division requires us to add 1 to the quotient when the remainder is non-zero. To achieve this, we need to add a number to the dividend so that the quotient remains the same when the remainder is zero and the quotient increases by 1 when the remainder is non-zero.

This ‘special’ number turns out to be (d-1). Let’s see what happens when we add (d-1) to the dividend n.

Since the remainder r is never greater than the divisor d,

0 ≤ r < d

adding (d-1), gives a new remainder r’

d-1 ≤ r' < 2d- 1

Case 1: When r is zero,

On adding (d-1), the new remainder r’ becomes (d-1). And since it’s an integer division (d-1/d) is zero. So, you get the quotient as it is.

Case 2: When r is non-zero

Since r is at least 1, adding (d-1) makes r’ atleast d and at the most (2d-2) which is less than 2d. So, adding (d-1) adds exactly 1(not more, not less) to the quotient because r’/d = 1.

Continuing with the example,

Illustrating addition of (d-1) to n.

So, (d-1) is the number at the sweet spot adding just the right amount so that the quotient remains the same when the remainder is zero and increases by one when the remainder is non-zero. This is how DIV_ROUND_UP works. Isn’t it amazing how two branches of decision making is embedded into a single one-shot formula ? Math is beautiful, ain’t it ?