Equivalenza in virgola mobile?
-
05-07-2019 - |
Domanda
Voglio essere in grado di confrontare due doppi trascurando una possibile perdita di precisione. Esiste già un metodo che gestisce questo caso?
In caso contrario, esiste una soglia / linea guida per sapere quanto è un'equivalenza adeguata tra due doppie?
Soluzione
La soglia dipende completamente dal problema stesso. Per alcuni problemi, potresti considerare 1.001 uguale a 1.002 e per alcuni problemi, potresti aver bisogno di una soglia molto più piccola.
La tecnica generale è:
Math.Abs(a - b) < some_epsilon // `a` is roughly equivalent to `b`
Altri suggerimenti
Un'opzione molto valida e completa per questo è:
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);
}
Nota che Double.Epsilon NON è un buon valore epsilon per questo. Questo crea un epsilon che si ridimensiona in qualche modo con la grandezza del tuo primo valore, il che aiuta parecchio.