Derniers journaux de LolZ :
- [31/08@12:20] Gestionnaire d'images hi-res
- [29/07@19:34] Sylpheed 2 iz houtte
- [05/07@13:11] Moiteur au sous-sol
- [04/07@08:06] 42
- [23/06@11:22] Tout le monde aux fenêtres, pas de maison!
- [22/03@22:41] Halte à la barbarie!
- [07/01@15:24] Après les CD, les jouets et les tutures
- [28/12@18:17] Joyeux sylpheed!
- [01/11@09:12] La gourmandise est toujours un vilain défaut!
- [21/10@14:30] LinuxFr devant slashdot!
- [30/09@11:45] Mailing lists manager
- [12/08@17:46] De la vraie, bonne musique
- [09/08@23:08] Recette d'été: la glamouille aux piroles
- [28/07@14:41] Ma question est simple
- [22/07@17:32] Sarge décision
- [14/07@09:56] Soft weblog pour hébergement
- [22/06@13:19] Distribution "samba"
- [07/05@16:18] L'Ayatollah et les produits américains
- [07/05@10:57] Petites frustrations du développeur
- [18/03@10:14] Passions express, épisode CVXXIV
j'ai un truc bizarre, reproductible sur plus de 4 environements:
Soit le script
http://www.lzi.ch/plop.phps(...)
Résultat:
http://www.lzi.ch/plop.php(...)
Pourquoi 19.89 et pas 19.90? Quelqu'un a déjà vu ça? Non, c'est pas des pentioumes buggés, enfin: pas officiellement :)
> Lire le journal (21 commentaires, moyenne: 1,7).
:)
bienvenu dans le monde des arrondis numérique
Histoire de codage
Je pense que tu viens de découvrir que les flottants ne sont généralement pas codés de manière exacte dans la machine. :) Ceci combiné à une troncature et on a ce que tu observes. Enfin, je peux me tromper, c'est juste une explication possible.
100.00
Essaye de mutiplier par 100.00 c'est peut etre un probleme du au typage dynamique.
-
[^]Re: 100.00
Posté par Lol Zimmerli (Jabber id, page perso, ) le 11/10/2005 à 11:49. (lien). Évalué à 1.Bonne idée, mais non: (
http://www.lzi.ch/plop.php(...) http://www.lzi.ch/plop.phps(...)
Et même avec 15.90, c'est ok. Qu'est-ce que le type qui a écrit ça a contre 1990?? :*)--
En fait, Bernardo n'était pas muet; c'est Zorro qui était sourd.-
[^]Re: 100.00
Posté par xalbat () le 11/10/2005 à 12:22. (lien). Évalué à 1.J'ai voulu tester la même chose dans Scilab (Version : 3.1.1)
Voila ce que l'on obtient :
-->a=19.90
a =
19.9
-->a*100
ans =
1990.
-->int(a*100)
ans =
1989.
-->a2=15.9
a2 =
15.9
-->int(a2*100)
ans =
1590.
-->b=a*100
b =
1990.
-->int(b)
ans =
1989.
-->int(1990)
ans =
1990.
-->round(b)
ans =
1990.
round(x) : arrondit les éléments de x aux entiers les plus proches.
int(X) : renvoie une matrice d'entiers dont les éléments sont les arrondis vers zéro des éléments de x.
-->int(b*10000)
ans =
19899999.
-->int(b*10000000)
ans =
1.990D+10
Voila ce qu'il en est dans Scilab : pareil en clair-
[^]Re: 100.00
Posté par Lol Zimmerli (Jabber id, page perso, ) le 11/10/2005 à 12:27. (lien). Évalué à 1.Et en python:
Python 2.3.5 (#2, Jun 19 2005, 13:28:00)
>>> 19.90 * 100
1989.9999999999998
>>> 15.90 * 100
1590.0
ça m'scie l'caramel :-/--
En fait, Bernardo n'était pas muet; c'est Zorro qui était sourd.-
[^]Re: 100.00
Posté par Vincent Behar () le 11/10/2005 à 12:38. (lien). Évalué à 3.ruby...
irb(main):001:0> 15.90 * 100
=> 1590.0
irb(main):002:0> 19.90 * 100
=> 1990.0
change de caramel ça ira mieux ;-)
-
[^]Re: 100.00
Posté par Amand Tihon (page perso, ) le 12/10/2005 à 01:22. (lien). Évalué à 1.mais :
>>> print 19.90 * 100
1990.0
:)
-
-
-
BCMath
BCMath est la pour régler ce genre de problème...
http://fr.php.net/manual/fr/ref.bc.php(...)
explication
Tiens j'ai vu ça quelque part il y a pas longtemps :
http://blog.leetsoft.com/articles/2005/09/27/wtf(...)
Casting a float to an integer means you lose all the information after the decimal. Rounding should not occur in this case.
Tout à fait
Normal, c'est du au fait que les nombre en virgule flottante ne sont pas précis en php.
Pour contourner ce problème, si on a besoin de précision (et donc éviter les problèmes d'arrondi) il faut utiliser http://lu.php.net/manual/fr/ref.bc.php(...) Binary Calculator.
Maintenant à toi de voir si ton projet a vraiment besoin de cette précision ou si l'arrondi est acceptable
-
[^]Re: Tout à fait
Posté par Cali_Mero () le 11/10/2005 à 12:36. (lien). Évalué à 3.Et c'est écrit en gros dans le manuel (qu'on ne lit décidément jamais assez) : http://www.php.net/manual/fr/language.types.float.php(...)
--
#define MAGIC 0xdefaced /* I should've patented this number -cliph */
Codage des floats
Un entier, c'est codé en binaire
0b => 0d
1b=> 1d
10b => 2d
etc....
et un nombre se décompose sur les puissances de 2
18 = 0*1 + 1*2^1 + 0*2^2 + 0*2^3 + 1*2^4 = 10010b
Quand tu code un flottant, la partie après la virgule est aussi codée en binaire en décomposant par puissance négative de 2
a*1/2^1 + b*1/2^2 +c*1/2^3 + ... + x*1/2^n
Un nombre comme 1/3 a un nombre de virgule infini. Donc on ne pourra jamais trouver un "décomposition en série de 1/2^n" finie égale à 1/3. Un float est stocké sur un nombre fini de bits et donc s'approchera plus ou moins bien de ton 1/3 mais n'y arrivera jamais exactement.
Conclusion quand tu réaffiche ton nombre, il affiche la valeur stockée.
Ex : 0.8126 si on a que 4bits de précisions
0.826 = 1/2 + 1/4 + 0/8 +1/16 (+1/10000)
La partie 1/10000 n'est pas codable avec notre système, quand on réaffichera notre nombre stocké, on aura 0.825 et non 0.826
-
[^]Re: Codage des floats
Posté par xalbat () le 11/10/2005 à 16:21. (lien). Évalué à 1.Effectivement, je suis OK avec toi, si je prend notre exemple si dessus on obtient donc :
19.90d = 19d + 0.90d
19d = 16 + 2 + 1 = 10011b
0.90d = 1/2 + 1/4 + 1/8 + 1/64 + 1/128 + 1/1024 + 1/2048 ...
= 1/2^1 + 1/2^2 + 1/2^3 + 1/2^6 + 1/2^7 + 1/2^10 + 1/2^11 + 1/2^14 + 1/2^15 + etc . etc.
= 111001100110011...
Donc comme dans ton exemple 0.90 n'est pas codable.
Maintenant, j'ai une question : qu'est-ce qui rend 15.90d codable et 19.90 non codable ? Parce si on regarde bien, seul 19.90 pose problème ci-dessus.
J'au eu beau chercher dans Wikipedia, Google, rien de probant-
[^]Re: Codage des floats
Posté par Éric (Jabber id, page perso, ) le 11/10/2005 à 16:42. (lien). Évalué à 4.Ca tient là aussi à la manière dont on stoque les flottants.
Ce que tu fais c'est retrancher la partie entière et remarquer que la partie décimale est identique. Et là tu te dis que la précision devrait être la même.
Ton erreur c'est que le soft ne sépare pas la partie entière et la partie décimale. Lui sépare un nombre et une puissance : X * 10^Y, il stocke X et Y.
Bref, ce n'est pas 15 + 0.90 et 19 + 0.90 qu'il faut comparer mais 0.1590 * 10^2 et 0.1990 * 10^2. La bonne question c'est donc : 0.1590 et 0.1990 sont exprimables en puissance de deux ?
Note : je parle de mémoire de mes anciens cours, je peux me tromper sur les détails, mais le principe est là. Tu ne peux pas te contenter de dire que vu que la partie décimale est la même si l'un est stockable l'autre l'est.
-
[^]Re: Codage des floats
Posté par Black Fox (page perso, ) le 11/10/2005 à 19:40. (lien). Évalué à 2.2 choix principaux : Soit un nombre est codable avec exactitude soit il ne l'est pas. Dans le cas ou il ne n'est pas deux choix : soit le nombre qui est stoqué (le plus proche possible donc) est plus petit que celui au quel on s'attends soit il est plus grand...
Ce qui en tout fait 3 cas, dont un ne donne pas ce à qui on s'attends quant on cast en int, la conclusion est simple : faire un cast d'un nombre IEEE-754 vers un int c'est chercher les emmerdes.
-
moi aussi
J'ai moi aussi un bug du à PHP.
j'ai fait un script pour la notation scientifique (cours de seconde math/physique)
http://kobold.myftp.org/math/ecriture_science.php(...)
Le script génère un nombre aléatoire.
genre 0,015668
et il faut que l'élève trouve que ça fait 1,5668 .10^"-2"
donc bref je compare deux nombres.
celuidonné par l'élève : 1,5668
et celui donnée par le script : 1,5668
et de temps en temps le script affiche faux alors que ce sont les mêmes nombres.
J'ai fait afficher les deux nombres par la page, il s'agit bien des deux nombres ci dessus.
mais quand je fais leur différence : j'observe une différence d'environ 1E-16
Conclusion j'ai modifié mon script pour qu'il donne juste aux élèves si la différence entre les deux nombres est inférieur à 1E-15 (mais mathématiquement ça me gêne !)
Si ça intéresse, je peux fournir le script à qui veut !
http://kobold.hd.free.fr/
-
[+] [^]Re: moi aussi
Posté par Kobold Cyber (Jabber id, page perso, ) le 12/10/2005 à 05:09. (lien). Évalué à -1.Au passage, quelqu'un saurait-il comment forcer PHP à afficher les nombres en écriture décimale.
parce que 0,00001 est écrit par PHP sous forme 1E-5 et que ça ne m'intéresse pas du tout dans le cas de mon script.
(je pose la question ici, vu que les forums me sont interdits faute de suffisament d'XP)--
http://kobold.hd.free.fr/
ha les joies des virgules flottantes
On a le meme genre de problème avec tout les langages (ca serait pas un pattern récurrent ca d'ailleur?)
En java, un System.out.println(19.90*100) donnerait le meme genre d'erreur, c'est pour cela qu'il faut systématiquement un formateur (NumberFormat en l'occurence).
En PHP, on peut s'en sortir avec un printf :
echo (int)(sprintf("%F", 19.90*100));
Mais ca me semble un peu gruick quand meme.
Les journaux sont destinés à des informations qui ne sont pas suffisamment intéressantes
pour être validées en dépêche (sinon n'hésitez pas à proposer votre information en
dépêche), qui sont sans rapport avec Linux ou le libre, ou simplement pour donner votre
avis. Si vous désirez poser une question, merci d'utiliser 

Cette discussion est archivée, il n'est plus possible de laisser des commentaires.
Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.