Use o botão abaixo para reportar erros ou dar sugestões.

Cálculo Numérico - Versão Python

2.4 Representação de números em máquina


Os computadores, em geral, usam a base binária para representar os números, onde as posições, chamadas de bits, assumem as condições “verdadeiro” ou “falso”, ou seja, 1 ou 0, respectivamente. Os computadores representam os números com uma quantidade fixa de bits, o que se traduz em um conjunto finito de números representáveis. Os demais números são tomados por proximidade àqueles conhecidos, gerando erros de arredondamento. Por exemplo, em aritmética de computador, o número 2 tem representação exata, logo 22 = 4, mas 3 não tem representação finita, logo (3)23.

Veja isso em Python:

>>> 2**2 == 4  
True  
>>> np.sqrt(3)**2 == 3  
False

2.4.1 Números inteiros


Tipicamente, um número inteiro é armazenado em um computador como uma sequência de dígitos binários de comprimento fixo denominado registro.

Representação sem sinal

Um registro com n bits da forma






dn-1 dn-2 d1 d0





representa o número (dn-1dn-2...d1d0)2.

Assim, é possível representar números inteiros entre 2n - 1 e 0, sendo

[111111] = 2n-1 + 2n-2 + + 21 + 20 = 2n - 1, [000011] = 3, [000010] = 2, [000001] = 1, [000000] = 0. (2.44)

Representação com bit de sinal

O bit mais significativo (o primeiro à esquerda) representa o sinal: por convenção, 0 significa positivo e 1 significa negativo. Um registro com n bits da forma






s dn-2 d1 d0





representa o número (-1)s(d n-2d1d0)2. Assim, é possível representar números inteiros entre - 2n-1 e 2n-1, com duas representações para o zero: (1000000)2 e (00000000)2.

Exemplo 2.4.1. Em um registro com 8 bits, teremos os números

[11111111] = -(26 + + 2 + 1) = -127, [10000001] = -1, [10000000] = -0, [01111111] = 26 + + 2 + 1 = 127, [00000010] = 2, [00000001] = 1, [00000000] = 0. (2.45)

Representação complemento de dois

O bit mais significativo (o primeiro à esquerda) representa o coeficiente de - 2n-1. Um registro com n bits da forma:






dn-1 dn-2 d1 d0





representa o número - dn-12n-1 + (d n-2d1d0)2.

Observação 2.4.1. Note que todo registro começando com 1 será um número negativo.

Exemplo 2.4.2. O registro com 8 bits [01000011] representa o número:

-0(27) + (1000011) 2 = 26 + 2 + 1 = 67. (2.46)

Agora, o registro [10111101] representa:

-1(27) + (0111101) 2 = -128 + 25 + 24 + 23 + 22 + 1 = -67. (2.47)

Note que podemos obter a representação de - 67 invertendo os dígitos de 67 em binário e somando 1.

Exemplo 2.4.3. Em um registro com 8 bits, teremos os números

[11111111] = -27 + 26 + + 2 + 1 = -1 [10000001] = -27 + 1 = -127 [10000000] = -27 = -128 [01111111] = 26 + + 2 + 1 = 127 [00000010] = 2 [00000001] = 1 [00000000] = 0 (2.48)

2.4.2 Sistema de ponto fixo


O sistema de ponto fixo representa as partes inteira e fracionária do número com uma quantidade fixas de dígitos.

Exemplo 2.4.4. Em um computador de 32 bits que usa o sistema de ponto fixo, o registro







d31 d30 d29 d1 d0






pode representar o número

  • (-1)d31(d 30d29d17d16,d15d14d1d0)2 se o sinal for representado por um dígito. Observe que, neste caso, o zero possui duas representações possíveis:
    [10000000000000000000000000000000] (2.49)

    e

    [00000000000000000000000000000000] (2.50)
  • (d30d29d17d16)2 - d31(215 - 2-16) + (0,d 15d14d1d0)2 se o sinal do número estiver representado por uma implementação em complemento de um. Observe que o zero também possui duas representações possíveis:
    [11111111111111111111111111111111] (2.51)

    e

    [00000000000000000000000000000000] (2.52)
  • (d30d29d17d16)2 - d31215 + (0,d 15d14d1d0)2 se o sinal do número estiver representado por uma implementação em complemento de dois. Nesse caso o zero é unicamente representado por
    [00000000000000000000000000000000] (2.53)

