Cambiamento del comportamento nell'arrotondamento nei metodi di formattazione NumberFormat e DecimalFormat

Java 8 introduce una modifica del comportamento nel comportamento di arrotondamento dei numeri decimali utilizzando il metodo format sul java.text.NumberFormat e java.text.DecimalFormat classi quando il valore è molto vicino a un pareggio, posizionandosi esattamente nella posizione di arrotondamento specificata nel pattern di formattazione. La modifica influenza i numeri con una rappresentazione numerica binaria che non è esatta.

Ad esempio, l'approssimazione binaria più vicina di 0,015 che è raggiungibile da un computer è 0,01499999999999999944488848768742172978818416595458984375. Se si arrotonda tale numero a due cifre, in Java 8 la risposta è .01 perché .004999999.... è minore di .005. Nelle versioni precedenti di Java, la versione è 0,02.

Questa regola contrassegna le chiamate ai metodi NumberFormat e DecimalFormat format quando vengono richiamati con una primitiva double o un oggetto java.lang.Double come primo parametro. Il seguente esempio mostra l'utilizzo dei metodi 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 + ") restituisce \" "+ myStr +" \ ". Previsto \"0.805\".");

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

}

Se si richiama questo codice utilizzando Java 7, viene visualizzato il seguente output:

format(0.8055) returns "0.806". Expecting "0.805".
format(0.015) returns "0.02". Expecting "0.01".
format(0.5555) returns "55.6%". Expecting "55.5%".

In Java 8, viene visualizzato il seguente output:

format(0.8055) returns "0.805". Expecting "0.805".
format(0.015) returns "0.01". Expecting "0.01".
format(0.5555) returns "55.5%". Expecting "55.5%".

Tenere presente questo comportamento perché potrebbe influire l'output del programma. JDK-7131459 bug report fornisce ulteriori informazioni e riporta una serie di report correlati, compresi i report di bug aperti su Java 8, che segnalano questa condizione come una regressione.

Per ulteriori informazioni sulle classi interessate, consultare le seguenti risorse: