Округление Bigdecimal значения с 2 десятичными местами

Мне нужна функция для преобразования Bigdecimal 10.12 for 10.12345 и 10.13 for 10.12556. Но никакая функция не удовлетворяет оба преобразования в одно и то же время. Пожалуйста, помогите добиться этого.

Ниже я пытаюсь.

BigDecimal a = new BigDecimal("10.12345");

a.setScale(2, BigDecimal.ROUND_UP)
a.setScale(2, BigDecimal.ROUND_CEILING)
a.setScale(2, BigDecimal.ROUND_DOWN)
a.setScale(2, BigDecimal.ROUND_FLOOR)
a.setScale(2, BigDecimal.ROUND_HALF_DOWN)
a.setScale(2, BigDecimal.ROUND_HALF_EVEN)
a.setScale(2, BigDecimal.ROUND_HALF_UP)

Выход:

10.12345::10.13
10.12345::10.13
10.12345::10.12
10.12345::10.12
10.12345::10.12
10.12345::10.12
10.12345::10.12


BigDecimal b = new BigDecimal("10.12556");

b.setScale(2, BigDecimal.ROUND_UP)
b.setScale(2, BigDecimal.ROUND_CEILING)
b.setScale(2, BigDecimal.ROUND_DOWN)
b.setScale(2, BigDecimal.ROUND_FLOOR)
b.setScale(2, BigDecimal.ROUND_HALF_DOWN)
b.setScale(2, BigDecimal.ROUND_HALF_EVEN)
b.setScale(2, BigDecimal.ROUND_HALF_UP)

Выход:

10.12556::10.13
10.12556::10.13
10.12556::10.12
10.12556::10.12
10.12556::10.12
10.12556::10.12
10.12556::10.12

Ответ 1

Я думаю, что RoundingMode, который вы ищете, это ROUND_HALF_EVEN. Из javadoc:

Округление режима округляется к "ближайшему соседу", если оба соседа не будут равноудаленными, и в этом случае округлите к четному соседу. Ведет себя как ROUND_HALF_UP, если цифра слева от отброшенной фракции нечетна; ведет себя как ROUND_HALF_DOWN, если он даже. Обратите внимание, что это режим округления, который минимизирует кумулятивную ошибку при неоднократном применении к последовательности вычислений.

Вот быстрый тестовый пример:

BigDecimal a = new BigDecimal("10.12345");
BigDecimal b = new BigDecimal("10.12556");

a = a.setScale(2, BigDecimal.ROUND_HALF_EVEN);
b = b.setScale(2, BigDecimal.ROUND_HALF_EVEN);

System.out.println(a);
System.out.println(b);

Правильно печатает:

10.12
10.13

Ответ 2

Добавьте 0.001 сначала к номеру, а затем вызовите setScale(2, RoundingMode.ROUND_HALF_UP)

Пример кода:

public static void main(String[] args) {
    BigDecimal a = new BigDecimal("10.12445").add(new BigDecimal("0.001"));
    BigDecimal b = a.setScale(2, BigDecimal.ROUND_HALF_UP);
    System.out.println(b);
}

Ответ 3

Вы можете вызвать метод setScale(newScale, roundingMode) три раза с изменением значения newScale от 4 до 3 до 2, например

Первый случай

    BigDecimal a = new BigDecimal("10.12345");

    a = a.setScale(4, BigDecimal.ROUND_HALF_UP); 
    System.out.println("" + a); //10.1235
    a = a.setScale(3, BigDecimal.ROUND_HALF_UP); 
    System.out.println("" + a); //10.124
    a = a.setScale(2, BigDecimal.ROUND_HALF_UP);
    System.out.println("" + a); //10.12

Второй случай

    BigDecimal a = new BigDecimal("10.12556");

    a = a.setScale(4, BigDecimal.ROUND_HALF_UP); 
    System.out.println("" + a); //10.1256
    a = a.setScale(3, BigDecimal.ROUND_HALF_UP); 
    System.out.println("" + a); //10.126
    a = a.setScale(2, BigDecimal.ROUND_HALF_UP);
    System.out.println("" + a); //10.13

Ответ 4

Вы можете попробовать следующее:

public static void main(String[] args) {
    BigDecimal a = new BigDecimal("10.12345");
    System.out.println(toPrecision(a, 2));
}

private static BigDecimal toPrecision(BigDecimal dec, int precision) {
    String plain = dec.movePointRight(precision).toPlainString();
    return new BigDecimal(plain.substring(0, plain.indexOf("."))).movePointLeft(precision);
}

ВЫВОД:

10.12