OVH Cloud OVH Cloud

Problème de précision

5 réponses
Avatar
Abadie Jean-François
Bonjour.
System.out.println ( 2.095 * 100.0 ); donne : 209.50000000000003
System.out.println ( 2.195 * 100.0 ); donne : 219.49999999999997 !!
System.out.println ( 2.295 * 100.0 ); donne : 229.5
Cela ne me paraît pas très normal !
Et c'est plutôt génant quand on veut obtenir Math.round(2.195D * 100.0D) !
Est-ce un bug et comment y remédier ?
Merci.
JF

5 réponses

Avatar
Vincent Cantin
Bonjour.
System.out.println ( 2.095 * 100.0 ); donne : 209.50000000000003
System.out.println ( 2.195 * 100.0 ); donne : 219.49999999999997 !!
System.out.println ( 2.295 * 100.0 ); donne : 229.5
Cela ne me paraît pas très normal !


Dans l'informatique, c'est normal. Les nombreux decimaux ne peuvent pas tout
le temps etre ecrit avec equivalence en base 2, et c'est donc en compilant
2.095 en base 2 que l'erreur se fait. Pour qu'il n'y ait pas d'erreur lors
de la conversion, il faudrait que 2.095 soit egal au quotient d'un nombre
entier et d'un exposant de 2 (1, 2, 4, 8, 16, 32, 64, 128, etc ...) et que
ce nombre entier et ce quotient puissent tenir en base de 2 sur le nombre de
bits mis a disposition par le format utilise pour les "float" de la norme
Java (en fait, Java utilise une norme deja etablie pour ce format, voir la
doc dans la class Math).

Et c'est plutôt génant quand on veut obtenir Math.round(2.195D * 100.0D) !
Est-ce un bug et comment y remédier ?


Ca n'est pas un bug, c'est juste que tu demandes un truc qui te semble
simple en decimale a un ordi qui ne comprend que le binaire et ou la
conversion exacte n'est pas garantie pour les nombre decimaux.

Ca revient au meme si tu veux faire 1/3 * 6 a la main (pour info, ca fait 2
;-) ), et si tu as une machine qui compte seulement en decimal et qui a une
memoire limitee et qui ne peut donc stocker qu'un nombre limite de decimales
: 0.3333333333333... * 6 = 1.9999999999999...

Ok ?

Merci.
JF


De rien.
Vincent Cantin

Avatar
Vincent Cantin
Et c'est plutôt génant quand on veut obtenir Math.round(2.195D * 100.0D) !
... comment y remédier ?


ben ... utilise "Math.round(2.195D * 100.0D)" puisque c'est ce que tu veux
obtenir :-)

Vincent

Avatar
sheeridan
Utilise java.math.BigDecimal.


Abadie Jean-François a écrit dans le message :
41dfa63e$0$11939$
Bonjour.
System.out.println ( 2.095 * 100.0 ); donne : 209.50000000000003
System.out.println ( 2.195 * 100.0 ); donne : 219.49999999999997 !!
System.out.println ( 2.295 * 100.0 ); donne : 229.5
Cela ne me paraît pas très normal !
Et c'est plutôt génant quand on veut obtenir Math.round(2.195D * 100.0D) !
Est-ce un bug et comment y remédier ?
Merci.
JF





Avatar
Vincent Cantin
... avec tout mon topos, il aurait pu au moins dire "merci pour la
precision", non ? :-)
Avatar
Abadie Jean-François
Merci pour la précision.
Je me suis débrouillé en faisant : Math.round(mydouble * 1000000000.0) *
1000000000
JF

"Vincent Cantin" a écrit dans le message de
news:
... avec tout mon topos, il aurait pu au moins dire "merci pour la
precision", non ? :-)