Изменение логики округления в методах format классов NumberFormat и DecimalFormat

Java 8 вводит изменение поведения округления десятичных чисел с помощью метода format в java.text.NumberFormat и в java.text.DecimalFormat классы, когда значение очень близко к галлоку, сидя точно в положении округления, указанном в шаблоне форматирования. Изменение проявляется в числах с неточным двоичным представлением.

Например, ближайшее двоичное представление числа 0,015, возможное на компьютере, равно 0,01499999999999999944488848768742172978818416595458984375. Если округлить это число до двух знаков после запятой, то в Java 8 ответ будет 0,01, так как 0,004999999.... меньше 0,005. В предыдущих версиях Java ответ - 0,02.

Это правило помечает методы format классов NumberFormat и DecimalFormat с простым типом double или объектом java.lang.Double в первом параметре. Пример использования методов format.

< span class="Code"> < span class= "JavaKeyword"> public static void < /span> main (< span class="JavaType"> String < /span> [] args) {

java.text.NumberFormat nf = java.text.NumberFormat.getInstance();
nf.setMaximumFractionDigits(3);
double aDouble;
String myStr;

aDouble = 0.8055d;
myStr = nf.format(aDouble);
System.out.println("формат (" + aDouble + ") возвращает \" "+ myStr +" \". Ожидается \"0.805\".");

nf.setMaximumFractionDigits(2);
aDouble = 0.015d;
myStr = nf.format(aDouble);
System.out.println("формат (" + aDouble + ") возвращает \" "+ myStr +" \". Ожидается \"0.01\".");


NumberFormat percent = NumberFormat.getPercentInstance();
percent.setMinimumFractionDigits(1);
percent.setMaximumFractionDigits(1);
percent.setRoundingMode(RoundingMode.HALF_EVEN);
myStr = percent.format(0.5555);
System.out.println("format (0.5555) возвращает \"" + myStr + " \". Ожидается \"55.5% \". ");

}

Если выполнить этот код в Java 7, будет выведена следующая информация:

< span class="Code"> формат (0.8055) возвращает "0.806". Ожидается "0.805".
формат (0.015) возвращает "0.02". Ожидается "0.01".
формат (0.5555) возвращает "55.6%". Ожидается "55.5%".

В Java 8 будет выведена следующая информация:

< span class="Code"> формат (0.8055) возвращает "0.805". Ожидается "0.805".
(0.015) возвращает "0.01". Ожидается "0.01".
формат (0.5555) возвращает "55.5%". Ожидается "55.5%".

Следует помнить об этом изменении, так как оно может повлиять на вывод данных программой. В отчете об ошибке JDK-7131459 содержится дополнительная информация и ссылки на связанные отчеты, включая отчеты для Java 8, в которых это обозначено как регрессионная ошибка.

Дополнительную информацию о затронутых классах можно найти в следующих ресурсах: