Округление больших десятичных значений с двумя десятичными знаками

Я хочу, чтобы функция конвертировала 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

6 ответов

Решение

Я думаю, что 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

Добавлять 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);
}

Ты можешь позвонить 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

Вы можете попробовать это:

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

Согласно документам,setScale(int, int), не рекомендуется начиная с Java 1.5, когда впервые были представлены перечисления:

НовыйsetScale(int, RoundingMode)метод следует использовать вместо этого устаревшего метода.

В конце концов, он устарел в Java 9.

Вы должны позвонитьsetScale(2, RoundingMode.HALF_EVEN)вместо. Это значительно упрощает проверку ошибок, поскольку вы не можете передать неопределенноеenum, но вы, безусловно, можете перейти в целочисленный режим, который не определен.

Не работает с большим десятичным числом, любой, пожалуйста, помогите

      public class BigDecimalRoundDoubleMain  {

    public static void main(String[] args) {
          
            System.out.println(BigDecimalRoundDoubleMain.roundDouble(137.875));
            System.out.println(BigDecimalRoundDoubleMain.roundDouble(137.855));
            System.out.println(BigDecimalRoundDoubleMain.roundDouble(60.62499999999999));
            System.out.println(BigDecimalRoundDoubleMain.roundDouble1(60.62499999999999));
            System.out.println(BigDecimalRoundDoubleMain.roundDouble(137.856));
            
    }
 
    private static double roundDouble(double d) {
         
        BigDecimal bigDecimal = new BigDecimal(d);

        bigDecimal = bigDecimal.setScale(2, RoundingMode.HALF_UP);
        return bigDecimal.doubleValue();
    }
    private static double roundDouble1(double d) {
     
        BigDecimal bigDecimal = new BigDecimal(Double.toString(d));

        bigDecimal = bigDecimal.setScale(2, RoundingMode.HALF_UP);
        return bigDecimal.doubleValue();
    }

}

вывод: 137,88, 137,85, 60,62 вместо 60,63 , 60,62 вместо 60,63 , 137,86

Другие вопросы по тегам