Somme de nombre décimal en java
J'ai un problème pour la managemente de nombre décimal en java (JDK 1.4).
J'ai deux double numéros de première et deuxième (comme la production de formaté Chaîne). Je fais un somme entre le premier et de second et je reçois un certain nombre avec plus de chiffres après la virgule!
final double first=198.4;//value extract by unmodifiable format method
final double second=44701.2;//value extract by unmodifiable format method
final double firstDifference= first+second; //I receive 44899.598 instead of 44899.6
final double calculatedDifference=44900.1; //comparison value for the flow
final double error=firstDifference-calculatedDifference;//I receive -0.50390605 instead 0.5
if(Math.abs(error)<=0.5d)){
//I must enter in this branch but the error not allows the correct flow!!!
}
/***
* the flow of program is uncorrect and there's a very visible bug in business view
*/
Je préfère ne pas la croissance de la valeur de seuil (0,5 d) parce que je ne suis pas sûr avec une situation similaire (quand j'ai commencé à coder, les spécifications parlait 0.1 d comme valeur de comparaison).
Si c'est la seule solution, la valeur de de 0,9 d est la plus sûre, la valeur de ce problème?
Comment je peux résoudre cette situation? J'ai pensé plus tard a séparer que ce problème dériver par l'utilisation de variables doubles, mais avec le flotteur, j'ai le même problème.
Une idée (avoir un code testé en ligne, si possible ;))?
if
condition!Votre
if
clause a une parenthèse. Sinon, le code est parfait, et les valeurs de son retour est aussi le même, vous êtes "s'attend".Je pense que la première des valeurs ont été pour
float
😉Je pense que les résultats mitigés pour les différents utilisateurs a quelque chose à voir avec le fait que l'OP est à l'aide du JDK 1.4 qui est relativement ancienne de ces jours. (bien que j'ai été obligé de soutenir 1.3 récemment au travail. Pouah!)
OriginalL'auteur alepuzio | 2011-03-24
Vous devez vous connecter pour publier un commentaire.
Vous pouvez obtenir l'erreur d'arrondi, mais je ne le vois pas ici.
imprime
Il y a deux façons de gérer cette situation de façon plus générale. Vous pouvez définir une erreur d'arrondi comme
OU de l'utilisation d'arrondi
OU d'utiliser des entiers avec précision fixe
OU Vous pouvez utiliser BigDecimal. C'est souvent la solution privilégiée pour de nombreux développeurs, mais une dernière option à mon humble avis. 😉
BigDecimal est adapté si vous n'êtes pas familier avec le travail avec les
double
de son mieux pour être correct que performant et BigDecimal la main, plus les erreurs d'arrondi. Toutefois, si vous êtes familier avecdouble
vous pouvez trouver BigDecimal lourd à la fois le code et l'exécuter. esp comme il y a souvent de simples solutions pour les erreurs d'arrondi.Dépend de l'application. Si vous travaillez sur des applications actuarielles primitives sont des ordures en matière de précision. Si vous êtes en train de faire une sorte de scientifique/actuarielle application BigDecimal est vraiment la seule solution.
BigDecimal est particulièrement utile si vous avez besoin de différents arrondissement de solutions. Cependant, pour des prix/l'argent en utilisant le double avec arrondi ou long/int fixe avec précision les valeurs peuvent faire le travail beaucoup plus rapide et souvent plus propre. J' ne pas suggèrent
float
dans 99% des cas.Bonne idée d'utiliser l'int au lieu du double. La classe BigDecimal me donne un problème avec l'arrondi 🙁
OriginalL'auteur Peter Lawrey
Cette erreur dépendra légèrement sur votre version de Java (et je vois que vous êtes en utilisant un peu ancien). Cependant, indépendamment de la version de Java, pour de meilleurs résultats lorsque vous êtes particulièrement inquiet au sujet de décimales de précision en java, vous devez utiliser le
BigDecimal
classe pour vos valeurs.C'est ce que les applications financières utiliser pour la manipulation des devises, et aussi ce que beaucoup d'industriels des applications Java à utiliser lorsque la précision est essentielle.
EDIT: je vois beaucoup de valide les commentaires que cette solution est livré avec un léger gain de performance (dépend aussi du nombre d'opérations que vous faites en premier lieu). Et vraiment, si c'est le seul endroit que vous rencontrez un problème et que vous ne se soucient de précision après celui-ci, ay, aller pour une solution de contournement. Mais si cela se produit fréquemment et en plus d'un endroit, ou si vous pensez que vous pourriez être l'expansion de votre application dans le futur, je voudrais utiliser le plus sûr
BigDecimal
.OriginalL'auteur gnomed
Double éléments de stocker un nombre en puissances de 2. Il n'est pas possible de représenter fidèlement beaucoup de chiffres en termes de puissances de 2, et ainsi, vous obtenez l'arrondi. Le même problème lors de l'utilisation de flotteurs.
Si vous voulez réduire ces, utiliser le type Décimal pour les nombres, ce qui devrait s'avérer être plus précis.
Pour les doubles et les flotteurs, vous devez utiliser le < comparateur de vérifier si 2 nombres sont suffisamment proches pour être considérées comme égales.
Voir ce pour plus de détails ->
Quel est le moyen le plus efficace pour les float et double comparaison?
OriginalL'auteur Kurru
Je l'ai testé et sur ma machine tout est correct (testé dans la version 1.6 de java). Si j'étais vous, je voudrais tester strictfp modificateur à la méthode qui a ci-dessus:
Le problème peut être connecté avec la version java, OS, PROCESSEUR que vous utilisez
OriginalL'auteur smas
Je suis d'accord avec Pierre, je ne vois pas ce qui se passe. Cependant, si ça vous arrive et si le nombre de décimales est fixe et connue dans votre cas d'utilisation, de toute façon, à l'aide de "int" pourrait être une solution, c'est même plus rapide que d'opérations en virgule flottante. Pour les vues, vous devrez convertir floating points, bien sûr.
OriginalL'auteur Nodebody