51
votes

Pourquoi Parseint de JavaScript (0.0000005) imprime-t-il "5"?

J'ai lu un article sur javascript parseint , qui avait cette question:

parseInt(0.5);      // => 0
parseInt(0.05);     // => 0
parseInt(0.005);    // => 0
parseInt(0.0005);   // => 0
parseInt(0.00005);  // => 0
parseInt(0.000005); // => 0

parseInt(0.0000005); // => 5

Pourquoi cela se produit-il?


3 commentaires

Quelque part dans cette question et réponse devrait probablement être un conseil fortement rédigé de ne pas parseint (x) pour x ce n'est pas une chaîne. Si vous avez déjà un nombre vraisemblablement, vous voulez math.round () ou math.floor () ou quelque chose. L'exemple ici montre que c'est essentiellement la chance que vous obteniez souvent une sortie raisonnable.


Bien que Eslint ne se plaigne pas, au moins PHPStorm (qui est également utile pour JavaScript et TypeScript) prévient qu'un nombre n'est pas attribuable en tant que paramètre de chaîne).


C'est un exemple de l'erreur habituelle de ne pas vérifier le type de valeurs d'entrée. Cet exemple et d'autres exemples de conversion implicite de chaînes sont couverts ici - alex-klaus.com/javascript-wat


3 Réponses :



8
votes

(c'est plus un long commentaire plutôt qu'une réponse concurrente.)

La conversion indésirable menant à cet effet étrange ne se produit que lors du passage de la valeur à parseint en tant que type de nombre - en ce cas il apparaît que le compilateur (ou l'interprète ou tout ce qui entraîne JS) convertit automatiquement le nombre en une chaîne pour vous, car le type de chaîne est le type attendu du paramètre de fonction

La fonction de conversion de chaîne, malheureusement, préfère le format de numéro d'ingénierie lorsqu'il deviendrait trop longtemps.

De plus, la conversion peut entraîner une perte de précision, ce que chaque programme Nombres décimaux (non-entières).

Si vous vous souvenez plutôt de placer la valeur à pair dans une chaîne vous-même, vous n'obtiendrez pas de tels résultats inattendus:

let n = '0.0000005';
console.log(parseInt(n))

Imprimera 0 comme vous le souhaitez.

leçons apprises:

  • Évitez la conversion de type implicite partout où vous le pouvez.
  • Évitez parseint et des fonctions similaires qui ne vous font pas savoir si la chaîne à analyser a des données supplémentaires non ajustées. Par exemple, int-parsing "x" ou "1x" devrait vous dire que ce n'est pas un numéro INT approprié. À cet égard, parseint présente un mauvais comportement en ignorant des données supplémentaires dans la chaîne et en ne nous le disant pas. Une bonne fonction d'analyseur vous indique où elle s'est arrêtée (afin que vous puissiez vérifier s'il reste des ordures) ou échoue lorsqu'il trouve des données inattendues.


0 commentaires

-2
votes

Veuillez respecter le type de données!

dans la console chromée:

parseInt ("0,5");
0
ParseInt ("0,05");
0
ParseInt ("0,005");
0
ParseInt ("0,0005");
0
ParseInt ("0,00005");
0
ParseInt ("0,000005");
0
ParseInt ("0,0000005");
0
ParseInt ("0,00000005");
0
ParseInt ("0,000000005");
0


0 commentaires