Flottant et résultat

Le
loiseauthierry
Bonjour,

Avec JavaScript, le résultat d'un calcul sur des flottants peut sembler
aberrant.

Ainsi, le résultat de :

10.2 - 4.3

retourne

5.8999999999999995

au lieu de

5.9

Je me dis alors qu'une simple calculatrice de poche à trois francs six
sous est bien plus performante sauf que, en interne, une calculatrice
stocke plus de chiffres qu'elle ne le montre. Elle a en mémoire 16
chiffres (par exemple), mais n'affiche que 14 chiffres en passant par
un arrondi.

Il suffit donc, pour le JavaScript, de faire quelque chose comme :

function simplifie(v) {
with (Math) {
v=(round(v*pow(10,14)))/pow(10,14);
}
return v;
}

a.2;
b=4.3;
c=a-b; // 5.8999999999999995
c=simplifie(c); // 5.9

c=a-b+0.000000007; // 5.900000006999999
c=simplifie(c); // 5.900000007

c.2-4.3+0.000000007; // 5.900000006999999
c=simpifie(10.2-4.3+0.000000007); // 5.900000007



Youpi ! Ça marche impeccable, y'a pas de bug Quoi que !


Prenons un grand entier décimal.

a0000000010.2;
b=4.3;


Là, du coup, il vaut mieux ne pas utiliser simplifie !!!

c0000000010.2-4.3+0.000000007;

donne 100000000005.9

et

simplifie(c)

donne 100000000005.89998

Argh !

Il faut donc tenir compte du nombre de chiffres dans la partie entière
pour déterminer le nombre de chiffres dans la partie décimale à prendre
en compte pour l'arrondi. (je ne sais pas si je suis clair, là).

Déterminer le nombre de chiffre dans la partie entière :

Math.ceil( Math.log(c)/Math.log(10) )

On modifie donc la function simplifie()



-
function simplifie(v) {
var n;
with (Math) {
nÎil(log(c)/log(10));
v=(round(v*pow(10,15-n)))/pow(10,15-n);
}
return v;
}
-



Qu'en pensez-vous ? Olivier ?

Thierry
--
* * __*__ *
* * * --oOOo°O°oOOo * *
<http://astrophoto.free.fr> *
* * -- oOOo oOOo -- *
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
loiseauthierry
Le #740121
Thierry Loiseau
nÎil(log(c)/log(10));


Oups! il fallait lire log(v)
----------------------------------------------------------------------
function simplifie(v) {
var n;
with (Math) {
nÎil(log(v)/log(10));
v=(round(v*pow(10,15-n)))/pow(10,15-n);
}
return v;
}
----------------------------------------------------------------------

Thierry

loiseauthierry
Le #740120
Thierry Loiseau
nÎil(log(c)/log(10));


Oups! il fallait lire log(v)
----------------------------------------------------------------------
function simplifie(v) {
var n;
with (Math) {
nÎil(log(v)/log(10));
v=round(v*pow(10,15-n))/pow(10,15-n);
}
return v;
}
----------------------------------------------------------------------

Thierry

Olivier Miakinen
Le #740116

[...]

Qu'en pensez-vous ? Olivier ?


Puisque tu me poses directement la question, j'avoue que je n'en pense
pas grand chose dans le cas général, préférant utiliser les entiers tant
que c'est possible. De retour au bureau je regarderai quand même la
norme ECMAScript pour voir s'il n'y a pas déjà une fonction d'affichage
qui arrondit à N chiffres significatifs (pour éviter de devoir faire une
fonction supplémentaire de normalisation, à base de logarithmes et de
puissances, d'autant que ces fonctions sont elles-mêmes sujettes aux
erreurs d'arrondi).

loiseauthierry
Le #740115
Olivier Miakinen

[...]

Qu'en pensez-vous ? Olivier ?


Puisque tu me poses directement la question, j'avoue que je n'en pense
pas grand chose dans le cas général, préférant utiliser les entiers tant
que c'est possible.


En fait, ce que je veux faire, c'est une fonction fiable (ou la moins
bancale possible) qui permet de retourner une valeur arrondie à la
manière d'une calculatrice. Bref, une fonction que l'on utiliserait qu'à
la fin d'un calcul (comme il est bon de faire lorsqu'il s'agit
d'arrondi).

De retour au bureau je regarderai quand même la norme ECMAScript pour voir
s'il n'y a pas déjà une fonction d'affichage qui arrondit à N chiffres


A priori, non. Mais je peux me tromper.

