Как округлить число до n знаков после запятой в Java - PullRequest
1149 голосов
/ 30 сентября 2008

То, что я хотел бы, - это метод преобразования двойного числа в строку, которая округляется с использованием метода половинного увеличения, т. Е. Если десятичное число округляется до 5, оно всегда округляется до предыдущего числа. Это стандартный метод округления, которого большинство людей ожидают в большинстве ситуаций.

Я также хотел бы, чтобы отображались только значащие цифры, т. Е. Не должно быть никаких завершающих нулей.

Я знаю, что один из способов сделать это - использовать метод String.format:

String.format("%.5g%n", 0.912385);

возвращается:

0.91239

, что здорово, однако оно всегда отображает числа с 5 десятичными разрядами, даже если они не имеют значения:

String.format("%.5g%n", 0.912300);

возвращается:

0.91230

Другой способ - использовать DecimalFormatter:

DecimalFormat df = new DecimalFormat("#.#####");
df.format(0.912385);

возвращается:

0.91238

Однако, как вы можете видеть, используется округление до половины. То есть он округляется вниз, если предыдущая цифра четная. Что я хотел бы это:

0.912385 -> 0.91239
0.912300 -> 0.9123

Каков наилучший способ добиться этого в Java?

Ответы [ 29 ]

4 голосов
/ 14 марта 2018

Для этого мы можем использовать этот форматер:

 DecimalFormat df = new DecimalFormat("#.00");
 String resultado = df.format(valor)

или

DecimalFormat df = new DecimalFormat("0.00"); :

Используйте этот метод, чтобы получить всегда два десятичных знака:

   private static String getTwoDecimals(double value){
      DecimalFormat df = new DecimalFormat("0.00"); 
      return df.format(value);
    }

Определение этих значений:

91.32
5.22
11.5
1.2
2.6

Используя метод, мы можем получить следующие результаты:

91.32
5.22
11.50
1.20
2.60

демо онлайн.

4 голосов
/ 20 февраля 2017

Я пришел сюда просто, чтобы получить простой ответ о том, как округлить число. Это дополнительный ответ, подтверждающий это.

Как округлить число в Java

Наиболее распространенным случаем является использование Math.round().

Math.round(3.7) // 4

Числа округляются до ближайшего целого числа. Значение .5 округляется в большую сторону. Если вам нужно другое поведение округления, чем это, вы можете использовать одну из других Math функций. См. Сравнение ниже.

круглый

Как указано выше, это округляет до ближайшего целого числа. .5 десятичные числа округлять вверх. Этот метод возвращает int.

Math.round(3.0); // 3
Math.round(3.1); // 3
Math.round(3.5); // 4
Math.round(3.9); // 4

Math.round(-3.0); // -3
Math.round(-3.1); // -3
Math.round(-3.5); // -3 *** careful here ***
Math.round(-3.9); // -4

1024 * CEIL *

Любое десятичное значение округляется до следующего целого числа. Это идет к ceil ing. Этот метод возвращает double.

Math.ceil(3.0); // 3.0
Math.ceil(3.1); // 4.0
Math.ceil(3.5); // 4.0
Math.ceil(3.9); // 4.0

Math.ceil(-3.0); // -3.0
Math.ceil(-3.1); // -3.0
Math.ceil(-3.5); // -3.0
Math.ceil(-3.9); // -3.0

пол

Любое десятичное значение округляется до следующего целого числа. Этот метод возвращает double.

Math.floor(3.0); // 3.0
Math.floor(3.1); // 3.0
Math.floor(3.5); // 3.0
Math.floor(3.9); // 3.0

Math.floor(-3.0); // -3.0
Math.floor(-3.1); // -4.0
Math.floor(-3.5); // -4.0
Math.floor(-3.9); // -4.0

ечать

Это похоже на округление в том, что десятичные значения округляют до ближайшего целого числа. Однако, в отличие от round, .5 значения округляются до четного целого числа. Этот метод возвращает double.

Math.rint(3.0); // 3.0
Math.rint(3.1); // 3.0
Math.rint(3.5); // 4.0 ***
Math.rint(3.9); // 4.0
Math.rint(4.5); // 4.0 ***
Math.rint(5.5); // 6.0 ***

Math.rint(-3.0); // -3.0
Math.rint(-3.1); // -3.0
Math.rint(-3.5); // -4.0 ***
Math.rint(-3.9); // -4.0
Math.rint(-4.5); // -4.0 ***
Math.rint(-5.5); // -6.0 ***
3 голосов
/ 07 января 2018

Если вы используете технологию, которая имеет минимальный JDK. Вот способ без каких-либо библиотек Java:

double scale = 100000;    
double myVal = 0.912385;
double rounded = (int)((myVal * scale) + 0.5d) / scale;
3 голосов
/ 05 ноября 2015

Я согласен с выбранным ответом, чтобы использовать DecimalFormat --- или альтернативно BigDecimal.

Пожалуйста, прочитайте Обновите внизу!

