#078 Apr 13, 2026

78. div_ceil — Divide and Round Up Without the Overflow Bug

Need to split items into fixed-size pages or chunks? The classic (n + size - 1) / size trick silently overflows. div_ceil does it correctly.

The classic footgun

Paging, chunking, allocating — any time you divide and need to round up, this pattern shows up:

1
2
3
fn pages_needed(total: u64, per_page: u64) -> u64 {
    (total + per_page - 1) / per_page // ⚠️ overflows when total is large
}

It works until total + per_page - 1 wraps around. With u64::MAX items and a page size of 10, you get a wrong answer instead of a panic or correct result.

The fix: div_ceil

Stabilized in Rust 1.73, div_ceil handles the rounding without intermediate overflow:

1
2
3
fn pages_needed(total: u64, per_page: u64) -> u64 {
    total.div_ceil(per_page)
}

One method call, no overflow risk, intent crystal clear.

Real-world examples

Allocating pixel rows for a tiled renderer:

1
2
3
4
let image_height: u32 = 1080;
let tile_size: u32 = 64;
let tile_rows = image_height.div_ceil(tile_size);
assert_eq!(tile_rows, 17); // 16 full tiles + 1 partial

Splitting work across threads:

1
2
3
4
let items: usize = 1000;
let threads: usize = 6;
let chunk_size = items.div_ceil(threads);
assert_eq!(chunk_size, 167); // each thread handles at most 167 items

It works on all unsigned integers

div_ceil is available on u8, u16, u32, u64, u128, and usize. Signed integers also have it (since Rust 1.73), but watch out — it rounds toward positive infinity, which for negative dividends means rounding away from zero.

1
2
let signed: i32 = -7;
assert_eq!(signed.div_ceil(2), -3); // rounds toward +∞, not toward 0

Next time you reach for (a + b - 1) / b, stop — div_ceil already exists and it won’t betray you at the boundaries.

← Previous 77. repeat_n — Repeat a Value Exactly N Times Next → 79. #[diagnostic::on_unimplemented] — Custom Error Messages for Your Traits