An integer type has a fixed number of bits, so it can represent only a fixed range of values. Overflow occurs when a calculation goes above that range. A `u16`, for example, holds values from 0 through 65,535; it cannot hold 65,536. Unlike a floating-point number, an integer cannot give up precision to extend its range. section 5.2
Listing 5.4 How u16 bit patterns translate to a fixed number of integers
fn main() {
let zero: u16 = 0b0000_0000_0000_0000;
let one: u16 = 0b0000_0000_0000_0001;
let two: u16 = 0b0000_0000_0000_0010;
// ...
let sixtyfivethousand_533: u16 = 0b1111_1111_1111_1101;
let sixtyfivethousand_534: u16 = 0b1111_1111_1111_1110;
let sixtyfivethousand_535: u16 = 0b1111_1111_1111_1111;
print!("{}, {}, {}, ..., ", zero, one, two);
println!("{}, {}, {}", sixty5_533, sixty5_534, sixty5_535);
}
Compare the first and last `u16` bit patterns. Once all 16 bits are 1, there is no next pattern available for a larger `u16` value. section 5.2
Listing 5.3 Exploring the effect of incrementing an integer past its range
fn main() {
let mut i: u16 = 0;
print!("{}..", i);
loop {
i += 1000;
print!("{}..", i);
if i % 10000 == 0 {
print!{"\n"}
}
}
}
This loop adds 1,000 to a `u16` on every pass. With default compilation, it eventually panics with an “attempt to add with overflow” message. section 5.2
When the answer will not fit
Try to store `200 + 200` in a `u8`. The answer, 400, exceeds that type’s maximum of 255. The supplied example panics with default compilation; with optimizations enabled, its unchecked result is 144. Do not assume that a successful optimized build means the arithmetic stayed in range. section 5.2 section 5.8
This makes overflow a safety issue that depends on how the program is built: Rust checks for it in debug builds, while optimized builds can disable those runtime checks. Going below an integer type’s lowest value is the related problem called underflow. section 1.6.1 section 5.8






