Je suis noyé dans la virgule flottante

Langellier

Membre actif
24 Juin 2002
938
29
Orne
sciences-paysages.fr
Bonjour
J'ai réalisé une calculette en javascript (en m'inspirant de scripts déjà existants :zen: ).
Quant à faire, j'ai autorisé les décimales et du coup j'ai un pb avec divers navigateurs.
je n'arrive pas à concevoir un javascript qui convienne à tous.
Voici celui que j'ai mis en ligne :
1) head :
Bloc de code:
function operation(val1, val2, operateur) {
  switch (operateur) {
     case 0 : return parseFloat(val1) + parseFloat(val2); break;
     case 1 : return val1 - val2; break;
     case 2 : return val1 * val2; break;
     case 3 : if (val2 != 0) return val1 / val2;else return "division par 0";
  }}
2) Body :
Bloc de code:
<form method="post" action="">       
<p>Saisissez 2 nombres  :<br />
(sans espaces, mais avec un point pour les d&#233;cimales.)<br />
<input type="text" name="nombre1" size="10" /> 
<input type="text" name="nombre2" size="10" /></p>
<p>Choisissez l'op&#233;ration :<br />
<select size="4" onchange="document.forms[0].resultat.value = 
operation(document.forms[0].nombre1.value, document.forms[0].nombre2.value, this.selectedIndex)">
       <option>addition</option>
       <option>soustraction</option>
       <option>multiplication</option>
       <option>division</option>
     </select></p>
<p>Voici le r&#233;sultat de l'op&#233;ration<br />
<input type="text" name="resultat" size="20" /> 
<input type="reset" value="Effacer" /></p>
</form>
Quand j'additionne par exemple 14.2 et 7.1, Safari et Firefox me donnent :
21,2999...7 !
Heureusement, iCab et IE 5.2 me donnent le bon r&#233;sultat 21.3
Un bug de Safari et Firefox ou de macOS X.10.39 ?
NB : Je n'ai pas essay&#233; sous windows.
 
c'est juste la faute &#224; pas de chance, les nombres qui ne peuvent tous &#234;tre repr&#233;sent&#233;s sur 32 bit (sur 64 bit non plus, mais il y en a beaucoup beaucoup plus)
et tu est tomb&#233; sur un de ceux l&#224;...

Il n'y a pas longtemps quelqu'un a eu le m&#234;me probl&#232;me en Java et en a parler sur MacG.
 
J'ai une autre question :
Pourquoi suis-je oblig&#233; de d&#233;clarer la virgule flottante (parseFloat) pour les additions et pas pour les autres op&#233;rations ?
 
J'ai une autre question :
Pourquoi suis-je oblig&#233; de d&#233;clarer la virgule flottante (parseFloat) pour les additions et pas pour les autres op&#233;rations ?
alors l&#224;... :heu:...
j'en sais rien du tout !
c'est &#233;trange :heu:

j'aimerai bien le savoir aussi.
 
J'ai trouvé une solution bricolée :
Bloc de code:
function operation(val1, val2, operateur) {
[B]nb = parseFloat(val1) + parseFloat(val2);[/B]
  switch (operateur) {
     case 0 : return [B]Math.round(nb*100)/100[/B]; break;
     case 1 : return val1 - val2; break;
     case 2 : return val1 * val2; break;
     case 3 : if (val2 != 0) return val1 / val2;else return "division par 0";
  }}
En gras la partie modifiée du script.
J'ai simplement demandé d'arrondir le résultat des additions à 2 décimales.
mais je ne comprends tjrs pas pq c'est nécessaire pour les additions et pas pour les autres opérations.
Si qqn a mieux...
Calculette améliorée
 
Pour les calculs en réels, l'affichage d'un arrondi déterminé est à peu près la seule solution pour avoir un résultat identique sur différentes machines, systèmes, etc. La représentation des nombres réels comme l'a dit truk2oof ne peut, par nature être parfaite : on ne peut pas représenter parfaitement un infini (les réels entre 0 et 1 par exemple) par un fini (les représentations 32 ou 64 bits par exemple). Ensuite, tout dépend de plein de choses : la représentation choisie (nature et taille) et surtout les algorithmes d'affichage puisque ce ce sont eux qui vont gérer l'arrondi (ou plus exactement le choix de la précision d'affichage). Le problème existe tout autant sur les calculatrices et dans tous les langages informatiques sauf ceux qui savent travailler à précision variable (pas infinie bien sûr mais aussi grande que nécessaire) ou ceux qui permettent d'imposer une précision en termes de décimales (Ada, par exemple).

Dans le temps, sous les vieux macOS sur motorola que tu connais bien, on avait par exemple des différences qui pouvaient être sensibles quand on accumulait les calculs suivant qu'on utilisait les nombres en double précision (ce qui était classique sur PC comme sur Mac) ou les nombres en précision étendue (disponibles sur motorola et sous MacOS) ce qui permettait de gagner quelques décimales.

Mais la solution que tu as adopté d'imposer une précision d'affichage est, me semble-t-il, une solution standard même si elle est souvent plus implicite qu'explicite.

Quant aux nuances entre addition et autres opérations, je ne connais pas javascript et n'ai pas idée de la chose. Mais à la base, ce n'est pas à proprement parler un bug, simplement la manifestation pour une fois visible que l'informatique n'est pas la mathématique.
 
Salut!
je vais ptet dire une grosse connerie mais le fait que le parsefloat est n&#233;cessaire pour l'addition est probablement li&#233; au fait que l'op&#233;rateur + est aussi op&#233;rateur de concat&#233;nation tt simplement.
Dans tes scripts tu ne d&#233;finis pas clairement que les param&#232;tres que tu fournis sont des nombres donc par d&#233;faut c'est interpr&#233;t&#233; en tant que chaine: ainsi 1+2 vaut 12
les autres op&#233;rateurs n'ayant pas d'autres roles, la transformation est implicite.


Sinon, pour des calculs simples tels qu'une calculette "basique" il y a la fonction eval qui est tr&#233;s interessante! (et te permet d'autres avantages tels que gestion pratique d'historique ou autre).

++
 
Salut!
je vais ptet dire une grosse connerie mais le fait que le parsefloat est n&#233;cessaire pour l'addition est probablement li&#233; au fait que l'op&#233;rateur + est aussi op&#233;rateur de concat&#233;nation tt simplement.
Dans tes scripts tu ne d&#233;finis pas clairement que les param&#232;tres que tu fournis sont des nombres donc par d&#233;faut c'est interpr&#233;t&#233; en tant que chaine: ainsi 1+2 vaut 12
les autres op&#233;rateurs n'ayant pas d'autres roles, la transformation est implicite.


Sinon, pour des calculs simples tels qu'une calculette "basique" il y a la fonction eval qui est tr&#233;s interessante! (et te permet d'autres avantages tels que gestion pratique d'historique ou autre).

++
Ah ben ouais &#231;a doit &#234;tre &#231;a pour le parsefloat ! :up:
 
J'ai un autre pb : j'ai &#233;t&#233; contraint &#224; faire un bouton de r&#233;initialisation (reset) que j'ai appel&#233; "Effacer avant de recommencer". Sinon quand l'internaute re-saisit deux nouveaux nombres ils ne sont pas pris en compte. Comment faire pour que tout nouveau nombre saisi soit automatiquement pris en compte ? Merci