[Cascavel-pm] Números Flutuantes

Flávio de Vasconcellos Corrêa flavio.correa em pop.com.br
Terça Setembro 16 16:57:34 CDT 2003


Em Seg 15 Set 2003 11:34, Marques & Corrêa Ltda. escreveu:
> Em Sáb 13 Set 2003 18:30, Fabiano Reese Righetti escreveu:
> >    Olá pessoal!
> >    Estou com o seguinte problema com pontos flutuantes: Quando efetuo a
> > seguinte conta ((((-1/5)*3)*5)+3) o resultado correto seria 0 (zero) mas
> > ele resulta no seguinte:
> >
> > $ perl -e 'printf "%0.55f\n",((((-1/5)*3)*5)+3);'
> > -0.0000000000000004440892098500626161694526672363281250000
> > $
> >
> >    Alguém saberia como tratar este tipo de problema?
> >
> > Abraços.
>
> Fabiano,
> 	a causa própriamente dita eu já li, mas não me lembro mais aonde e nem
> quando exatamente. Este problema eu já enfrentei em C/C++, PASCAL, PHP e
> outros. Se me recordo bem, posso estar enganado :), quando você divide dois
> valores tipo "float" o valor é sempre "meio-exato", a solução que tenho
> adotado é diminuir a precisão. No seu caso, se fosse o meu, faria da
> seguinte forma:
>
> $ perl -e 'printf "%0.15f\n",((((-1/5)*3)*5)+3);'.
>
> Como eu trabalho com aplicações financeiras/contábeis e não fins
> científicos, que pode ser o caso, faria :
>
> $ perl -e 'printf "%0.2f\n",((((-1/5)*3)*5)+3);'.
> _______________________________________________
> Cascavel-pm mailing list
> Cascavel-pm em mail.pm.org
> http://cascavel.pm.org/mailman/listinfo/cascavel-pm

Fabiano,
        vou transcrever uma explicação que encontrei no livro "Programação 
Orientada 
a Objetos usando Delphi 3" de Faiçal Farhat de Carvalho, ed. Érica 1a. 
edição, 1998, pag. 119

        "               Números reais. 
        
        Os computadores lidam com muita facilidade com números inteiros. A 
representação binária de um número inteiro é absolutamente exata. Entretanto, 
a coisa muda um pouco de figura quando entram em cena os números reais. É 
fácil intuir a complexidade que surge. Quando trabalhamos com números reais, 
muitas vezes estamos lidando com aproximações. Por exemplo, a expressão 1/3 
pode ser representada como 0,3333 - quatro casas depois da vírgula. Essa 
aproximação pode ser conveniente para a maioria dos softwares financeiros. 
Porém para um controlador de rota de naves espaciais tripuladas, esse nível 
de precisão pode ser inadequado - especialmente para o astronauta, que 
certamente ficaria mais satisfeito em saber que no computador da sua nave a 
fração 1/3 é igual a 0,333333333333333333333333333333.
        Isso nos mostra que a representação de números reais pode apresentar 
muitas 
variações. Na verdade, quando o assunto é número real, surgem alguns 
personagens que simplismente não aparecem quando a novela é a dos números 
inteiros: precisão, número de dígitos significativos, underflow, mantissa, 
base, expoente, são alguns exemplos. Esse é um assunto complexo. Não vamos 
tratar aqui de cada um desses termos. É importante, porém, termos uma boa 
noção de que existe com freqüência uma certa margem de erro quando lidamos 
com números reais. Muitas vezes, esses erros são insignificantes. Em alguns 
casos, porém, erros acumulados de arredondamentos podem prejudicar 
significamente o resultado de um cálculo. É preciso, portanto, ficar atento a 
essas peculiaridades dos números reais."

Então Fabiano quando você calcula a expressão (-1/5), pronto você já tem o seu 
número real e a sua exatidão já era. Pra zerar a tua conta só com:

perl -e 'printf "%0.55f\n", ((-3*5)/5)+3;', se você acompanhar o cálculo só 
existem números inteiros.

Não me lembro se no perl tem typecast, deve ter ;), tome cuidado com os 
arredontamentos consecutivos nos cálculos, você pode ser o inferno de um 
setor estatístico/financeiro.

Flávio de Vasconcellos Corrêa.




Mais detalhes sobre a lista de discussão Cascavel-pm