Javascript parseInt () avec des zéros non significatifs


120

La fonction parseInt de Javascript ne semble pas fonctionner complètement.

parseInt("01") returns 1
parseInt("02") returns 2
parseInt("03") returns 3
parseInt("04") returns 4
parseInt("05") returns 5
parseInt("06") returns 6
parseInt("07") returns 7
parseInt("08") returns 0
parseInt("09") returns 0

Vous ne pouvez pas expliquer cela. Essaie. (jsFiddle)

Edit Depuis que cette question a été posée et répondue, la "fonction" de passer par défaut à la base octale est devenue obsolète. [ 1 ] [ 2 ]


29
You must be kidding
georg


3
Depuis les âges, tout nombre commençant par 0 représente OCTAL et 0x représente hexa-décimal. Je pense que c'est universel pour toutes les langues, mais encore une fois, je me trompe peut-être.
Selvakumar Arumugam

3
FYI: jsFiddle , est un meilleur testeur JavaScript en ligne que w3schools.com/jsref/tryit.asp .
Rocket Hazmat

2
@JohnHartsock Ouais, c'est parce que nous étions tous les deux sur ce post stackoverflow.com/questions/8761997/…
savinger

Réponses:


181

C'est parce que si un nombre commence par un «0», il est traité comme base 8 (octal).

Vous pouvez forcer la base en passant la base comme 2ème paramètre.

parseInt("09", 10) // 9

Selon la documentation , le 2ème paramètre est facultatif, mais il n'est pas toujours supposé être 10, comme vous pouvez le voir dans votre exemple.


1
oui, mais s'il est supposé octal, il devrait renvoyer 11 pour 09 au lieu de 0.
Peeyush Kushwaha

2
@PeeyushKushwaha: Autre moyen. 11en base 8 est 9en base 10. 09n'est pas un nombre valide en base 8.
Rocket Hazmat

Mais je veux 09 après parseInt, y a-t-il un moyen de contourner
Pardeep Jain

39

Les appels à parseIntdoivent toujours spécifier une base dans le deuxième argument:

parseInt("08", 10);

Les versions antérieures de JavaScript traitent les chaînes commençant par 0octal (lorsqu'aucune base n'est spécifiée) et ni 08ni09 sont des nombres octaux valides.

À partir de la documentation Mozilla :

Si radix est indéfini ou 0, JavaScript suppose ce qui suit:

  • Si la chaîne d'entrée commence par "0x" ou "0X", la base est 16 (hexadécimal).
  • Si la chaîne d'entrée commence par "0", la base est huit (octal). Cette fonctionnalité n'est pas standard et certaines implémentations ne la prennent pas délibérément en charge (à la place en utilisant la base 10). Pour cette raison, spécifiez toujours une base lors de l'utilisation de parseInt .
  • Si la chaîne d'entrée commence par une autre valeur, la base est 10 (décimal).

Si le premier caractère ne peut pas être converti en nombre, parseInt renvoie NaN.

Et du standard ECMAScript 3 :

Lorsque la base est 0 ou non définie et que le numéro de la chaîne commence par un chiffre 0 non suivi d'un x ou d'un X , l'implémentation peut, à sa discrétion, interpréter le nombre comme étant octal ou décimal. Les implémentations sont encouragées à interpréter les nombres dans ce cas comme étant décimaux.

La dernière version de JavaScript ( ECMAScript 5 ) abandonne ce comportement , mais vous devez toujours spécifier la base pour satisfaire les navigateurs plus anciens.


Comme cela est obsolète, à l'avenir, vous seriez d'accord avec l'utilisation de zéros non significatifs, n'est-ce pas?
Pacerier

15

Il y a un paramètre Radix

parseInt(value, base)

Où base est la base.

Dans ce cas, vous évaluez des nombres en base10 (décimaux), utilisez donc

parseInt(value, 10);

4

Cela ne semble pas tout à fait valable dans les nouveaux navigateurs. Internet Explorer 9 et 10 renverra 8 si vous exécutez 'parseInt ("08")' alors qu'Internet Explorer 8 et les versions précédentes renverront 0 (IE10 en mode quirks renverra également 0).

La dernière version de Chrome renvoie également 8, ils doivent donc avoir changé l'interprétation récemment.


Oui, le comportement a changé. Je mettrai à jour ma réponse. developer.mozilla.org/en-US/docs/JavaScript/Reference/…
Wayne

1
Oui, la dernière version de Firefox et Chrome n'a pas de problème maintenant.
mythicalcoder

3

Ce problème est désormais obsolète. Mais vous pouvez toujours utiliser radix in parseIntpour convertir le nombre d'autres bases en base-10. Par exemple,

var baseTwoNumber = parseInt('0010001', 2);

renvoie 17(qui est en base 10 de 0010001).


0

Conseil: comme vous le savez maintenant, lorsque la valeur par défaut est octal est obsolète. Voici comment résoudre ce problème dans les anciens navigateurs

// ES-5 15.1.2.2
if (parseInt('08') !== 8 || parseInt('0x16') !== 22) {
    parseInt = (function (origParseInt) {
        var hexRegex = /^0[xX]/;
        return function parseIntES5(str, radix) {
            str = String(str).trim();
            if (!Number(radix)) {
                radix = hexRegex.test(str) ? 16 : 10;
            }
            return origParseInt(str, radix);
        };
    }(parseInt));
}

PS: si vous n'utilisez qu'un nombre constant avec un zéro non significatif (au lieu d'une chaîne), il est toujours traité comme base 8 dans tous les navigateurs actuels.
Agamemnus

0

Le problème semble avoir changé maintenant dans la plupart des navigateurs.

Firefox 51.0.1 (64 bits)

parseInt("09")   // 9

Chrome 55.0.2883.95 (64 bits)

parseInt("09")   // 9

Safari 10.0 (12602.1.50.0.10)

parseInt("09")   // 9

=====

Pratique recommandée

Cela dit, pour être plus sûr et pour éviter les problèmes, utilisez le paramètre base / radix comme suggéré dans la réponse acceptée .

parseInt("09", 10)    // 9

Test supplémentaire

Je voulais juste tester cela aussi, si l'argument n'est pas une chaîne. Chrome & Safari donne le résultat exact. Firefox renvoie également un résultat correct, mais avec un avertissement.

parseInt(09)     // 9. (Warning: SyntaxError: 09 is not a legal ECMA-262 octal constant)

Si la valeur commence par 0 et est un nombre, parseInt utilisera toujours la base 8. Essayez parseInt (020)
sirrocco

Oui. J'ai même signalé la réponse suggérée. Et je connais les meilleures pratiques et les mauvaises fonctionnalités à éviter. J'ai donc également donné la pratique recommandée dans ma réponse.
mythicalcoder
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.