Risco de operações lógicas em variáveis ​​de ponto flutuante em c ++

Video: Linguagem C #04: Variáveis Reais (ponto flutuante)

erros de arredondamento em ponto flutuante computação pode criar confusão com operações lógicas em C ++, então você deve ter cuidado realizar operações lógicas sobre as variáveis ​​de ponto flutuante. Considere o seguinte exemplo:

flutuar f1 = 10,0 flutuador-f2 = f 1/3-boleano b1 = (f1 == (f2 * 3.0)) - // são estes dois iguais?

Mesmo que seja óbvio para nós que f1 é igual a f2 3 vezes, o valor resultante de b1 não é necessariamente verdade. A variável de ponto flutuante não pode conter um número ilimitado de algarismos significativos. Portanto, f2 não é igual ao número que chamaríamos de “três-e-um-terço”, mas sim para 3,3333 ..., parando depois de algum número de casas decimais.

UMA flutuador variável suporta cerca de 7 dígitos de precisão, enquanto um Duplo suporta uma skosh mais de 16 dígitos. Estes números são aproximados porque o computador é susceptível de gerar um número como 3.3333347 devido a excentricidades nos cálculos de ponto flutuante.

Agora, em matemática pura, o número de 3s após o ponto decimal é infinita, mas nenhum computador construído pode lidar com um número infinito de dígitos. Então, depois de multiplicar 3,3333 por 3, você começa 9,9999 em vez dos 10 que você obteria se multiplicaram “três-e-um-terço” - na verdade, uma erro de arredondamento. Essas pequenas diferenças podem ser imperceptível para uma pessoa, mas não para o computador. Igualdade significa exatamente isso - exato igualdade.

Os processadores modernos são sofisticados em realizar esses cálculos. O processador pode, de fato, acomodar o erro de arredondamento, mas de dentro C ++, você não pode prever exatamente o que qualquer processador irá fazer.

A comparação mais seguro seguinte:

Video: Sistemas em ponto flutuante e erros de arredondamento

flutuar f1 = 10,0 flutuador-f2 = f 1/3-flutuador f3 = f2 * 3,0-flutuador delta = f1 - f3-boleano bEqual = -0,0001 lt; delta && delta lt; 0.0001-

Esta comparação é verdade E se f1 e F3 estão dentro de algum pequeno delta do outro, que ainda deve ser verdade mesmo se você levar algum pequeno erro de arredondamento em conta.



A lógica AND && e lógico OR || operadores em C ++ executar o que é chamado Avaliação do curto-circuito. Considere o seguinte:

condition1 && condition2

E se condition1 não é verdade, o resultado global não é verdade, não importa o que o valor de condition2. (Por exemplo, condition2 poderia ser verdade ou falso . Sem alterar o resultado) A mesma situação ocorre na seguinte:

condition1 || condition2

E se condition1 é verdade, o resultado é verdade, não importa o que o valor de condition2 é.

Video: Convertendo Ponto Flutuante pra Binário + IEEE-754

Para economizar tempo, C ++ não avalia condition2 se ele não precisa. Por exemplo, na expressão condition1 && condition2, C ++ não avaliar condition2 E se condition1 é falso. Da mesma forma, na expressão condition1 || condition2, C ++ não avaliar condition2 E se condition1 é verdade. Isto é conhecido como a avaliação de curto-circuito.

avaliação curto-circuito que pode significar condition2 não é avaliada mesmo que essa condição tem efeitos colaterais. Considere o seguinte trecho de código reconhecidamente inventado:

int nArg1 = 1-int nArg2 = 2-int nArg3 = 3-boleano b = (nArg1 gt; nArg2) && (NArg2 ++ gt; nArg3) -

a variável nArg2 nunca é incrementado porque a comparação nArg2 ++ gt; nArg3 não é executada. Não há necessidade, porque nArg1 gt; nArg2 já retornou um falso Portanto, a expressão global deve ser falso.


Publicações relacionadas