i32 în Rust

Tipul implicit pentru numere întregi cu semn, pe 32 de biți: de la -2147483648 la 2147483647.

Sintaxă
let x: i32 = 42;
let y = -7_i32;

i32::MIN  // -2147483648
i32::MAX  //  2147483647
i32::BITS // 32

Ce face i32

i32 este un număr întreg cu semn pe 32 de biți. Este tipul pe care Rust îl alege când scrii un număr întreg fără alt indiciu (let x = 5;). Există și celelalte dimensiuni: i8, i16, i64, i128, variantele fără semn u8 … u128, plus isize/usize (mărimea unui pointer, folosite pentru indici și lungimi).

Limitele sunt i32::MIN și i32::MAX. Dacă rezultatul unei operații iese din interval (overflow), în modul debug (cargo run) programul intră în panică, iar în modul release (--release) valoarea „se întoarce” (după MAX urmează MIN). Ca să alegi explicit comportamentul, folosește metodele checked_*, saturating_*, wrapping_* sau overflowing_*.

Împărțirea între întregi taie zecimalele (7 / 2 == 3), iar % dă restul cu semnul deîmpărțitului (-7 % 3 == -1). Conversia cu as între tipuri întregi poate pierde biți fără niciun avertisment; i8::try_from(x) verifică.

Ce returnează

Este un tip, nu o funcție.

Exemple

Exemplul 1: Limite, literali și operații

Liniuța de jos (_) separă cifrele pentru lizibilitate. Sufixul (_i64) alege tipul.

fn main() {
    println!("i32: de la {} la {}, {} biți", i32::MIN, i32::MAX, i32::BITS);

    let populatie_iasi = 271_692;
    let lumina_an_km = 9_460_730_472_580_i64;
    println!("Iași: {populatie_iasi}, un an-lumină: {lumina_an_km} km");

    println!("7 / 2 = {}, 7 % 2 = {}", 7 / 2, 7 % 2);
    println!("-7 / 2 = {}, -7 % 2 = {}", -7 / 2, -7 % 2);
    println!("ca zecimal: {}", 7 as f64 / 2.0);
}

Rezultat

i32: de la -2147483648 la 2147483647, 32 biți
Iași: 271692, un an-lumină: 9460730472580 km
7 / 2 = 3, 7 % 2 = 1
-7 / 2 = -3, -7 % 2 = -1
ca zecimal: 3.5

Exemplul 2: Conversii: as taie biții, try_from verifică

fn main() {
    let mare: i32 = 300;
    println!("300 as u8 = {}", mare as u8);
    println!("u8::try_from(300) = {:?}", u8::try_from(mare));
    println!("u8::try_from(200) = {:?}", u8::try_from(200_i32));

    let negativ: i32 = -1;
    println!("-1 as u32 = {}", negativ as u32);
    println!("3.99 as i32 = {}", 3.99_f64 as i32);
    println!("1e12 as i32 = {}", 1e12_f64 as i32);
}

Rezultat

300 as u8 = 44
u8::try_from(300) = Err(TryFromIntError(PosOverflow))
u8::try_from(200) = Ok(200)
-1 as u32 = 4294967295
3.99 as i32 = 3
1e12 as i32 = 2147483647

Exemplul 3: Depășire în modul debug

Valoarea vine din text, ca să nu poată fi calculată la compilare (atunci compilatorul ar da direct eroare). La adunarea cu 1, programul compilat în modul debug intră în panică.

fn main() {
    let maxim: i32 = "2147483647".parse().unwrap();
    println!("maxim = {maxim}");
    let urmator = maxim + 1;
    println!("urmator = {urmator}");
}

Rezultat (programul se oprește cu panică, codul de ieșire 101)

maxim = 2147483647

thread 'main' (71204) panicked at src/main.rs:4:19:
attempt to add with overflow
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Greșeli frecvente

  • Calculezi sume mari (bani în bani, milisecunde, populații) în i32: limita este puțin peste 2 miliarde. Folosește i64.
  • Te bazezi pe faptul că în release depășirea „se întoarce”: în debug același cod intră în panică. Dacă vrei întoarcerea, scrie wrapping_add.
  • Folosești as pentru conversii care pot pierde date (x as u8) fără să verifici: folosește try_from.

Comenzi înrudite

  • i32::checked_add: Adună și returnează Some(rezultat) sau None dacă rezultatul depășește limitele tipului.
  • i32::wrapping_add: Adună cu „întoarcere”: după MAX urmează MIN. overflowing_add spune și dacă a avut loc depășirea.
  • i32::saturating_sub: Scade, dar se oprește la limita tipului în loc să depășească: i32::MIN.saturating_sub(1) rămâne i32::MIN.
  • f64: Tipul implicit pentru numere cu zecimale: virgulă mobilă pe 64 de biți (precizie dublă, IEEE 754).
  • u8: Întreg fără semn pe 8 biți (0-255): tipul unui octet, folosit pentru date binare și text ASCII/UTF-8.