Você está na página 1de 49

Aritmética de ponto utuante

Vicente Helano
UFCA | Centro de Ciências e Tecnologia
De nição das operações
Dados 𝑥, 𝑦 ∈ ℝ , de nimos

𝑥 ⊕ 𝑦 = fl(fl(𝑥) + fl(𝑦))
𝑥 ⊖ 𝑦 = fl(fl(𝑥) − fl(𝑦))
𝑥 ⊗ 𝑦 = fl(fl(𝑥) × fl(𝑦))
𝑥 ⊘ 𝑦 = fl(fl(𝑥)/ fl(𝑦))
Sequência básica das operações
Para realizar 𝑥 ⊙ 𝑦, fazemos
1. arredondamos os operandos 𝑥 e 𝑦, obtendo os valores fl(𝑥) e fl(𝑦)


2. realizamos a operação aritmética de modo exato usando os valores de fl(𝑥) e
𝑦
fl( )

3. arredondamos o resultado do passo 2


Sequência básica das operações
Atenção! Para realizar a adição ou a subtração, inicialmente, é necessário igualar os
expoentes de 𝑥 e 𝑦, sempre mantendo inalterado o maior dos expoentes. Isto não é
necessário para as operações de multiplicação e divisão.
Exemplo
Suponha um sistema decimal com 𝑡 = 3 , 𝑒min = −1 e 𝑒max = 2 , calcule
(350)10 ⊕ (1,5)10
Exemplo
Suponha um sistema decimal com 𝑡 = 3 , 𝑒min = −1 e 𝑒max = 2 , calcule 𝑥 ⊘ 𝑦 com
𝑥 = (1,625) 10 e 𝑦= (1,7) 10
Exemplo
Suponha um sistema decimal com 𝑡 = 3 , 𝑒min = −1 e 𝑒max = 2 , calcule 𝑥 ⊘ 𝑦 com
𝑥 = (1,625) 10 e 𝑦 = (1,7)
10
In [ ]: fl_x = 1.62
fl_y = 1.7
res = fl_x/fl_y
print(f'{res:1.4e}')
Exemplo
Por m, arredondamos o resultado

In [ ]: print(f'{res:1.2e}')
Over ow e under ow
= 3 , 𝑒min = −1 e 𝑒max = 2 .
Considere um sistema decimal com 𝑡
−1 2
Tomemos 𝑥 = (1,10)10 × 10 e 𝑦 = (7,00)10 × 10 , quanto valem 𝑥 ⊘ 300 e
2 ⊗ 𝑦?
In [ ]: x = 1.10 * 10**(-1) # ou 1.1e-1
y = 7.00 * 10**(2) x/300 = 0.0003666666666666667
div = x/300.0
prod = 2.0*y

print(f"x/300 = {div}")
print(f"2*y = {prod}")
Over ow e under ow 2*y = 1400.0

Considere um sistema decimal com 𝑡 = 3 , 𝑒min = −1 e 𝑒max = 2 .


Mas os limites deste sistema são

Menor normal positivo: 0.1


Maior normal positivo: 999.0
Menor subnormal positivo: 0.001
Maior subnormal positivo: 0.099
Exemplo
Logo,

fl(0.000366 …) =
fl(1400) =
Over ow e under ow
Aviso: o comportamento do float da Python é muitas vezes diferente do estabelecido
no padrão IEEE.

In [ ]: import numpy as np

a = np.float64(1.0) # formato IEEE754


b = np.float64(0.0) # formato IEEE754
a/b
Over ow e under ow
Aviso: o comportamento do float da Python é muitas vezes diferente do estabelecido
no padrão IEEE.

In [ ]: a = 1.0
b = 0.0
a/b
Perda de precisão
Em diversas ocasiões, podemos ter perda de precisão em operações de ponto utuante.
Precisamos citar duas das que mais ocorrem:

soma de número grande a número pequeno


subtração de números muito próximos
Adição de número grande a pequeno
Considere um sistema decimal com 𝑡 = 3 , 𝑒min = −1 e 𝑒max = 2 .
Adição de número grande a pequeno
Considere um sistema decimal com 𝑡 = 3 , 𝑒min = −1 e 𝑒max = 2 .

