Abra o console do navegador, digite 0.1 + 0.2 em JavaScript e, em vez de 0.3, o resultado é 0.30000000000000004. Não é um bug do JavaScript — é uma consequência direta de como o padrão IEEE 754 representa números fracionários em binário, e o mesmo resultado aparece em Python, Java, C# e praticamente qualquer linguagem baseada nesse padrão.
As três partes de um número de ponto flutuante
Um número IEEE 754 é armazenado como três componentes: um sinal (positivo ou negativo), uma mantissa (os dígitos significativos do número) e um expoente (a potência pela qual a vírgula é deslocada). É semelhante à notação científica: 1.5 × 10², mas em binário.
Por que 0.1 não pode ser representado exatamente em binário
0.1 em decimal é uma fração infinita em binário (de forma semelhante a como 1/3 é infinito em decimal). Um computador só armazena uma quantidade limitada de bits de mantissa, então o número é arredondado para o valor representável mais próximo — e é exatamente esse arredondamento que causa o "erro" visível.
Onde isso realmente atrapalha: carrinho de compras e troco
Uma tela de checkout que soma preços como floats simples pode desviar um ou dois centavos do total esperado depois de itens suficientes — cada soma arredonda um pouco, e os erros se acumulam em vez de se cancelar. É por isso que sistemas de pagamento costumam trabalhar com centavos como números inteiros, ou usam um tipo decimal dedicado, em vez de somar floats diretamente.
Para que serve isso
- Entender e diagnosticar erros de arredondamento inesperados em cálculos financeiros ou científicos.
- Ver a representação binária exata de um número de ponto flutuante específico.
- Explicar a um colega ou estudante por que comparar números fracionários por igualdade exata é uma má prática.
Números subnormais perto de zero
Quando o valor de um número é pequeno demais para a representação normal (uma mantissa que começa com um 1 implícito), o IEEE 754 muda para o modo subnormal (desnormalizado), onde esse 1 implícito é descartado — isso permite representar números ainda menores em magnitude ao custo de uma perda gradual de precisão em vez de um salto brusco para zero. Essa transição "suave" para zero é preferível a um zero abrupto, mas cálculos subnormais são notavelmente mais lentos que os normais em alguns processadores.