Rust Fundamentals · 15 XP Pro

Integer types

Rust has many integer types. The name says whether it is signed and how many bits it uses: i8, i16, i32, i64 are signed, u8, u16, u32, u64 are unsigned (never negative). Unannotated integer literals default to i32. Each type has limits, available as u8::MAX, i32::MIN and so on. A u8 holds 0..=255.

What happens when a result does not fit? In a debug build, ordinary + panics on overflow. When you want a specific behaviour, say so with a method:

  • a.wrapping_add(b) wraps around: 250u8.wrapping_add(10) is 4.
  • a.saturating_add(b) sticks at the limit: 250u8.saturating_add(10) is 255.
  • a.checked_add(b) reports failure instead of a number. It returns an Option, and .is_none() is true when the addition overflowed.
let big: u8 = 200;
println!("{}", big.wrapping_add(100));   // 44
println!("{}", big.saturating_add(100)); // 255
println!("{}", big.checked_add(100).is_none()); // true

Converting to a wider type safely is done with u64::from(x), which only exists when no information can be lost.

Your task

Write these public functions:

  • add_wrapping(a: u8, b: u8) -> u8 using wrapping_add.
  • add_saturating(a: u8, b: u8) -> u8 using saturating_add.
  • add_overflows(a: u8, b: u8) -> bool, true when a + b does not fit in a u8 (use checked_add and is_none).
  • widening_product(a: u32, b: u32) -> u64 that multiplies without overflow by converting both inputs with u64::from first.

Next lesson →

Sign in to run your code. It's free.