Calculemos 400 ⊕ 0,1


O problema da Basileia
Euler concluiu em 1735 que:

∞ 1 2
∑𝑘
𝑘=1
2
𝜋
= 6
O problema da Basileia
Desejamos aproximar a série por:


100.000.000
𝜋 2
1

6 𝑘=1
𝑘2
O problema da Basileia
Maiores primeiro:

In [ ]: n = 10000000
somaM = 0.0
for k in range(1,n+1):
somaM = somaM + 1.0/(k**2)
O problema da Basileia
Menores primeiro:

In [ ]: n = 10000000
somam = 0.0
for k in range(n,0,-1):
somam = somam + 1.0/(k**2)
O problema da Basileia
Comparação:

In [ ]: exato = (np.pi**2)/6
print("ER(MaioresPrimeiro): %.14e" % (abs(exato - somaM)/exato))
print("ER(MenoresPrimeiro): %.14e" % (abs(exato - somam)/exato))
Subtração de números próximos
Considere um sistema decimal com 𝑡 = 3 , 𝑒min = −1 e 𝑒max = 2 .
2
Calculemos 9,34 × 10 ⊖ 9,33 × 10
2
Subtração de números próximos

Agora, considere o problema de calcular o valor da função abaixo para 𝑥 = 10 ,
𝑘
𝑘 = 0, 1, … , 12 .

𝑓 (𝑥) =
1 − cos 𝑥
sen2 𝑥
Subtração de números próximos
In [ ]: def f(x):
return (1.0 - np.cos(x))/(np.sin(x)*np.sin(x))
Subtração de números próximos
In [ ]: def f(x):
return (1.0 - np.cos(x))/(np.sin(x)*np.sin(x))

In [ ]: for i in range(13):
x = 10.0**(-i)
print("%.15f %.15f" % (x, f(x)))
Subtração de números próximos
Resolvemos este problema multiplicando ambos o numerador e o denominador de 𝑓 por
1 + cos 𝑥 .

1 − cos 𝑥
𝑓 (𝑥) =
sen2 𝑥
Subtração de números próximos
In [ ]: def h(x):
return 1.0/(1.0 + np.cos(x))
Subtração de números próximos
In [ ]: def h(x):
return 1.0/(1.0 + np.cos(x))

In [ ]: for i in range(13):
x = 10.0**(-i)
print("%.15f %.15f %.15f" % (x, f(x), h(x)))
Análise de erros de aritmética
Considerando o arredondamento para o mais próximo, é possível mostrar que

fl(𝑥) − 𝑥| 1
ER(fl(𝑥)) =
|

𝑥
| |
≤ 2𝜀

sempre que 𝑥 for um número normal.


Precisão de máquina
De nição.
Precisão de máquina
Qual a precisão de máquina de um sistema decimal com 𝑡 = 3 , 𝑒min = −1 e
𝑒max =2 ?
Precisão de máquina
E no sistema de precisão dupla do IEEE?
Precisão de máquina
E no sistema de precisão dupla do IEEE?

Usando a numpy , podemos consultar o valor de 𝜀:

In [ ]: import numpy as np

np.finfo(np.float64).eps
Análise de erros de aritmética
De nindo 𝛿 = [fl(𝑥) − 𝑥] /𝑥 e isolando fl(𝑥), obtemos

fl(𝑥) = 𝑥(1 + 𝛿).


Análise de erros de aritmética
De nindo 𝛿 = [fl(𝑥) − 𝑥] /𝑥 e isolando fl(𝑥), obtemos

fl(𝑥) = 𝑥(1 + 𝛿).

Lembre-se: 𝑥 normal → |𝛿| ≤ 1


2
𝜀 .
Análise de erros de aritmética
⊙ +−× /
Agora, denote por uma das operações , , ou .
Dados 𝑥 ̂ = fl( )  ̂ = fl( )
𝑥 e𝑦 𝑦 , podemos escrever

