Introdução aos números em ponto flutuantes
Nesta seção examinaremos resumidamente como o computador representa números reais. A seção seguinte foi redigida para aqueles que desejam conhecer mais, estudando-a pode-se compreender a matemática associada ao conteito de representação de números em um computador digital e a razão do termo ponto flutuante.
Normalmente deve-se utilizar um número fixo de bits para representar cada número. Por exemplo, se determinado computador usar apenas 2 bytes (ou 16 bits) para representar um real e convencionar-se que o primeiro byte armazena a parte inteira e o segundo byte a parte decimal, teríamos uma variabilidade pequena de números. Como visto no texto introdutório sobre inteiros, com 8 bits, teríamos (simplificadamente) desde o 11111111 (primeiro bit indica negativo) até o 01111111, que em decimal seriam desde -127 até o 127, pois
[ Ponto fixo | Ponto flutuante (PF) | PF super simplificado | Exemplo | Erros | Entrada/saída ]
Para apresentar o conceito que interessa, de ponto flutuante, apresentarei sua contra-parte, como seria uma representação em ponto fixo. Vamos continuar usando 2 bytes (logo 16 bits) e considerar 3 agrupamentos: P1. o primeiro bit para representar o sinal do número (s=0 para positivo e s=1 para negativo); P2. os próximos 7 como a parte "decimal" (após vírgula decimal); e P3. os últimos 8 bits para o valor inteiro do número.
Assim, para obter o maior valor positivo que poderia ser representado nesta notação, deveríamos deixar o primeiro bit em zero
(para ser positivo) e todos os seguintes "ligados": 0 1111111 11111111 (deixei espaço em branco para indicar os 3 agrupamentos).
Assim, a parte "decimal" P2 (1111111) corresponde em decimal:
- maior valor positivo em binário 00111111 011111112 = 255.992188 em decimal; - menor valor estritamente positivo em binário 00000001 000000002 = 0.007812 em decimal. |
Um modelo de representação para real mais eficiente: ponto flutuante
Uma alternativa mais eficiente e amplamente utilizada na prática é a representação em ponto flutuante. Nessa representação também quebramos o número em três agrupamentos, a primeira sendo o sinal s, a segunda o expoente e e a terceira sendo mantissa m, assim o valor do número seria s x m x be. Se a mantissa tiver p dígitos, o número é: s x d0d1...dp-1 x be.
Assim, nota-se que a diferença entre a representações em ponto flutuante e em ponto fixo é o tratamento do segundo agrupamento. Para poder comparar ambas as representações, vamos novamente supor um computador com reais usando apenas 2 bytes.
Desse modo, o maior real positivo nesse ponto flutuante é obtido usando a maior potência e maior mantissa possiveis, respectivamente 0111111 e 11111111, que em decimal são,
De forma análoga, podemos computar o menor valor estritamente positivo que conseguimos com essa representação. Como são 7 bits para expoente e 8 bits para a mantissa, devemos pegar no agrupamento P2 a sequência 1111111 (maior potência negativa possível) e no agrupamento P3 o menor valor positivo, que seja maior que zero, portanto 00000001. Convertendo 1111111 para decimal, temos o valor -64, logo o menor positivo é: 2-64 que é aproximadamente 5.42101086243e-20 (tremendamente pequeno).
Portanto o maior positivo e o menor , convertendo para decimal, seria a soma de (1) e (2): 255.992188. Desse modo, em ponto fixo:
- maior valor positivo em binário 00111111 011111112 > 1.70141183 * 1038 em decimal; - menor valor estritamente positivo em binário 1111111 000000012 ~= 5.42101086243e-20 em decimal. |
Comparando os resultados de ponto flutuante com ponto fixo, tabelas 1 e 2, percebemo que ponto flutuante produz resultados muito melhores em termos de capacidade de "simular" os números reais.
Representação em ponto flutuante
Esta técnica de representação é a mais utilizada nos computadores, ela utiliza um bit para sinal, uma quantidade pequena de bits para o expoente e uma quantidade maior de bits para a parte "principal" do número. Em um dos padrões de representação (IEEE 754) o número é representado com 11 bits para o expoente e 52 bits para a mantissa.
Exemplo de representação em ponto flutuante
Para ilustrar o funcionamento de ponto flutuante, suponha um computador que use representação em decimal (os computadores na verdade usam base binária), tendo apenas 3 dígitos para mantissa e o expoente sendo de -4 até -4, assim teríamos p=3 e -4<e<4.
Deste modo, o maior valor real que pode ser representado seria o 999000, pois tomando a maior mantissa e maior expoente, teríamos 103 x 999 = 999000.
Já o menor valor estritamente positivo que conseguiríamos seria o 0.001, pois tomando a menor mantissa positiva e menor expoente possível (-3), teríamos 10-3 x 1 = 0.001.
Desse modo, nesse computador simples, a variação de números "reais" que poderiam ser representados nesse computador, seria:
- maior valor positivo: 999 x 103 = 999000; - menor valor estritamente positivo: 1 x 10-3 = 0.001. |
A primeira questão que aparece ao tratar números não inteiros no computador digital é a perda de precisão ou os erros numéricos. Por exemplo, mesmo em notação decimal o valor 1/3 não será representado perfeitamente, ele será registrado com algo semelhante a 0.3333 (se o computador utilizar 4 dígitos).
Um exemplo do problema numérico está ilustrado no exemplo abaixo, quando tentamos imprimir as somas de 0.1 até 0.9. Experimente copiar este trecho de código e roder em C ou em Python, você verá que o algoritmo nunca parará! Isso mesmo, laço infinito, pois como o computador utiliza notação binário e como o decimal 0.1 em binário corresponde a um binário periódico (como a dízima periódica resultante do 1/3 que é 0.3...).
C | Python | |
---|---|---|
|
Entrada e saída de flutuantes em C e em Python
Em C deve-se utilizar o formatador %f para indicar que os bits devem ser tratados como número em ponto flutuante, enquanto em Python deve-se utilizar a função float(...), como indicado no exemplo abaixo.
C | Python | |
---|---|---|
|
Aos alunos estudando com a linguagem C, tomem um cuidado adicional: o compilador C aceita utilizar o formatador
de inteiro na leitura e na impressão de uma variável em flutuante. Ele trunca o valor, assim se tiver float x=1.5;
e fizer
Uma boa fonte para pesquisar é examinar o texto na WikiPedia: floating-point.
Leônidas de Oliveira Brandão
http://line.ime.usp.br
Alterações:
2020/08/10: novas seções iniciais;
2020/04/18: inserido nomes nas tabelas, correcao tab. 1 ("x+=1.0"->"x+=0.1")
2017/04/14: primeira versão