Страницы

Поиск по вопросам

среда, 28 ноября 2018 г.

Как в Java сравнить 2 вещественных числа на равенство?

У меня есть 2 вещественных числа, например типа double. Я хочу их сравнить на равенство с заданной точность. Как правильно выполнять такое сравнение?
Пока в голову приходит такой вариант:
double x, y; ... public boolean isEqual(double x, double y, double eps){ return Math.abs(x-y) < eps; }
Кажется, что в Java должны быть встроенные способы сравнить 2 вещественных числа. Такие существуют?


Ответ

Вообще, это довольно интересный вопрос.
Да, в общем случае всегда рекомендуется использовать что-то вроде:
bool isEqual = fabs(a1 – a2) <= epsilon;
Но более интересный вопрос, какое значение для epsilon использовать.
К примеру, в C++ в float.h есть константа FLT_EPSILON, равная 1E-5. Всё, можно такое же значение использовать, да?
Вполне, если числа большие. Но если у вас число в промежутке [0;1], то начинаются проблемы. Точность вычисления будет соизмерима с фактическим значением, что приведёт к тому, что на такое сравнение нельзя будет положиться.
Относительный эпсилон
Для сравнения чисел можно руководствоваться правилом:
Для сравнения a1 и a2 вычисляем diff = fabs(a1-a2). Если diff меньше ,чем n% от max(abs(a1), abs(a2)), тогда a1 и a2 можно считать равными.
public static bool almostEqualRelative(float a, float b, float maxRelDiff = FLT_EPSILON) { // находим разницу float diff = fabs(a - b); A = fabs(a); B = fabs(b); // находим большее float largest = (b > a) ? b : a;
if (diff <= largest * maxRelDiff) return true;
return false; }
Более сложно и подробней про это можно почитать в этой занятной статье.

Комментариев нет:

Отправить комментарий