fl(𝑥̂ ⊙ 𝑦)̂  = (𝑥̂ ⊙ 𝑦)(1


̂  + 𝛿),

onde 𝛿 é o valor de uma perturbação usada para representar o erro que poderá ocorrer
ao nal da operação.
Exemplo
Sejam 𝑥 e 𝑦 números reais positivos.
Estime o erro relativo que ocorrerá na operação 𝑥 ⊕ 𝑦 em um sistema de ponto
utuante arbitrário
Exemplo

(𝑥 + 𝑦) − (𝑥 ⊕ 𝑦)|
Com efeito, o erro relativo será:
ER(𝑥 ⊕ 𝑦) =
|

|(𝑥 + 𝑦)|
|| 𝑥(𝛿1 + 𝛿3 ) + 𝑦(𝛿2 + 𝛿3 ) ||
≈| ( 𝑥 + 𝑦) |
| |
Exemplo
Tomemos 𝛿 = max {|𝛿1 + 𝛿3 |, |𝛿2 + 𝛿3 |} . Então,

|| 𝑥(𝛿1 + 𝛿3 ) + 𝑦(𝛿2 + 𝛿3 ) || ≤ || 𝑥𝛿 + 𝑦𝛿 || = |𝛿| ≤ | 𝜀 | + | 𝜀 | = |𝜀|


|| (𝑥 + 𝑦) | | | | |
|2| |2| | |
| | 𝑥+𝑦 |
Outro exemplo
Obtenha um limitante para o erro da operação

fl(𝑧 ̂ × fl(𝑥̂ + 𝑦))


̂ 

onde 𝑥̂  = fl(𝑥) , 𝑦 ̂ = fl(𝑦) e 𝑧 ̂ = fl(𝑧) .


Outro exemplo
Sabemos que

𝑥
fl( ̂ + 𝑦)̂  = (𝑥̂ + 𝑦)(1
̂  + 𝛿1 ),

para algum 𝛿1 , com |𝛿1 | ≤ 𝜖/2 .


Outro exemplo
Pelo mesmo motivo,
fl(𝑧 ̂ × fl(𝑥̂ + 𝑦))
̂  = [𝑧 ̂ × fl(𝑥̂ + 𝑦)̂ ] (1 + 𝛿2 )
= 𝑧 ̂ × (𝑥̂ + 𝑦)(1
̂  + 𝛿1 )(1 + 𝛿2 )
= 𝑧 ̂ × (𝑥̂ + 𝑦)(1̂  + 𝛿1 + 𝛿2 + 𝛿1 𝛿2 )

≈ 𝑧 ̂ × (𝑥̂ + 𝑦)(1


̂  + 𝛿1 + 𝛿2 )
= 𝑧 ̂ × (𝑥̂ + 𝑦)(1
̂  + 𝛿)
Outro exemplo
Pelo mesmo motivo,
fl(𝑧 ̂ × fl(𝑥̂ + 𝑦))
̂  = [𝑧 ̂ × fl(𝑥̂ + 𝑦)̂ ] (1 + 𝛿2 )
= 𝑧 ̂ × (𝑥̂ + 𝑦)(1
̂  + 𝛿1 )(1 + 𝛿2 )
= 𝑧 ̂ × (𝑥̂ + 𝑦)(1̂  + 𝛿1 + 𝛿2 + 𝛿1 𝛿2 )

≈ 𝑧 ̂ × (𝑥̂ + 𝑦)(1


̂  + 𝛿1 + 𝛿2 )
= 𝑧 ̂ × (𝑥̂ + 𝑦)(1
̂  + 𝛿)

fazendo 𝛿 = 𝛿1 + 𝛿2 e supondo |𝛿1 𝛿2 | ≤ 𝜖2 /4 ≈ 0 .


Outro exemplo
Observe que |𝛿| = |𝛿1 + 𝛿2 | ≤ |𝛿1 | + |𝛿2 | ≤ 𝜖/2 + 𝜖/2 = 𝜖 .
Vicente Helano
UFCA | Centro de Ciências e Tecnologia

Você também pode gostar