3.7. Fundamentos da Notação de Ponto Flutuante

A utilização da notação de ponto flutuante é muito grande em computadores, tanto para cálculos matemáticos com precisão, renderização de imagens digitais (criação de imagens pelo computador) entre outros. Os processadores atuais se dedicam muito em aperfeiçoar a técnica de seus chips para a aritmética de ponto flutuante, devido à demanda de aplicativos gráficos e jogos 3D que se utilizam muito deste recurso.

Nesta subseção iremos descrever os fundamentos da aritmética de ponto flutuante, para isso, serão apresentados alguns conceitos básicos, que juntamente com os conceitos da seção anterior, servirão para o entendimento do processo desta aritmética em um sistema computacional.

3.7.1. Notação de Excesso

Para trabalhar com a Notação Ponto Flutuante, precisamos entender a representação dos números inteiros (negativos e não negativos) utilizando a Notação de Excesso.

Neste sistema, cada número é codificado como um padrão de bits, de comprimento convencionado. Para estabelecer um sistema de excesso, primeiro escolhemos o comprimento do padrão a ser empregado, em seguida, escrevemos todos os diferentes padrões de bits com este comprimento, na ordem em que eles seriam gerados se estivéssemos contando em binário.

Logo, observamos que o primeiro desses padrões, que representa um dígito 1 como seu bit mais significativo, figura aproximadamente no centro da lista.

Tabela 3.3. Notação de excesso com 3 bits.

Valor Binário (Notação de Excesso) Valor Representado

000

-4

001

-3

010

-2

011

-1

100 (centro)

0

101

1

110

2

111

3


Como podemos observar na Tabela 3.3, “Notação de excesso com 3 bits.”, escolhemos este padrão para representar o ZERO, os padrões que o seguem serão utilizados para representar 1, 2, 3…, os padrões que o precedem serão adotados para a representação dos inteiros negativos -1, -2, -3…

Logo na Tabela 3.3, “Notação de excesso com 3 bits.” podemos observar o código resultante para padrões de três bits de comprimento.

Exemplo:

O valor 1 equivale a 1012

O valor -1 equivale a 0112

[Nota]

No sistema de Notação de Excesso é fácil distinguir entre padrões que representam valores negativos e positivos, pois aqueles que apresentam um 0 no bit mais significativo são números negativos, servindo o mesmo como bit de sinal.

3.7.2. Notação de Ponto Flutuante

O primeiro ponto a ser discutido, é o motivo da criação da Notação de Ponto Flutuante, já que na seção anterior já tínhamos trabalhado com a representação de números não inteiros utilizando a Notação de Ponto Fixo.

O problema do Ponto Fixo, é que o tamanho da parte inteira e da fracionária fica fixo com relação a seu armazenamento em memória, logo para números com a parte apenas inteira, a região alocada para tratar a parte fracionária será inutilizada e vice-versa. Logo, para evitar este desperdício criou-se a Notação de Ponto Flutuante.

Ponto Flutuante

Vamos explicar a notação de ponto flutuante por meio de um exemplo que emprega somente um byte de memória.

Primeiramente, escolhemos o bit mais significativo do byte para ser o bit de sinal do número. Um ‘0’ neste bit significa que o valor representado é não negativo, enquanto o ‘1’ indica que é negativo.

Em seguida dividimos os sete bits restantes em dois grupos, o campo de expoente e o campo da mantissa, como mostrado na Figura 3.5, “Divisão de 1 byte nos campos da Notação de Ponto Flutuante”.

Figura 3.5. Divisão de 1 byte nos campos da Notação de Ponto Flutuante

images/sistema-de-numeracao/sinal_expoente_mantissa.png

Seja um byte contendo o padrão de bits 01101011. Interpretando este padrão no formato que acabamos de definir, constatamos que o bit de sinal é ‘0’, o expoente é ‘110’, e a mantissa é ‘1011’.

Para decodificarmos o byte, extraímos primeiro a mantissa e colocamos o ponto binário à sua esquerda, obtendo:

.1011

