JavaRush/Java блог/Random UA/Округлення чисел у Java

Округлення чисел у Java

Стаття з групи Random UA
учасників
Числа з плаваючою точкою (float, double) застосовуються при обчисленні виразів, які потребують точності до десяткового знака. Висока точність часто потрібна у бухгалтерських та інших обчислювальних операціях. Округлення чисел у Java - 1Але чи завжди нам потрібний довгий "хвіст" чисел після коми? Чи може нам достатньо точності в три знаки речової частини? І чи є нас такий варіант влаштовує, як правильно виконати округлення? Саме про це ми сьогодні і поговоримо: розглянемо способи округлення чисел у Java .

String format

Як перший спосіб ми розглянемо округлення double:
double value = 34.766674;
String result = String.format("%.3f",value);
System.out.print(result);//  34,767
В результаті ми відформатуємо наше число з плаваючою комою 34766674 з точністю до 3 десяткових розрядів , тому що в інструкції для форматування ми вказали три знаки після коми "%.3f. У свою чергу %f при форматуванні рядка позначає тип чисел з плаваючою комою, яке включає тип даних double і float в Java.У прикладі вище ми виводабо отримане значення в консоль.Тепер питання: як би можна було це скоротити?Все просто: потрібно використовувати printf, який у свою чергу є format + print. приклад у нас скоротився б до:
double value = 34.766674;
System.out.printf("%.3f",value);
У екземпляра out класу PrintStream крім цього є ще метод format, який працює аналогічно:
double value = 34.766674;
System.out.format("%.3f",value);
Округлення відбувається за режимом HALF_UP — у бік числа, яке ближче до обрізаного (до 0 або 10). Якщо ці числа рівновіддалені (у разі 5), то округлення виконується у велику сторону. Приклад:
String firstResult = String.format("%.3f",7.0004);// 7,000
String secondResult = String.format("%.3f",7.0005);// 7,001
String thirdResult = String.format("%.3f",7.0006);// 7,001
Детальніше режими округлення ми розберемо трохи нижче. Округлення чисел у Java - 2

DecimalFormat

Ще один варіант - використовувати клас DecimalFormat . Він призначений для форматування будь-якого числа в Java, чи це ціле чи число з плаваючою комою. Під час створення екземпляра DecimalFormat ми можемо передати йому рядок форматування. Вона вкаже, скільки десяткових розрядів потрібно відформатувати для введення. Як буде виглядати наш приклад з використанням DecimalFormat :
double value = 34.766674;
DecimalFormat decimalFormat = new DecimalFormat( "#.###" );
String result = decimalFormat.format(value);
System.out.print(result);//34,767
Рядок #.### — це шаблон, який вказує, що ми форматуємо значення, що передається, до 3 десяткових знаків. Щоб змінити шаблон після створення об'єкта DecimalFormat, можна використовувати його методи applyPattern і applyLocalizedPattern :
DecimalFormat decimalFormat = new DecimalFormat("#.###");
decimalFormat.applyPattern("#.#");
decimalFormat.applyLocalizedPattern("#.#####");
Але ми сьогодні говоримо про округлення, чи не так? При обрізанні числа зі знаками після коми, що виходять за заданий шаблон, DecimalFormat округлює число у більшу сторону, якщо останній число, що обрізається, більше 5. Але що якщо число — 5? Виходить, що воно рівно посередині між найближчими цілими. Що тоді? І тут враховується попереднє число. Якщо воно парне, округлення виконується:
DecimalFormat decimalFormat = new DecimalFormat("#.###");
String result = decimalFormat.format(7.4565);
System.out.println((result));// 7,457
Якщо непарне — не робиться:
DecimalFormat decimalFormat = new DecimalFormat("#.###");
String result = decimalFormat.format(7.4575);
System.out.println((result));// 7,457
Є невелика різниця між форматуванням чисел із плаваючою комою з використанням String.format() та DecimalFormat.format(). Перший завжди друкуватиме кінцеві нулі, навіть якщо немає дробової частини. Наприклад:
String firstResult = String.format("%.3f", 7.000132);
System.out.println((firstResult)); // 7.000

DecimalFormat decimalFormat = new DecimalFormat("#.###");
String secondResult = decimalFormat.format(7.000132);
System.out.println((secondResult));  // 7
Як бачимо, при форматуванні числа 7.000132 з точністю до трьох десяткових розрядів, метод format() у String виводить 7.000, тоді як у DecimalFormat метод format() виведе 7. Тобто ви можете вибирати String.format() чи DecimalFormat . format() в залежності від того, потрібні вам кінцеві нулі чи ні. Застосовуючи вищеописані способи, ми отримували результат у вигляді рядка. Давайте розглянемо способи, як можна отримати назад саме числові значення.

