🎓 A1Learner
🔍

Rust Integer Methods

Integer methods are operations that belong to whole numbers. The checked, wrapping, saturating, and overflowing families work for many operations.

checked_ works for division too

checked_div refuses two different traps. One is dividing by zero. The other is the one division that overflows. That is the most negative number divided by -1:

println!("{:?}", 10i32.checked_div(0));
println!("{:?}", i32::MIN.checked_div(-1));
println!("{:?}", 20i32.checked_div(4));

Powers with pow

Integers have no ^ sign for powers — that sign means XOR in Rust. The pow method does the job, and its exponent is always a u32:

println!("{}", 2u32.pow(10));
println!("{}", 10i32.pow(3));

The checked version of pow

pow itself follows the overflow rules of the build. checked_pow turns the same question into an Option:

println!("{:?}", 2u8.checked_pow(7));
println!("{:?}", 2u8.checked_pow(8));

The gap between two numbers: abs_diff

Subtracting two far-apart numbers can overflow. abs_diff measures the gap safely — for signed types the answer is unsigned, so even the widest gap fits:

println!("{}", 80i32.abs_diff(100));
println!("{}", i32::MIN.abs_diff(i32::MAX));

The one value abs cannot flip

abs() has one impossible case: the most negative value has no positive twin in its own type. checked_abs admits defeat, and unsigned_abs answers in the unsigned twin type:

println!("{:?}", i8::MIN.checked_abs());
println!("{}", i8::MIN.unsigned_abs());

Whole square roots: isqrt

Unsigned integers have isqrt, the whole part of the square root. Both 16 and 17 answer 4, because 4 × 4 = 16 and the next square is 25:

println!("{}", 17u32.isqrt());
println!("{}", 16u32.isqrt());

Example

fn main() {
    let base: u32 = 2;
    println!("2^10 = {}", base.pow(10));
    let big: u8 = 200;
    println!("200 + 100 checked = {:?}", big.checked_add(100));
    println!("200 + 100 saturated = {}", big.saturating_add(100));
    let pair = big.overflowing_mul(2);
    println!("200 * 2 = {} (overflowed: {})", pair.0, pair.1);
    let morning = 18i32;
    let evening = -4i32;
    println!("temperature swing = {}", morning.abs_diff(evening));
    println!("whole root of 50 = {}", 50u32.isqrt());
}

Key points

  • The four families exist for add, sub, mul, div, rem, pow, neg and abs.
  • They are checked_, wrapping_, saturating_ and overflowing_.
  • Learn the pattern once.
  • Then guess any name.
  • checked_ returns an Option.
  • It gives Some(answer), or None when the operation cannot be done.
  • For division, dividing by zero is one of those cases.
  • Use pow(n) to raise a number to a power: the exponent is a u32, so 2u32.pow(10) is 1024
  • Use abs_diff to measure the distance between two numbers: it can never overflow, and signed inputs give an unsigned answer
  • Use unsigned_abs for the size of the most negative value: i8::MIN has no positive twin, but i8::MIN.unsigned_abs() is 128
  • Use isqrt on an unsigned integer for the whole part of a square root: 17u32.isqrt() is 4

In this example, the pattern from Number Overflow stretches across many operations. pow raises 2 to the 10th power. The same u8 value, 200, meets three families. checked_add refuses 300 with None. saturating_add stops at 255. overflowing_mul wraps 400 to 144 and raises its flag. abs_diff measures the temperature swing from -4 to 18 as 22, with no subtraction to overflow on the way. Finally isqrt gives the whole part of the square root of 50: 7, because 7 × 7 = 49.

Note

Plain operators and pow follow the overflow checks of the build.

The four families answer the same in debug and release.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Rust Playground

Exercise

What does 10i32.checked_div(0) return?