@clz em Zig — Referência e Exemplos

@clz em Zig

O @clz (Count Leading Zeros) conta o número de bits zero consecutivos a partir do bit mais significativo (esquerda) de um valor inteiro. É uma operação fundamental para manipulação de bits, cálculo de log2, detecção do bit mais significativo e algoritmos de alocação.

Sintaxe

@clz(value: T) Log2T

Parâmetros

  • value (T): Valor inteiro (unsigned ou signed) cujos zeros à esquerda serão contados.

Valor de retorno

Retorna o número de zeros consecutivos do bit mais significativo. Para um tipo de N bits, o resultado varia de 0 (nenhum zero) a N (valor é zero).

Exemplos práticos

Exemplo 1: Contagem básica de leading zeros

const std = @import("std");

pub fn main() void {
    // u8: 8 bits
    std.debug.print("clz(0b10000000) = {}\n", .{@clz(@as(u8, 0b10000000))}); // 0
    std.debug.print("clz(0b00010000) = {}\n", .{@clz(@as(u8, 0b00010000))}); // 3
    std.debug.print("clz(0b00000001) = {}\n", .{@clz(@as(u8, 0b00000001))}); // 7
    std.debug.print("clz(0b00000000) = {}\n", .{@clz(@as(u8, 0b00000000))}); // 8
}

Exemplo 2: Calcular log2 inteiro

const std = @import("std");

fn log2Floor(valor: u32) u5 {
    if (valor == 0) @panic("log2(0) indefinido");
    return 31 - @clz(valor);
}

fn proximaPotenciaDe2(valor: u32) u32 {
    if (valor <= 1) return 1;
    const bits = 32 - @clz(valor - 1);
    return @as(u32, 1) << @intCast(bits);
}

pub fn main() void {
    std.debug.print("log2(1) = {}\n", .{log2Floor(1)});     // 0
    std.debug.print("log2(8) = {}\n", .{log2Floor(8)});     // 3
    std.debug.print("log2(100) = {}\n", .{log2Floor(100)}); // 6

    std.debug.print("prox_pot2(5) = {}\n", .{proximaPotenciaDe2(5)});   // 8
    std.debug.print("prox_pot2(16) = {}\n", .{proximaPotenciaDe2(16)}); // 16
    std.debug.print("prox_pot2(17) = {}\n", .{proximaPotenciaDe2(17)}); // 32
}

Exemplo 3: Número mínimo de bits necessários

const std = @import("std");

fn bitsNecessarios(valor: u64) u7 {
    if (valor == 0) return 1;
    return @intCast(64 - @clz(valor));
}

pub fn main() void {
    std.debug.print("Bits para 255: {}\n", .{bitsNecessarios(255)});   // 8
    std.debug.print("Bits para 256: {}\n", .{bitsNecessarios(256)});   // 9
    std.debug.print("Bits para 1000: {}\n", .{bitsNecessarios(1000)}); // 10
}

Casos de uso comuns

  1. log2 inteiro: Calcular logaritmo base 2 eficientemente.
  2. Potência de 2 mais próxima: Encontrar próxima potência de 2 acima de um valor.
  3. Alocadores: Determinar bucket de tamanho em alocadores por tamanho.
  4. Compressão: Codificação de comprimento variável baseada em magnitude.

Builtins relacionados

Tutoriais relacionados

Continue aprendendo Zig

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