ieee754 floating-point computer-science precision programming-fundamentals

Padrão IEEE 754 para Ponto Flutuante: Entendendo a Aritmética Computacional

Por que 0.1 + 0.2 != 0.3 na programação? Aprenda a mecânica da representação e precisão de ponto flutuante IEEE 754.

2026-04-11

Padrão IEEE 754 para Ponto Flutuante: Entendendo a Aritmética Computacional

Se você já passou algum tempo programando, provavelmente encontrou um fenômeno estranho: 0.1 + 0.2 não é igual a 0.3. Em vez disso, você obtém algo como 0.30000000000000004. Isso não é um erro na sua linguagem; é uma consequência fundamental de como os computadores representam números reais usando o padrão IEEE 754.

Neste guia, desmistificaremos o padrão IEEE 754, explicaremos como os números de ponto flutuante são armazenados e forneceremos dicas para lidar com problemas de precisão em seu código.


O que é IEEE 754?

O Padrão IEEE para Aritmética de Ponto Flutuante (IEEE 754) é o padrão mais amplamente utilizado para computação de ponto flutuante. Estabelecido em 1985, ele define formatos para representar números reais em binário e as operações realizadas sobre eles.

Os formatos mais comuns são:

  • Precisão Simples (32 bits): Usado em float em C/C++/Java.
  • Precisão Dupla (64 bits): Usado em double em C/C++/Java e é o tipo de número padrão em JavaScript e Python.

Como funciona: A anatomia de um Float

Um número de ponto flutuante é representado de forma semelhante à notação científica ($1.23 \times 10^4$), mas em binário. Ele consiste em três partes:

  1. Bit de Sinal (1 bit): 0 para positivo, 1 para negativo.
  2. Expoente: Determina a escala do número.
  3. Mantissa (Significando): Representa os dígitos significativos.

Layout de Precisão Dupla de 64 bits:

  • Sinal: 1 bit
  • Expoente: 11 bits
  • Mantissa: 52 bits

A fórmula utilizada é: $(-1)^{sinal} \times (1.mantissa) \times 2^{expoente - bias}$


Por que $0.1 + 0.2 \neq 0.3$?

A causa raiz é que a maioria das frações decimais não pode ser representada exatamente em binário.

  • Na base 10, uma fração pode être representada exatamente se os fatores primos de seu denominador forem apenas 2 e 5 (os fatores de 10).
  • Na base 2, uma fração só pode ser representada exatamente se os fatores primos de seu denominador forem apenas 2.

$0.1$ é $1/10$. Como 10 tem um fator 5, ele se torna uma sequência repetitiva infinita em binário: 0.00011001100110011...

Os computadores devem arredondar essa sequência infinita para caber em 32 ou 64 bits, levando aos pequenos erros que vemos.


Valores Especiais

O IEEE 754 também define vários valores especiais para lidar com casos extremos:

  • NaN (Not a Number): Resultado de operações indefinidas (ex: 0/0).
  • Infinito ($\infty$): Resultado de estouro (overflow) ou divisão por zero (1/0).
  • Zero Negativo (-0): Distinto do zero positivo em alguns cálculos.

Melhores Práticas para Desenvolvedores

  1. Nunca use == para floats: Sempre verifique se a diferença é menor que um valor minúsculo (epsilon).
    if (Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON) { ... }
    
  2. Use decimais para dinheiro: Para cálculos financeiros, use bibliotecas especializadas (como decimal.js) ou armazene valores como inteiros (ex: centavos em vez de reais).
  3. Esteja atento ao intervalo: A precisão dupla pode representar números muito grandes, mas a precisão diminui à medida que os números aumentam.

Perguntas Frequentes FAQ

P: O ponto flutuante é não determinístico? R: Geralmente, não. Dados os mesmos valores de entrada e o mesmo modo de arredondamento, o IEEE 754 deve produzir os mesmos resultados. No entanto, diferentes compiladores ou instruções de CPU (como FMA) podem causar variações sutis.

P: O que é "BigInt"? R: O BigInt (no JS) lida com inteiros de precisão arbitrária. Ele não lida com frações. Para frações, você precisa de uma biblioteca Decimal.

P: Quantos dígitos decimais de precisión um double possui? R: Um double de 64 bits tem cerca de 15 a 17 dígitos decimais significativos.


Ferramentas Relacionadas