@floatFromInt em Zig
O @floatFromInt converte um valor inteiro para um tipo de ponto flutuante. É a operação inversa de @intFromFloat. Essa conversão é necessária em Zig porque a linguagem não realiza conversões numéricas implícitas, mantendo todo o código explícito e previsível.
Sintaxe
@floatFromInt(valor: anytype) FloatType
O tipo de retorno é inferido pelo contexto.
O que faz
O @floatFromInt converte um valor inteiro (com ou sem sinal, de qualquer tamanho) para um tipo de ponto flutuante. Se o valor inteiro não puder ser representado exatamente no tipo float de destino (por exemplo, um i64 muito grande convertido para f32), o resultado é arredondado para o valor representável mais próximo.
Parâmetros
- valor (
anytype): Um valor inteiro de qualquer tipo (u8,i32,u64,comptime_int, etc.) a ser convertido para ponto flutuante.
Valor de retorno
Retorna o valor convertido como o tipo de ponto flutuante de destino, inferido pelo contexto.
Exemplos práticos
Exemplo 1: Conversões básicas
const std = @import("std");
test "conversão inteiro para float" {
const a: i32 = 42;
const b: u8 = 255;
const x: f64 = @floatFromInt(a);
const y: f32 = @floatFromInt(b);
try std.testing.expect(x == 42.0);
try std.testing.expect(y == 255.0);
// Também funciona com negativos
const c: i16 = -100;
const z: f64 = @floatFromInt(c);
try std.testing.expect(z == -100.0);
}
Exemplo 2: Cálculo de média
const std = @import("std");
fn media(valores: []const i32) f64 {
var soma: i64 = 0;
for (valores) |v| {
soma += v;
}
// Converter soma e contagem para float antes de dividir
const soma_f: f64 = @floatFromInt(soma);
const n: f64 = @floatFromInt(valores.len);
return soma_f / n;
}
test "calcular média" {
const notas = [_]i32{ 85, 92, 78, 96, 88 };
const resultado = media(¬as);
try std.testing.expectApproxEqAbs(87.8, resultado, 0.001);
}
Exemplo 3: Normalização de valores
const std = @import("std");
fn normalizar(valor: u16) f32 {
// Converter valor de 0-65535 para 0.0-1.0
const max: f32 = @floatFromInt(std.math.maxInt(u16));
const v: f32 = @floatFromInt(valor);
return v / max;
}
fn normalizarParaAudio(amostra: i16) f32 {
// Converter amostra de áudio PCM (-32768 a 32767) para -1.0 a 1.0
const max: f32 = @floatFromInt(std.math.maxInt(i16));
const v: f32 = @floatFromInt(amostra);
return v / max;
}
test "normalização" {
try std.testing.expectApproxEqAbs(0.0, normalizar(0), 0.001);
try std.testing.expectApproxEqAbs(1.0, normalizar(65535), 0.001);
try std.testing.expectApproxEqAbs(0.5, normalizar(32767), 0.01);
try std.testing.expectApproxEqAbs(0.0, normalizarParaAudio(0), 0.001);
try std.testing.expectApproxEqAbs(1.0, normalizarParaAudio(32767), 0.001);
}
Casos de uso comuns
- Cálculos matemáticos: Converter contadores, índices ou medições inteiras para float antes de operações de divisão, raiz quadrada, etc.
- Processamento de áudio: Converter amostras PCM inteiras para valores normalizados de ponto flutuante.
- Gráficos e renderização: Converter dimensões de pixel (inteiros) para coordenadas de mundo (float).
- Estatística: Calcular médias, desvios padrão e outras medidas a partir de dados inteiros.
- Progresso e porcentagens: Calcular porcentagem de conclusão dividindo valores inteiros.
fn progresso(atual: usize, total: usize) f64 {
const a: f64 = @floatFromInt(atual);
const t: f64 = @floatFromInt(total);
return (a / t) * 100.0;
}
Observações sobre precisão
Tipos de ponto flutuante têm precisão limitada. Um f32 tem apenas 23 bits de mantissa, então inteiros maiores que 2^24 podem perder precisão ao serem convertidos. Para máxima precisão, use f64 (52 bits de mantissa) ou f128 quando necessário.
Builtins relacionados
- @intFromFloat — Operação inversa: converte float para inteiro
- @as — Conversão de tipo genérica
- @floatCast — Conversão entre tipos de float
- @intFromEnum — Converte enum para inteiro