@bitSizeOf em Zig
O @bitSizeOf retorna o tamanho de um tipo em bits, sem incluir padding de alinhamento. Diferente de @sizeOf, que retorna bytes incluindo padding, @bitSizeOf retorna a quantidade exata de bits que compõem o tipo. Isso é particularmente útil ao trabalhar com tipos de bits não-padrão como u3, u24 ou i12.
Sintaxe
@bitSizeOf(comptime T: type) comptime_int
O que faz
O @bitSizeOf consulta a quantidade exata de bits que um tipo usa para representar seus dados, sem considerar bytes de padding adicionados para alinhamento. Para tipos padrão como u32, o resultado é simplesmente 32. Para tipos como u24, retorna 24 (enquanto @sizeOf retornaria 4 bytes = 32 bits, incluindo padding).
Parâmetros
- T (
type, comptime): O tipo cujo tamanho em bits será consultado.
Valor de retorno
Retorna um comptime_int representando o número exato de bits do tipo.
Exemplos práticos
Exemplo 1: Comparação com @sizeOf
const std = @import("std");
test "bitSizeOf vs sizeOf" {
// Para tipos alinhados, bitSizeOf == sizeOf * 8
try std.testing.expect(@bitSizeOf(u8) == 8);
try std.testing.expect(@bitSizeOf(u16) == 16);
try std.testing.expect(@bitSizeOf(u32) == 32);
try std.testing.expect(@bitSizeOf(u64) == 64);
// Para tipos de bits arbitrários, os valores diferem
try std.testing.expect(@bitSizeOf(u24) == 24);
try std.testing.expect(@sizeOf(u24) == 4); // 4 bytes com padding
try std.testing.expect(@bitSizeOf(u3) == 3);
try std.testing.expect(@sizeOf(u3) == 1); // 1 byte mínimo
try std.testing.expect(@bitSizeOf(bool) == 1);
try std.testing.expect(@sizeOf(bool) == 1); // 1 byte mínimo
}
Exemplo 2: Packed structs e layout de bits
const std = @import("std");
const Flags = packed struct {
leitura: bool, // 1 bit
escrita: bool, // 1 bit
execucao: bool, // 1 bit
especial: bool, // 1 bit
reservado: u4, // 4 bits
};
const CorRGB565 = packed struct {
vermelho: u5, // 5 bits
verde: u6, // 6 bits
azul: u5, // 5 bits
};
test "tamanho de packed structs" {
// Packed structs empacotam campos sem padding
try std.testing.expect(@bitSizeOf(Flags) == 8);
try std.testing.expect(@sizeOf(Flags) == 1);
try std.testing.expect(@bitSizeOf(CorRGB565) == 16);
try std.testing.expect(@sizeOf(CorRGB565) == 2);
}
Exemplo 3: Cálculos de capacidade de armazenamento
const std = @import("std");
fn bitsParaArmazenar(comptime T: type, n: usize) usize {
return @bitSizeOf(T) * n;
}
fn bytesNecessarios(comptime T: type, n: usize) usize {
const total_bits = bitsParaArmazenar(T, n);
return (total_bits + 7) / 8; // Arredondar para cima
}
test "cálculo de armazenamento" {
// 10 valores u12 precisam de 120 bits = 15 bytes
try std.testing.expect(bitsParaArmazenar(u12, 10) == 120);
try std.testing.expect(bytesNecessarios(u12, 10) == 15);
// 8 valores bool precisam de 8 bits = 1 byte
try std.testing.expect(bitsParaArmazenar(bool, 8) == 8);
try std.testing.expect(bytesNecessarios(bool, 8) == 1);
// 3 valores u3 precisam de 9 bits = 2 bytes
try std.testing.expect(bitsParaArmazenar(u3, 3) == 9);
try std.testing.expect(bytesNecessarios(u3, 3) == 2);
}
Casos de uso comuns
- Packed structs: Verificar o tamanho exato de campos empacotados para protocolos binários.
- Formatos de imagem: Trabalhar com formatos de cor como RGB565 (16 bits) ou RGB555 (15 bits).
- Compressão de dados: Calcular o espaço mínimo necessário para armazenar dados com tipos de bits arbitrários.
- Protocolos de comunicação: Definir e verificar layouts de bits em cabeçalhos de protocolo.
- Hardware e registradores: Validar que campos de registradores packed ocupam a quantidade correta de bits.
Builtins relacionados
- @sizeOf — Retorna o tamanho em bytes (com padding)
- @alignOf — Retorna o alinhamento do tipo
- @typeInfo — Informações completas sobre o tipo
- @bitReverse — Inverte a ordem dos bits