Изменение логики округления в методах 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 ("format(" + aDouble + ") возвращает \" + myStr + "\". Ожидаем \" 0.805\ ".");

nf.setMaximumFractionDigits(2);
aDouble = 0.015d;
myStr = nf.format(aDouble);
System.out.println ("format(" + 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".
format( 0.015 ) возвращает " 0.02 ". Ожидание " 0.01 ".
format( 0.5555 ) возвращает " 55.6 %". Ожидание " 55.5 %".

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

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

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

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