#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
Комментариев нет:
Отправить комментарий