@popCount em Zig — Referência e Exemplos

@popCount em Zig

O @popCount (Population Count) conta o número de bits com valor 1 em um inteiro. Também conhecido como “Hamming weight”. Mapeia diretamente para instruções de CPU como POPCNT (x86), resultando em operação extremamente eficiente. Usado em bitboards, compressão, hashing e verificação de paridade.

Sintaxe

@popCount(value: T) Log2T

Parâmetros

  • value (T): Valor inteiro cujos bits em 1 serão contados.

Valor de retorno

Retorna o número de bits com valor 1 no valor. Para um tipo de N bits, resultado varia de 0 a N.

Exemplos práticos

Exemplo 1: Contagem básica de bits

const std = @import("std");

pub fn main() void {
    std.debug.print("popCount(0b11001010) = {}\n", .{@popCount(@as(u8, 0b11001010))}); // 4
    std.debug.print("popCount(0xFF) = {}\n", .{@popCount(@as(u8, 0xFF))});             // 8
    std.debug.print("popCount(0) = {}\n", .{@popCount(@as(u8, 0))});                   // 0
    std.debug.print("popCount(7) = {}\n", .{@popCount(@as(u32, 7))});                  // 3
}

Exemplo 2: Verificar potência de 2

const std = @import("std");

fn ePotenciaDe2(valor: u64) bool {
    // Potências de 2 têm exatamente 1 bit ligado
    return valor != 0 and @popCount(valor) == 1;
}

pub fn main() void {
    std.debug.print("1 é pot2? {}\n", .{ePotenciaDe2(1)});     // true
    std.debug.print("16 é pot2? {}\n", .{ePotenciaDe2(16)});   // true
    std.debug.print("15 é pot2? {}\n", .{ePotenciaDe2(15)});   // false
    std.debug.print("1024 é pot2? {}\n", .{ePotenciaDe2(1024)}); // true
    std.debug.print("0 é pot2? {}\n", .{ePotenciaDe2(0)});     // false
}

Exemplo 3: Distância de Hamming

const std = @import("std");

fn distanciaHamming(a: u32, b: u32) u6 {
    // Distância de Hamming = número de bits diferentes
    return @popCount(a ^ b);
}

pub fn main() void {
    const d1 = distanciaHamming(0b1011101, 0b1001001);
    std.debug.print("Distância de Hamming: {}\n", .{d1}); // 2

    const d2 = distanciaHamming(0, 0xFF);
    std.debug.print("Distância 0 vs 0xFF: {}\n", .{d2}); // 8
}

Casos de uso comuns

  1. Verificar potência de 2: Potências de 2 têm exatamente um bit em 1.
  2. Distância de Hamming: Número de bits diferentes entre dois valores.
  3. Paridade: Paridade é @popCount(x) % 2.
  4. Bitboards: Contar peças em jogos de tabuleiro representados por bits.
  5. Hashing: Função auxiliar em algoritmos de hash.

Builtins relacionados

  • @clz — Contar zeros à esquerda
  • @ctz — Contar zeros à direita
  • @bitReverse — Inverter ordem dos bits
  • @byteSwap — Inverter ordem dos bytes

Tutoriais relacionados

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.