1.2. Aritmética de ponto flutuante#
Um número no Sistema de Ponto Flutuante (STF) é caracterizado por uma base \(b\), um número de dígitos significativos \(n\) e um expoente \(exp\). Assim, dizemos que um número real \(n_r\) está representado no SPF se estiver na forma
em que \(m=d_1 d_2...d_n\) é a mantissa com \(n\) dígitos significativos \(d_1, d_2,...,d_n\) satisfazendo \(0 \leq d_i \leq (b-1)\), \(i=1,...,n\) e \(d_1 \neq 0\).
O expoente \(exp\) da base \(b\) varia da seguinte maneira
sendo \( exp_{min} \leq 0 \) e \(exp_{max} \geq 1\) com \(exp_{min}\) e \(exp_{max}\) inteiros.
Considerando o sistema de ponto flutuante normalizado, na forma genérica \(SPF(b,n,exp_{min}, exp_{max})\), temos que apenas um conjunto finito de números reais podem ser exatamente representados, tal que
a) o número zero é representado como:
b) o menor positivo exatamente representável é
c) o maior positivo exatamente representável é
d) o número máximo de mantissas positivas possíveis é
e) o número máximo de expoentes possíveis é
f) o número máximo de reais positivos é
g) assim, considerando os números negativos e o zero, o número total de números reais exatamente representáveis é
Exemplo 1.2.1: Em Python também dispomos de algumas funções para acessar as informações do sistema de ponto flutuante:
import sys
print ("Máximo representável:", sys.float_info.max)
print ("Mínimo represenável:", sys.float_info.min)
print ("Épsilon da máquina:", sys.float_info.epsilon)
print ("Todas informações:", sys.float_info)
Máximo representável: 1.7976931348623157e+308
Mínimo represenável: 2.2250738585072014e-308
Épsilon da máquina: 2.220446049250313e-16
Todas informações: sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)
Exemplo 1.2.2: Considere o sistema de ponto flutuante normalizado SPF (3, 2,−1, 2), de base 3, 2 dígitos na mantissa, menor expoente igual a −1 e maior expoente 2.
Para esse sistema tem-se que os números
e
são exatamente representáveis, no entanto,
não é exatamente representável, uma vez que a mantissa é de 2 dígitos. Nesse sistema \((x+y)=(0.12)_3 \times 3^2\). Ou seja, \((x+y)=y\).
Assim, pode ocorrer de propriedades bem conhecidas no conjunto dos números reais, como as propriedades comutativa e associativa na adição e as propriedades comutativa e distributiva na multiplicação, não serem verdadeiras no sistema de ponto flutuante
Por exemplo, em um sistema de ponto flutuante, base decimal, 3 dígitos e arredondamento, as seguintes operações geram erros de arredondamento
Sejam \(x=5.26\), \(y=9.34\) e \(z = 5.04\). Então:
e
Ou seja,
Exemplo 1.2.3: Exemplos de somas que fornecem resultados diferentes de forem realizadas em uma ordem diferente. Tente explicar.
print ("0.2 + 0.4 - 0.5 =", 0.2 + 0.4 - 0.5)
print ("- 0.5 + 0.4 + 0.2 =", - 0.5 + 0.4 + 0.2)
print ("0.2 -0.1 + 0.2 - 0.1 =", 0.2 -0.1 + 0.2 - 0.1)
print ("0.2 - 0.1 + (0.2 - 0.1) =", 0.2 - 0.1 + (0.2 - 0.1))
print ("0.2 + 0.3 + 0.1 =", 0.2 + 0.3 + 0.1 )
print ("0.2 + 0.1 + 0.3 =", 0.2 + 0.1 + 0.3)
0.2 + 0.4 - 0.5 = 0.10000000000000009
- 0.5 + 0.4 + 0.2 = 0.10000000000000003
0.2 -0.1 + 0.2 - 0.1 = 0.20000000000000004
0.2 - 0.1 + (0.2 - 0.1) = 0.2
0.2 + 0.3 + 0.1 = 0.6
0.2 + 0.1 + 0.3 = 0.6000000000000001
Exemplo 1.2.4: Alguns exemplos de operações simples que ilustram erros devido à limitação do computador em representar certos números reais.
0.1 + 0.2 == 0.3
False
0.4 + 0.2
0.6000000000000001
from decimal import Decimal
Decimal(0.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')
Exemplo 1.2.5: Considere o seguinte processo iterativo
e
O resultado dessa sequência é
Agora observe o programa abaixo. Você pode explicar os resultados?
x = 1/3
for i in range(20):
x = 4*x -1
print (x)
0.33333333333333326
0.33333333333333304
0.33333333333333215
0.3333333333333286
0.3333333333333144
0.33333333333325754
0.33333333333303017
0.3333333333321207
0.3333333333284827
0.3333333333139308
0.3333333332557231
0.3333333330228925
0.3333333320915699
0.3333333283662796
0.3333333134651184
0.33333325386047363
0.33333301544189453
0.3333320617675781
0.3333282470703125
0.33331298828125
Exercícios:
(Fontes: Ruggiero (2016), Chapra e Canale (2016))
1. Seja um sistema de aritmética de ponto flutuante de quatro dígitos e base decimal. Dados os números:
efetue as seguintes operações e obtenha o erro relativo no resultado, supondo que \(x, y\) e z estão exatamente representados:
a) \(\mathrm{x}+\mathrm{y}+\mathrm{z}\)
d) \((\mathrm{xy}) / \mathrm{z}\)
b) \(x-y-z\)
e) \(\mathrm{x}(\mathrm{y} / \mathrm{z})\)
c) \(\mathrm{x} / \mathrm{y}\)
2. (a) Calcule o polinômio \(y = x^3-5x^2+6x+0,55\) em \(x = 1,37\). Use aritmética com 3 algarismos significativos e truncamento. Estime o erro.
(b) Repita (a), mas expresse \(y\) como \(y = ((x – 5)x + 6)x + 0,55\) Estime o erro e compare com a parte (a)
3. Use aritmética com 5 algarismos significativos para determinar as raízes da equação
com as fórmulas
e
Então, calcule os erros percentuais para o seu resultado.
4. Faça seu próprio programa para determinar o épsilon da máquina do seu computador.
Respostas:
1. \(a)\mathrm{x}+\mathrm{y}+\mathrm{z}=0.7240 \times 10^4\) \(\quad \left|\mathrm{ER}_{\mathrm{x}+\mathrm{y}+\mathrm{z}}\right|<10^{-3}\)
\(b) \mathrm{x}-\mathrm{y}-\mathrm{z}=0.7234 \times 10^4\) \(\quad \left|\mathrm{ER}_{\mathrm{x}-\mathrm{y}-\mathrm{z}}\right|<1.0002 \times 10^{-3}\)
\(c)\mathrm{x} / \mathrm{y}=0.3374 \times 10^8\) \(\quad \left|E R_{x / y}\right|<\frac{1}{2} \times 10^{-3}\)
\(d) (\mathrm{xy}) / \mathrm{z}=0.6004\) \(\quad \left|\mathrm{ER}_{(\mathrm{xy}) / \mathrm{z}}\right|<10^{-3}\)
\(e) \mathrm{x}(\mathrm{y} / \mathrm{z})=0.6005\) \(\quad\left|\mathrm{ER}_{\mathrm{x}(\mathrm{y} / \mathrm{z})}\right|<10^{-3}\)