@shlExact em Zig — Referência e Exemplos

@shlExact em Zig

O @shlExact realiza um shift left (deslocamento à esquerda) e garante que nenhum bit significativo é perdido (descartado pelo topo). Se algum bit 1 for deslocado para fora, causa panic em modo safe ou undefined behavior em release. É a versão “exata” do shift, útil quando o overflow de bits não é aceitável.

Sintaxe

@shlExact(value: T, shift_amt: Log2T) T

Parâmetros

  • value (T): Valor inteiro a ser deslocado.
  • shift_amt (Log2T): Número de posições para deslocar (tipo log2 do tamanho de T).

Valor de retorno

Retorna T — o resultado do shift left, garantindo que nenhum bit foi perdido.

Exemplos práticos

Exemplo 1: Shift exato seguro

const std = @import("std");

pub fn main() void {
    // Shift seguro: 1 << 4 = 16 (cabe em u8)
    const a: u8 = @shlExact(@as(u8, 1), 4);
    std.debug.print("1 << 4 = {}\n", .{a}); // 16

    // Shift seguro: 3 << 2 = 12
    const b: u8 = @shlExact(@as(u8, 3), 2);
    std.debug.print("3 << 2 = {}\n", .{b}); // 12

    // Isso causaria panic em safe mode:
    // @shlExact(@as(u8, 1), 8) — deslocaria o bit 1 para fora!
}

Exemplo 2: Construir flags com shift exato

const std = @import("std");

const Permissao = struct {
    pub fn flag(comptime bit: u5) u32 {
        return @shlExact(@as(u32, 1), bit);
    }
};

pub fn main() void {
    const LEITURA = Permissao.flag(0);    // 1
    const ESCRITA = Permissao.flag(1);    // 2
    const EXECUCAO = Permissao.flag(2);   // 4

    const permissoes = LEITURA | ESCRITA | EXECUCAO;
    std.debug.print("Permissões: 0b{b:0>3}\n", .{permissoes}); // 0b111
}

Exemplo 3: Multiplicação por potência de 2 verificada

const std = @import("std");

fn multiplicarPor2(valor: u16, potencia: u4) !u16 {
    // Usar @shlExact em vez de << para detectar overflow
    return @shlExact(valor, potencia);
}

test "multiplicar por potência de 2" {
    try std.testing.expect(multiplicarPor2(10, 3) catch unreachable == 80);
    try std.testing.expect(multiplicarPor2(1, 15) catch unreachable == 32768);
}

Casos de uso comuns

  1. Bit flags: Criar flags de bit com garantia de não overflow.
  2. Multiplicação por potência de 2: Shift como multiplicação verificada.
  3. Protocolos binários: Montar campos de bits com garantia de integridade.
  4. Criptografia: Operações de bit que não devem perder informação.

Builtins relacionados

Tutoriais relacionados

Continue aprendendo Zig

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