@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
- log2 inteiro: Calcular logaritmo base 2 eficientemente.
- Potência de 2 mais próxima: Encontrar próxima potência de 2 acima de um valor.
- Alocadores: Determinar bucket de tamanho em alocadores por tamanho.
- Compressão: Codificação de comprimento variável baseada em magnitude.
Builtins relacionados
- @ctz — Contar zeros à direita (trailing zeros)
- @popCount — Contar bits em 1
- @bitReverse — Inverter ordem dos bits
- @byteSwap — Inverter ordem dos bytes