Округление с DecimalFormat в Java

Посмотрите на следующие операторы в Java.

System.out.println(new DecimalFormat("0").format(2.4)); //returns 2

System.out.println(new DecimalFormat("0").format(2.5)); //returns 2  <---Concentrate here
System.out.println(Math.round(2.5));                    //returns 3

System.out.println(new DecimalFormat("0").format(2.6)); //returns 3
System.out.println(new DecimalFormat("0").format(3.5)); //returns 4

В приведенных выше утверждениях все остальные случаи очевидны, кроме следующих.

System.out.println(new DecimalFormat("0").format(2.5));

Он должен возвращать 3, но возвращает 2. Как?

Ответ 1

Это преднамеренное поведение. Из документации:

Округление

DecimalFormat использует полу-четное округление (см. ROUND_HALF_EVEN) для форматирования.

О ROUND_HALF_EVEN:

Округление режима округляется к "ближайшему соседу", если оба соседа не будут равноудаленными, и в этом случае округлите к четному соседу. Ведет себя как ROUND_HALF_UP, если цифра слева от отброшенной фракции нечетна; ведет себя как ROUND_HALF_DOWN, если он даже. Обратите внимание, что это режим округления, который минимизирует кумулятивную ошибку при неоднократном применении к последовательности вычислений.

Это также известно как округление банкиров.

Math.Round с другой стороны использует следующую формулу, которая является "нормальным" округлением:

(long)Math.floor(a + 0.5d)

Ответ 2

Режим округления по умолчанию DecimalFormat равен RoundingMode.HALF_EVEN. Это означает, что он округляется или округляется, если число приближается к соседнему соседу. Когда число находится точно между двумя соседями (в вашем случае 2 и 3), округляется до ближайшего четного числа (в вашем случае 2).

Как вы можете видеть, когда вы пробовали его с 3.5, он округлялся до 4.

Если вы хотите более "интуитивно понятное" поведение, вызовите setRoundingMode(RoundingMode.HALF_UP) http://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html#setRoundingMode(java.math.RoundingMode)

это то же самое, что и HALF_EVEN, но если число точно совпадает между двумя соседями, оно всегда будет округлено вверх.