Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I return a flag on integer overflow in Rust?

Swift has integer overflow arithmetic functions which return a flag whether the number has overflowed or not. Do we have same thing in Rust?

like image 214
eonil Avatar asked Oct 23 '14 22:10

eonil


People also ask

How do you deal with overflow in Rust?

To remove the overflow error, change the value of variable2 from 0 to any negative number within the range −1 to −32767.

How does rust handle integer overflow?

Instead, if overflow occurs, Rust performs two's complement wrapping. In short, values greater than the maximum value the type can hold “wrap around” to the minimum of the values the type can hold. In the case of a u8 , the value 256 becomes 0, the value 257 becomes 1, and so on.

How do I fix integer overflow?

In languages where integer overflow can occur, you can reduce its likelihood by using larger integer types, like Java's long or C's long long int. If you need to store something even bigger, there are libraries built to handle arbitrarily large numbers.

Does rust allow overflow?

Numeric overflow prevents a difficult situation. On the one hand, overflow (and underflow) is known to be a common source of error in other languages. Rust, at least, does not have to worry about memory safety violations, but it is still possible for overflow to lead to bugs.


3 Answers

As you note, there are intrinsics for this but these are unsafe and somewhat annoying to use.

Before Rust 1.0, the standard library provided wrappers that detect the overflow for the 4 arithmetic operations in the form of CheckedAdd, CheckedSub, CheckedMul and CheckedDiv.

As of Rust 1.0, these traits no longer exist and there are just inherent methods on each numeric type, such as i32::checked_add.

However, these just detect overflow and do not return the overflowed-result:

fn main() {
    println!("{:?}", 5u16.checked_add(65530u16));
    println!("{:?}", 6u16.checked_add(65530u16));
}

(playground)

Prints:

Some(65535)
None
like image 111
huon Avatar answered Nov 04 '22 04:11

huon


Since Rust 1.7.0, there's overflowing_<operation>(rhs) defined on integer types.

Example for overflowing_add:

Calculates self + rhs

Returns a tuple of the addition along with a boolean indicating whether an arithmetic overflow would occur. If an overflow would have occurred then the wrapped value is returned.

Example:

use std::i64;

assert_eq!(5i64.overflowing_add(2), (7, false));
assert_eq!(i64::MAX.overflowing_add(1), (i64::MIN, true));

(playground)

like image 20
Danilo Bargen Avatar answered Nov 04 '22 05:11

Danilo Bargen


Rust has integer arithmetic intrinsics such as add_with_overflow.

pub unsafe extern "rust-intrinsic" fn add_with_overflow<T>(
    x: T, 
    y: T
) -> (T, bool)
like image 4
eonil Avatar answered Nov 04 '22 05:11

eonil