354

Given integer values x and y, C and C++ both return as the quotient q = x/y the floor of the floating point equivalent. I'm interested in a method of returning the ceiling instead. For example, ceil(10/5)=2 and ceil(11/5)=3.

The obvious approach involves something like:

q = x / y;
if (q * y < x) ++q;

This requires an extra comparison and multiplication; and other methods I've seen (used in fact) involve casting as a float or double. Is there a more direct method that avoids the additional multiplication (or a second division) and branch, and that also avoids casting as a floating point number?

ks1322
  • 33,961
  • 14
  • 109
  • 164
andand
  • 17,134
  • 11
  • 53
  • 79
  • 102
    the divide instruction often returns both quotient and remainder at the same time so there's no need to multiply, just `q = x/y + (x % y != 0);` is enough – phuclv Jan 25 '14 at 11:17
  • 1
    @LưuVĩnhPhúc Seriously you need to add that as the answer. I just used that for my answer during a codility test. It worked like a charm though I am not certain how the mod part of the answer works but it did the job. – Zachary Kraus Aug 26 '14 at 00:56
  • 3
    @AndreasGrapentin the answer below by Miguel Figueiredo was submitted nearly a year before Lưu Vĩnh Phúc left the comment above. While I understand how appealing and elegant Miguel's solution is, I'm not inclined to change the accepted answer at this late date. Both approaches remain sound. If you feel strongly enough about it, I suggest you show your support by up-voting Miguel's answer below. – andand Aug 26 '14 at 02:51
  • Related question http://stackoverflow.com/q/3407012/61505 – KindDragon Oct 14 '16 at 08:37
  • 2
    Strange, I have not seen any sane measurement or analysis of the proposed solutions. You talk about speed on near-the-bone, but there is no discussion of architectures, pipelines, branching instructions and clock cycles. – Rado Dec 18 '16 at 19:35
  • @AndreasGrapentin although Luu Vinh Phuc's answer is elegant, it has an inequality comparison, as well as another modulo, which effectively slows it down (compiler may optimize away the modulo, however the comparison is still there). The accepted answer has no comparisons, and has just one division, so it seems to be a better answer. It is hard to know for sure without looking at what a compiler would spit out in each case. – vasia Nov 10 '17 at 02:42
  • 1
    See also: https://stackoverflow.com/questions/63436490/divide-integers-with-floor-ceil-and-outwards-rounding-modes-in-c – andand May 08 '21 at 03:23

11 Answers11

519

For positive numbers where you want to find the ceiling (q) of x when divided by y.

unsigned int x, y, q;

To round up ...

q = (x + y - 1) / y;

or (avoiding overflow in x+y)

q = 1 + ((x - 1) / y); // if x != 0
Sparky
  • 13,505
  • 4
  • 26
  • 27
  • 9
    @bitc: For negative numbers, I believe C99 specifies round-to-zero, so `x/y` is the ceiling of the division. C90 didn't specify how to round, and I don't think the current C++ standard does either. – David Thornley Apr 30 '10 at 14:46
  • 6
    See Eric Lippert's post: http://stackoverflow.com/questions/921180/c-round-up/926806#926806 – Mashmagar Apr 30 '10 at 14:53
  • 3
    Note: This might overflow. q = ((long long)x + y - 1) / y will not. My code is slower though, so if you know that your numbers will not overflow, you should use Sparky's version. – Jørgen Fogh Apr 30 '10 at 15:09
  • @David Thornley: iirc, that only applies to conversions from floating point to int. In the above code negative numbers cause havoc: q = (11 + (-5) - 1) / (-5); – bitc Apr 30 '10 at 15:13
  • 1
    @bitc: I believe David's point was that you would not use the above calculation if the result is negative - you would just use `q = x / y;` – caf May 01 '10 at 05:44
  • 17
    The second one has a problem where x is 0. ceil(0/y) = 0 but it returns 1. – Omry Yadan May 27 '13 at 00:52
  • 3
    @OmryYadan would `x == 0 ? 0 : 1 + ((x - 1) / y)` resolve this safely and efficiently? – jamesmstone Apr 05 '17 at 00:50
  • 2
    From review, @jamesmstone no, your suggestion doesn't solve the issue. As the first comment rightly noticed, it works only for positive numbers. Try for examlpe `x = -y` or `x = -2*y` etc for any postive `y` and you'll see the same bug. And I even didn't start to discuss the case of negative `y`. Suggestion to look at Eric Lippert's answser at https://stackoverflow.com/questions/921180/c-round-up/926806#926806 to get some details is really good one. – SergGr Apr 05 '17 at 03:49
  • 2
    change the second one to `q = !!x + ((x - !!x) / y)` and it won't have problems with `x == 0`, nor will it branch or overflow. – Phernost Nov 06 '19 at 15:00
