web-dev-qa-db-fra.com

Pourquoi est-ce que parseInt (8,3) == NaN et parseInt (16,3) == 1?

Je lis this mais je suis dérouté par ce qui est écrit dans le parseInt avec un argument de base chapitre

table of parseInt(_, 3) outcomes

Pourquoi est-ce que parseInt(8, 3)NaN et parseInt(16, 3)1?

Autant que je sache, 8 et 16 ne sont pas des nombres de base 3, donc parseInt(16, 3) devrait renvoyer NaN aussi

the first ten base-3 natural numbers

191
Devid Farinelli

C’est quelque chose qui tracasse tout le temps, même quand ils sont au courant. :-) Vous voyez cela pour la même raison, parseInt("1abc") renvoie 1: parseInt s'arrête au premier caractère non valide et renvoie le résultat. S'il n'y a pas de caractères valides à analyser, il retourne NaN.

parseInt(8, 3) signifie "analyser "8" en base 3" (notez que le nombre 8 est converti en chaîne; détails dans la spécification ). Mais en base 3, les nombres à un chiffre ne sont que 0, 1 Et 2. C'est comme si on lui demandait d'analyser "9" En octal. Puisqu'il y avait aucun caractère valide, vous avez NaN.

parseInt(16, 3) lui demande d'analyser "16" en base 3. Puisqu'il peut analyser le 1, c'est le cas, puis il s'arrête au 6 car il ne peut pas l'analyser. Donc, il retourne 1.


Étant donné que cette question suscite beaucoup d’attention et que les résultats de recherche peuvent occuper une place importante dans la liste, voici un aperçu des options permettant de convertir des chaînes en nombres en JavaScript, avec leurs différentes particularités et applications (extraites d’une autre réponse ici sur SO):

  • parseInt(str[, radix]) - Convertit autant que possible le début de la chaîne en un nombre entier (entier), en ignorant les caractères supplémentaires à la fin. Donc, parseInt("10x") est 10; le x est ignoré. Prend en charge un argument facultatif radix (number base), donc parseInt("15", 16) est 21 (15 Au format hexadécimal). S'il n'y a pas de base, suppose que le nombre est décimal sauf si la chaîne commence par 0x (Ou 0X), Auquel cas elle saute celles-ci et suppose hex (Certains navigateurs traitaient les chaînes commençant par 0 Comme octales; ce comportement n'a jamais été spécifié, et était spécifiquement interdit dans la spécification ES5.) Renvoie NaN si aucun chiffre analysable n'a été trouvé.

  • parseFloat(str) - Comme parseInt, mais utilise des nombres à virgule flottante et ne prend en charge que les décimales. Encore une fois, les caractères supplémentaires de la chaîne sont ignorés, donc parseFloat("10.5x") est 10.5 (Le x est ignoré). Comme seul le nombre décimal est pris en charge, parseFloat("0x15") est 0 (Car l'analyse se termine au x). Renvoie NaN si aucun chiffre analysable n'a été trouvé.

  • Unary +, Par exemple +str - (Par exemple, conversion implicite) Convertit la chaîne entière en un nombre utilisant la virgule flottante et la notation numérique standard de JavaScript (chiffres uniquement). un point décimal = décimal; 0x préfixe = hex; 0o préfixe = octal [ES2015 +]; certaines implémentations de traiter un 0 initial comme octal, mais pas en mode strict). +"10x" Est NaN car le x est non ignoré. +"10" Est 10, +"10.5" Est 10.5, +"0x15" Est 21, +"0o10" Est 8 [ES2015 +]. Compris: +"" Est 0, Et non pas NaN comme on pourrait s'y attendre.

  • Number(str) - Exactement comme une conversion implicite (par exemple, comme le unaire + ci-dessus), mais plus lentement sur certaines implémentations. (Pas que ça risque d'avoir de l'importance.)

372
T.J. Crowder

Pour la même raison que

>> parseInt('1foobar',3)
<- 1

Dans la doc , parseInt prend une chaîne. Et

Si la chaîne n'est pas une chaîne, elle est convertie en chaîne.

Alors 16, 8, ou '1foobar' est d'abord converti en chaîne.

Ensuite

Si parseInt rencontre un caractère qui n'est pas un chiffre dans la base spécifiée, il l'ignore ainsi que tous les caractères suivants.

Ce qui signifie qu'il se convertit là où il peut. Le 6, 8 et foobar sont ignorés et seul ce qui est avant est converti. S'il n'y a rien, NaN est retourné.

54
njzk2