Вопрос-ответ

Round a double to 2 decimal places [duplicate]

Округление двойного числа до 2 знаков после запятой

Если значение равно 200.3456, оно должно быть отформатировано в 200.34. Если это 200, то оно должно быть 200.00.

Переведено автоматически
Ответ 1

Вот утилита, которая округляет (вместо усечения) значение double до указанного количества знаков после запятой.

Например:

round(200.3456, 2); // returns 200.35

Оригинальная версия; будьте осторожны с этим

public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();

long factor = (long) Math.pow(10, places);
value = value * factor;
long tmp = Math.round(value);
return (double) tmp / factor;
}

Это плохо работает в угловых случаях либо с очень большим количеством знаков после запятой (например, round(1000.0d, 17)), либо с большой целой частью (например, round(90080070060.1d, 9)). Спасибо Слоину за указание на это.

Я использовал приведенное выше для счастливого округления "не слишком больших" двойных чисел до 2 или 3 знаков после запятой в течение многих лет (например, для измерения времени в секундах для целей ведения журнала: 27.987654321987 -> 27.99). Но я думаю, лучше избегать этого, поскольку легко доступны более надежные способы с более чистым кодом.

Итак, используйте это вместо

(Адаптировано из этого ответа Луиса Вассермана и этого ответа Шона Оуэна.)

public static double round(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();
}

Обратите внимание, что HALF_UP это режим округления, которому "обычно учат в школе". Ознакомьтесь с документацией RoundingMode, если вы подозреваете, что вам нужно что-то еще, например, банковское округление.

Конечно, если вы предпочитаете, вы можете встроить вышесказанное в однострочный:

new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()

И в каждом конкретном случае

Всегда помните, что представления с плавающей запятой с использованием float и double неточны. Например, рассмотрим эти выражения:

999199.1231231235 == 999199.1231231236 // true
1.03 - 0.41 // 0.6200000000000001

Для точности вам нужно использовать BigDecimal. И при этом используйте конструктор, который принимает строку, а не тот, который принимает double . Например, попробуйте выполнить это:

System.out.println(new BigDecimal(1.03).subtract(new BigDecimal(0.41)));
System.out.println(new BigDecimal("1.03").subtract(new BigDecimal("0.41")));

Несколько отличных дополнительных материалов по теме:


Если вам нужно форматирование строки вместо (или в дополнение к) строго округляющихся чисел, посмотрите другие ответы.

В частности, обратите внимание, что round(200, 0) возвращает200.0. Если вы хотите вывести "200.00", вам следует сначала округлить, а затем отформатировать результат для вывода (что прекрасно объяснено в ответе Джеспера).

Ответ 2

Если вы просто хотите напечатать double с двумя цифрами после запятой, используйте что-то вроде этого:

double value = 200.3456;
System.out.printf("Value: %.2f", value);

Если вы хотите получить результат в виде String вместо вывода на консоль, используйте String.format() с теми же аргументами:

String result = String.format("%.2f", value);

Или используйте class DecimalFormat:

DecimalFormat df = new DecimalFormat("####0.00");
System.out.println("Value: " + df.format(value));
Ответ 3

Я думаю, это проще:

double time = 200.3456;
DecimalFormat df = new DecimalFormat("#.##");
time = Double.valueOf(df.format(time));

System.out.println(time); // 200.35

Обратите внимание, что это фактически выполнит округление за вас, а не просто форматирование.

Ответ 4

Самый простой способ - это проделать подобный трюк;

double val = ....;
val = val*100;
val = Math.round(val);
val = val /100;

если значение val начинается с 200.3456, то оно переходит в 20034.56, затем округляется до 20035, затем мы делим его, чтобы получить 200.34.

если вы хотите всегда округлять в меньшую сторону, мы всегда можем выполнить усечение, приведя значение к int:

double val = ....;
val = val*100;
val = (double)((int) val);
val = val /100;

Этот метод сработает в большинстве случаев, потому что при очень больших двойных значениях (положительных или отрицательных) он может переполниться. но если вы знаете, что ваши значения будут находиться в соответствующем диапазоне, то это должно сработать для вас.

java