@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
- Verificar alinhamento: Determinar o alinhamento de um endereço de memória.
- Bitmap: Encontrar o primeiro bit livre em um bitmap de alocação.
- Fatoração: Encontrar potência de 2 que divide um número.
- Iteração de bits: Percorrer eficientemente todos os bits ligados.
Builtins relacionados
- @clz — Contar zeros à esquerda (leading zeros)
- @popCount — Contar bits em 1
- @bitReverse — Inverter ordem dos bits
- @byteSwap — Inverter ordem dos bytes