Introdução
Converter números entre diferentes bases numéricas (decimal, binário, hexadecimal, octal) é uma operação frequente em programação de sistemas, protocolos de rede e manipulação de dados de baixo nível. Zig facilita essas conversões com formatação e parsing integrados.
Nesta receita, você aprenderá a converter números entre bases de forma prática e eficiente.
Pré-requisitos
- Zig instalado (versão 0.13+). Veja o guia de instalação
- Conhecimento básico de Zig. Consulte a introdução ao Zig
Converter Número para Diferentes Bases
Use formatadores de std.fmt para exibir números em diferentes bases:
const std = @import("std");
pub fn main() !void {
const numero: u32 = 255;
std.debug.print("Número: {d}\n\n", .{numero});
std.debug.print("Decimal: {d}\n", .{numero});
std.debug.print("Binário: {b}\n", .{numero});
std.debug.print("Octal: {o}\n", .{numero});
std.debug.print("Hexadecimal: {x}\n", .{numero});
std.debug.print("Hex maiúsc.: {X}\n", .{numero});
// Com padding e prefixo
std.debug.print("\nCom formatação:\n", .{});
std.debug.print("Binário 8 bits: {b:0>8}\n", .{numero});
std.debug.print("Binário 16 bits: {b:0>16}\n", .{numero});
std.debug.print("Hex 2 dígitos: {X:0>2}\n", .{numero});
std.debug.print("Hex 4 dígitos: {X:0>4}\n", .{numero});
std.debug.print("Hex 8 dígitos: {X:0>8}\n", .{numero});
}
Saída esperada
Número: 255
Decimal: 255
Binário: 11111111
Octal: 377
Hexadecimal: ff
Hex maiúsc.: FF
Com formatação:
Binário 8 bits: 11111111
Binário 16 bits: 0000000011111111
Hex 2 dígitos: FF
Hex 4 dígitos: 00FF
Hex 8 dígitos: 000000FF
Converter Strings para Números em Diferentes Bases
const std = @import("std");
pub fn main() !void {
// Parsear string hexadecimal
const hex_str = "FF";
const valor_hex = try std.fmt.parseInt(u32, hex_str, 16);
std.debug.print("Hex \"{s}\" = {d}\n", .{ hex_str, valor_hex });
// Parsear string binária
const bin_str = "11001010";
const valor_bin = try std.fmt.parseInt(u32, bin_str, 2);
std.debug.print("Bin \"{s}\" = {d}\n", .{ bin_str, valor_bin });
// Parsear string octal
const oct_str = "377";
const valor_oct = try std.fmt.parseInt(u32, oct_str, 8);
std.debug.print("Oct \"{s}\" = {d}\n", .{ oct_str, valor_oct });
// Parsear decimal
const dec_str = "42";
const valor_dec = try std.fmt.parseInt(u32, dec_str, 10);
std.debug.print("Dec \"{s}\" = {d}\n", .{ dec_str, valor_dec });
// Auto-detectar base (0x para hex, 0o para octal, 0b para binário)
const auto_hex = try std.fmt.parseInt(u32, "0xFF", 0);
const auto_bin = try std.fmt.parseInt(u32, "0b1010", 0);
const auto_oct = try std.fmt.parseInt(u32, "0o77", 0);
std.debug.print("\nAuto-detecção:\n", .{});
std.debug.print("0xFF = {d}\n", .{auto_hex});
std.debug.print("0b1010 = {d}\n", .{auto_bin});
std.debug.print("0o77 = {d}\n", .{auto_oct});
}
Tabela de Conversão
const std = @import("std");
pub fn main() !void {
std.debug.print("{s:>5} {s:>10} {s:>5} {s:>8}\n", .{ "Dec", "Bin", "Oct", "Hex" });
std.debug.print("{s:>5} {s:>10} {s:>5} {s:>8}\n", .{ "---", "---", "---", "---" });
const valores = [_]u8{ 0, 1, 7, 8, 10, 15, 16, 42, 100, 127, 255 };
for (&valores) |v| {
std.debug.print("{d:>5} {b:0>8} {o:>5} {X:0>2}\n", .{ v, v, v, v });
}
}
Converter Número para String em Base Específica
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const numero: u32 = 12345;
// Converter para string hexadecimal
const hex = try std.fmt.allocPrint(allocator, "{X}", .{numero});
defer allocator.free(hex);
// Converter para string binária
const bin = try std.fmt.allocPrint(allocator, "{b}", .{numero});
defer allocator.free(bin);
// Converter para string octal
const oct = try std.fmt.allocPrint(allocator, "{o}", .{numero});
defer allocator.free(oct);
std.debug.print("{d} em hex: {s}\n", .{ numero, hex });
std.debug.print("{d} em bin: {s}\n", .{ numero, bin });
std.debug.print("{d} em oct: {s}\n", .{ numero, oct });
// Com buffer fixo (sem alocação)
var buf: [64]u8 = undefined;
const resultado = try std.fmt.bufPrint(&buf, "0x{X:0>8}", .{numero});
std.debug.print("Formatado: {s}\n", .{resultado});
}
Manipulação de Bits
const std = @import("std");
pub fn main() !void {
const valor: u8 = 0b10110011;
std.debug.print("Valor: {b:0>8} ({d})\n\n", .{ valor, valor });
// Operações bit a bit
std.debug.print("NOT: {b:0>8}\n", .{~valor});
std.debug.print("AND 0x0F: {b:0>8}\n", .{valor & 0x0F});
std.debug.print("OR 0x0F: {b:0>8}\n", .{valor | 0x0F});
std.debug.print("XOR 0xFF: {b:0>8}\n", .{valor ^ 0xFF});
std.debug.print("Shift L 2: {b:0>8}\n", .{@as(u8, valor << 2)});
std.debug.print("Shift R 2: {b:0>8}\n", .{valor >> 2});
// Contar bits
std.debug.print("\nBits em 1: {d}\n", .{@popCount(valor)});
std.debug.print("Zeros à esquerda: {d}\n", .{@clz(valor)});
std.debug.print("Zeros à direita: {d}\n", .{@ctz(valor)});
}
Dicas e Boas Práticas
Literais numéricos em Zig: Use
0xpara hex,0opara octal,0bpara binário diretamente no código.std.fmt.parseIntcom base 0: Auto-detecta a base pelo prefixo da string.Formatadores:
{b}binário,{o}octal,{x}hex minúsculo,{X}hex maiúsculo.Padding:
{X:0>8}formata com zeros à esquerda em 8 dígitos.
Receitas Relacionadas
- Operações Matemáticas - Funções matemáticas
- Hex Encoding/Decoding - Codificação hexadecimal
- Formatar Strings com std.fmt - Formatação avançada
- Aritmética Segura (Overflow) - Overflow em operações