Observe que 16 dígitos são usados para representar a parte fracionária, 15 são para representar a parte inteira e um dígito, o d31, está relacionado ao sinal do número.

2.4.3 Sistema de ponto flutuante


O sistema de ponto flutuante não possui quantidade fixa de dígitos para as partes inteira e fracionária do número.

Podemos definir uma máquina F em ponto flutuante de dois modos:

F(β,|M|,|E|,BIAS) ou F(β,|M|,EMIN,EMAX) (2.54)

onde

  • β é a base (em geral 2 ou 10),
  • |M| é o número de dígitos da mantissa,
  • |E| é o número de dígitos do expoente,
  • BIAS é um valor de deslocamento do expoente (veja a seguir),
  • EMIN é o menor expoente,
  • EMAX é o maior expoente.

Considere uma máquina com um registro de 64 bits e base β = 2. Pelo padrão IEEE754, 1 bit é usado para o sinal, 11 bits para o expoente e 52 bits são usados para o significando tal que











s c10 c9 c0 m1 m2 m51 m52










represente o número (o BIAS = 1023 por definição)

x = (-1)sM × 2c-BIAS, (2.55)

onde a característica é representada por

c = (c10c9c1c0)2 = c10210 + + c 121 + c 020 (2.56)

e o significando por

M = (1.m1m2m51m52)2. (2.57)

Observação 2.4.2. Em base 2 não é necessário armazenar o primeiro dígito (por quê?).

Exemplo 2.4.5. O registro

[0|10000000000|10100000000000000000] (2.58)

representa o número

(-1)0(1 + 2-1 + 2-3) × 21024-1023 = (1 + 0.5 + 0.125)2 = 3.25. (2.59)

O expoente deslocado

Uma maneira de representar os expoentes inteiros é deslocar todos eles uma mesma quantidade. Desta forma permitimos a representação de números negativos e a ordem deles continua crescente. O expoente é representado por um inteiro sem sinal do qual é deslocado o BIAS.

Tendo |E| dígitos para representar o expoente, geralmente o BIAS é predefinido de tal forma a dividir a tabela ao meio de tal forma que o expoente um seja representado pelo sequência [100000].

Exemplo 2.4.6. Com 64 bits, pelo padrão IEEE754, temos que |E| := 11. Assim, (10000000000)2 = 210 = 1024. Como queremos que esta sequência represente o 1, definimos BIAS := 1023, pois

1024 - BIAS = 1. (2.60)

Com 32 bits, temos |E| := 8 e BIAS := 127. E com 128 bits, temos |E| := 15 e BIAS := 16383.

Com |E| = 11 temos

[11111111111] = reservado [11111111110] = 2046 - BIAS = 102310 = EMAX = [10000000001] = 210 + 1 - BIAS = 2 10 [10000000000] = 210 - BIAS = 1 10 [01111111111] = 1023 - BIAS = 010 [01111111110] = 1022 - BIAS = -110 = [00000000001] = 1 - BIAS = -1022 = EMIN [00000000000] = reservado (2.61)

O maior expoente é dado por EMAX = 1023 e o menor expoente é dado por EMIN = -1022.

O menor número representável positivo é dado pelo registro

[0|00000000001|00000000000000000000] (2.62)

quando s = 0, c = 1 e M = (1.000...000)2, ou seja,

MINR = (1 + 0)2 × 21-1023 0.2225 × 10-307. (2.63)

O maior número representável é dado por

[0|11111111110|1111111111111111] (2.64)

quando s = 0, c = 2046 e M = (1.111111111111)2 = 2 - 2-52, ou seja,

MAXR = (2 - 2-52) × 22046-1023 21024 0.17977 × 10309. (2.65)

Observação 2.4.3. Em Python, podemos podemos obter o maior e o menor double positivo não nulo com os comandos:

>>> import sys  
>>> sys.float_info.max  
1.7976931348623157e+308  
>>> sys.float_info.min  
2.2250738585072014e-308

Outras informações sobre a representação em ponto flutuante podem ser obtidas com sys.float_info.

Casos especiais

O zero é um caso especial representado pelo registro

[0|00000000000|000000000000...00000000] (2.66)

