---
title: Slides for P3724R3 — Integer division
document: P3895R1
date: 2025-03-03
audience: LEWG
reply-to:
  - "Jan Schultke < <janschultke@gmail.com>"
paper-type: proposal
---

# Integer division  P3724R3

Jan Schultke
 | 
Slides for P3724R3
—
Integer division
 | 
Telecons 2026
 | 
Slide 1

## Introduction

- C++ supports integer division with rounding towards zero
- many other rounding modes are useful:

int

bucket_size

=

1000

,

elems

=

100

;

int

buckets_req

=

elems

/

bucket_size

;

//

WRONG, zero

int

buckets_req

=

div_to_pos_inf

(

elems

,

bucket_size

)

;

//

OK, one

- hardware division *always* rounds towards zero
  - only mode where `r = x - y * q` doesn't overflow
- software division in other langs. sometimes supports other modes

Jan Schultke
 | 
Slides for P3724R3
—
Integer division
 | 
Telecons 2026
 | 
Slide 2

## Why does this need to be in the standard?

- users need it all the time, and try to implement it
- they fail miserably: almost all attempts on StackOverflow/blogs wrong

[[StackOverflowCeil]](https://stackoverflow%2ecom/q/2745074/5740428) answer (67 upvotes) fails at rounding to +∞:

q

=

(

x

%

y

)

?

x

/

y

+

1

:

x

/

y

;

Mistake: incrementing negative quotients: `x=-1, y=2, q=1`

- pulling in third-party library for one division function is silly

Jan Schultke
 | 
Slides for P3724R3
—
Integer division
 | 
Telecons 2026
 | 
Slide 3

## Computing remainders is hard

The following function has unintended UB:

auto

div_rem_ceil

(

_BitInt

(

4

)

x

,

_BitInt

(

4

)

y

)

{

_BitInt

(

4

)

q

=

div_ceil

(

x

,

y

)

;

//

round to

+

∞

_BitInt

(

4

)

r

=

x

-

y

*

q

;

//

overflow

return

div_result

<

_BitInt

(

4

)

>

{

q

,

r

}

;

}

`div_rem_ceil(7, 2)` overflows: `q == 4, y * q == 8`

Jan Schultke
 | 
Slides for P3724R3
—
Integer division
 | 
Telecons 2026
 | 
Slide 4

## Which rounding modes to support

| `div_to_zero`<sub>📘</sub><sub>(`trunc`)</sub> | `div_ties_to_zero`<sub>📘</sub> |
| --- | --- |
| `div_away_zero` | `div_ties_away_zero`<sub>📘</sub><sub>(`round`)</sub> |
| `div_to_pos_inf`<sub>📘</sub><sub>(`ceil`)</sub> | `div_ties_to_pos_inf` |
| `div_to_neg_inf`<sub>📘</sub><sub>(`floor`)</sub> | `div_ties_to_neg_inf` |
|  | `div_ties_to_even`<sub>⚖️📘</sub><sub>(`roundeven`)</sub> |
|  | `div_ties_to_odd`<sub>⚖️</sub> |

- marked functions are must-have, others fill the gaps
- ⚖️ — unbiased | 📘 — ISO/IEC 60559
- most `div_*mode*` functions have `div_rem_*mode*` counterpart (20 total)

Jan Schultke
 | 
Slides for P3724R3
—
Integer division
 | 
Telecons 2026
 | 
Slide 5

## Library interface

template

<

class

T

>

struct

div_result

{

T

quotient

,

remainder

;

friend

constexpr

auto

operator

<=>

(

/*

...

*/

)

=

default

;

}

;

template

<

class

T

>

constexpr

div_result

<

T

>

div_rem_

mode

(

T

x

,

T

y

)

;

template

<

class

T

>

constexpr

T

div_

mode

(

T

x

,

T

y

)

;

template

<

class

T

>

constexpr

T

mod

(

T

x

,

T

y

)

;

- no `noexcept` because narrow contract (*Preconditions*:)
- no `rounding_mode` constant template- or run-time parameter
- `mod` is `div_rem_to_neg_inf(x, y).remainder`
  - as in − 2 mod 5 = 3 , and as in `mod` in Haskell, Ada, CSS, etc.

Jan Schultke
 | 
Slides for P3724R3
—
Integer division
 | 
Telecons 2026
 | 
Slide 6

## Other design considerations

- no SIMD overloads, but could be added in the future
  - branchless implementation possible
- no functions that compute only remainder (except `mod`)
  - these are not usually needed
  - undesirable remainder sign for most rounding modes
- all functions are in `<numeric>`
- feature-test macro: `__cpp_lib_integer_division`

Jan Schultke
 | 
Slides for P3724R3
—
Integer division
 | 
Telecons 2026
 | 
Slide 7

## Implementation experience

- Appendix A has simplified implementation for educational purposes
- eisenwave/integer-division [[GitHub]](https://github%2ecom/Eisenwave/integer-division) repo has full implementation
- all functions can be made branchless and are suitable for SIMD port

Implementation is always in terms of `/` and `%`.

div_result

<

int

>

div_rem_to_neg_inf

(

int

x

,

int

y

)

{

bool

quotient_negative

=

(

x

^

y

)

<

0

;

int

adjust

=

int

(

(

x

%

y

!=

0

)

&

quotient_negative

)

;

return

{

x

/

y

-

adjust

,

x

%

y

+

adjust

*

y

}

;

}

Jan Schultke
 | 
Slides for P3724R3
—
Integer division
 | 
Telecons 2026
 | 
Slide 8

## References

[P3724R1]

Jan Schultke.

Integer division

2025-09-29

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3724r1.html

[GitHub]

Jan Schultke.

integer-division GitHub repository

https://github.com/Eisenwave/integer-division

[StackOverflowCeil]

Fast ceiling of an integer division in C / C++

https://stackoverflow.com/q/2745074/5740428
