Эквивалентность с плавающей точкой?
-
05-07-2019 - |
Вопрос
Я хочу иметь возможность сравнивать два двойных значения без учета возможной потери точности. Уже есть метод, который обрабатывает этот случай? Р>
Если нет, есть ли пороговое значение / руководство, чтобы узнать, насколько адекватна эквивалентность между двумя двойными числами?
Решение
Порог полностью зависит от самой проблемы. Для некоторых проблем вы можете считать 1,001 равным 1,002, а для некоторых проблем вам может потребоваться намного меньший порог.
Общая техника:
Math.Abs(a - b) < some_epsilon // `a` is roughly equivalent to `b`
Другие советы
Очень хороший, тщательный вариант для этого:
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);
}
Обратите внимание, что Double.Epsilon НЕ является хорошим значением epsilon для этого. Это создает эпсилон, который несколько масштабируется с величиной вашего первого значения, что немало помогает.