significatifs (pour éviter de devoir faire une fonction supplémentaire de
normalisation, à base de logarithmes et de puissances, d'autant que ces
fonctions sont elles-mêmes sujettes aux erreurs d'arrondi).


Voici ici des infos sur la méthode Math :


@++ et bon dimanche,
Thierry
--
* * __*__ *
* * * -----oOOo---°O°---oOOo------ * *
* * -------- oOOo oOOo -------- *


YD
Le #739876
Olivier Miakinen
De retour au bureau je regarderai quand même la norme ECMAScript pour voir
s'il n'y a pas déjà une fonction d'affichage qui arrondit à N chiffres


A priori, non. Mais je peux me tromper.


Méthode toFixed de l'objet Number ?
(http://phrogz.net/objjob/method.asp?idq6)

--
Y.D.


loiseauthierry
Le #739875
YD
Olivier Miakinen
De retour au bureau je regarderai quand même la norme ECMAScript pour voir
s'il n'y a pas déjà une fonction d'affichage qui arrondit à N chiffres


A priori, non. Mais je peux me tromper.


Méthode toFixed de l'objet Number ?
(http://phrogz.net/objjob/method.asp?idq6)


Vous avez toujours réponse à tout, vous !

Merci Yves,

Thierry
--
* * __*__ *
* * * -----oOOo---°O°---oOOo------ * *
* * -------- oOOo oOOo -------- *



loiseauthierry
Le #739874
YD
Olivier Miakinen
De retour au bureau je regarderai quand même la norme ECMAScript pour voir
s'il n'y a pas déjà une fonction d'affichage qui arrondit à N chiffres


A priori, non. Mais je peux me tromper.


Méthode toFixed de l'objet Number ?
(http://phrogz.net/objjob/method.asp?idq6)


----------------------------------------------------------------------
function simplifie(v) {
var n;
with (Math) {
nÎil(log(v)/log(10));
v=round(v*pow(10,15-n))/pow(10,15-n);
}
return v;
}
c0000000010.2-4.3+0.000000007;
c=simplifie(c);
----------------------------------------------------------------------

En effet, pour les exemples précédents, ça fonctionne pile-poil. Yep !

fix=(100000000010.2-4.3+0.000000007).toFixed(14);
fix=parseFloat(fix);

retourne bien 100000000005.9 et

fix=(10.2-4.3).toFixed(14);
fix=parseFloat(fix);

retourne bien 5.9

donc, la function devient... inutile ?

----------------------------------------------------------------------
c0000000010.2-4.3+0.000000007;
c=parseFloat(c.toFixed(14));
----------------------------------------------------------------------

Merci !

Thierry
--
* * __*__ *
* * * -----oOOo---°O°---oOOo------ * *
* * -------- oOOo oOOo -------- *



loiseauthierry
Le #739873
YD
Olivier Miakinen
De retour au bureau je regarderai quand même la norme ECMAScript pour voir
s'il n'y a pas déjà une fonction d'affichage qui arrondit à N chiffres


A priori, non. Mais je peux me tromper.


Méthode toFixed de l'objet Number ?
(http://phrogz.net/objjob/method.asp?idq6)


----------------------------------------------------------------------
function simplifie(v) {
var n;
with (Math) {
nÎil(log(v)/log(10));
v=round(v*pow(10,15-n))/pow(10,15-n);
}
return v;
}
c0000000010.2-4.3+0.000000007;
c=simplifie(c);
----------------------------------------------------------------------

En effet, pour les exemples précédents, ça fonctionne pile-poil. Yep !

fix=(100000000010.2-4.3+0.000000007).toFixed(14);
fix=parseFloat(fix);

retourne bien 100000000005.9 et

fix=(10.2-4.3).toFixed(14);
fix=parseFloat(fix);

retourne bien 5.9

donc, la function devient... inutile :-)))

----------------------------------------------------------------------
c0000000010.2-4.3+0.000000007;
c=parseFloat(c.toFixed(14));
----------------------------------------------------------------------

Merci !

Thierry
--
* * __*__ *
* * * -----oOOo---°O°---oOOo------ * *
* * -------- oOOo oOOo -------- *



YD
Le #739872
[...]
donc, la function devient... inutile :-)))
----------------------------------------------------------------------
c0000000010.2-4.3+0.000000007;
c=parseFloat(c.toFixed(14));
----------------------------------------------------------------------


Je n'ai pas tout compris ce que tu cherches exactement mais
attention, toutefois. Quelques résultats un peu surprenants se
produisent avec certaines valeurs. Pour 0.045.toFixed(2) Firefox
donne 0.04 alors que IE donne 0.05... Ce sujet avait été évoqué
il y a bien longtemps ici même.
(voir : http://ygda.free.fr/decim.htm)

--
Y.D.

loiseauthierry
Le #739871
YD
[...]
donc, la function devient... inutile :-)))
----------------------------------------------------------------------
c0000000010.2-4.3+0.000000007;
c=parseFloat(c.toFixed(14));
----------------------------------------------------------------------


Je n'ai pas tout compris ce que tu cherches exactement mais


Eviter de tomber sur des "aberration" comme l'exemple donné
précédemment, ie 5.899999... au lieu de 5.9

attention, toutefois. Quelques résultats un peu surprenants se
produisent avec certaines valeurs. Pour 0.045.toFixed(2) Firefox
donne 0.04 alors que IE donne 0.05... Ce sujet avait été évoqué
il y a bien longtemps ici même.
(voir : http://ygda.free.fr/decim.htm)


Ah, effectivement. Avec Safari, le résultat est 0.05 ainsi que IE 5.2
Mac. Par contre, avec FF, 0.035 retourne 0.04

Bug de FF ?

Thierry
--
* * __*__ *
* * * -----oOOo---°O°---oOOo------ * *
* * -------- oOOo oOOo -------- *


Publicité
Poster une réponse
Anonyme