Страницы

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

среда, 25 декабря 2019 г.

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

#java


У меня есть 2 вещественных числа, например типа double. Я хочу их сравнить на равенство
с заданной точность. Как правильно выполнять такое сравнение?

Пока в  голову приходит такой вариант:

double x, y;
...
public boolean isEqual(double x, double y, double eps){
    return Math.abs(x-y) < eps;
}


Кажется, что в Java должны быть встроенные способы сравнить 2 вещественных числа.
Такие существуют? 
    


Ответы

Ответ 1



Вообще, это довольно интересный вопрос. Да, в общем случае всегда рекомендуется использовать что-то вроде: 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; } Более сложно и подробней про это можно почитать в этой занятной статье.

Ответ 2



Можно использовать класс BigDecimal. Пример : BigDecimal decimal = new BigDecimal("0.58499999999999996447286321199499070644378662109375"); BigDecimal decimal2 = new BigDecimal("0.58499999999999996447286321199499070644378662109374"); System.out.println(decimal.compareTo(decimal2)); Double x = 0.58499999999999996447286321199499070644378662109375; Double y = 0.58499999999999996447286321199499070644378662109374; System.out.println(x>y); Вывод: 1 false

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

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