Округление с 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
, но если число точно совпадает между двумя соседями, оно всегда будет округлено вверх.