3

Possible Duplicate:
Workarounds for JavaScript parseInt octal bug

I would think it has something to do with octal parsing, since it only happens on 8 or 9. There was also the thought that this was a Chrome bug, but it replicates in Firefox as well.

Is this intentional behavior? If so, why?

Community
  • 1
  • 1
Bryan Agee
  • 4,924
  • 3
  • 26
  • 42
  • My guess is that parseInt takes a string parameter, and if you're passing 08 (which is of type number), it first converts it to a string without the leading zero. try typing in the console - (08 + '') and you'll see that you get "8" and not "08", which means it runs parseInt("8") - which is a decimal conversion. – yoavmatchulsky Mar 15 '12 at 16:43

3 Answers3

12

The solution here is simple. NEVER call parseInt() without specifying the desired radix. When you don't pass that second parameter, parseInt() tries to guess what the radix is based on the format of the number. When it guesses, it often gets it wrong.

Specify the radix like this and you will get the desired result:

parseInt("08", 10) == 8;

As to what rules it uses for guessing, you can refer to the MDN doc page for parseInt().

If radix is undefined or 0, JavaScript assumes the following:

  • If the input string begins with "0x" or "0X", radix is 16 (hexadecimal).
  • If the input string begins with "0", radix is eight (octal). This feature is non-standard, and some implementations deliberately do not support it (instead using the radix 10). For this reason always specify a radix when using parseInt.
  • If the input string begins with any other value, the radix is 10 (decimal). If the first character cannot be converted to a number, parseInt returns NaN.

So, according to these rules, parseInt() will guess that "08" is octal, but then it encounters a digit that isn't allowed in octal so it returns 0.

When you pass a number to parseInt(), it has nothing to do because the value is already a number so it doesn't try to change it.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
5

"Is this intentional behavior?"

Yes.

"If so, why?"

A leading 0 is the notation used for denoting an octal number as defined in the specification. The symbols 8 and 9 don't exist in octal numbering, so parseInt uses the first valid number it finds, which is 0.

If you do...

parseInt('123@xq$_.f(--_!2*')

...the result will be...

123

...because a valid number was found at the beginning of the string. Anything invalid beyond that is discarded.

0

You can fix this like that :

parseInt("080".replace(/^[0]+/g,""));
Alytrem
  • 2,620
  • 1
  • 12
  • 13
  • I did in fact use this type of hack { data.replace(/^0+/,'') } to deal with a sorting issue, but wanted to know why it was acting that way. – Bryan Agee Mar 15 '12 at 16:40
  • 3
    Why, oh why would you do this when you can just pass the radix to parseInt and it will do the right thing for you? – jfriend00 Mar 15 '12 at 16:42
  • Right, I learn things everyday :-) – Alytrem Mar 15 '12 at 16:45
  • This is dangerous. Instead (as described above) use `parseInt('08', 10)`. If the `'08'` were stored in a `var` which could be string *or* int, and you want each to work as expected, you should just pass it to `parseInt` with the correct base. Plus it's more legible. – Marshall Mar 15 '12 at 16:51