Integers
In Rust, integers are primitive types used to represent whole numbers.
-
Signed integers (
i) can store both positive and negative numbers. The sign takes one bit, so the range of values is reduced compared to unsigned integers of the same size. -
Unsigned integers (
u) can store only non-negative numbers, allowing them to represent a larger range of positive numbers than their signed counterparts.
Integer Types and Their Sizes
| Type | Size | Range |
|---|---|---|
i8 | 8-bit | -128 to 127 |
u8 | 8-bit | 0 to 255 |
i16 | 16-bit | -32,768 to 32,767 |
u16 | 16-bit | 0 to 65,535 |
i32 | 32-bit | -2,147,483,648 to 2,147,483,647 |
u32 | 32-bit | 0 to 4,294,967,295 |
i64 | 64-bit | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
u64 | 64-bit | 0 to 18,446,744,073,709,551,615 |
i128 | 128-bit | Huuuuugeee |
u128 | 128-bit | Huuuge aswell |
isize | Architecture-dependent | Varies based on CPU architecture (32 or 64-bit) |
usize | Architecture-dependent | Varies based on CPU architecture (32 or 64-bit) |
The isize and usize types depend on the system’s architecture.
On a 32-bit system, they are 32 bits wide, and on a 64-bit system, they are 64 bits wide.
Creating and Using Integers
You can create integers using literals. By default, Rust infers i32 if no specific type is provided.
let signed: i32 = -42;
let unsigned: u32 = 42;
You can specify integer literals using suffixes:
let small = 120i8;
let large: u64 = 1_000_000;
Note: The _ is used for readability and does not affect the value.
Arithmetic Operations
Rust supports standard arithmetic operations on integers,
including addition (+), subtraction (-), multiplication (*), division (/), and modulus (%):
let sum = 5 + 10;
let product = 4 * 6;
let quotient = 10 / 2;
let remainder = 10 % 3;
Overflow Handling
By default, Rust checks for overflow in debug mode. For example, if you try to assign a value that exceeds the range of the integer type, it will panic in debug mode.
In release mode, Rust allows overflow with wrapping behavior (modulo behavior).
You can also use methods like .wrapping_add(), .checked_add(), .saturating_add(),
and .overflowing_add() to handle overflows explicitly.
let result = 255u8.wrapping_add(1); // wraps to 0
Conversion Between Integer Types
If you need to convert between integer types, you can use as for casting:
let small: u8 = 100;
let large: u32 = small as u32;
Rust will not automatically convert between different integer types to ensure type safety.
Common Methods
Rust’s integer types come with useful methods:
-
Checking even/odd:
let num: i32 = 4;println!("{}", num.is_even()); // trueprintln!("{}", num.is_odd()); // false -
Converting to/from Strings:
let num_str = 42.to_string();let parsed_num: i32 = "42".parse().unwrap();
Example: Handling Overflow Explicitly
Let’s say you want to safely add two u8 values without panicking or wrapping:
fn safe_add(a: u8, b: u8) -> Option<u8> {
a.checked_add(b)
}
let result = safe_add(250, 10);
println!("{:?}", result); // None (would overflow)