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 redondeo de números decimales al utilizar el método format en las clases java.text.NumberFormat y java.text.DecimalFormat cuando el valor está muy cerca de una posición equidistante, exactamente en la posición de redondeo especificada en el patrón de formateo. 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("format(" + aDouble + ") returns \"" + myStr + "\". Expecting \"0.805\".");

nf.setMaximumFractionDigits(2);
aDouble = 0.015d;
myStr = nf.format(aDouble);
System.out.println("format(" + aDouble + ") returns \"" + myStr + "\". Expecting \"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) returns \"" + myStr + "\". Expecting \"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: