Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 487
Morgan H Avatar asked May 13 '26 18:05

Morgan H


1 Answers

You could use a combination of isize::is_negative(), isize::wrapping_abs(), usize::checked_add() and usize::checked_sub().

const fn add(lhs: usize, rhs: isize) -> Option<usize> {
    if rhs.is_negative() {
        lhs.checked_sub(rhs.wrapping_abs() as usize)
    } else {
        lhs.checked_add(rhs as usize)
    }
}

Why isize::is_negative() vs rhs < 0? In this case, it doesn't change anything, as logical operations on literals count as constant expressions.

However, while it is allowed for literals it is not allowed in general, as traits methods cannot be const. So if you had a wrapping type, e.g. Foo(isize) then it wouldn't be allowed to say foo < Foo(0) in a const context. Though, it would be possible to say foo.is_negative() as Foo could still implement a const fn is_negative().

Yes, you'd still be able to say foo.0 < 0, but that's besides the point I was trying to make.

like image 63
vallentin Avatar answered May 17 '26 07:05

vallentin