Как округлить число до нужного количества знаков после запятой в Java?
Лучший способ: BigDecimal и setScale
Самый надёжный и точный способ округления чисел с плавающей точкой в Java — использование класса BigDecimal. В отличие от double и float, которые имеют погрешности двоичного представления, BigDecimal работает с десятичной арифметикой и даёт предсказуемый результат.
Решение с BigDecimal
Вот универсальный метод, который округляет число до N знаков после запятой:
import java.math.BigDecimal;
import java.math.RoundingMode;
public class RoundingExample {
public static double roundToNDecimalPlaces(double value, int places) {
if (places < 0) throw new IllegalArgumentException("Количество знаков не может быть отрицательным");
BigDecimal bd = BigDecimal.valueOf(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
public static void main(String[] args) {
double price = 123.456789;
double rounded = roundToNDecimalPlaces(price, 2);
System.out.println(rounded); // 123.46
double division = 10.0 / 3.0;
System.out.println(roundToNDecimalPlaces(division, 2)); // 3.33
double negative = -2.345;
System.out.println(roundToNDecimalPlaces(negative, 2)); // -2.35
}
}
Почему это работает?
BigDecimal.valueOf(value)— преобразует double в BigDecimal без потери точности (важно: не используйтеnew BigDecimal(double), он может дать неожиданный результат из-за двоичного представления).setScale(places, RoundingMode.HALF_UP)— устанавливает количество знаков после запятой и режим округления.HALF_UP— это стандартное математическое округление (0.5 округляется вверх).bd.doubleValue()— преобразует результат обратно в double, если нужно. Если вы работаете с деньгами или точными значениями, лучше оставить результат какBigDecimal.
Альтернативный вариант: вывод с форматированием
Если вам нужно только отобразить число с определённым количеством знаков, а не хранить его в переменной, используйте String.format():
double price = 123.456789;
String formatted = String.format("%.2f", price);
System.out.println(formatted); // 123.46
Но помните: String.format() возвращает строку, а не число. Для вычислений это не подходит.
Чего делать не стоит
- Не используйте
Math.round(value * 100) / 100— это даёт целочисленное деление, если не привести к double. - Не используйте
new BigDecimal(double)— он может сохранить неточное двоичное представление (например,new BigDecimal(2.345)даст 2.3449999999999998). - Не используйте
floatдля точных расчётов — у него ещё меньше точности, чем уdouble.
Итог
Для округления чисел в Java используйте BigDecimal.setScale() с подходящим RoundingMode. Это гарантирует точность и предсказуемость. Если нужно просто показать число — используйте String.format().
Альтернативный подход: DecimalFormat для форматирования
Если ваша задача — только вывести число с определённым количеством знаков после запятой (например, для отчёта или UI), можно воспользоваться классом DecimalFormat из пакета java.text. Он удобен для работы с шаблонами и локализацией.
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
public class DecimalFormatExample {
public static void main(String[] args) {
double price = 123.456789;
// Шаблон: ровно 2 знака после запятой
DecimalFormat df = new DecimalFormat("#.##");
df.setRoundingMode(java.math.RoundingMode.HALF_UP);
String formatted = df.format(price);
System.out.println(formatted); // 123.46
// Для фиксированного количества знаков (например, 2.00 вместо 2)
DecimalFormat dfFixed = new DecimalFormat("0.00");
dfFixed.setRoundingMode(java.math.RoundingMode.HALF_UP);
System.out.println(dfFixed.format(2.0)); // 2.00
}
}
Когда это полезно?
- Когда нужно учитывать локаль (например, в Германии запятая — разделитель, а точка — для тысяч).
- Когда нужно гибко управлять отображением (например, показывать минимум 2 знака, но не больше 4).
Недостатки
DecimalFormatвозвращает строку, а не число.- При неправильном шаблоне может отбросить дробную часть (например,
#.##для 123.0 покажет "123", а не "123.00"). - Для точных вычислений всё равно лучше использовать
BigDecimal.
Совет: Если вы работаете с деньгами, используйте BigDecimal для хранения и вычислений, а DecimalFormat — только для вывода на экран. Это даёт и точность, и красивый вывод.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги