Skip to content

Glossary

IEEE 754

O padrão de ponto flutuante por trás de todo processador

By Published 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