Os expoentes reservados são usados para casos especiais:

  • c = [0000...0000] é usado para representar o zero (se m = 0) e os números subnormais (se m0).
  • c = [1111...1111] é usado para representar o infinito (se m = 0) e NaN (se m0).

Os números subnormais8 tem a forma

x = (-1)s(0.m 1m2m51m52)2 × 21-BIAS. (2.67)

2.4.4 Precisão e épsilon de máquina


A precisão p de uma máquina é o número de dígitos significativos usado para representar um número. Note que p = |M| + 1 em binário e p = |M| para outras bases.

O épsilon de máquina, ϵmach = ϵ, é definido de forma que 1 + ϵ seja o menor número representável maior que 1, isto é, 1 + ϵ é representável, mas não existem números representáveis em (1, 1 + ϵ).

Exemplo 2.4.7. Com 64 bits, temos que o épsilon será dado por

1 (1.00000000....0000)2 × 20 ϵ +(0.00000000....0001)2 × 20 = 2-52 (1.00000000....0001)2 × 201 (2.68)

Assim, ϵ = 2-52.

Em Python, podemos obter o épsilon de máquina com os comandos:

>>> import sys  
>>> sys.float_info.epsilon  
2.220446049250313e-16

Observe, também, os seguintes resultados:

>>> eps = sys.float_info.epsilon  
>>> 1 + 1e-16 == 1  
True  
>>> 1 + eps == 1  
False

2.4.5 Distribuição dos números


Utilizando uma máquina em ponto flutuante, temos um número finito de números que podemos representar.

Um número muito pequeno geralmente é aproximado por zero (underflow) e um número muito grande (overflow) geralmente faz o cálculo parar. Além disso, os números não estão uniformemente espaçados no eixo real. Números pequenos estão bem próximos enquanto que números com expoentes grandes estão bem distantes.

Se tentarmos armazenar um número que não é representável, devemos utilizar o número mais próximo, gerando os erros de arredondamento.

Exercícios


E 2.4.1. Usando a representação complemento de dois de números inteiros com 8 bits, escreva o número decimal que corresponde aos seguintes barramentos:

a)
[01100010].
b)
[00011101].
c)
[10000000].
d)
[11100011].
e)
[11111111]

Resposta. a) 26 + 25 + 21 = 98; b) 24 + 23 + 22 + 20 = 29; c)  - 27; d)  - 27 + 26 + 25 + 21 + 20 = -29; e) - 27 + 26 + 25 + 24 + 23 + 22 + 21 + 20 = -1. Observe que o dígito mais significativo (mais à esquera) tem peso negativo.

E 2.4.2. Usando a representação complemento de dois de números inteiros com 16 bits, escreva o número decimal que corresponde aos seguintes barramentos:

a)
[0110001001100010].
b)
[0001110100011101].
c)
[1110001011100011].
d)
[1111111111111111].

Resposta. a) 25186; b) 7453; c)  - 7453; d)  - 1.

E 2.4.3. Usando a representação de ponto flutuante com 64 bits, escreva o número decimal que corresponde aos seguintes barramentos:

a)
[0|10000000000|1110000].
b)
[1|10000000001|01110000].

Resposta. a) 3,75; b)  - 5,75.

E 2.4.4. Explique a diferença entre o sistema de ponto fixo e ponto flutuante.

E 2.4.5. Considere a seguinte rotina escrita para ser usada no Python:

     x=1.0  
     while x+1>x:  
         x=x+1  
 

Explique se esta rotina finaliza em tempo finito, em caso afirmativo calcule a ordem de grandeza do tempo de execução supondo que cada passo do laço demore 10-7s. Justifique sua reposta.

Resposta. Devido à precisão finita do sistema de numeração, o laço para quando x for suficientemente grande em comparação a 1 a ponto de x+1 ser aproximado para 1. Isso acontece quando 1 é da ordem do épsilon de máquina em relação a x, isto é, quando x 2%eps. O tempo de execução fica em torno de 28 anos.

Creative Commons License Este texto é disponibilizado nos termos da licença Creative Commons Atribuição-CompartilhaIgual 3.0 Não Adaptada (CC-BY-SA 3.0). Página gerada em 15/5/2019 às 15:24:50.

Informe erros ou edite você mesmo!