Como verificar a igualdade de dois números de ponto flutuante (float)?
sobes.tech IA
Resposta da IA
Não é recomendado comparar diretamente com o operador == devido às peculiaridades da representação e arredondamento. Em vez disso, deve-se verificar se o valor absoluto da diferença entre os números está dentro de um pequeno limite (épsilon).
bool are_equal(float a, float b, float epsilon = 0.00001f) {
return std::abs(a - b) < epsilon;
}
Uma abordagem mais robusta leva em consideração o erro relativo, especialmente ao comparar números muito grandes ou muito pequenos:
#include <cmath>
#include <limits>
bool are_equal_robust(float a, float b, float epsilon = std::numeric_limits<float>::epsilon()) {
// Compara a diferença considerando a escala dos números
// É importante tratar casos com zero e infinito separadamente
if (a == b) {
return true; // Trata casos onde a=b (incluindo infinito e NaN se forem iguais entre si – o que não é verdade para NaN, mas para infinito sim)
}
float absolute_difference = std::abs(a - b);
float max_abs = std::max(std::abs(a), std::abs(b));
if (max_abs < epsilon) {
return absolute_difference < epsilon; // Ambos os números próximos de zero
} else {
return absolute_difference / max_abs < epsilon; // Comparação da diferença relativa
}
}
A escolha de epsilon depende da precisão requerida e do intervalo de valores a serem comparados. std::numeric_limits<float>::epsilon() representa o menor número tal que 1.0 + epsilon difere de 1.0.
É importante lembrar que a comparação com NaN (Not a Number) sempre retorna false, incluindo a comparação de NaN consigo mesmo (nan == nan é sempre false). Se for necessário tratar NaN, isso deve ser feito separadamente.