5
CÁLCULOS NUMÉRICOS, PRECISÃO E ERROS DE ARREDONDAMENTO A linguagem Fortran foi, originalmente, designada para ajudar na solução de problemas numéricos e está ainda é a maior classe de problemas para os quais programas em Fortran são usados. Entretanto, é extremamente importante que o programador e o usuário destes programas estejam atentos às limitações intrínsecas de um computador na solução de problemas numéricos e aos passos que podem ser tomados para melhorar esta questão. Os números inteiros (INTEGER) são armazenados exatamente, sem qualquer parte fracionária, e todos os cálculos realizados neles, exceto a divisão, levam a um resultado que é matematicamente preciso. Poderia haver, entretanto, um problema se, por exemplo, a soma de dois inteiros exceder o maior inteiro que um computador pudesse armazenar. No caso da divisão, qualquer parte fracionária no resultado (matemático) é descartada. Tipicamente, os números inteiros podem estar no intervalo -10 9 a +10 9 . Os números inteiros são normalmente usados para contagens e operações similares. Os números reais (REAL), por outro lado, são armazenados como uma aproximação ao valor matemático por meio de uma representação conhecida como ponto flutuante, que permite o armazenamento de um amplo intervalo de valores em um mesmo grau de precisão. Tipicamente, um número real será armazenado em um computador com aproximadamente seis ou sete dígitos decimais de precisão, com expoente variando entre -10 38 e +10 38 . Alguns computadores, particularmente aqueles da classe de supercomputadores, excedem consideravelmente estes intervalos. Os cálculos numéricos usam, normalmente, números reais e, a menos que informado, esta discussão sobre métodos numéricos assumirá que todos os números são reais. Uma vez estabelecido que os números reais usados em cálculos numéricos são aproximações, mantido um determinado grau de precisão, devemos analisar que efeito isto pode ter nos resultados destes cálculos. Para ilustrar esta questão mais facilmente, vamos assumir a existência de um computador que armazena os seus números em uma forma normalizada de ponto flutuante decimal, ou seja, em um decimal equivalente à maneira na qual os números em ponto flutuante (binários) são armazenados num computador típico. Ainda, assumiremos que estes números são armazenados com precisão de quatro dígitos. Finalmente, assumiremos, também, que o expoente deve ficar no intervalo -9 a +9. Então, um número decimal normalizado e não nulo terá a forma 0.d 1 d 2 d 3 d 4 x 10 p , sendo que d 1 abrange o intervalo 1-9 e d 2 , d 3 e d 4 abrangem o intervalo 0-9. O número 0.d 1 d 2 d 3 d 4 é chamado de mantissa, enquanto que p é chamado de expoente. A Tabela 1 mostra alguns exemplos da maneira que números são armazenados neste computador.

FORTRAN 90 - Calculos numericos

Embed Size (px)

Citation preview

Page 1: FORTRAN 90 - Calculos numericos

CÁLCULOS NUMÉRICOS, PRECISÃO E ERROS DE ARREDONDAMENTO

A linguagem Fortran foi, originalmente, designada para ajudar na solução de problemas

numéricos e está ainda é a maior classe de problemas para os quais programas em Fortran são

usados. Entretanto, é extremamente importante que o programador e o usuário destes programas

estejam atentos às limitações intrínsecas de um computador na solução de problemas numéricos e

aos passos que podem ser tomados para melhorar esta questão.

Os números inteiros (INTEGER) são armazenados exatamente, sem qualquer parte

fracionária, e todos os cálculos realizados neles, exceto a divisão, levam a um resultado que é

matematicamente preciso. Poderia haver, entretanto, um problema se, por exemplo, a soma de dois

inteiros exceder o maior inteiro que um computador pudesse armazenar. No caso da divisão,

qualquer parte fracionária no resultado (matemático) é descartada. Tipicamente, os números inteiros

podem estar no intervalo -109 a +109. Os números inteiros são normalmente usados para contagens e

operações similares.

Os números reais (REAL), por outro lado, são armazenados como uma aproximação ao

valor matemático por meio de uma representação conhecida como ponto flutuante, que permite o

armazenamento de um amplo intervalo de valores em um mesmo grau de precisão. Tipicamente, um

número real será armazenado em um computador com aproximadamente seis ou sete dígitos

decimais de precisão, com expoente variando entre -1038 e +1038. Alguns computadores,

particularmente aqueles da classe de supercomputadores, excedem consideravelmente estes

intervalos. Os cálculos numéricos usam, normalmente, números reais e, a menos que informado,

esta discussão sobre métodos numéricos assumirá que todos os números são reais.