Em seguida, extraímos o conteúdo do campo do expoente e o interpretamos como um inteiro codificado em três bits pelo método de representação de excesso, nos dando o número positivo 2 (vide Tabela 3.3, “Notação de excesso com 3 bits.”). Isto indica que devemos deslocar o ponto binário dois bits à direita (um expoente negativo codifica um deslocamento para a esquerda do ponto binário com a adição do valor 0).

Como resultado temos:

10.11

Que representa na Notação de Ponto Fixo:

= 1×21 + 0×20 + 1×2-1 + 1×2-2

= 2+0+0,5+0,25 = 2,75

Em seguida, notamos que o bit de sinal do nosso exemplo é 0, assim, o valor representado é positivo (+2,75).

Vídeo sobre o Notação de Ponto Flutuante: http://youtu.be/psyH7eBVLr4

[Nota]

O uso da notação de excesso para representar o expoente no sistema de Ponto Flutuante se dá pela comparação relativa das amplitudes de dois valores, consistindo apenas em emparelhar as suas representações da esquerda para a direita em busca do primeiro bit em que os dois diferem. Assim, se ambos os bits de sinal forem iguais a ‘0’, o maior dos dois valores é aquele que apresentar, da esquerda para a direita, um ‘1’ no bit em que os padrões diferem, logo ao comparar:

images/sistema-de-numeracao/figura7.png

Conclui-se que o primeiro padrão é maior que o segundo, sem haver a necessidade de decodificar as representações em Ponto Flutuante, tarefa que seria mais custosa.

Quando os bits de sinal forem iguais a ‘1’, o maior número é aquele que apresentar o ‘0’ na diferença dos padrões (sempre percorrendo o número da esquerda para a direita).

3.7.3. Problema com Arredondamento

Consideremos o incômodo problema de representar o número 2,625 no sistema de ponto flutuante de um byte. Primeiramente, escrevemos 2,625 em binário, obtendo 10.101. Entretanto, ao copiarmos este código no campo da mantissa, não haverá espaço suficiente, e o último 1 (o qual representa a última parcela: 0,125) se perde, como pode ser observado na figura abaixo:

2,62510 → 10.1012

Expoente → 110

Mantissa → 10101

Logo temos:

images/sistema-de-numeracao/bit_perdido.png

Ao ignorarmos este problema, e continuarmos a preencher o campo do expoente e do bit do sinal, teremos o padrão de bits 01101010, que representa o valor 2,5 e não 2,625: o fenômeno assim observado é denominado erro de arredondamento, devido o campo da mantissa ter apenas quatro bits, enquanto, por questão de precisão, seriam necessários no mínimo cinco bits.

Overflow e Underflow

Os projetistas do hardware devem encontrar um compromisso entre a mantissa e o expoente dos números em ponto flutuante. A relação entre mantissa e expoente é expressa do seguinte modo: o aumento do número de bits reservados à mantissa aumenta a precisão do número, enquanto o aumento do número de bits reservados ao expoente aumenta o intervalo de variação dos números representados.

Quando o expoente é muito grande ou muito pequeno para ser armazenado no espaço reservado para ele, ocorrem os fenômenos chamados de overflow e underflow respectivamente. Outro fenômeno é o próprio overflow da mantissa como mostrado acima.

3.7.4. Adição e Subtração em Ponto Flutuante

A adição e a subtração de ponto flutuante tratam os expoentes junto com o valor dos operandos, logo há a necessidade de equalizar os expoentes e efetuar a operação sobre a mantissa equalizada e o resultado deve ser normalizado para a representação utilizada:

Vamos analisar a seguinte adição em Ponto Flutuante:

01101010 + 01011100 = ?

Processo:

Mantissa 1 = 1010

Expoente = 110 (2 na Notação de Excesso)

Mantissa 2 = 1100

Expoente = 101 (1 na Notação de Excesso)

Equalizando os expoentes, temos:

images/sistema-de-numeracao/figura8.png

Normalizando:

Resultado = 1000

Expoente = 110 (2 na Notação de Excesso)

Representação do resultado (01101010 + 01011100) em Ponto Flutuante = 01101000