comptime_float em Zig — O que é e Como Usar

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

  1. Precisão máxima em comptime: Constantes matemáticas e cálculos intermediários mantêm alta precisão até serem convertidos.
  2. Literais flexíveis: O valor 3.14 pode ser atribuído tanto a f32 quanto a f64 sem cast explícito.
  3. Tabelas pré-calculadas: Permite gerar lookup tables com cálculos precisos durante a compilação.
  4. 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ísticacomptime_floatf32f64
Precisão~128 bits32 bits64 bits
Existe em runtimeNuncaSimSim
Erro de arredondamentoMínimoSignificativoModerado
Operações de I/ONãoSimSim

Armadilhas Comuns

  • Não pode existir em runtime: Variáveis comptime_float em funções normais causam erro. Devem ser convertidas para f32 ou f64.
  • Perda de precisão: Ao converter de comptime_float para f32, há perda de precisão. Use f64 quando 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

Tutoriais Relacionados

Continue aprendendo Zig

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