Як округлити число до N десяткових місць на Java

1. Огляд

У цій короткій статті ми розглянемо, як округлити число до n десяткових знаків у Java.

2. Десяткові числа в Java

Java пропонує два примітивні типи, які можна використовувати для зберігання десяткових чисел: плаваючі та подвійні . 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. ROUNDING Подвійна з з 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 Math:

 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.