Сравнение BigDecimal

199
02 июля 2018, 20:30

Даны две точки и середина между ними. Почему результат сравнения неверный? Изначально я использовал тип double, оказалось, что он не очень подходит для подобных задач. И я подумал, что ситуацию исправит класс BigDecimal.

public class Main {    
    public static void main(String[] args) {
        BigDecimal x1 = new BigDecimal(9.32006951);
        BigDecimal x2 = new BigDecimal(9.33406361);
        BigDecimal x = new BigDecimal(9.32706656);
        if (x1.add(x.negate()).abs().compareTo(x2.add(x.negate()).abs()) == 0)
            System.out.println("равны");
        else System.out.println("не равны");
    }
}

Если Вы предлагаете использовать вместо этого сравнение разности с эпсилон, то как быть с немного иной задачей:

Дан отрезок и его середина. Имеется два метода. На вход функции подается число из отрезка, результатом функции будет ближайшая точка к входному параметру (начало или конец отрезка). Если на вход функции подается середина отрезка, то для первого метода результатом функции должно быть начало отрезка, для второго - его конец.

Код функции (на самом деле, тут несколько отрезков):

static double getClosest(double x, int k) {
        BigDecimal min = new BigDecimal(xi[0]);
        BigDecimal x_ = new BigDecimal(x);
        BigDecimal xa;
        for (int i = 1; i < 6; i++) {
            xa = new BigDecimal(xi[i]);
            if ((xa.add(x_.negate()).abs().compareTo(min.add(x_.negate()).abs()) == -1) || (xa.add(x_.negate())).abs().compareTo(min.add(x_.negate()).abs()) == 0 && k == 2)
                min = xa;
        }
        return min.doubleValue();
    }

Проблема в том, что здесь нужно сравнить по модулю эти числа, и они не обязательно будут равны. А сравнение разности чисел с эпсилон удобно, если нужна проверка на равенство.

Answer 1

Нужно задать одинаковую точность, для этого есть метод setScale(), вот описание в доке:
https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html#setScale-int-java.math.RoundingMode-

В main должно быть:

 BigDecimal x1 = new BigDecimal(9.32006951).setScale(8, RoundingMode.HALF_UP); 

Так же для x и x2, в этом случае результат сравнения будет нужный.

READ ALSO
Ошибка с FirebaseListAdapter

Ошибка с FirebaseListAdapter

При компиляции кода выдает ошибку:

195
Как можно отобразить несколько точек на mapView если координаты этих точек находятся в бд firebase?

Как можно отобразить несколько точек на mapView если координаты этих точек находятся в бд firebase?

Есть база данных, куда приходят данные о местоположение пользователя

175
Не создается файл в java

Не создается файл в java

Создаю файл таким вот кодомНо, как ни стараюсь, не получается создать файл, хотя выполняется код без ошибок

171
Почему создание экземпляра RecyclerView излишне?

Почему создание экземпляра RecyclerView излишне?

Изучаю в Android RecyclerView, при ,казалось бы ,логическом

170