131

For positive numbers:

q = x/y + (x % y != 0);
Yun
  • 3,056
  • 6
  • 9
  • 28
Miguel Figueiredo
  • 1,319
  • 1
  • 8
  • 2
  • 22
    most common architecture's divide instruction also includes remainder in its result so this really needs only one division and would be very fast – phuclv Jan 25 '14 at 11:15
  • 1
    This is the most elegant solution. [I have extended it to negative numbers and floor / up rounding too](https://stackoverflow.com/q/63436490/5740428). – Jan Schultke Aug 16 '20 at 12:42
66

Sparky's answer is one standard way to solve this problem, but as I also wrote in my comment, you run the risk of overflows. This can be solved by using a wider type, but what if you want to divide long longs?

Nathan Ernst's answer provides one solution, but it involves a function call, a variable declaration and a conditional, which makes it no shorter than the OPs code and probably even slower, because it is harder to optimize.

My solution is this:

q = (x % y) ? x / y + 1 : x / y;

It will be slightly faster than the OPs code, because the modulo and the division is performed using the same instruction on the processor, because the compiler can see that they are equivalent. At least gcc 4.4.1 performs this optimization with -O2 flag on x86.

In theory the compiler might inline the function call in Nathan Ernst's code and emit the same thing, but gcc didn't do that when I tested it. This might be because it would tie the compiled code to a single version of the standard library.

As a final note, none of this matters on a modern machine, except if you are in an extremely tight loop and all your data is in registers or the L1-cache. Otherwise all of these solutions will be equally fast, except for possibly Nathan Ernst's, which might be significantly slower if the function has to be fetched from main memory.

Tatsuyuki Ishi
  • 3,883
  • 3
  • 29
  • 41
Jørgen Fogh
  • 7,516
  • 2
  • 36
  • 46
  • 3
    There was an easier way to fix overflow, simply reduce y/y: `q = (x > 0)? 1 + (x - 1)/y: (x / y);` – Ben Voigt Apr 30 '10 at 22:40
  • -1: this is an inefficient way, as it trades a cheap * for a costly %; worse than the OP approach. –  Apr 11 '14 at 08:43
  • 8
    No, it does not. As I explained in the answer, the % operator is free when you already perform the division. – Jørgen Fogh Apr 11 '14 at 22:03
  • 1
    Then `q = x / y + (x % y > 0);` is easier than `? :` expression? – Han May 29 '14 at 16:00
  • 1
    It depends on what you mean by "easier." It may or may not be faster, depending on how the compiler translates it. My guess would be slower but I would have to measure it to be sure. – Jørgen Fogh May 29 '14 at 19:27
  • 1
    I don't see how adding a branch instruction should make this faser, actually. – einpoklum Feb 13 '16 at 20:47
26

You could use the div function in cstdlib to get the quotient & remainder in a single call and then handle the ceiling separately, like in the below

#include <cstdlib>
#include <iostream>

int div_ceil(int numerator, int denominator)
{
        std::div_t res = std::div(numerator, denominator);
        return res.rem ? (res.quot + 1) : res.quot;
}

int main(int, const char**)
{
        std::cout << "10 / 5 = " << div_ceil(10, 5) << std::endl;
        std::cout << "11 / 5 = " << div_ceil(11, 5) << std::endl;

        return 0;
}
Nathan Ernst
  • 4,540
  • 25
  • 38
  • 14
    As an interesting case of the double bang, you could also `return res.quot + !!res.rem;` :) – Sam Harwell Apr 30 '10 at 22:32
  • Doesn't ldiv always promote the arguments into long long's? And doesn't that cost anything, up-casting or down-casting? – einpoklum Feb 13 '16 at 20:51
  • 1
    @einpoklum: `std::div` is overloaded for `int`, `long`, `long long` and `intmax_t` (the latter two since C++11); whether it internally promotes would be an implementation detail (and I can't see a strong reason for why they wouldn't implement it independently for each). `ldiv` promotes, but `std::div` shouldn't need to. – ShadowRanger Sep 18 '20 at 12:17