Math

Не можна не згадати спеціальний клас, заточений під різні арифметичні операції з числами - Math . Округлення чисел у Java - 3У цьому класі є й методи для округлення, але на відміну від описаних, вони не дозволяють задати певну кількість знаків після коми, а округляють до цілого числа:
  • Math.ceil() округляє до найближчого цілого числа вгору, але віддає не цілий тип, а double:

    double value = 34.777774;
    double result = Math.ceil(value);
    System.out.println((result)); //35.0

    Навіть якщо у нас буде 34.0000000, все одно після використання Math.ceil ми отримаємо 35,0.

    Math.floor() округляє до найближчого цілого вниз, також результатом віддає double:

    double value = 34.777774;
    double result = Math.floor(value);
    System.out.println((result)); //34.0

    Знову ж таки, навіть якщо у нас буде значення 34.999999999, то після використання Math.floor ми отримаємо 34,0.

  • Math.round () - округляє до найближчого цілого числа, як результат віддає int:

    double value = 34.777774;
    int result = Math.round(value);
    System.out.println((result)); //35

    Якщо в нас число 34.5, округлення виконується до 35, якщо трохи менше 34.499, число обрізається до 34.

    Щоб не просто обрізати всю речову частину, а регулювати цей процес до певної кількості знаків і при цьому округляти, число множать на 10 n (10 в ступені n), де n дорівнює кількості необхідних знаків після коми. Після цього застосовують якийсь метод класу Math для округлення, а потім знову ділять на 10^n:

    double value = 34.777774;
    double scale = Math.pow(10, 3);
    double result = Math.ceil(value * scale) / scale;
    System.out.println((result)); //34.778

    Math.pow - приймає два аргументи. Перший — число, другий — ступінь, на який його треба звести.

Округлення з BigDecimal

BigDecimal - це клас, який дозволяє працювати з числами з плаваючою комою. Зокрема, його основною фішкою є те, що в ньому можна зберігати подрібнені числа довільної довжини (тобто немає обмеження в діапазоні числа). Крім цього, цей клас зберігає різні методи для арифметичної обробки, включаючи заокруглення. Клас даного об'єкта можна створити, задавши в конструктор double, string відображення числа з плаваючою комою, double і MathContext і так далі. MathContext - комбінація правила округлення RoundingMode і числа, що описує загальну кількість цифр у значенні. Правила заокруглення RoundingMode: DOWN — заокруглення убік до нуля. UP – режим заокруглення від нуля. CEILING - округлення у бік позитивної нескінченності. FLOOR — заокруглення у бік негативної нескінченності. HALF_UP — округлення до «найближчого сусіда», якщо обидва сусіди не рівновіддалені (тобто коли округлене число — 5). У цьому випадку виконується заокруглення вгору. HALF_DOWN — округлення у бік «найближчого сусіда». Якщо обидва сусіди нерівновіддалені, у цьому випадку округлення вниз. HALF_EVEN — заокруглення до «найближчого сусіда», якщо обидва сусіди нерівні. У цьому випадку округляються до парного сусіда (як описано вище DecimalFormat). UNNECESSARY— використовується для підтвердження того, що ця операція має точний результат. Отже, округлення не потрібне. Приклад:
MathContext context = new MathContext(5, RoundingMode.HALF_UP);
double value = 34.777554;
BigDecimal result = new BigDecimal(value, context);
System.out.println(result); //34.778
Крім можливості задавати правило округлення в конструкторі, BigDecimal дозволяє встановити режим округлення вже після створення екземпляра. Для цього використовується метод setScale , який потрібно задати кількість знаків після коми і правила округлення:
double value = 34.777554;
BigDecimal result = new BigDecimal(value);
result = result.setScale(3, RoundingMode.DOWN);
System.out.println(result); //34.777
Також у BigDecimal є внутрішні int змінні, призначені для завдання режиму округлення ( ROUND_DOWN , ROUND_CEILING , ROUND_FLOOR ...) Є правила округлення, аналогічні представленим у класі RoundingMode і аналогічно використовуються в setScale :
BigDecimal result = new BigDecimal(value);
result = result.setScale(3, BigDecimal.ROUND_DOWN);
Докладніше про клас BigDecimal - у цій статті .
Коментарі
  • популярні
  • нові
  • старі
Щоб залишити коментар, потрібно ввійти в систему
Для цієї сторінки немає коментарів.