Équivalence en virgule flottante?
-
05-07-2019 - |
Question
Je veux pouvoir comparer deux doublons sans tenir compte d'une éventuelle perte de précision. Existe-t-il déjà une méthode qui gère ce cas?
Dans la négative, existe-t-il un seuil / une directive permettant de savoir combien équivaut à une équivalence adéquate entre deux doubles?
La solution
Le seuil est complètement dépendant du problème lui-même. Pour certains problèmes, vous pouvez considérer que 1,001 est égal à 1,002 et, dans certains cas, vous aurez peut-être besoin d'un seuil beaucoup plus bas.
La technique générale est la suivante:
Math.Abs(a - b) < some_epsilon // `a` is roughly equivalent to `b`
Autres conseils
Une très bonne option complète pour cela est:
public static bool DoubleEquality(double a, double b)
{
const double epsilonValue = 1e-15;
if (double.IsNaN(a))
return double.IsNaN(b);
else if (double.IsInfinity(a))
return double.IsInfinity(b);
else if (a == 0)
return b == 0;
else
return Math.Abs(a - b) <= Math.Abs(a * epsilonValue);
}
Notez que Double.Epsilon n’est PAS une bonne valeur pour epsilon. Cela crée un epsilon qui s'adapte quelque peu à la magnitude de votre première valeur, ce qui aide beaucoup.