5.8 Overflow in Arithmetic Operations
Integer overflow is a frequent source of bugs. Rust has specific measures to handle or mitigate overflow.
5.8.1 Debug Mode
In debug builds, Rust checks for integer overflow and panics if it occurs:
let x: u8 = 255;
let y = x + 1; // This panics in debug mode
5.8.2 Release Mode
In release builds, integer overflow defaults to two’s complement wrapping (for example, 255 + 1 in an 8-bit type becomes 0):
// In release mode, no panic—y wraps around to 0
let x: u8 = 255;
let y = x + 1;
5.8.3 Explicit Overflow Handling
If you need consistent behavior across both debug and release modes, Rust provides methods in the standard library:
- Wrapping:
wrapping_add,wrapping_sub, etc. - Checked:
checked_addreturnsNoneon overflow. - Saturating:
saturating_addcaps values at the numeric boundary. - Overflowing:
overflowing_addreturns a tuple(result, bool_overflowed).
5.8.4 Floating-Point Overflow
Floating-point types (f32 and f64) do not panic or wrap on overflow; they follow IEEE 754 rules and produce special values like ∞ (f64::INFINITY or f64::NEG_INFINITY) or NaN (f64::NAN, not a number). For example:
let big = f64::MAX;
let overflow = big * 2.0; // f64::INFINITY
let nan_value = 0.0 / 0.0; // f64::NAN
Rust does not raise a runtime error for these special floating-point values, so you must handle or check for ∞ or NaN when needed.
Handling NaN in Floating-Point Comparisons
When performing floating-point arithmetic (f32 or f64), be aware of special cases involving NaN (Not a Number) due to the IEEE 754 standard. Key considerations include:
- NaN is never equal to anything, including itself.
- All ordering comparisons (
<,>,<=,>=) with NaN returnfalse. - Rust does not implement
Ordfor floating-point types, buttotal_cmp()provides a well-defined total ordering. - Min/max functions prioritize non-NaN values over NaN.
- Use
.is_nan()to explicitly check for NaN.
These rules preserve numerical correctness but can lead to surprising results in code relying on equality checks.