Однако, если вы do хотите округлить двойное значение и получить результат значения double, вы можете использовать org.apache.commons.math3.util.Precision.round(..), как указано выше. Реализация использует BigDecimal, работает медленно и создает мусор.

Аналогичный, но быстрый и не содержащий мусора метод предоставляется утилитой DoubleRounder в библиотеке decimal4j:

 double a = DoubleRounder.round(2.0/3.0, 3);
 double b = DoubleRounder.round(2.0/3.0, 3, RoundingMode.DOWN);
 double c = DoubleRounder.round(1000.0d, 17);
 double d = DoubleRounder.round(90080070060.1d, 9);
 System.out.println(a);
 System.out.println(b);
 System.out.println(c);
 System.out.println(d);

Будет выводить

 0.667
 0.666
 1000.0
 9.00800700601E10

См https://github.com/tools4j/decimal4j/wiki/DoubleRounder-Utility

Отказ от ответственности: Я участвую в проекте decimal4j.

Обновление: Как отметил @iaforek, DoubleRounder иногда возвращает нелогичные результаты. Причина в том, что он выполняет математически правильное округление. Например, DoubleRounder.round(256.025d, 2) будет округлено до 256,02, поскольку двойное значение, представленное как 256,025d, несколько меньше рационального значения 256,025 и, следовательно, будет округлено в меньшую сторону.

Примечания:

  • Это поведение очень похоже на поведение конструктора BigDecimal(double) (но не на valueOf(double), который использует конструктор строк).
  • Проблема может быть обойдена с двойным шагом округления до более высокой точности, но это сложно, и я не буду вдаваться в подробности здесь

По этим причинам и всему, что упомянуто в этом посте, я не могу рекомендовать использовать DoubleRounder .

2 голосов
/ 25 ноября 2016

DecimalFormat - лучший способ вывода, но я не предпочитаю его. Я всегда делаю это все время, потому что он возвращает двойное значение. Так что я могу использовать это больше, чем просто вывод.

Math.round(selfEvaluate*100000d.0)/100000d.0;

OR

Math.round(selfEvaluate*100000d.0)*0.00000d1;

Если вам нужно большое количество знаков после запятой, вы можете использовать вместо него BigDecimal. В любом случае .0 важно. Без этого допускается округление 0.33333d5 до 0.33333 и допускается только 9 цифр. Вторая функция без .0 имеет проблемы с возвращением 0.30000 0.30000000000000004.

1 голос
/ 22 апреля 2014

Где dp = десятичное место, которое вы хотите, и значение является двойным.

    double p = Math.pow(10d, dp);

    double result = Math.round(value * p)/p;
1 голос
/ 11 ноября 2016

Имейте в виду, что String.format () и DecimalFormat создают строку, используя локаль по умолчанию. Таким образом, они могут написать отформатированное число с точкой или запятой в качестве разделителя между целыми и десятичными частями. Чтобы убедиться, что округленная строка соответствует желаемому формату, используйте java.text.NumberFormat следующим образом:

  Locale locale = Locale.ENGLISH;
  NumberFormat nf = NumberFormat.getNumberInstance(locale);
  // for trailing zeros:
  nf.setMinimumFractionDigits(2);
  // round to 2 digits:
  nf.setMaximumFractionDigits(2);

  System.out.println(nf.format(.99));
  System.out.println(nf.format(123.567));
  System.out.println(nf.format(123.0));

Будет напечатано на английском языке (независимо от того, какой у вас язык): 0,99 123,57 123,00

Пример взят из Farenda - , как правильно конвертировать double в String .

0 голосов
/ 13 февраля 2018

Обычно округление выполняется путем масштабирования: round(num / p) * p

/**
 * MidpointRounding away from zero ('arithmetic' rounding)
 * Uses a half-epsilon for correction. (This offsets IEEE-754
 * half-to-even rounding that was applied at the edge cases).
 */
double RoundCorrect(double num, int precision) {
    double c = 0.5 * EPSILON * num;
//  double p = Math.pow(10, precision); //slow
    double p = 1; while (precision--> 0) p *= 10;
    if (num < 0)
        p *= -1;
    return Math.round((num + c) * p) / p;
}

// testing edge cases
RoundCorrect(1.005, 2);   // 1.01 correct
RoundCorrect(2.175, 2);   // 2.18 correct
RoundCorrect(5.015, 2);   // 5.02 correct

RoundCorrect(-1.005, 2);  // -1.01 correct
RoundCorrect(-2.175, 2);  // -2.18 correct
RoundCorrect(-5.015, 2);  // -5.02 correct
0 голосов
/ 22 ноября 2016

Если учесть 5 или n десятичных чисел. Может быть, этот ответ решит вашу проблему.

    double a = 123.00449;
    double roundOff1 = Math.round(a*10000)/10000.00;
    double roundOff2 = Math.round(roundOff1*1000)/1000.00;
    double roundOff = Math.round(roundOff2*100)/100.00;

    System.out.println("result:"+roundOff);

Вывод будет: 123.0 1
Это можно решить с помощью цикла и рекурсивной функции.

...