Search code examples
rustunsignedsigned

How do I add a signed integer to an unsigned integer in Rust, checking for unsigned overflow?


I want to add an isize to a usize and include bounds checking so that the result does not overflow the bounds of a usize. How can this be done?


Solution

  • Rustc 1.66+ supports some mixed integer operations. Note, this was previously unstable under the mixed_integer_ops feature flag.

    With this you can do:

    fn main() {
        let x: usize = foo();
        let y: isize = bar();
        let (res, flag): (usize, bool) = x.overflowing_add_signed(y); // returns a (usize, bool) pair to indicate if overflow occurred
        println!("{x} + {y} = {res}, overflowed? {flag}");
    }
    

    These *_add_signed methods on unsigned integers all accept a signed argument and return an unsigned result. There's a few variants, depending on how specifically you want to handle the overflow case:

    • overflowing_, shown above, returns a pair, with the wrapped result and a boolean flag indicating if overflow occurred.
    • checked_ returns an Option, which is None on overflow.
    • saturating_ prevents overflow by clamping to the max and min values (i.e. MAX + 1 == MAX, MIN - 1 == MIN).
    • wrapping_ doesn't address your use case - it only returns the wrapped result and doesn't indicate if overflow occurred.

    There are also analogous methods on signed integers, for additions or subtractions which accept an unsigned argument and return a signed result, named *_add_unsigned and *_sub_unsigned.

    (note: adapted from my answer at https://stackoverflow.com/a/73153135/6112457)