Problème de précision de soustraction double
Mon collègue a fait cette expérience:
public class DoubleDemo {
public static void main(String[] args) {
double a = 1.435;
double b = 1.43;
double c = a - b;
System.out.println(c);
}
}
Pour cette première année de fonctionnement je l'attendais cette sortie:
0.005
Mais de façon inattendue la sortie a été:
0.0050000000000001155
Pourquoi ne double échoue dans une telle opération simple? Et si le double n'est pas le type de données pour ce travail, que dois-je utiliser?
source d'informationauteur Carlos Gavidia | 2012-03-28
Vous devez vous connecter pour publier un commentaire.
double
est stockée en interne sous forme d'une fraction dans binaire -- comme1/4 + 1/8 + 1/16 + ...
La valeur
0.005
-- ou la valeur1.435
-- ne peut pas être stockée sous forme de fraction exacte en binaire, doncdouble
ne peut pas stocker la valeur exacte0.005
et la soustrait de la valeur n'est pas tout à fait exacte.Si vous vous souciez de précision décimale de l'arithmétique, de l'utilisation
BigDecimal
.Vous pouvez également trouver cet article utile de lecture.
double et float sont pas exactement les nombres réels.
Il y a un nombre infini de nombres réels dans toute la gamme, mais seulement dans un nombre limité de bits pour représenter les! pour cette raison, les erreurs d'arrondi, est attendu pour le double et les flotteurs.
Le nombre que vous obtenez est le nombre le plus proche possible qui peut être représenté par un double dans la représentation à virgule flottante.
Pour plus de détails, vous pouvez lire cet article [avertissement: peut-être de haut niveau].
Vous pouvez utiliser
BigDecimal
d'obtenir exactement un nombre décimal [mais vous serez de nouveau rencontrer des erreurs d'arrondi lorsque vous essayez d'obtenir1/3
].double
etfloat
arithmétique ne vont jamais être tout à fait correct en raison de l'arrondissement qui se produit "sous le capot".Essentiellement les doubles et les flotteurs peuvent avoir une quantité infinie de décimales, mais dans la mémoire qu'ils doivent être représentés par un certain nombre de bits. Donc, quand vous faites cela décimal de l'arithmétique d'une procédure d'arrondi se produit et est souvent coupé par une très petite quantité si vous prenez tous les décimales en compte.
Comme suggéré plus haut, si vous avez besoin d'complètement valeurs exactes puis utilisez
BigDecimal
qui stocke ses valeurs différemment. Voici l'API