Cambio en el comportamiento de redondeo de números en los métodos de formato NumberFormat y DecimalFormat

Java 8 introduce un cambio de comportamiento en el comportamiento de redondeo de números decimales utilizando el método format en el java.text.NumberFormat y el java.text.DecimalFormat cuando el valor está muy cerca de un empate, sentado exactamente en la posición de redondeo especificada en el patrón de formato. El cambio afecta a los números con una representación numérica binaria que no es exacta.

Por ejemplo, la aproximación binaria más cercana de 0.015 que puede calcular un sistema PC es 0.01499999999999999944488848768742172978818416595458984375. Si redondea ese número a dos dígitos , en Java 8 la respuesta es .01 porque .004999999... es menor que .005. En versiones anteriores de Java, el resultado es 0.02.

Esta regla señala las llamadas a los métodos format NumberFormat y DecimalFormat cuando los métodos se invocan con una primitiva double o un objeto java.lang.Double como primer parámetro. El ejemplo siguiente muestra el uso de los métodos format.

public static void main(String[] 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("formato (" + aDouble + ") devuelve \" "+ myStr +" \". Se espera \"0.805\".");

nf.setMaximumFractionDigits(2);
aDouble = 0.015d;
myStr = nf.format(aDouble);
System.out.println("formato (" + aDouble + ") devuelve \" "+ myStr +" \". Se espera \"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) devuelve \"" + myStr + " \". Se espera \"55.5% \". ");

}

Si ejecuta este código utilizando Java 7, el resultado será:

format(0.8055) devuelve "0.806". Se esperaba "0.805".
format (0.015) devuelve "0.02". Se esperaba "0.01".
format (0.5555) devuelve "55.6%". Se esperaba "55.5%".

En Java 8, el resultado obtenido es:

format(0.8055) devuelve "0.805". Se esperaba "0.805".
format (0.015) devuelve "0.01". Se esperaba "0.01".
format (0.5555) devuelve "55.5%". Se esperaba "55.5%".

Tenga en cuenta este cambio de comportamiento, pues podría afectar a los resultados del programa. El informe de error JDK-7131459 proporciona más información y muestra varios informes afines, incluidos informes de error para Java 8 que notifican este comportamiento como una regresión.

Para obtener más información sobre las clases afectadas, consulte los recursos siguientes: