Comment vérifier l'égalité de deux nombres à virgule flottante (float) ?
sobes.tech IA
Réponse de l'IA
Il n'est pas recommandé de comparer directement avec l'opérateur == en raison des particularités de la représentation et de l'arrondi. À la place, il faut vérifier si la valeur absolue de la différence entre les nombres est dans une petite marge (epsilon).
bool are_equal(float a, float b, float epsilon = 0.00001f) {
return std::abs(a - b) < epsilon;
}
Une approche plus robuste prend en compte l'erreur relative, surtout lors de la comparaison de nombres très grands ou très petits :
#include <cmath>
#include <limits>
bool are_equal_robust(float a, float b, float epsilon = std::numeric_limits<float>::epsilon()) {
// Compare la différence en tenant compte de l'échelle des nombres
// Il est important de traiter séparément les cas avec zéro et infini
if (a == b) {
return true; // Gère les cas où a=b (y compris infini et NaN si ils sont égaux entre eux – ce qui n'est pas le cas pour NaN, mais pour infini oui)
}
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; // Les deux nombres sont proches de zéro
} else {
return absolute_difference / max_abs < epsilon; // Comparaison de la différence relative
}
}
Le choix de epsilon dépend de la précision requise et de la plage de valeurs à comparer. std::numeric_limits<float>::epsilon() représente le plus petit nombre tel que 1.0 + epsilon est différent de 1.0.
Il est important de se rappeler que la comparaison avec NaN (Not a Number) retourne toujours false, y compris la comparaison de NaN avec lui-même (nan == nan est toujours false). Si la gestion de NaN est nécessaire, cela doit être fait séparément.