Округление 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