Ponto flutuante
Ponto flutuante (do inglês floating point) ou vírgula flutuante[1] é um formato de representação digital de números reais, que é usada nos computadores.
O número é dividido numa mantissa (M) e um expoente (E). O valor representado é obtido pelo produto: M · 2E
Desta forma é possível cobrir um largo espectro de números, maximizando o número de bits significativos e consequentemente a precisão da aproximação. Esta forma de representação foi criada por Konrad Zuse para os seus computadores Z1 e Z3.
O número de bits alocados para representar a mantissa e o expoente depende da norma utilizada. A maioria dos sistemas que operam com ponto flutuante utilizam representações definidas na norma IEEE 754.
A Norma 754-2008 define os formatos adequados para representar números em ponto flutuante de precisão simples (32 bits) e de precisão dupla (64 bits).
O formato de ponto flutuante de precisão simples (32 bits) consiste num bit de sinal (s), 8 bits de expoente (e) e uma mantissa de 23 bits (m). O bit de sinal (s) é 0 (zero) para números positivos e 1 para números negativos. O campo de expoente (e) corresponde à soma de 127 com o expoente de base 2 do número representado. O campo de mantissa (m) corresponde à parte fracionária da mantissa do número representado. Considera-se a sempre a mantissa normalizada entre 1 e 2. Desta forma a sua parte inteira é sempre apenas um bit igual a 1 (um) que não é necessário representar.
v = S × M × 2E
Onde:
S = 1 − 2 × s
M = 1.m = 1 + m × 2−23
E = e − 127
Índice |
[editar] Exemplos
A fração decimal:
0,125
é representada por: 1/10 + 2/100 + 5/1000. Da mesma forma, a fração binária:
0,001
tem valor: 0/2 + 0/4 + 1/8. Os dois valores são idênticos, sendo o primeiro escrito na base 10 e o segundo na base 2.
| Valor | S × M × 2E | s | m | e | IEEE 754 - Single Precision |
|---|---|---|---|---|---|
| 1 | 1 × 1 × 20 | 0 | 0x00 | 127 | 0 0111 1111 000 0000 0000 0000 0000 0001 |
| -1 | -1 × 1 × 20 | 1 | 0x00 | 127 | 1 0111 1111 000 0000 0000 0000 0000 0001 |
| 0,5 | 1 × 1 × 2−1 | 0 | 0x00 | 126 | 0 0111 1110 000 0000 0000 0000 0000 0000 |
| -0,5 | -1 × 1 × 2−1 | 1 | 0x00 | 126 | 1 0111 1110 000 0000 0000 0000 0000 0000 |
| 0,15625 | 1 × 1,25 × 2−3 | 0 | 0x200000 | 124 | 0 0111 1100 010 0000 0000 0000 0000 0000 |
[editar] Valores Especiais
As notações com os bits do campo expoente (e) todos a um ou todos a zero são reservadas para valores especiais. O zero é representado com e=0 e m=0. Outros valores de m com e=0 indicam números não normalizados. Nestas casos considera-se a mantissa entre 0 e 1.
| IEEE 754 - Single Precision | Valor | ||||
|---|---|---|---|---|---|
| s | e | m | |||
| 0 | 0000 0000 | 000 0000 0000 0000 0000 0000 | +0 | Zero | |
| 1 | 0000 0000 | 000 0000 0000 0000 0000 0000 | -0 | ||
| 0 | 1111 1111 | 000 0000 0000 0000 0000 0000 | +Inf | Infinito Positivo | |
| 1 | 1111 1111 | 000 0000 0000 0000 0000 0000 | -Inf | Infinito Negativo | |
| 0 | 1111 1111 | 010 0000 0000 0000 0000 0000 | +NaN | Not a Number | |
| 1 | 1111 1111 | 010 0000 0000 0000 0000 0000 | -NaN | ||
[editar] Implementação em Linguagens de Programação
Muitas frações decimais não podem ser representadas exatamente como frações binárias finitas. Por consequência, diversos números armazenados na máquina em váriaveis do tipo ponto flutuante (float, double, real) são apenas aproximações. [2]
Considere, por exemplo, a fração 1/3. Uma aproximação decimal seria:
-
- 0,3
- ou, melhor:
- 0,33
- ou, ainda melhor:
- 0,333
e assim por diante. Não existe uma fração finita capaz de resultar em exatamente 1/3.
Um outro exemplo interessante é a fração 1/10. Em muitas linguagens de programação, apesar de rotinas de impressão mostrar o valor 0,100000, se exibirmos o número com maior precisão (por exemplo, 20 casas decimais), veremos que o valor real armazendo será algo aproximado de:
0,10000000149001612000 (o valor pode mudar segundo o hardware e a linguagem utilizada).
Assim, ao programar é preciso ter cuidado com números em ponto flutuante, em especial com acumuladores e comparações.
Referências
- ↑ O termo "vírgula flutuante" é uma adaptação do termo inglês para os países que utilizam a vírgula como separador decimal. No entanto, como a maioria das linguagens de programação utilizam o inglês como base e os separadores decimais são representados com um ponto, este termo não é muito utilizado e/ou conhecido, sendo preferido e amplamente utilizado o seu equivalente em inglês.
- ↑ Floating Point Arithmetic: Issues and Limitations (em inglês). Python v2.6.4 documentation.