@ctz em Zig — Referência e Exemplos

@ctz em Zig

O @ctz (Count Trailing Zeros) conta o número de bits zero consecutivos a partir do bit menos significativo (direita) de um valor inteiro. Mapeia diretamente para instruções de CPU eficientes (TZCNT/BSF em x86). Essencial para verificar alinhamento, encontrar o bit menos significativo e algoritmos de bitmap.

Sintaxe

@ctz(value: T) Log2T

Parâmetros

  • value (T): Valor inteiro cujos zeros à direita serão contados.

Valor de retorno

Retorna o número de zeros consecutivos do bit menos significativo. Para um tipo de N bits, o resultado varia de 0 a N.

Exemplos práticos

Exemplo 1: Contagem básica

const std = @import("std");

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

Exemplo 2: Verificar alinhamento

const std = @import("std");

fn alinhamentoDe(endereco: usize) usize {
    if (endereco == 0) return 0;
    const zeros = @ctz(endereco);
    return @as(usize, 1) << @intCast(zeros);
}

fn estaAlinhado(endereco: usize, alinhamento: usize) bool {
    return alinhamentoDe(endereco) >= alinhamento;
}

pub fn main() void {
    std.debug.print("Alinhamento de 16: {}\n", .{alinhamentoDe(16)});     // 16
    std.debug.print("Alinhamento de 24: {}\n", .{alinhamentoDe(24)});     // 8
    std.debug.print("Alinhamento de 4096: {}\n", .{alinhamentoDe(4096)}); // 4096

    std.debug.print("16 alinhado a 8? {}\n", .{estaAlinhado(16, 8)});    // true
    std.debug.print("24 alinhado a 16? {}\n", .{estaAlinhado(24, 16)});  // false
}

Exemplo 3: Iterar sobre bits ligados

const std = @import("std");

fn iterarBits(mascara: u32) void {
    var m = mascara;
    while (m != 0) {
        const bit = @ctz(m);
        std.debug.print("Bit {} está ligado\n", .{bit});
        m &= m - 1; // Limpar bit menos significativo
    }
}

pub fn main() void {
    iterarBits(0b10110100);
    // Bit 2 está ligado
    // Bit 4 está ligado
    // Bit 5 está ligado
    // Bit 7 está ligado
}

Casos de uso comuns

  1. Verificar alinhamento: Determinar o alinhamento de um endereço de memória.
  2. Bitmap: Encontrar o primeiro bit livre em um bitmap de alocação.
  3. Fatoração: Encontrar potência de 2 que divide um número.
  4. Iteração de bits: Percorrer eficientemente todos os bits ligados.

Builtins relacionados

Tutoriais relacionados

Continue aprendendo Zig

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