Uma vez estabelecido que os números reais usados em cálculos numéricos são

aproximações, mantido um determinado grau de precisão, devemos analisar que efeito isto pode ter

nos resultados destes cálculos.

Para ilustrar esta questão mais facilmente, vamos assumir a existência de um

computador que armazena os seus números em uma forma normalizada de ponto flutuante

decimal, ou seja, em um decimal equivalente à maneira na qual os números em ponto flutuante

(binários) são armazenados num computador típico. Ainda, assumiremos que estes números são

armazenados com precisão de quatro dígitos. Finalmente, assumiremos, também, que o expoente

deve ficar no intervalo -9 a +9. Então, um número decimal normalizado e não nulo terá a forma

0.d1d2d3d4 x 10p, sendo que d1 abrange o intervalo 1-9 e d2, d3 e d4 abrangem o intervalo 0-9. O

número 0.d1d2d3d4 é chamado de mantissa, enquanto que p é chamado de expoente. A Tabela 1

mostra alguns exemplos da maneira que números são armazenados neste computador.

Page 2: FORTRAN 90 - Calculos numericos

Tabela 1: Armazenamento de números1 em um computador de ponto flutuante decimal.

Valor externo Representação interna

37.5 0.3750 x 102

123.456 0.1235 x 103

123456789.12345 0.1234 x 109

9876543210.1234 não pode ser representado – expoente = 10

0.0000012345678 0.1234 x 10-5

0.9999999999999 0.1 x 101

0.0000000000375 não pode ser representado – expoente = -101 Aqui é usado ponto, ao invés da vírgula, como separador decimal.

Note que dois dos números apresentados na Tabela 1 não podem ser representados em

nosso computador decimal. O primeiro destes, 9 876 543 210.123 45, necessitaria de um expoente

igual a 10, maior que o computador permite. Qualquer tentativa de armazenar um número cujo

expoente é muito grande criará uma condição conhecida como overflow e, normalmente, causará

um erro neste estágio do processamento. Obviamente, uma vez que um cálculo tenha gerado uma

condição como esta, os cálculos subsequentes, que usam este resultado, estarão incorretos.

Uma situação similar surge com o último número da Tabela 1, 0.000 000 000 037 5,

que necessitaria de um expoente igual a -10, menor que o permitido pelo computador. Esta situação

é conhecida como underflow, menos séria que o overflow, uma vez que o efeito é que um número

está muito próximo de zero para ser distinguido de zero. Muitos computadores não reportarão isto

na forma de erro e armazenarão o número como zero. Em alguns cálculos, entretanto, é importante

saber quando a situação de underflow ocorreu; alguns computadores relatam a sua ocorrência como

um erro não fatal. Em particular, um underflow não relatado pode resultar em uma tentativa de

divisão por zero, se o divisor é muito pequeno ou num resultado errado de um teste para um número

nulo.

Agora, podemos visualizar como o nosso computador decimal fará cálculos aritméticos

simples. Antes de seguir adiante, entretanto, notamos que a maioria dos computadores realizam

operações aritméticas em um conjunto especial de registradores1 que permitem a utilização de mais

dígitos de precisão que a memória principal. Portanto, assumiremos que o nosso computador tem

registros aritméticos capazes de armazenar números de oito dígitos decimais – isto é, o dobro da

precisão da memória. Quando o resultado de uma operação aritmética é armazenado na memória,

assumiremos que ele será arredondado à precisão do computador – em nosso caso, quatro dígitos

decimais.

1 Maiores detalhes sobre registradores em http://en.wikipedia.org/wiki/Processor_register.

Page 3: FORTRAN 90 - Calculos numericos

Considere, primeiro, a soma de duas frações 11/9 e 1/3. O primeiro número, 11/9, será

armazenado como 0.1222 x 101 em nosso computador, enquanto que o segundo, 1/3, será

armazenado como 0.3333 x 100. Entretanto, antes que estes números possam ser somados, eles

devem ser convertidos para terem o mesmo expoente, sendo que os dígitos após espaço na descrição

a seguir representam os dígitos extras, disponíveis nos registradores aritméticos:

0.1222 x 101 + 0.0333 3 x 101 → 0.1555 3 x 101 (nos registradores)

→ 0.1555 x 101 (na memória)

Observe que o processo é tomar o número com expoente mais baixo e então aumentá-lo

até atingir o expoente do outro número, fazendo o deslocamento correspondente na mantissa para a

direita (então, desnormalizando-a).

A representação interna correta de (11/9 + 1/3), ou seja 14/9, é 0.1556 x 101 e é

importante notar que mesmo neste cálculo simples, realizado em aritmética de ponto flutuante,

