Bonjour à tous,
Je crois que cette curiosité n'est pas spécifique à JAVA mais je la pose quand même :
pourquoi :
System.out.println(100.0*1.1);
donne :
110.00000000000001
??
que faire pour avoir le bon résultat?
A+
Bonjour à tous,
Je crois que cette curiosité n'est pas spécifique à JAVA mais je la pose quand même :
pourquoi :
System.out.println(100.0*1.1);
donne :
110.00000000000001
??
que faire pour avoir le bon résultat?
A+
Salut,
Les nombres flottants correspondent à des approximations, car il est tout bonnement impossible de représenter tous les nombres flottants sur une zone mémoire limité... car on peut toujours rajouté une décimales
Essayes de représenter tous les nombres flottant entres 0.0 et 1.0 et tu verras le problème
Donc on a affaire à des approximations sur la partie flottante, basé sur une norme (IEEE 754) intégré dans tous les processeurs actuels. Ainsi chez moi 1.1 vaut en réalité 1.100000000000000088817841970012523233890533447265625.
Le problème étant qu'avec certains calcul cette approximation peut s'accumuler et amener des erreurs. Il faut ainsi arrondir les résultats pour éviter les erreurs les plus courantes.
Mais si on veut un calcul précis, il faut utiliser des BigDecimal (ce qui implique également un code plus lourd) :
Attention à ne pas initialiser les BigDecimal avec un double ou un float, car sinon on conserve l'approximation :
Code : Sélectionner tout - Visualiser dans une fenêtre à part System.out.println( new BigDecimal("1.1").multiply(new BigDecimal("100.0")) );
Code : Sélectionner tout - Visualiser dans une fenêtre à part System.out.println( new BigDecimal(1.1) ); // 1.100000000000000088817841970012523233890533447265625
a++
Et dans le cas ou tu preferes rester avec des types de base, le probleme de l'affichage se resoud en utilisant un formatteur pour l'affichage. Voir NumberFormat et DecimalFormat (ceci ne fait que cacher le manque de precision, le probleme est toujours present).
Merci de penser au tagquand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.
suivez mon blog sur Développez.
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook
mmm 2^-50 donne ceci:
8.8817841970012523233890533447265625E-16
la 50ème décimale binaire de la mantise nécessite donc 52 décimales en base 10
la transformation flottant -> décimal peut toujours etre faite de manière exacte, car on peut représenter en décimal toutes les puissance négatives de 2. Par contre, on ne peux pas représenter en somme puissance de 2 tous les nombres décimaux.![]()
Hi,
Alors j'en conclu que le calcul est effectué avec un type plus grand que double, car 2^50 fait 1125899906842624, soit environ 10^17, ce qui est donc la limite en chiffres décimaux pour ce type.
il ne s'agit pas de 2^50 mais de 2^-50 !
c'est pas parce que tu a besoin de n chiffre pour répresenter un nombre X que tu as beosin de ~n chiffre pour représenter 1/n
et en l'occurence 1/1125899906842624 donne bien
8.881784197001252323389053344726562500000000000000000000000000000000000000000000000000E-16
donc les chiffre significatif d'adiguba sont bel est bien corrects pour représenter exactement le flottant
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 public class Test { public static void main(String[] argv){ BigDecimal bd = new BigDecimal("1"); bd=bd.setScale(100); System.out.println("1/2^50="+bd.divide(new BigDecimal("1125899906842624""),BigDecimal.ROUND_UNNECESSARY)); } }
C'est juste que d'habitue on arrondi au quelques décimale pour garder la cohérence avec la mathématique en base 10![]()
Partager