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;
}
Youpi ! Ça marche impeccable, y'a pas de bug... Quoi que !
Prenons un grand entier décimal.
a=100000000010.2;
b=4.3;
...
Là, du coup, il vaut mieux ne pas utiliser simplifie !!!
c=100000000010.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=ceil(log(c)/log(10));
v=(round(v*pow(10,15-n)))/pow(10,15-n);
}
return v;
}
----------------------------------------------------------------------
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
[...]
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).
[...]
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).
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
Olivier Miakinen <om+ wrote:
[...]
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).
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).
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).
[...] 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.
[...]
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)
[...] 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
YD wrote:
[...] 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
[...]
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
[...] 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