Если значение 200.3456
, оно должно быть отформатировано до 200.34
.
Если оно 200
, то оно должно быть 200.00
.
Круглые два-два десятичных знака
Ответ 1
Здесь утилита, в которой округляет (вместо усечения) значение, равное удвоенному числу десятичных знаков.
Например:
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)
). Благодаря Sloin для указания этого.
Я использовал это выше, чтобы круглые "не слишком большие" удваивались до 2 или 3 десятичных знаков с радостью в течение многих лет (например, чтобы очистить время в секундах для целей ведения журнала: 27.987654321987 → 27.99). Но я думаю, что лучше избегать этого, так как более надежные способы доступны, с более чистым кодом.
Итак, используйте это вместо
(адаптирован из этого ответа Луи Вассермана и этот Шон Оуэн.)
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
Обратите внимание, что HALF_UP
- это режим округления, обычно используемый в школе. Просматривайте документацию RoundingMode, если вы подозреваете, что вам нужно что-то еще, например Roundings Bankers.
Конечно, если вы предпочитаете, вы можете включить вышеперечисленное в однострочный: new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()
И в каждом случае
Всегда помните, что представления с плавающей запятой с использованием float
и double
являются неточными.
Например, рассмотрим следующие выражения:
999199.1231231235 == 999199.1231231236 // true
1.03 - 0.41 // 0.6200000000000001
Для точности вы хотите использовать BigDecimal. И в то время как на нем, используйте конструктор, который берет строку, никогда не берущую двойную. Например, попробуйте выполнить это:
System.out.println(new BigDecimal(1.03).subtract(new BigDecimal(0.41)));
System.out.println(new BigDecimal("1.03").subtract(new BigDecimal("0.41")));
Отличное дальнейшее чтение по теме:
- Пункт 48: "Избегайте
float
иdouble
, если требуются точные ответы" в "Эффективной Java" (2-е изд.) Джошуа Блоха. - Что каждый программист должен знать о арифметике с плавающей точкой
Если вы хотите, чтобы форматирование строк вместо (или в дополнение к) строго округляло числа, см. другие ответы.
В частности, обратите внимание, что round(200, 0)
возвращает 200.0
. Если вы хотите вывести " 200.00", сначала нужно округлить, а затем отформатировать результат для вывода (что отлично объяснено в ответе Jesper).
Ответ 2
Если вы просто хотите напечатать double
с двумя цифрами после десятичной точки, используйте что-то вроде этого:
double value = 200.3456;
System.out.printf("Value: %.2f", value);
Если вы хотите получить результат в String
вместо того, чтобы печатать на консоли, используйте String.format()
с теми же аргументами:
String result = String.format("%.2f", value);
Или используйте класс 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;
Этот метод будет работать в большинстве случаев, потому что для очень больших удвоений (положительных или отрицательных) он может переполняться. но если вы знаете, что ваши значения будут в соответствующем диапазоне, это должно сработать для вас.
Ответ 5
Используйте Apache commons math:
Precision.round(10.4567, 2)
Ответ 6
function Double round2(Double val) {
return new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue();
}
Обратите внимание: toString()!!!!
Это потому, что BigDecimal преобразует точную двоичную форму double!!!
Это различные предлагаемые методы и их неудачные случаи.
// Always Good!
new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue()
Double val = 260.775d; //EXPECTED 260.78
260.77 - WRONG - new BigDecimal(val).setScale(2,RoundingMode.HALF_UP).doubleValue()
Double val = 260.775d; //EXPECTED 260.78
260.77 - TRY AGAIN - Math.round(val * 100.d) / 100.0d
Double val = 256.025d; //EXPECTED 256.03d
256.02 - OOPS - new DecimalFormat("0.00").format(val)
// By default use half even, works if you change mode to half_up
Double val = 256.025d; //EXPECTED 256.03d
256.02 - FAIL - (int)(val * 100 + 0.5) / 100.0;
Ответ 7
double value= 200.3456;
DecimalFormat df = new DecimalFormat("0.00");
System.out.println(df.format(value));
Ответ 8
Если вам действительно нужен тот же двойной, но округленный по своему желанию, вы можете использовать BigDecimal, например
new BigDecimal(myValue).setScale(2, RoundingMode.HALF_UP).doubleValue();
Ответ 9
double d = 28786.079999999998;
String str = String.format("%1.2f", d);
d = Double.valueOf(str);
Ответ 10
Округление двойника обычно не является тем, что нужно. Вместо этого используйте String.format()
, чтобы представить его в нужном формате.
Ответ 11
Для двух округлых цифр. Очень просто, и вы в основном обновляете переменную, а не просто показываете, что делает DecimalFormat.
x = Math.floor(x * 100) / 100;
Ответ 12
В вашем вопросе кажется, что вы хотите избежать округления чисел? Я думаю..Format() будет округлять числа, используя половину, afaik?
поэтому, если вы хотите округлить, 200.3456 должно быть 200.35 для точности 2. но в вашем случае, если вы просто хотите первые 2, а затем отказаться от остальных?
Вы можете умножить его на 100, а затем наложить на int (или взять пол номера), прежде чем снова делить на 100.
200.3456 * 100 = 20034.56;
(int) 20034.56 = 20034;
20034/100.0 = 200.34;
У вас могут быть проблемы с действительно большими номерами, близкими к границе. В этом случае преобразование в строку и подстроку будет работать так же легко.
Ответ 13
value = (int)(value * 100 + 0.5) / 100.0;