Bonjour,
est ce que qu'elle qu'un peut m'expliquer pour quoi le caste en int après la multiplication par 100 de ces double : 5000.1,5000.11,5000.12,5000.21,5000.44, ce passe mal?
Version imprimable
Bonjour,
est ce que qu'elle qu'un peut m'expliquer pour quoi le caste en int après la multiplication par 100 de ces double : 5000.1,5000.11,5000.12,5000.21,5000.44, ce passe mal?
Il serait intéressant de voir le code et l'erreur associée.
Parce que les dixièmes ne se représentent pas bien en virgule flottante qui utilise des puissance de 1/2 et que le cast vers int abandonne la partie décimale au lieu de faire un arrondi:
Sortie:Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 public class Main { public static void main(String[] args) { double[] ds = {5000.1,5000.11,5000.12,5000.21,5000.44}; for (double d: ds) { double val = (d*100); int i = (int)(val); int j = (int) Math.round(val); System.out.printf("%.15f*100.0 -> %.15f. (int)=%d (round)=%d\n",d,val,i,j); } } }
pour 5000.44 ca représente une erreur de calcul de ~1.16E-14%, ce qui est dans la tolérance des doublesCode:
1
2
3
4
5 5000,100000000000000*100.0 -> 500010,000000000060000. (int)=500010 (round)=500010 5000,110000000000000*100.0 -> 500010,999999999940000. (int)=500010 (round)=500011 5000,120000000000000*100.0 -> 500012,000000000000000. (int)=500012 (round)=500012 5000,210000000000000*100.0 -> 500021,000000000000000. (int)=500021 (round)=500021 5000,440000000000000*100.0 -> 500043,999999999940000. (int)=500043 (round)=500044
le résultat c'est 500010 au lieu de 500011, si on refait le test avec 6000.11 on a le bon résultat.Code:
1
2
3
4
5 public static void main(String[] args) { double a = 5000.11; int b = (int)(a*100); System.out.println(b); }
y'a t'il un lien qui résume les erreur de ce type?
c'est dans à peu près tous les cours sur les flottants:
-> Les flottants sont des approximations en virgule flottante de nombres réels
-> Les flottant sont composé d'une mantise et d'un exposant, la mantise et l'exposant étant chacun représenté sous forme d'un somme de puissance de 2 (1/2 pour les puissance négative).
Après, les cours de maths te diront que certains nombres ayant une réprésentation à virgule finie dans un base N n'ont pas nécessairement une représentation finie dans une base M. Ce qui implique inévitablement une perte de précision lors du passage de l'un à l'autre (décimale -> binaire -> décimale)
ainsi 1.1 (c'est à dire 1+1/10) en décimal deviens en hexadecimal 1.1999999999999999... 1+1/F + 1/FF + 9/FFF + 9/FFF + 9/FFFF + 9 / FFFFF + 9/FFFFFF + .....
C'est bel et bien la meme valeur, mais comme l'ordinateur est obligé de se limiter en nombre de décimal (stockage oblige), il dois couper à un moment donné et ça deviens pour lui 1.199999999999a, qui n'est plus tout à fait le meme nombre.