1. Вступ
У реальному житті рідко потрібно бачити довгі «хвости» після коми. Наприклад, коли ви обчислюєте вартість товару, зарплату, середній бал або площу кімнати — зазвичай вистачає двох знаків після коми, а не 15.
Наприклад, результат ділення:
double x = 10.0 / 3.0;
System.out.println(x); // 3.3333333333333335
Користувач, побачивши такий результат, може злякатися й подумати, що програма зʼїхала з глузду. Тому числа часто треба округлювати — до найближчого цілого, до двох знаків після коми тощо.
У Java для цього є кілька зручних інструментів.
2. Метод Math.round(): округлення до найближчого цілого
Найпростіший спосіб округлити число — скористатися методом Math.round(). Він приймає число з плаваючою комою (можна і float, і double) та повертає найближче ціле.
Як працює Math.round
- Якщо дробова частина менша за 0.5 — округлює донизу.
- Якщо дробова частина 0.5 або більше — округлює вгору.
Приклади:
System.out.println(Math.round(2.3)); // 2
System.out.println(Math.round(2.7)); // 3
System.out.println(Math.round(2.5)); // 3
System.out.println(Math.round(-2.5)); // -2
Тип поверненого значення
- Якщо передати float, повернеться int.
- Якщо передати double, повернеться long.
float f = 5.8f;
int roundedF = Math.round(f); // 6
double d = 5.8;
long roundedD = Math.round(d); // 6
Зверніть увагу: іноді це дивує: округлили double, а отримали long! Якщо вам потрібен int, доведеться зробити явне перетворення типу:
int rounded = (int) Math.round(5.6); // 6
3. Округлення до потрібної кількості знаків після коми
Часто потрібно округлити не до цілого, а, наприклад, до двох знаків після коми (для грошей, відсотків тощо).
У Java немає «магічного» методу на кшталт Math.roundTo2Digits(), але це легко зробити вручну.
Спосіб 1: математичний трюк із множенням і діленням
- Множимо число на 100 (якщо треба два знаки).
- Округлюємо до цілого за допомогою Math.round.
- Ділимо назад на 100.
Приклад:
double value = 3.14159;
double rounded = Math.round(value * 100.0) / 100.0;
System.out.println(rounded); // 3.14
Як це працює:
- 3.14159 * 100 = 314.159
- Math.round(314.159) = 314
- 314 / 100.0 = 3.14
4. Форматування чисел: клас DecimalFormat
Іноді потрібно не просто округлити число, а й вивести його акуратно — з певною кількістю знаків після коми, провідними нулями, роздільниками розрядів тощо. Для цього у Java є клас DecimalFormat із пакета java.text.
Як працює DecimalFormat
- Створюємо об’єкт із потрібним шаблоном.
- Викликаємо в нього метод format(...).
import java.text.DecimalFormat;
double value = 3.14159;
DecimalFormat df = new DecimalFormat("0.00");
System.out.println(df.format(value)); // 3.14
Як влаштований шаблон
- "0.00" — завжди два знаки після коми (навіть якщо число ціле).
- "0.###" — до трьох знаків після коми, зайві нулі не виводяться.
- "#,##0.00" — додає роздільники тисяч (наприклад, "1,234.56").
Приклади різних шаблонів:
| Шаблон | Число | Результат |
|---|---|---|
|
2 | 2.00 |
|
2.5 | 2.50 |
|
2.567 | 2.57 |
|
2.567 | 2.567 |
|
2.5 | 2.5 |
|
12345.678 | 12,345.68 |
Приклад із роздільниками тисяч
DecimalFormat df = new DecimalFormat("#,##0.00");
System.out.println(df.format(1234567.89)); // 1,234,567.89
Приклад: виведення без зайвих нулів
DecimalFormat df = new DecimalFormat("0.##");
System.out.println(df.format(3.1)); // 3.1
System.out.println(df.format(3.141)); // 3.14
System.out.println(df.format(3.145)); // 3.15
5. Форматування за допомогою String.format
Іноді для простих випадків зручно використовувати String.format — вбудований спосіб форматувати рядки, подібний до printf в інших мовах.
double value = 3.14159;
System.out.println(String.format("%.2f", value)); // 3.14
Тут "%.2f" означає «вивести число з двома знаками після коми».
Порівняння підходів:
- DecimalFormat — потужніший, підтримує шаблони та локалізацію, зручний для роздільників тисяч.
- String.format — простіший, якщо треба лише вказати кількість знаків після коми.
6. Особливості округлення: Math.floor, Math.ceil, Math.rint
- Math.floor(x) — округлює вниз (у менший бік), у тому числі для відʼємних чисел.
- Math.ceil(x) — округлює вгору (у більший бік).
- Math.rint(x) — округлює до найближчого цілого, але повертає double.
Приклади:
System.out.println(Math.floor(2.7)); // 2.0
System.out.println(Math.ceil(2.1)); // 3.0
System.out.println(Math.rint(2.5)); // 2.0 (так, це не помилка.)
System.out.println(Math.rint(3.5)); // 4.0
Увага: Math.rint іноді округлює «до найближчого парного» — це правило (так зване «banker's rounding») допомагає зменшувати накопичення помилок під час масових обчислень.
7. Корисні нюанси
Візуалізація: таблиця округлень
| Число | Math.round | Math.floor | Math.ceil | Math.rint |
|---|---|---|---|---|
| 2.3 | 2 | 2.0 | 3.0 | 2.0 |
| 2.5 | 3 | 2.0 | 3.0 | 2.0 |
| 3.5 | 4 | 3.0 | 4.0 | 4.0 |
| -2.3 | -2 | -3.0 | -2.0 | -2.0 |
| -2.5 | -2 | -3.0 | -2.0 | -2.0 |
Округлення — це не форматування!
Дуже важливо розуміти різницю між округленням і форматуванням.
- Округлення — зміна значення числа (наприклад, 2.718 → 2.72).
- Форматування — зміна того, як число виглядає під час виведення (наприклад, 2.718 → "2.72" на екрані, але в памʼяті залишається 2.718).
double x = 2.718;
System.out.println(String.format("%.2f", x)); // 2.72
System.out.println(x); // 2.718
Якщо ви хочете використовувати округлене число в подальших обчисленнях — округлюйте математично. Якщо лише для виведення — форматуйте.
8. Типові помилки під час округлення та форматування чисел
Помилка № 1: Округлили лише для виведення, а потім використовуєте «хвостате» число.
Дуже типова ситуація — вивести акуратно відформатоване значення на екран, а потім у розрахунках використовувати початкове «довге» число. Для грошей, балів і підсумків спочатку округлюйте (наприклад, Math.round або трюк із множенням/діленням), потім зберігайте/передавайте користувачеві.
Помилка № 2: Очікування, що Math.round(x) поверне double із двома знаками після коми.
Math.round() завжди округлює до найближчого цілого: для float повертає int, для double — long. Для двох знаків використовуйте множення/ділення або форматування.
Помилка № 3: Використання DecimalFormat для обчислень.
DecimalFormat.format() повертає рядок. Використовувати його в арифметиці не можна: отримаєте помилку компіляції або NumberFormatException під час зворотного перетворення.
Помилка № 4: Неправильний шаблон DecimalFormat.
Шаблон має відповідати очікуванням: "0.00" завжди покаже два знаки ("2.00"), а "0.##" прибере зайві нулі ("2", "2.1", "2.12").
Помилка № 5: Втрата точності під час ділення на 100.
Якщо ділити int на int, результат теж int!
int a = 5;
System.out.println(a / 2); // 2, а не 2.5!
Щоб ділення було «дробовим», хоча б один операнд має бути double:
int a = 5;
System.out.println(a / 2.0); // 2.5
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