i32::count_ones în Rust

Numără biții de 1 din reprezentarea binară a numărului (de exemplu 0b1011 are 3).

Sintaxă
const fn count_ones(self) -> u32
const fn count_zeros(self) -> u32
const fn leading_zeros(self) -> u32
const fn trailing_zeros(self) -> u32

Ce face i32::count_ones

count_ones() numără câți biți sunt 1 în cei 32 de biți ai numărului (operația se mai numește popcount). Este foarte rapidă: procesoarele moderne au o instrucțiune dedicată. Perechile: count_zeros(), leading_zeros() (zerourile de la stânga), trailing_zeros() (zerourile de la dreapta).

Pentru numere negative se numără biții din reprezentarea în complement față de 2: (-1_i32).count_ones() == 32. Se folosește la seturi de opțiuni păstrate ca biți (permisiuni, zilele săptămânii), la verificarea puterilor lui 2 și în algoritmi.

Ce returnează

u32.

Exemple

Exemplul 1: Biții unui număr

fn main() {
    for n in [0b1011_i32, 255, 1024, -1] {
        println!(
            "{n:>5} = {:032b}  unu: {:>2}  zero la stânga: {:>2}  zero la dreapta: {}",
            n,
            n.count_ones(),
            n.leading_zeros(),
            n.trailing_zeros()
        );
    }
}

Rezultat

   11 = 00000000000000000000000000001011  unu:  3  zero la stânga: 28  zero la dreapta: 0
  255 = 00000000000000000000000011111111  unu:  8  zero la stânga: 24  zero la dreapta: 0
 1024 = 00000000000000000000010000000000  unu:  1  zero la stânga: 21  zero la dreapta: 10
   -1 = 11111111111111111111111111111111  unu: 32  zero la stânga:  0  zero la dreapta: 0

Exemplul 2: Zile de lucru păstrate ca biți

Bitul 0 este luni, bitul 6 este duminică. count_ones spune câte zile sunt alese.

const ZILE: [&str; 7] = ["L", "Ma", "Mi", "J", "V", "S", "D"];

fn main() {
    let program_ana: i32 = 0b0011111; // luni-vineri
    let program_dan: i32 = 0b1100101; // luni, miercuri, sâmbătă, duminică

    for (nume, p) in [("Ana", program_ana), ("Dan", program_dan)] {
        let zile: Vec<&str> = (0..7).filter(|i| p & (1 << i) != 0).map(|i| ZILE[i]).collect();
        println!("{nume}: {} zile {:?}", p.count_ones(), zile);
    }
    println!("zile comune: {}", (program_ana & program_dan).count_ones());
    println!("64 este putere a lui 2: {}", 64_i32.count_ones() == 1);
}

Rezultat

Ana: 5 zile ["L", "Ma", "Mi", "J", "V"]
Dan: 4 zile ["L", "Mi", "S", "D"]
zile comune: 2
64 este putere a lui 2: true

Greșeli frecvente

  • Te aștepți ca count_ones pe un număr negativ să numere „cifrele”: numără biții din complementul față de 2 (-1 are 32 de biți de 1).

Comenzi înrudite

  • i32::from_str_radix: Transformă un text în număr într-o bază aleasă (2 = binar, 16 = hexazecimal etc.).
  • i32: Tipul implicit pentru numere întregi cu semn, pe 32 de biți: de la -2147483648 la 2147483647.
  • u8: Întreg fără semn pe 8 biți (0-255): tipul unui octet, folosit pentru date binare și text ASCII/UTF-8.