comptime_float em Zig — O que é e Como Usar
Definição
comptime_float é o tipo de ponto flutuante de alta precisão que existe apenas em tempo de compilação. Quando você escreve um literal como 3.14 ou 2.71828 em Zig, ele é inicialmente do tipo comptime_float. Internamente, o compilador usa representação de 128 bits (conforme IEEE 754), permitindo cálculos em comptime com muito mais precisão do que f32 ou f64.
Assim como comptime_int, o comptime_float não existe em runtime. Antes da execução, ele deve ser convertido para um tipo concreto como f32 ou f64.
Por que comptime_float Importa
- Precisão máxima em comptime: Constantes matemáticas e cálculos intermediários mantêm alta precisão até serem convertidos.
- Literais flexíveis: O valor
3.14pode ser atribuído tanto af32quanto af64sem cast explícito. - Tabelas pré-calculadas: Permite gerar lookup tables com cálculos precisos durante a compilação.
- Sem erro de arredondamento prematuro: O arredondamento só ocorre quando o valor é convertido para o tipo concreto.
Exemplo Prático
Literais Float e Coerção Automática
const std = @import("std");
pub fn main() void {
// 3.14 é comptime_float, convertido para cada tipo
const a: f32 = 3.14;
const b: f64 = 3.14;
std.debug.print("f32: {d:.10}\n", .{a}); // menos precisão
std.debug.print("f64: {d:.10}\n", .{b}); // mais precisão
}
Constantes Matemáticas em Comptime
const std = @import("std");
const PI = 3.14159265358979323846;
const E = 2.71828182845904523536;
// Cálculos em comptime com alta precisão
const TAU = 2.0 * PI;
const GRAUS_PARA_RAD = PI / 180.0;
pub fn main() void {
const angulo_graus: f64 = 45.0;
const angulo_rad: f64 = angulo_graus * GRAUS_PARA_RAD;
std.debug.print("45° = {d:.6} rad\n", .{angulo_rad});
std.debug.print("TAU = {d:.10}\n", .{@as(f64, TAU)});
}
Tabela de Senos em Comptime
const std = @import("std");
const TAMANHO_TABELA = 8;
const tabela_seno = blk: {
var tabela: [TAMANHO_TABELA]f64 = undefined;
for (0..TAMANHO_TABELA) |i| {
const angulo = @as(f64, @floatFromInt(i)) * (2.0 * std.math.pi / @as(f64, TAMANHO_TABELA));
tabela[i] = @sin(angulo);
}
break :blk tabela;
};
pub fn main() void {
for (tabela_seno, 0..) |valor, i| {
std.debug.print("sen[{}] = {d:.4}\n", .{ i, valor });
}
}
comptime_float vs f32/f64
| Característica | comptime_float | f32 | f64 |
|---|---|---|---|
| Precisão | ~128 bits | 32 bits | 64 bits |
| Existe em runtime | Nunca | Sim | Sim |
| Erro de arredondamento | Mínimo | Significativo | Moderado |
| Operações de I/O | Não | Sim | Sim |
Armadilhas Comuns
- Não pode existir em runtime: Variáveis
comptime_floatem funções normais causam erro. Devem ser convertidas paraf32ouf64. - Perda de precisão: Ao converter de
comptime_floatparaf32, há perda de precisão. Usef64quando precisar de mais dígitos significativos. - Comparação com zero: Cálculos em comptime podem dar resultado exato onde runtime teria erro de arredondamento. Não assuma que o comportamento em comptime será igual ao de runtime.
Termos Relacionados
- comptime_int — Tipo inteiro de precisão arbitrária em comptime
- Comptime — Execução em tempo de compilação
- Type Coercion — Regras de conversão automática de tipos
- anytype — Parâmetro de tipo inferido