Introdução ao ponto flutuante
Nesta página
Visão geral
O que é ponto flutuante?
Existem dois tipos de números:
- ponto fixo onde um certo número de dígitos está disponível antes e depois do ponto de base.
- ponto flutuante onde um certo número de dígitos está disponível para a mantissa e para o expoente.
Um exemplo usando dígitos decimais com três casas decimais antes do ponto decimal e duas casas decimais após a casa decimal:
- 0 seria representado como 000,00
- 0,123 seria representado como 000,12
- 0,00123 seria representado como 000,00
- 1 seria representado como 001,00
- 1.123 seria representado como 001.12
- 1,00123 seria representado como 001,00
- 123,456 seria representado como 123,45
- 1234,56 é um erro porque seria armazenado como 234,56 e isso está errado
Um exemplo usando dígitos decimais com cinco casas decimais para a mantissa e uma casa decimal para o expoente:
- 0 pode ser representado como 0,00000 x 10^0
- 0,1 pode ser representado como 0,10000 x 10^0
- 0,0000123456 pode ser representado como 0,12345 x 10^-4
- 0,000000000123456 pode ser representado como 0,12345 x 10^-9
- 0,00000000001 é um erro porque o expoente não é grande o suficiente para armazenar o número
- 1 pode ser representado como 0,10000 x 10^1
- 1,123 pode ser representado como 0,11230 x 10^1
- 1,00123 pode ser representado como 0,10012 x 10^1
- 123,45678 pode ser representado como 0,12345 x 10^2
- 123456789.1 pode ser representado como .12345 x 10^9
- 1000000000 é um erro porque o expoente não é grande o suficiente para armazenar o número
Portanto, um número de ponto flutuante pode representar números com magnitudes muito diferentes (0,000000000123456 e 123456789,1) com a mesma precisão relativa.
Os números de ponto fixo são úteis quando um determinado número de casas decimais é sempre necessário, independentemente da magnitude do número (dinheiro, por exemplo). Os números de ponto flutuante são úteis quando a magnitude varia e a precisão ainda é necessária. Por exemplo: para um engenheiro rodoviário, as distâncias são medidas em metros e 0,01 metro é insignificante, mas para um projetista de microchips a diferença entre 0,0000001 metros e 0,000000001 metros é enorme - e um físico pode precisar usar números enormes e muito, muito números minúsculos no mesmo cálculo. Precisão em muitas magnitudes diferentes é o que torna os números de ponto flutuante úteis.
Como funciona
Computadores não usam decimal - eles usam binário e isso causa problemas para ponto flutuante porque nem todo número decimal pode ser representado exatamente por um número de ponto flutuante e isso introduz erros de arredondamento nos cálculos.
Tendo feito todos os exemplos em decimal é importante notar que por serem binários, ao invés de armazenar um número de ponto flutuante como uma soma de frações decimais:
123.875 = 1/10^-2 + 2/10^-1 + 3/10^0 + 8/10^1 + 7/10^2 + 5/10^3
computadores armazenam números de ponto flutuante como uma soma de frações binárias:
123.875 = 1/2^-6 + 1/2^-5 + 1/2^-4 + 1/2^-3 + 1/2^-1 + 1/2^0 + 1/2^1 + 1/2^2 + 1/2^3
Existem muitas maneiras diferentes de armazenar padrões de bits que representam essas frações, mas a que a maioria dos computadores usa agora é baseada no padrão IEEE-754. Possui regras para armazenar representações decimais e binárias e para tipos de dados de diferentes tamanhos.
A maneira como os números normais são armazenados usando o padrão IEEE é:
- um bit para o sinal - armazenado no MSB, 1 significa negativo e 0 significa positivo
- alguns bits para o expoente - o viés é subtraído para obter expoentes positivos e negativos
- alguns bits para a mantissa - dígitos após a casa decimal com um 1 implícito antes da casa decimal.
Para permitir um underflow mais gradual, os números desnormalizados (quando os bits do expoente são todos zero) são tratados especialmente: o expoente é definido como -126 e o 1 implícito à esquerda antes da casa decimal NÃO é adicionado à mantissa.
Números de ponto flutuante IEEE-754 de 32 bits
Para um número normal de ponto flutuante IEEE-754 de 32 bits:
- bit 32 é o sinal
- bits 24-31 são o expoente - a polarização é 127
- bits 1-23 são a mantissa
Assim, um número normal é calculado como:
-1^sign * 2^(exponent-bias) * 1.mantissa
Se o padrão de bits fosse:
0 10000101 11101111100000000000000
Então o valor é:
-1^0 * 2^(133-127) * 1.111011111
-1^0 * 2^6 * (1 + 1/2 + 1/4 + 1/8 + 1/32 + 1/64 + 1/128 + 1/256 + 1/512)
1 * 64 * 991/512
123.875
Existem alguns valores especiais:
0 11111111 11111111111111111111111 = NaN
0 11111111 00000000000000000000000 = +infinity
1 11111111 00000000000000000000000 = -infinity
0 00000000 00000000000000000000000 = +Zero
1 00000000 00000000000000000000000 = -Zero
Especificações do formato IEEE-754 de 32 bits podem ser encontradas em:
- http://floating-point-gui.de/formats/fp
- https://en.wikipedia.org/wiki/Single-precision_floating-point_format
- https://en.wikipedia.org/wiki/IEEE_floating_point