Javascript ne sait pas compter ?

Ca fait longtemps que j’ai trouvé ca, et j’n’ai jamais compris pourquoi…

Attention, ca va aller tres vite, ca prend quelques secondes :

Tapez dans votre barre d’adresse le code suivant :
[html]java script:alert(0.20+0.20+0.20);[/html]
(pas d’espaces entre java et script… c’est iPB qui le met tout seul @_@)

Euh, oui ? ;D
Mais encore ?

Je serais tenté de dire que c’est du au traitement binaire des calculs de javascript
sachant que les nombres a virgules sont toujours des approximation en binaire, ca peu venir de ca

enfin je dis ca… mais j’en suis pas convaincu non plus.

ouais m’enfin le minimum pour un langage, qu’il soit de script ou de programmation, c’est qu’il sache compter correctement >_<

0.20+0.20+0.20 = 0.60000000000001
J’trouve que ca fait tache quand meme, quelqu’en soit la raison.
Car travailler sur de l’approximation… d’approximation… Hopla effet papillon (j’exagere un peu mais bon, dans l’absolu j’pense pas etre fou en demandant a un langage de me calculer correctement 3x0.20)

3x0.20 = 0.6000000000000001
0.20+0.20+0.10+0.10 = 0.6
0.30+0.30 = 0.6

gnia >_<

Et (1.20+0.20+0.20) = 1.599999999999999 ^^

Bienvenue en informatique :stuck_out_tongue: Aucune operation sur les flottant n’est garantie exacte et on ne compare jamais deux flottants entre eux de maniere stricte. Ca s’applique a tous les langages et c’est pas limite a Javascript. Selon la representation memoire qu’on choisit et la maniere dont on applique les instructions au niveau machine, on peut voir differentes choses. Il y en a des plus ou moins adaptees selon la situation et des moyens de minimiser ce genre de bordel mais JS etant un langage interprete, faiblement types, ils ont un choix limite et je m’y connais pas assez pour dire si ils ont fait le meilleurs. Je leur laisse le benefice du doute :stuck_out_tongue: Au final le probleme est toujours exactement le meme et il faut faire avec et bien comprendre ce qu’on fait et comment minimiser les erreurs. Par exemple y a des cours entiers dedies juste a ca en ecole d’inge en info/math apps (en tout cas la ou j’ai ete).

A lire: What Every Computer Scientist Should Know About Floating Point Arithmetic (PDF)

Traduction approximative de la javascript FAQ: En Javascript les nombre sont representes comme des IEEE-754 doubles (tous les nombres), ca donne une 15 a 16 chiffres. Les entiers sont precis jusqu’a 9e15. A partir de la les operations sont precises autant que possible mais jamais plus. Les operations sur les entriers sont precises si le veritable resultat et toutes les etapes intermediaires sont des entiers dans l’intervale acceptable.

Et chacun sait, en particulier sur x86, que le bit de moindre interet (comme on dit en francais : LSB (Less Signifant Bit)) est souvent « n’impore quoi » (c’est pas vraiment « n’importe quoi », parce que c’est coherent, mais bon, grosso modo : c’est « n’importe quoi ») selon l’ordre d’execution et l’etat du FPU…

C’est trops bien le x86… :stuck_out_tongue:

Ah bah merci bien pour toutes ces précisions, je ne savais pas ^^

Ca doit bien foutre le bordel quand on doit développer des trucs couillus du genre un moteur physique pour un jeu :]
C’est ptetre pour ca qu’on ne transmet pas les points d’impact / collisions des elements pour que les clients calculent eux-meme les déplacements.

Hmmm… Interessant comme problème…

Oui en gros je crois que la probleme vient du fait que R n’est pas denombrable alors que ce qui le represente sur un ordinateur l’est (entier).

Mais pourquoi ne pas representer un reel comme 2 entiers ?

Genre 0,20 + 0,20 ca ferai :
0 + 0 = 0 pour la partie entiere.
20 -> 2 //on vire tout les zeros en partant de la droite mais pas tous si on a 0.400 + 0.22 > 0.40 + 0.22, oui il faudrai compter le nombre de chiffre apres la virgule de tout les nombre…
et 2 + 2 = 4
ca ferai 0.4

En gros on recode tout comme ça. C’est un peu chiant pour la division et les 0.3333… mais ca doit etre faisable.

Le seul probleme je pense c’est que cette methode est plus longue a l’exection.

Parceque c’est pas optimal. Lit l’article cite plus haut.

[quote=“Terenas, post:7, topic: 27948”]Ah bah merci bien pour toutes ces précisions, je ne savais pas ^^

Ca doit bien foutre le bordel quand on doit développer des trucs couillus du genre un moteur physique pour un jeu :]
C’est ptetre pour ca qu’on ne transmet pas les points d’impact / collisions des elements pour que les clients calculent eux-meme les déplacements.

Hmmm… Interessant comme problème…[/quote]
Boaf, les problèmes de précision des float interviennent de façon assez anecdotique (enfin de mon temps, c’était ça). Mais je me souviens, dans la même veine, d’un bug de VC (v5 il me semble) qui m’a rendu fou un WE entier juste avant une release éditeur de Nomad Soul. Certains calculs en float étaient faux en mode release, et justes en mode debug. Et comme ça tenait à pas grand chose, il a fallu batailler des heures dans des milliers de lignes de code avant d’envisager l’ombre d’une idée que cela puisse venir autre part que de l’algo lui même (qui se résumait à quelques multiplications et additions).
De toutes manières, c’est un grand classique en matière de prog. Tu conçois un algo ultra-méga-complexe, tu le codes, tu le testes : marche pas. Tu revois tout ton algo. Tu debug dans tous les sens. Tu décomposes l’algo en fines tranches jusqu’à ce qu’il soit à la limite du palpable.
Et deux jours plus tard, tu te rends compte que tout ton algo est nickel. C’est simplement que (au choix) :

  • t’as fait une faute de frappe en tapant ton code (genre + à la place d’un -, ou 0 à la place de 1)
  • les données en entrée étaient mauvaises
  • un bug du compilateur
  • tu appelais la mauvaise version de ton algo (pré-code)
  • Etc.

Antoine