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

1. Обзор

В этой короткой статье мы рассмотрим, как округлять число до n десятичных знаков в 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));

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

4. Округление чисел типа Double с помощью BigDecimal

Чтобы округлить двойное 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:

 org.apache.commons commons-math3 3.5 

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

После добавления библиотеки в проект мы можем использовать метод Precision.round () , который принимает два аргумента - значение и масштаб:

Precision.round(PI, 3);

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

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

5. Округление удвоений с помощью DoubleRounder

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

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

 org.decimal4j decimal4j 1.0.3 

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

DoubleRounder.round(PI, 3);

Однако DoubleRounder дает сбой в нескольких случаях, например:

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

6. Метод Math.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.