É correto comparar dois arredondado números de ponto flutuante usando o operador ==?
-
04-07-2019 - |
Pergunta
Ou há uma chance de que a operação irá falhar?
Graças.
Eu escolhi o termo errado eo que eu realmente quis dizer foi o arredondamento para 0, não truncamento.
O ponto é, eu preciso comparar a parte inteira de dois duplos e eu estou apenas fazendo-os para int e, em seguida, usando ==, mas, como alguém observou em uma das minhas perguntas anteriores, este poderia jogar um estouro exceção se a dupla pode não se encaixar no inteiro.
Portanto, a pergunta seria 'É correto usar o operador == para comparar duas duplas que tenham sido previamente arredondado para 0, ou devo ficar com o elenco para o método int e pegar uma possível exceção?
Solução
Aqui está o site atualizado que discute as vantagens e desvantagens de vários métodos de comparação dos números de ponto flutuante. (Você ainda pode ver o site antigo aqui .)
O método que eu iria com o método "erro relativo". Encontrar a diferença entre os dois números, convertê-lo em uma porcentagem dos números, e se essa percentagem é suficientemente pequeno, então você tem igualdade.
Outras dicas
Ainda pior é que, às vezes, até mesmo para o mesmo número exato, ele irá falhar. Isso ocorre porque alguns compiladores ou processadores usarão mais bits de precisão num registo CPU do que na memória (MSVC tem 3 opções diferentes de comportamento de ponto flutuante, por exemplo). Assim, um valor recém-computadorizada podem não ter esses bits truncado e aparecerá a ser desigual. NUNCA use == em carros alegóricos.
Ele ainda pode falhar devido aos problemas normais com representação de ponto flutuante. Ao invés de truncar-los, use um delta que representaria a precisão equivalente.
Ele pode falhar em casos onde você tem dois carros alegóricos que você normalmente considerar o mesmo,
10.19999999
10.20000001
mas quando você truncar eles dão resultados diferentes.
10.19
10.20
Considerando que, se eu tivesse usado um delta de 0,001 para comparar com a diferença, eu teria visto que estes dois valores são efetivamente o mesmo.
Nunca é correto usar ==
com ponto flutuante.
O que significa "truncada" significa em um contexto de ponto flutuante? Que função biblioteca específica está ligando? Qual é o resultado? O que faz você acreditar que os valores "truncado" são mais comparáveis ??do que os valores não-truncado?
ponto flutuante é uma aproximação dos valores decimais. ponto flutuante só pode representar potências de dois precisamente. Todos os outros valores estão sujeitos a algum erro, não importa o que as operações de ponto flutuante que você faz.
Se, no entanto, converter para inteiro, você pode usar ==
.
Se o seu valor absoluto é menor que 2 ^ 23 para simples ou 2 ^ 52 para double você pode usar round () e então fazer a comparação. valores maiores não podem ser precisly armazenada e isso abre para situações onde N == N + 1.