Changement de comportement d'arrondi dans les méthodes de format NumberFormat et DecimalFormat

Java 8 introduit un changement de comportement dans le comportement d'arrondi des nombres décimaux à l'aide de la méthode format sur le java.text.NumberFormat et java.text.DecimalFormat classes lorsque la valeur est très proche d'une égalité, en restant exactement à la position d'arrondi spécifiée dans le modèle de formatage. Cette modification a des conséquences sur les nombres avec une représentation numérique binaire qui n'est pas exacte.

Par exemple, l'approximation binaire la plus proche de 0,015 pouvant être obtenue par un ordinateur est 0,01499999999999999944488848768742172978818416595458984375. Si vous arrondissez vers le bas ce nombre à deux chiffres, dans Java 8, vous obtiendrez 0,01 car la partie 4999999.... est inférieure à 5. Dans les versions précédentes de Java, le résultat obtenu aurait été 0,02.

Cette règle marque les appels vers les méthodes NumberFormat et DecimalFormat format lorsqu'elles sont appelées avec une primitive double ou un objet java.lang.Double en tant que premier caractère. L'exemple suivant présente l'utilisation des méthodes 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 + ") renvoie \" "+ myStr +" \". Attendu: \"0.805\".") ;

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

}

Si vous appelez ce code en utilisant Java 7, la sortie suivante s'affiche :

format(0.8055) renvoie "0.806". "0.805" attendu.
format(0.015) renvoie "0.02". "0.01" attendu.
format(0.5555) renvoie "55.6%". "55.5%" attendu.

Dans Java 8, la sortie suivante s'affiche :

format(0.8055) renvoie "0.805". "0.805" attendu.
format(0.015) renvoie "0.01". "0.01" attendu.
format(0.5555) renvoie "55.5%". "55.5%" attendu.

Tenez compte de ce changement de comportement car il peut avoir des conséquences sur la sortie du programme. Le rapport de bogue JDK-7131459 fournit des informations supplémentaires et présente plusieurs rapports, notamment des rapports de bogue pour Java 8 indiquant que ce problème est une régression.

Pour plus d'informations sur les classes concernées, voir les ressources suivantes :