3 votes

JavaScript Math.min renvoie une valeur incorrecte

Je utilise la fonction de John Resig pour trouver la valeur minimale dans un tableau mais elle retourne une valeur arrondie vers le bas. Voici une démonstration et voici le code.

 var arr = Math.min.apply(Math, [310127563311820800, 310127563190202368, 310127563110502401, 310127562443595776, 310127562326163457, 310127561751556097]);
document.write(arr);

Pouvez-vous m'expliquer ce qui se passe et pourquoi cela renvoie une valeur erronée(arrondie vers le bas) ?

4voto

dystroy Points 145126

Le problème ne réside pas dans la recherche du minimum mais dans l'utilisation de ces nombres. Vous ne pouvez pas les représenter comme des nombres en JavaScript car les entiers ne peuvent être conservés complètement que entre -9007199254740992 et +9007199254740992.

Cela est dû au fait que tous les nombres en JavaScript sont des flottants double précision IEEE754 et que la taille de la mantisse est de 53.

Consultez plus de détails dans la spécification ECMAScript sur le type de nombre :

Notez que tous les entiers positifs et négatifs dont la magnitude n'excède pas 253 sont représentables dans le type Number (en effet, l'entier 0 a deux représentations, +0 et -0).

Pour gérer ces nombres (et trouver leur minimum), vous devez utiliser une autre représentation que le nombre natif JavaScript. Heureusement, de nombreuses bibliothèques permettent de manipuler de gros nombres, par exemple bignum (mais vous devriez faire des recherches et choisir celle qui vous convient).

1voto

kennebec Points 33886

Vous perdrez de la précision en javascript à moins de faire en sorte que l'entrée soit des chaînes de caractères de chiffres.

S'ils sont tous des entiers positifs, vous pouvez les trier et retourner l'élément d'index le plus bas, en gardant à l'esprit qu'une chaîne avec plus de chiffres doit être plus grande qu'une avec moins -

var input= ['310127563311820800', '310127563190202368', '310127563110502401',
'310127562443595776', '310127562326163457', '310127561751556097'];

var minim= input.slice(0).sort(function(a, b){
    if(a=== b) return 0;
    if(a.length!= b.length) return a.length-b.length;
    return a>b? 1:-1;  
})[0];

alert(minim);

/*  valeur retournée: (String)
310127561751556097
*/

Vous pouvez sauter la partie slice(0) si vous n'avez pas besoin de conserver l'original dans son ordre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X