Рубрики
Без рубрики

Как округлить число до N десятичных знаков в Java

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

Автор оригинала: baeldung.

1. Обзор

В этом коротком уроке мы узнаем, как округлить число до n десятичных знаков в Java.

Дальнейшее чтение:

Количество цифр в целом числе в Java

Проверьте, является ли число простым в Java

Проверьте, является ли строка числовой в Java

2. Десятичные числа в Java

Java предоставляет два примитивных типа, которые мы можем использовать для хранения десятичных чисел: float и double . Double является типом по умолчанию:

double PI = 3.1415;

Однако мы никогда не должны использовать ни один из типов для точных значений , таких как валюты. Для этого, а также для округления мы можем использовать класс BigDecimal .

3. Форматирование десятичного числа

Если мы просто хотим напечатать десятичное число с n цифрами после десятичной точки, мы можем просто отформатировать выходную строку:

System.out.printf("Value with 3 digits after decimal point %.3f %n", PI);
// OUTPUTS: Value with 3 digits after decimal point 3.142

В качестве альтернативы мы можем отформатировать значение с помощью класса DecimalFormat :

DecimalFormat df = new DecimalFormat("###.###");
System.out.println(df.format(PI));

Десятичный формат позволяет нам явно задавать поведение округления, предоставляя больший контроль над выводом, чем String.format () , используемый выше.

4. Округление Удваивается С Помощью BigDecimal

Чтобы округлить double s до n десятичных знаков, мы можем написать вспомогательный метод :

private static double round(double value, int places) {
    if (places < 0) throw new IllegalArgumentException();

    BigDecimal bd = new BigDecimal(Double.toString(value));
    bd = bd.setScale(places, RoundingMode.HALF_UP);
    return bd.doubleValue();
}

В этом решении следует отметить одну важную вещь: при построении BigDecimal мы должны всегда использовать BigDecimal(String) конструктор . Это предотвращает проблемы с представлением неточных значений.

Мы можем достичь того же результата, используя библиотеку Apache Commons Math :


    org.apache.commons
    commons-math3
    3.5

Последнюю версию можно найти здесь .

Как только мы добавим библиотеку в проект, мы сможем использовать Precision.round() метод, который принимает два аргумента – value и scale:

Precision.round(PI, 3);

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

Обратите внимание, что мы можем изменить поведение округления, передав нужный метод округления в качестве третьего параметра.

5. Округление Удваивается С Помощью Двойного Округления

Двойной округлитель – это утилита в библиотеке decimal4j . Он обеспечивает быстрый и свободный от мусора метод округления двойников от 0 до 18 десятичных знаков.

Мы можем получить библиотеку (последнюю версию можно найти здесь ), добавив зависимость в pom.xml :


    org.decimal4j
    decimal4j
    1.0.3

Теперь мы можем просто использовать:

DoubleRounder.round(PI, 3);

Тем не менее, Двойной округлитель не удается в нескольких сценариях:

System.out.println(DoubleRounder.round(256.025d, 2));
// OUTPUTS: 256.02 instead of expected 256.03

6. Математический метод round()

Другой способ округления чисел-использовать Math.Round() Метод.

В этом случае мы можем контролировать n количество десятичных знаков путем умножения и деления на 10^n :

public static double roundAvoid(double value, int places) {
    double scale = Math.pow(10, places);
    return Math.round(value * scale) / scale;
}

Этот метод не рекомендуется, так как он усекает значение . Во многих случаях значения округляются неправильно:

System.out.println(roundAvoid(1000.0d, 17));
// OUTPUTS: 92.23372036854776 !!
System.out.println(roundAvoid(260.775d, 2));
// OUTPUTS: 260.77 instead of expected 260.78

В результате этот метод указан здесь только в учебных целях.

7. Заключение

В этой статье мы рассмотрели различные методы округления чисел до n десятичных знаков.

Мы можем просто отформатировать вывод без изменения значения или округлить переменную с помощью вспомогательного метода. Мы также обсудили несколько библиотек, которые занимаются этой проблемой.

Код, используемый в этой статье, можно найти на GitHub .