This is a super quick blog post on how to get different rounding modes with integer division: floor to get an integer smaller than or equal to the real value, round to get the integer that closest to the real value, and ceiling to get an integer greater than or equal to the real value.
These operations are useful when you need to align memory allocations, calculate dispatch sizes for compute shaders, work with objects on a grid, and many other things.
Unsigned Integers
- Floor: A / B
- Round: (A+B/2) / B
- Ceiling: (A+B-1) / B alternately: (A-1) / B+1 (thanks @clift_m!)
void RoundTest(unsigned int a, unsigned int b)
{
printf("%i / %i = %0.2f\n", a, b, float(a) / float(b));
printf("floor = %i\n", a / b);
printf("round = %i\n", (a + b / 2) / b);
printf("ceiling = %i\n\n", (a - 1) / b + 1);
}
Running the above with a couple different values:

Signed Integers
Here are routines that handle signed integers, and a testing program for them, courtesy of @insouris.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 30
static int div_floor(int a, int b) { return (a ^ b) < 0 && a ? (1 - abs(a)) / abs(b) - 1 : a / b; }
static int div_round(int a, int b) { return (a ^ b) < 0 ? (a - b / 2) / b : (a + b / 2) / b; }
static int div_ceil(int a, int b) { return (a ^ b) < 0 || !a ? a / b : (abs(a) - 1) / abs(b) + 1; }
int main()
{
for (int a = -N; a <= N; a++) {
for (int b = -N; b <= N; b++) {
if (!b)
continue;
const float f = a / (float)b;
const int ef = (int)floorf(f);
const int er = (int)roundf(f); // X.5 to X+1, or -X.5 to -X
const int ec = (int)ceilf(f);
const int of = div_floor(a, b);
const int orn = div_round(a, b);
const int oc = div_ceil(a, b);
const int df = ef != of;
const int dr = er != orn;
const int dc = ec != oc;
if (df || dr || dc)
fprintf(stderr, "%d/%d=%g%s\n", a, b, f, (a ^ b) < 0 ? " (diff sign)" : "");
if (df) fprintf(stderr, "floor: %d != %d\n", of, ef);
if (dr) fprintf(stderr, "round: %d != %d\n", orn, er);
if (dc) fprintf(stderr, "ceil: %d != %d\n", oc, ec);
}
}
return 0;
}