introduziu-se um erro no quarto dígito significante devido ao arredondamento feito durante o

cálculo.

Considere, agora, o resultado de um cálculo um pouco mais longo, no qual cinco

números, 4, 0.0004, 0.0004, 0.0004 e 0.0004, são somados. Uma vez que cálculos aritméticos em

computadores sempre envolvem apenas dois operandos em cada estágio, os passos são como

seguem:

(1) 0.4000 x 101 + 0.0000 4 x 101 → 0.4000 4 x 101 (nos registradores)

→ 0.4000 x 101 (na memória)

(2) 0.4000 x 101 + 0.0000 4 x 101 → 0.4000 4 x 101 (nos registradores)

→ 0.4000 x 101 (na memória)

etc.

O resultado será 0.4000 x 101, ou seja, 4.0, quando podemos facilmente ver que seria

4.002, arredondado para quatro dígitos significativos. A denormalização forçou alguns dos números

tornarem-se efetivamente nulos durante o processo de adição.

Agora, considere o que acontece se a adição for realizada na ordem inversa:

(1) 0.4000 x 10-3 + 0.4000 x 10-3 → 0.8000 x 10-3 (nos registradores)

→ 0.8000 x 10-3 (na memória)

(2) 0.8000 x 10-3 + 0.4000 x 10-3 → 1.2000 x 10-3 (nos registradores)

→ 0.1200 0 x 10-2 (nos registradores)

Page 4: FORTRAN 90 - Calculos numericos

→ 0.1200 x 10-2 (na memória)

(3) 0.1200 x 10-2 + 0.0400 0 x 10-2 → 0.1600 x 10-2 (nos registradores)

→ 0.1600 x 10-2 (na memória)

(4) 0.0001 6 x 101 + 0.4000 x 101 → 0.4001 6 x 101 (nos registradores)

→ 0.4002 x 101 (na memória)

Então, neste caso o resultado é 4.002, que é a resposta correta para quatro dígitos

significativos. Este exemplo mostra que, sempre que possível, é preferível adicionar números

positivos para aumentar o valor do resultado, com o objetivo de minimizar os erros devido ao

arredondamento. Similarmente, é preferível adicionar números negativos para diminuir o valor, com

o mesmo objetivo.

Um exemplo muito mais sério de problemas envolvendo arrendondamento surge ao

subtrair dois números. Considere, por exemplo, o efeito de subtrair 12/41 de 5/17. 5/17 é

representado como 0.2941 x 100 e 12/41 como 0.2927 x 100 em nosso computador decimal e, então,

a subtração procede como segue:

0.2941 x 100 – 0.2927 x 100 → 0.0014 x 100 (nos registradores)

→ 0.1400 x 10-2 (na memória)

Entretanto, 5/17-12/41 é igual a 1/697, ou 0.1435 x 10-2. O erro no cálculo é, portanto,

da ordem de 2,4%, o qual é, dificilmente, a precisão que esperamos de um computador – mesmo no

nosso caso hipotético.

Este exemplo ilustra que deve-se sempre ter cuidado ao subtrair números que podem

ser quase idênticos (ou ao somar uma série de números que podem ser positivos e negativos), pois a

perda de precisão resultante dos cálculos em ponto flutuante pode afetar seriamente a precisão dos

cálculos.

O leitor fica alertado que mesmo tendo-se mostrado este problema com um

computador hipotético com somente quatro dígitos significativos, máquinas reais com seis ou mais

dígitos significativos encontram os mesmos problemas de arredondamento. Mostramos aqui que

podem haver problemas de arredondamento após apenas quatro ou cinco adições. Os computadores

modernos são capazes de velocidades superiores a um bilhão de operações de ponto flutuante em

um segundo. Ainda mais, alguns problemas podem rodar por dias, mesmo em máquinas rápidas.

Para mitigar os efeitos de arredondamento, deve-se prestar atenção aos algoritmos

numéricos empregados e à precisão com a qual as operações aritméticas serão realizadas. O

primeiro tópico é discutido em mais detalhes em livros de análise numérica. Com respeito ao

Page 5: FORTRAN 90 - Calculos numericos

segundo tópico, a linguagem Fortran fornece vários tipos de variáveis numéricas para aquelas partes

de um cálculo nas quais a perda de precisão pode ser séria. Para muitos problemas, embora nem

todos, o aumento da precisão dos cálculos em ponto flutuante é suficiente para obter respostas

satisfatórias.

FONTE: ELLIS, T. M. R.; PHILIPS, I. R.; LAHEY, T. M. Fortran 90 Programming. New York:

Addison-Wesley. 1994. 825p.