You are on page 1of 0

7-1

Capítulo
SETE
Números em Ponto Fixo e Ponto Flutuante
7. 1 Números em ponto fixo
Observação inicial: os termos “ponto fixo” e “ponto flutuante” são traduções diretas dos
termos ingleses “fixed point” e “floating point”, que se referem ao símbolo utilizado nos
países de língua inglesa para representar a vírgula decimal. As traduções corretas seriam,
respectivamente, “vírgula fixa” e “vírgula flutuante”. Entretanto, devido ao fato dos termos
“ponto fixo” e “ponto flutuante” já serem de uso corrente na literatura especializada nacional,
eles serão empregados aqui também .
Todos os números tratados até agora foram números inteiros, onde uma vírgula binária não
apareceu explicitamente. Entretanto, estes números podem ser interpretados como
apresentando uma vírgula à direita do dígito menos significativo (a posição das unidades).
Assim, por exemplo, o número binário em complemento de dois
0 1 1 0 0 1 1 1
que corresponde ao número decimal 103, pode ser interpretado como apresentando uma
vírgula à extrema direita
0 1 1 0 0 1 1 1,
sem que isto altere o valor por ele representado. Tem-se então uma representação em “ponto
fixo”, mas sem parte fracionária. Caso deseje-se representar frações, deve-se reservar um
certo número de bits para isto. Naturalmente, a quantidade de bits utilizáveis para a parte
inteira diminui correspondentemente. Por exemplo, para a mesma cadeia de bits acima, tem-
se os seguintes números, conforme a posição da vírgula:
0 1 1 0 0 1 1, 1 Decimal = 51,5 (1 bit para fração)
0 1 1 0 0 1, 1 1 Decimal = 25,75 (2 bits para fração)
0 1 1 0 0, 1 1 1 Decimal = 12,875 (3 bits para fração)
0 1 1, 0 0 1 1 1 Decimal = 3,21875 (5 bits para fração)
0, 1 1 0 0 1 1 1 Decimal = 0,8046875 (7 bits para fração)
, 01 1 0 0 1 1 1 Decimal = 0,40234375 (8 bits para fração)
Ao contrário dos exemplos acima, a vírgula não é representada explicitamente. Para uma
determinada notação em ponto fixo, indica-se somente quantos bits são usados para a fração
e quantos bits representam a parte inteira. Todos os números manipulados seguem então a
mesma notação. Dos ‘n’ bits utilizados para representar os números, utilizam-se então ‘t’ bits
(t≥0) para a parte inteira e ‘f’ bits (f≥0) para a parte fracionária, com a restrição de que
t+f=n. Observe-se ainda que:
7-2
• a quantidade total de valores representáveis permanece a mesma (2
n
), independente da
posição da vírgula (isto é, independente dos valores de ‘t’e ‘f’).
• a faixa de valores representáveis depende da posição da vírgula (e da convenção
utilizada, naturalmente). De um modo geral, a faixa é dada pelas mesmas fórmulas
vistas anteriormente (sinal/magnitude, complemento de dois, etc), mas todos os
números são agora divididos por um fator igual a 2
f
. Assim, por exemplo, em
complemento de dois, o maior número negativo é dado por –2
n-1
/2
f
(ou seja, –2
n-f-1
);
o maior número positivo é calculado por (2
n-1
–1)/2
f
.
• os números fracionários não são contínuos, mas sim estão separados entre si por uma
diferença igual a 2
-f
.
A tabela a seguir ilustra estas observações para números de 8 bits, representados em
complemento de dois (a coluna intervalo indica a diferença entre dois números consecutivos):
n t f Quant. num. Menor num. Maior num. Intervalo
8 8 0 256 -128 127 1
8 7 1 256 -64 63,5 0,5
8 6 2 256 -32 31,75 0,25
8 5 3 256 -16 15,875 0,125
8 4 4 256 -8 7,9375 0,0625
8 3 5 256 -4 3,96875 0,03125
8 2 6 256 -2 1,984375 0,015625
8 1 7 256 -1 0,9921875 0,0078125
8 0 8 256 -0,5 0,49609375 0,00390625
Tabela 7.1 - Números em ponto fixo de 8 bits
7. 2 Soma e subtração em ponto fixo
As operações de soma e subtração em ponto fixo se realizam exatamente da mesma maneira
que para números inteiros. Naturalmente, somente podem ser somados (ou subtraídos)
números que possuam a mesma posição para a vírgula. Ou seja, ‘t’ e ‘f’ devem ser iguais
para todos os operandos.
Entretanto, números em ponto fixo com diferentes posições para a vírgula também podem
ser operados, desde que um dos números seja convertido para a representação do outro.
Sejam os números ‘m
1
’ e ‘m
2
’, com comprimentos ‘t
1
’ e ‘f
1
’, e ‘t
2
’ e ‘f
2
’, respectivamente.
O resultado deve ter a representação de ‘m1’, ou seja, comprimentos ‘t
1
’ e ‘f
1
’ para as partes
inteira e fracionária.
Se ‘t
1
’ > ‘t
2
’ (a parte inteira de m
1
utiliza mais bits que a parte inteira de m
2
), então valem as
regras:
1. A parte inteira de m
2
, com t
2
bits, deve ser extendida para t
1
bits. Os bits devem ser
tais que o sinal e o valor do número sejam mantidos. Assim, por exemplo, para
números inteiros positivos, t
1
– t
2
bits em zero são acrescentados à esquerda de m
2
.
Para números em complemento de dois, o sinal deve ser duplicado para a esquerda por
t
1
– t
2
bits.
2. A parte fracionária de m
2
deve ser reduzida para f
1
bits. Isto pode ocorrer de duas
maneiras: por truncagem ou por arredondamento. Na truncagem, os f
2
–f
1
bits a direita
de m
2
são simplesmente eliminados. No arredondamento, primeiro soma-se 2
–(f
1
+1)
à
7-3
m
2
e depois realiza-se a truncagem. Note-se que isto equivale a somar um ‘1’ na
posição f
2
– f
1
do número; em termos aritméticos, significa que se a fração a ser
eliminada é maior ou igual a 0,5 arredonda-se para cima, senão arredonda-se para
baixo.
A tabela abaixo ilustra alguns exemplos de conversão. Considere-se que o número final deve
ser representado com 4 bits de parte inteira e 4 bits de parte fracionária. ‘T’ representa a nova
fração sob truncagem, e ‘A’ representa a nova fração sob arredondamento.
Num.original Representação Parte inteira Fração (T) Fração (A)
01,101101 Int. positivo 0001 1011 1011
11,101101 Int. positivo 0011 1011 1011
010,00111 Int. positivo 0010 0011 0100
01,101101 Compl.dois 0001 1011 1011
11,101101 Compl.dois 1111 1011 1011
010,00111 Compl.dois 0010 0011 0100
Tabela 7.2 - Exemplos de redução de fração
Se ‘t
1
’ < ‘t
2
’ (a parte inteira de m
1
utiliza menos bits que a parte inteira de m
2
), então valem
as regras:
1. A parte inteira de m
2
, com t
2
bits, deve ser reduzida para t
1
bits. Isto só é possível se
esta parte inteira puder ser representada com somente t
1
bits. Se isto não for possível,
a operação não pode ser realizada, pois ocorre estouro de representação. Para esta
redução valem as regras analisadas na multiplicação, quando se reduzia um número de
‘2n’ bits para ‘n’ bits.
2. A parte fracionária de m
2
deve ser ampliada para f
1
bits. Para isto, simplesmente
acrescenta-se f
1
– f
2
bits em zero à direita da fração de m
1
.
A tabela a seguir ilustra alguns exemplos de conversão. Considere-se que o número final
deve ser representado com 4 bits de parte inteira e 4 bits de parte fracionária.
Num.original Representação Parte inteira Fração
01101,101 Int. positivo 1101 1010
111011,01 Int. positivo Estouro 0100
01000,111 Int. positivo 1000 1110
0110110,1 Compl.dois Estouro 1000
11101,101 Compl.dois 1101 1010
0001011,1 Compl.dois Estouro 1000
Tabela 7.3 - Exemplos de redução de mantissa
Observe-se que sempre é possível converter um número em ponto fixo para uma
representação que tenha menos bits na parte fracionária (ou mais bits na parte inteira),
enquanto que o contrário nem sempre é possível Assim, quando se deve operar dois
números em ponto fixo com t1 e t2 diferentes, costuma-se normalizar os operandos para
aquela representação com maior parte inteira.
7. 3 Multiplicação em ponto fixo
A operação de multiplicação em ponto fixo se realiza exatamente da mesma maneira que a
multiplicação de números inteiros (com ou sem sinal). Deve-se somente observar a nova
posição da vírgula: se os dois operandos (de ‘n’ bits cada) tiverem ‘t’ bits de parte inteira e
‘f’ bits de parte fracionária, o resultado apresentará ‘2n’ bits, com ‘2t’ bits de parte inteira e
‘2f’ bits de parte fracionária.
7-4
De um modo mais geral, se o multiplicando apresentar t
1
e f
1
bits para as partes inteira e
fracionária, e se o multiplicador tiver t
2
e f
2
bits, então o resultado terá t
1
+t
2
bits na parte
inteira e f
1
+f
2
bits na parte fracionária. Como na multiplicação inteira, nunca ocorre estouro
de representação se forem considerados todos os bits do resultado.
Após a multiplicação, se o resultado deve ser reduzido para ‘n’ bits (t + f), isto deve ser feito
em duas etapas:
1. A redução da parte inteira para ‘t’ bits. Para isto elimina-se os bits mais significativos,
da mesma maneira que o realizado para a multiplicação inteira. Nesta redução pode
ocorrer estouro.
2. A redução da parte fracionária para ‘f’ bits. Para isto eliminam-se os bits menos
significativos, por truncagem ou por arredondamento, tal como foi explicado na soma
de números em ponto fixo.
7. 4 Divisão em ponto fixo
A operação de divisão em ponto fixo é realizada exatamente da mesma maneira que a divisão
de números inteiros, observando-se as posições das vírgulas do dividendo e do divisor. Os
algoritmos de divisão inteira necessitam de ‘2n’ bits para o dividendo e ‘n’ bits para o
divisor. Se o divisor tem ‘t’ bits inteiros e ‘f’ bits de fração, então o dividendo deve
apresentar ‘2t’ bits na parte inteira e ‘2f’ bits na parte fracionária.
1. Para estender a parte inteira, duplicam-se os bits mais significativos de acordo com a
representação (zeros para números positivos, ou com o bit de sinal para números em
complemento de 2).
2. Para estender a parte fracionária, basta acrescentar zeros à direita.
Desta maneira obtém-se, após a execução da divisão, um quociente em ‘n’ bits (t+f) e um
resto, também em ‘n’ bits (mas com ‘2f’ bits de parte fracionária!).
7. 5 Números em ponto flutuante
A faixa de números que podem ser representados em ponto fixo é insuficiente para a maioria
das aplicações científicas, onde existe a necessidade de representar-se números muito
grandes e/ou números muito pequenos. Para contornar este problema, desenvolveu-se a
notação científica, onde um quintilhão é representado por 1,0 x 10
18
, em vez de escrevê-lo
por extenso (1 000 000 000 000 000 000). A representação de números em ponto flutuante é
basicamente a versão binária da notação científica.
A cada número em ponto flutuante estão associados na realidade três outros números: a
mantissa ‘m’, o expoente ‘e’ e a base ‘b’. No caso dos computadores atuais, a base utilizada
é a binária, ou seja, b=2. O número em ponto flutuante é então calculado por:
N = m x b
e
Como a base é uma constante para um determinado sistema, o número em ponto flutuante é
então representado por um par (m,e), onde ‘m’ é uma fração ou um inteiro, e ‘e’ é o exponte
(sempre um inteiro). Note-se que ambos, mantissa e expoente, podem ser positivos ou
negativos.
A precisão de um número em ponto flutuante é determinada primariamente pelo número de
bits utilizados pela mantissa. A faixa de representação R depende do número de bits do
expoente. Apesar dos números em ponto flutuante representarem números reais, a faixa R
não é contínua. Somente uma quantidade limitada de números (2
n
, onde n é a quantidade
7-5
total de bits da mantissa e do expoente) pode ser representada. Os números estão então
dispersos dentro desta faixa.
Os números em ponto flutuante são inerentemente redundantes, no sentido que um mesmo
número pode ser representado de mais de uma maneira. Por exemplo, um quintilhão pode
ser representado por 1,0.10
18
, ou 0,1.10
19
, ou mesmo 100.10
16
. Assim, é desejável que
exista uma forma normalizada de representar um número. Para tanto, utiliza-se somente
“mantissas normalizadas”. Uma mantissa está normalizada quando é constituída somente de
uma parte fracionária (não existe parte inteira) e quando o primeiro dígito a direita da vírgula
é diferente de zero. Assim, a forma normalizada de representar um quintilhão é dada por
0,1.10
19
.
Na base binária, a normalização da mantissa exige que os seus dois bits mais significativos
sejam diferentes. Assim, para números positivos a mantissa inicia sempre por 0,1
2
. Para
números em complemento de dois, isto implica em que o dígito mais significativo da
mantissa e o bit de sinal sejam diferentes - para números positivos a mantissa inicia então por
0,1
2
e para números negativos a mantissa inicia por 1,0
2
. Assim, a normalização restringe a
magnitude |M| de uma mantissa ao intervalo
1/2 ≤ |M| < 1
Um número não normalizado é normalizado facilmente, através de deslocamentos da
mantissa para a direita ou esquerda e incrementos ou decrementos do expoente,
respectivamente. Note-se que um eventual estouro de representação na mantissa é facilmente
resolvido: basta deslocar a mantissa para a direita, corrigir o bit mais significativo, e somar
um ao expoente. Um estouro de representação no expoente, entretanto, indica um estouro na
capacidade de representação dos números em ponto flutuante. Se o expoente ultrapassou o
maior expoente positivo, fala-se em “overflow”; se o expoente ultrapassou o menor
negativo, fala-se então em “underflow”, e o resultado fornecido normalmente é zero.
A representação do número zero apresenta algumas características peculiares, que
influenciam fortemente no formato utilizado para representar números em ponto flutuante em
binário. A mantissa deve ser naturalmente, igual a zero, mas o expoente pode apresentar
qualquer valor, uma vez que 0.b
e
é igual a 0 para todos os valores de ‘b’ e ‘e’. Com isto
tem-se:
1. A mantissa do número zero deve apresentar todos os seus bits em zero, para facilitar o
teste por zero. Note-se que isto vai contra a definição formal de uma mantissa
normalizada.
2. O número zero é na realidade a menor quantidade absoluta possível de representação.
Durante a realização de diversos cálculos, entretanto, arredondamentos e truncagens
podem levar a resultados que sejam números bem pequenos, mas não exatamente
iguais a zero. Para indicar o fato do zero estar bem próximo em magnitude destes
números, o expoente escolhido para o zero deve ser o maior número negativo repre-
sentável. Assim, por exemplo, se o expoente possuir ‘k’ bits e for representado em
complemento de dois, o expoente utilizado para o zero deverá ser –2
k-1
.
3. Pelas considerações anteriores, tem-se que o zero é representado por 0.b
–2
k-1
.
Entretanto, para facilitar o teste de um número para verificar se ele é igual a zero, é
desejável que o número zero seja uma sequência de bits em zero, sem nenhum bit em
um. Isto está em contradição com a representação acima. Para resolver este problema,
codifica-se o expoente “em excesso de 2
k-1
”, ou seja, um expoente em zero significa
na realidade a maior magnitude negativa representável. A codificação em excesso
indica que existe uma quantidade a mais somada ao expoente (no caso, 2
k-1
); para
obter-se o valor real do expoente deve-se subtrair esta quantidade do valor armazenado
no campo de expoente. Ou seja, e
real
= e – 2
k-1
. Para um expoente de 8 bits em
complemento de dois, por exemplo, tem-se então uma codificação em “excesso de
128”: o expoente –128 é representado por 0; o expoente 0 é representado por 128; e o
expoente 127 (o maior possível) é dado por 255.
7-6
7. 6 Formatos de números em ponto flutuante
Um número em ponto flutuante, representado em binário, deve fornecer as informações
relativas à mantissa (seu sinal e sua magnitude) e ao expoente (também seu sinal e sua
magnitude). Diversas representações podem ser utilizadas para isto (sinal/magnitude,
complemento de dois, etc). Devido a isto, existem diversos formatos adotados para
representar os números em ponto flutuante. Muitos deles são específicos para uma
determinada família de computadores ou para um determinado fabricante.
Por exemplo, o formato da série S/360-370 da IBM segue o formato comentado abaixo:
• o número utiliza 32 bits: 1 bit para o sinal da mantissa, 7 bits para o expoente e 24 bits
para o valor da mantissa.
• a mantissa é representada em sinal magnitude; o expoente é representado em excesso-
de-64.
• o bit mais significativo representa o sinal da mantissa; os sete bits seguintes
representam o expoente; e os 24 bits menos significativos representam o valor da
mantissa.
• a base utilizada é a base 16 (hexadecimal).
Assim, o número 0,125 x 16
5
tem a seguinte representação:
0 1000101 001000000000000000000000
E o número – 0,125 x 16
-5
tem a representação:
1 0111011 001000000000000000000000
Note-se que, como a base é 16, a mantissa é normalizada para dígitos hexadecimais (e não
para dígitos binários).
O formato recomendado pela IEEE (Institute of Electrical and Electronics Engineers) é
descrito a seguir (existem três formatos: simples, de 32 bits, duplo, de 64 bits e quádruplo,
de 128 bits):
Simples Duplo Quádruplo
Campos:
S = sinal 1 bit 1 bit 1 bit
E = expoente 8 bits 11 bits 15 bits
L = primeiro bit (não representado) (não representado) 1 bit
F = fração 23 bits 52 bits 111 bits
Expoente
Excesso-de 127 1023 16383
Maior valor 255 2047 32767
Menor valor 0 0 0
Tabela 7.4 - Formato IEEE
Nesta notação, cinco grupos diferentes de números podem ser representados: números
normalizados, zero, números não-normalizados, infinito e não-números (NaN):
1. Os números normalizados utilizam um expoente que vai de 1 a 254 (ou 1 a 2046, ou 1
a 32766), o primeiro bit da mantissa (L) é sempre zero e por isto não é representado. O
valor do número é calculado por
(–1)
s
. 2
E-excesso
. (L.F)
onde L.F representa a mantissa propriamente dita; L é o primeiro bit e F é a fração.
2. O Zero é representado por um número todo em zero (E=F=L=0); note-se que o zero
neste caso pode ter sinal.
7-7
3. Números não normalizados possuem o expoente em zero (E=0) e uma fração não zero.
Seu uso é restrito para representação do números que não podem ser normalizados
sem causar “underflow”.
4. O Infinito é representado pelo maior valor do expoente (E=255 ou 2047 ou 32767) e
por uma fração em zero (F=L=0). Note-se que o infinito pode ter sinal.
5. Não-números (Not a Number) são representados pelo maior expoente e por uma fração
diferente de zero. Seu uso previsto inclui a indicação de códigos de erro, situações
imprevistas, etc.
O bit de sinal (S) é representado no bit mais significativo; os bits seguintes representam o
expoente. Os bits menos significativos são destinados à mantissa. Note-se que o bit L não é
representado (exceto na notação quádrupla).
7. 7 Soma e subtração de números em ponto flutuante
Números em ponto flutuante, para poderem ser somados ou subtraídos, devem apresentar o
mesmo expoente. Neste caso, a soma ou subtração é realizada sobre as mantissas. O número
resultado é formado com a mantissa resultado e o expoente dos operandos.
Como os expoentes devem ser iguais antes de poder-se realizar a operação propriamente dita,
expoentes diferentes devem ser igualados. O menor dos expoentes deve ser tornado igual ao
maior, e a mantissa correspondente a este expoente deve ser convenientemente deslocada
para a direita, de forma que o número representado pelo par (mantissa, expoente) não se
altere.
Sejam X e Y dois números em ponto flutuante; sejam X
m
e Y
m
suas mantissas e X
e
e Y
e
os
seus expoentes. As seguintes regras valem então para a soma (ou subtração):
1. Se X
e
=Y
e
, então X±Y=(X
m
±Y
m
) . 2
Xe
2. Se X
e
<Y
e
, então X±Y=(X
m
.2
(Xe-Ye)
±Y
m
) . 2
Ye
3. Se X
e
>Y
e
, então X±Y=(X
m
±Y
m
.2
(Ye-Xe)
) . 2
Xe
Por exemplo, no caso 2, a mantissa X
m
associada ao menor expoente X
e
deve ser deslocada
para a direita Y
e
–X
e
vezes, para formar uma nova mantissa X
m
.2
(Xe-Ye)
. Esta nova
mantissa, que corresponde agora a um expoente Y
e
, pode ser operada com Y
m
. Note-se que,
quando a mantissa X
m
é deslocada para a direita, existe uma perda de precisão nos seus bits
menos significativos, que são eliminados. E se a diferença Y
e
-X
e
for maior que o número de
bits utilizados para representar a mantissa, nem é necessário realizar-se a soma (ou
subtração): todos os bits significativos de X
m
seriam eliminados pelo deslocamento para a
direita (isto equivale a somar dois números, onde um deles é muito menor que o outro).
Como os números em ponto flutuante são normalmente armazenados na forma normalizada,
após a operação a mantissa resultado deve ser normalizada, através de deslocamentos para a
esquerda (direita) e decrementos (incrementos) do expoente, tal como explicado na seção 5.
Note-se que um eventual estouro de representação é resolvido através de um deslocamento
para a direita (exceto no caso em que o expoente já é o maior possível, caso em que
realmente ocorre estouro).
7. 8 Multiplicação de números em ponto flutuante
Números em ponto flutuante são multiplicados facilmente. Basta multiplicar as mantissas e
somar os expoentes. A multiplicação segue essencialmente as mesmas regras da
multiplicação inteira; inclusive a mantissa resultado tem o dobro de bits de comprimento. Ela
7-8
é entretanto facilmente reduzida para o número normal de bits, através da eliminação dos
seus bits menos significativos (por truncagem ou arredondamento).
X x Y = (X
m
x Y
m
) . 2
(Xe+Ye)
Após a multiplicação o resultado também deve ser normalizado; durante este processo pode
ocorrer estouro de representação (se ocorrer estouro na representação do expoente).
7. 9 Divisão de números em ponto flutuante
Números em ponto flutuante são divididos facilmente. Basta dividir as mantissas e subtrair
os expoentes. A mantissa do dividendo é inicialmente expandida para o dobro do seu número
de bits (pela inclusão de zeros a direita) e depois as duas mantissas são divididas pelo mesmo
algoritmo utilizado para números inteiros. Note-se que agora o resto é normalmente
desprezado, e as etapas que na divisão inteira corrigiam quociente e resto podem ser
eliminadas.
X ÷ Y = (X
m
÷ Y
m
) . 2
(Xe–Ye)
Após a divisão o resultado também deve ser normalizado; durante este processo pode ocorrer
estouro de representação (se ocorrer estouro na representação do expoente).