14

There's a solution for both positive and negative x but only for positive y with just 1 division and without branches:

int div_ceil(int x, int y) {
    return x / y + (x % y > 0);
}

Note, if x is positive then division is towards zero, and we should add 1 if reminder is not zero.

If x is negative then division is towards zero, that's what we need, and we will not add anything because x % y is not positive

cubuspl42
  • 7,833
  • 4
  • 41
  • 65
RiaD
  • 46,822
  • 11
  • 79
  • 123
  • interesting, because there are common cases with y being constant – Wolf Nov 09 '17 at 15:02
  • 1
    mod requires division so its not just 1 division here, but maybe complier can optimize two similar divisions into one. – M.kazem Akhgary Jan 04 '18 at 08:53
  • [This comment](https://stackoverflow.com/questions/2745074/fast-ceiling-of-an-integer-division-in-c-c?rq=1#comment32189436_14878734) implies that modern architectures can divide and calculate module with one instruction. That still requires a smart compiler, of course. – cubuspl42 Oct 25 '21 at 12:03
12

How about this? (requires y non-negative, so don't use this in the rare case where y is a variable with no non-negativity guarantee)

q = (x > 0)? 1 + (x - 1)/y: (x / y);

I reduced y/y to one, eliminating the term x + y - 1 and with it any chance of overflow.

I avoid x - 1 wrapping around when x is an unsigned type and contains zero.

For signed x, negative and zero still combine into a single case.

Probably not a huge benefit on a modern general-purpose CPU, but this would be far faster in an embedded system than any of the other correct answers.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
8

I would have rather commented but I don't have a high enough rep.

As far as I am aware, for positive arguments and a divisor which is a power of 2, this is the fastest way (tested in CUDA):

//example y=8
q = (x >> 3) + !!(x & 7);

For generic positive arguments only, I tend to do it like so:

q = x/y + !!(x % y);
Greg Kramida
  • 4,064
  • 5
  • 30
  • 46
OffBy0x01
  • 178
  • 1
  • 9
  • It would be interesting to see how ```q = x/y + !!(x % y);``` stacks up against ```q = x/y + (x % y == 0);``` and the ```q = (x + y - 1) / y;``` solutions performance-wise in contemporary CUDA. – Greg Kramida May 31 '20 at 22:16
  • 1
    seems like `q = x/y + (x % y == 0);` should be `q = x/y + (x % y != 0);` instead – Sean W Jul 01 '20 at 15:28
5

This works for positive or negative numbers:

q = x / y + ((x % y != 0) ? !((x > 0) ^ (y > 0)) : 0);

If there is a remainder, checks to see if x and y are of the same sign and adds 1 accordingly.

Eliahu Aaron
  • 4,103
  • 5
  • 27
  • 37
Mark Conway
  • 59
  • 1
  • 3
4

For signed or unsigned integers.

q = x / y + !(((x < 0) != (y < 0)) || !(x % y));

For signed dividends and unsigned divisors.

q = x / y + !((x < 0) || !(x % y));

For unsigned dividends and signed divisors.

q = x / y + !((y < 0) || !(x % y));

For unsigned integers.

q = x / y + !!(x % y);

Zero divisor fails (as with a native operation). Cannot cause overflow.

Corresponding floored and modulo constexpr implementations here, along with templates to select the necessary overloads (as full optimization and to prevent mismatched sign comparison warnings):

https://github.com/libbitcoin/libbitcoin-system/wiki/Integer-Division-Unraveled

evoskuil
  • 1,011
  • 1
  • 7
  • 13
3

simplified generic form,

int div_up(int n, int d) {
    return n / d + (((n < 0) ^ (d > 0)) && (n % d));
} //i.e. +1 iff (not exact int && positive result)

For a more generic answer, C++ functions for integer division with well defined rounding strategy

Community
  • 1
  • 1
Atif Hussain
  • 412
  • 5
  • 9
-3

Compile with O3, The compiler performs optimization well.

q = x / y;
if (x % y)  ++q;
user2165
  • 1,951
  • 3
  • 20
  • 39
dhb
  • 1
  • 1