2

How can I round up when performing division on two int values in C++ without using std::ceil?

Typically I end up doing something like the following:

double res = ceil(a / (double) b);

Is there any way I can duplicate the result without using std::ceil?

coder_jam
  • 94
  • 12

2 Answers2

6

If a and b are both positive, you can avoid floating point completely and get both exact results (no problems with FP rounding) and faster execution time through the classical method:

int res = (a + (b - 1)) / b;

For negative a you don't need any correction - the truncation performed by integer division already has the semantics matching your ceil formula; so, if you want a more general case:

int res = (a<0 ? a : (a + (b - 1))) / b;
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • 1
    What about the integer overflow here? (if any of a and b are sufficiently large) – Luis Machuca May 26 '20 at 23:05
  • What about negative `b`? – norok2 May 26 '20 at 23:12
  • 1
    @LuisMachuca if that's a problem, you can do something like `a / b + !!(a % b)`, which should not pose any problem, but it's probably going to be a bit slower (it has a branch and in general is more convoluted code). – Matteo Italia May 26 '20 at 23:18
  • @norok2: never really thought about that; generally when I use this formula `b` is positive or even known at compile time (typically if I have to e.g. divide by 10 rounding up I just write `(a + 9) / 10`). – Matteo Italia May 26 '20 at 23:20
  • 3
    If they are both positive, `(a-1)/b + 1` is better because it cannot overflow. – Eric Postpischil May 26 '20 at 23:26
  • @EricPostpischil: nice, never thought about that alternative, maybe you should post that as an answer. *Edit* just noticed, `a` must be *strictly* positive, otherwise for `a == 0` you get +1 instead of 0. – Matteo Italia May 26 '20 at 23:30
  • 1
    @norok2 So far, [none](https://godbolt.org/z/vZx3Kx) of the proposed solutions compares equal to `std::ceil` when both `a` and `b` are allowed to be signed. – Bob__ May 27 '20 at 09:37
3

you could do this

double res = (double) (((a % b) == 0) ? (a / b) : (a / b) + 1);

basically if there is a remainder, add 1 to the truncated integer result

Erix
  • 7,059
  • 2
  • 35
  • 61