1
/// Essence division rounds towards negative infinity.
2
/// Returns `None` for zero divisors or a quotient outside the integer range.
3
13733030
pub fn floor_div(dividend: i32, divisor: i32) -> Option<i32> {
4
13733030
    let (quotient, _) = floor_div_mod(dividend, divisor)?;
5
13724720
    i32::try_from(quotient).ok()
6
13733030
}
7

            
8
/// Essence modulo has the divisor's sign and is undefined for zero divisors.
9
/// Widened arithmetic also handles `i32::MIN % -1`, whose remainder is zero.
10
32579955
pub fn floor_mod(dividend: i32, divisor: i32) -> Option<i32> {
11
32579955
    let (_, remainder) = floor_div_mod(dividend, divisor)?;
12
32570574
    i32::try_from(remainder).ok()
13
32579955
}
14

            
15
46312985
fn floor_div_mod(dividend: i32, divisor: i32) -> Option<(i64, i64)> {
16
46312985
    let (dividend, divisor) = (i64::from(dividend), i64::from(divisor));
17
46312985
    let quotient = dividend.checked_div(divisor)?;
18
46295294
    let remainder = dividend % divisor;
19
46295294
    if remainder != 0 && (dividend < 0) != (divisor < 0) {
20
205315
        Some((quotient - 1, remainder + divisor))
21
    } else {
22
46089979
        Some((quotient, remainder))
23
    }
24
46312985
}