Glossary
IEEE 754
O padrão de ponto flutuante por trás de todo processador
By Buğra SözeriPublished Updated
IEEE 754 é o padrão para aritmética de ponto flutuante, publicado pela primeira vez em 1985 e atualizado em 2008 e 2019. Define formatos de ponto flutuante binário e decimal, comportamento de arredondamento, tratamento de exceções e os valores especiais (NaN, ±Infinito, −0).
O formato padrão de dupla precisão é o que os Números do JavaScript, floats do Python e a maioria dos outros tipos “número” em linguagens modernas usam:
- 64 bits no total
- 1 bit de sinal
- 11 bits de expoente
- 52 bits de mantissa
- ~15-17 dígitos decimais significativos de precisão
- Intervalo de aproximadamente 4,9e−324 a 1,8e+308
O famoso exemplo: 0.1 + 0.2 === 0.3 retorna false em quase todas as linguagens. A razão: 0.1 e 0.2 não têm representações binárias exatas (assim como 1/3 não tem representação decimal exata). Seus valores armazenados são muito próximos, mas não exatamente 0.1 e 0.2, e a soma amplifica o pequeno erro. O resultado é 0.30000000000000004.
Implicações para nossas ferramentas: a maioria das conversões é precisa para ~15 dígitos decimais, o que é mais do que qualquer entrada que aceitamos. Onde isso importa: valores de criptomoedas, onde 18 decimais de Wei excedem o intervalo de Number — usamos BigInt lá para manter a precisão exata.
Exemplo prático
Considere o cálculo 0.1 + 0.2 em JavaScript. O literal 0.1 em binário IEEE 754 é na verdade 0.10000000000000000555111512312578… (o double representável mais próximo). 0.2 é 0.20000000000000001110223024625157…. Somá-los e arredondar para o double representável mais próximo dá 0.30000000000000004440892098500626…, exibido como 0.30000000000000004. A resposta matemática verdadeira 0.3 também não é representável exatamente em binário — sua representação é aproximadamente 0.299999…9989…. O erro está no último ulp (unidade no último lugar), cerca de 1 em 10¹⁶. Para números visíveis é invisível; para somas de milhões de pequenos valores, acumula: somar 0.1 cem vezes em um loop e comparar com 10.0 retornará false (o resultado é 9.99999999999999822364…). Use a soma de Kahan ou soma compensada quando a precisão importa em acumulações longas.
Dois outros problemas com valores especiais que vale a pena conhecer: números subnormais (valores muito pequenos próximos a zero com precisão reduzida) trocam alcance representável por underflow suave, e NaNs sinalizadores (sNaN) podem ser usados para interceptar memória não inicializada, embora a maioria das linguagens mapeie todos os NaNs para NaNs quietos (qNaN) e nunca exponha essa distinção ao código do usuário.
Quando e por que importa
IEEE 754 importa sempre que o código compara floats por igualdade, soma muitos números pequenos ou lida com valores próximos aos limites do formato. O bug financeiro clássico é calcular “total = total + 0.01” em um loop um milhão de vezes e descobrir que o resultado está levemente errado o suficiente para falhar uma reconciliação de balanço. A correção é nunca usar floats para dinheiro — use BigDecimal, decimal.Decimal do Python, decimal.js do JavaScript, ou armazene valores como inteiros (centavos em vez de reais, satoshis em vez de bitcoin, wei em vez de ETH). O outro bug clássico é o cancelamento catastrófico que ocorre ao subtrair dois floats quase iguais — os dígitos significativos principais se cancelam, deixando apenas o ruído nos bits inferiores. Livros de análise numérica dedicam capítulos inteiros a algoritmos (como a fórmula de variância estável, soma de Kahan, algoritmo online de Welford) que evitam essa armadilha. Referência: Goldberg D. — O que todo cientista da computação deve saber sobre aritmética de ponto flutuante.
Os cinco valores especiais que todos esquecem: IEEE 754 define +0 e −0 como distintos (eles são iguais por comparação, mas produzem resultados diferentes na divisão — 1/+0 é +∞ enquanto 1/−0 é −∞), +Infinity e −Infinity para estouro, e NaN (Não É um Número) para operações indefinidas como 0/0 ou √−1. NaN é famosamente diferente de si mesmo — NaN === NaN é false — o que é como IEEE 754 propaga erros por meio do cálculo em vez de mascarar. A verificação Number.isNaN() existe em toda linguagem moderna precisamente porque a verificação de igualdade óbvia não funciona.
Quando você genuinamente precisa de decimal exato — e o que usar em vez disso: para dinheiro, nunca use floats. BigDecimal do Java, decimal.Decimal do Python, bibliotecas JavaScript como decimal.js e o tipo NUMERIC do PostgreSQL implementam aritmética decimal exata. O custo é cerca de 10-100× mais lento do que operações com float nativas, o que é aceitável para qualquer sistema de transações voltado ao usuário. Para computação científica onde o comportamento de arredondamento importa, o arredondamento para par mais próximo do IEEE 754 (arredondamento do banqueiro) é o que produz somas acumuladas estáveis; o arredondamento metade para cima envolve viés para cima. A maioria das linguagens usa arredondamento metade para par por esse motivo. Referência: IEEE 754-2019 — Aritmética de Ponto Flutuante.
Frequently asked questions
- O que é IEEE 754?
- IEEE 754 é o padrão internacional para aritmética de ponto flutuante usado em praticamente todos os processadores e linguagens de programação. Define como números reais são representados em binário como campos de sinal, expoente e mantissa.
- Por que 0.1 + 0.2 não é igual a 0.3 na maioria das linguagens?
- 0.1 e 0.2 não podem ser representados exatamente em ponto flutuante binário — são armazenados como o valor representável mais próximo. Adicionar duas aproximações amplifica o erro de arredondamento, produzindo 0.30000000000000004 em dupla precisão IEEE 754.
- Qual é a diferença entre float (32 bits) e double (64 bits)?
- Um float de 32 bits tem cerca de 7 dígitos decimais significativos de precisão; um double de 64 bits tem cerca de 15–17. Cálculos financeiros e científicos geralmente requerem dupla precisão para evitar acumular erros de arredondamento.
- Como lidar com aritmética decimal exata no código?
- Use uma biblioteca decimal (módulo decimal do Python, BigDecimal do Java, tipo NUMERIC do SQL) em vez de floats nativos. Alternativamente, trabalhe em centavos inteiros para moedas — armazene R$ 1,99 como 199 e apenas converta para uma string decimal para exibição.
Related
Published May 15, 2026 · Last reviewed May 31, 2026