133

Javascript's parseInt function does not seem to completely work.

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

You can't explain that. Give it a try. (jsFiddle)

Edit Since this question was asked and answered, the "feature" of defaulting to octal radix has been deprecated. [1] [2]

savinger
  • 6,544
  • 9
  • 40
  • 57
  • 9
    `You can't explain that.` Yes you can => https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/parseInt – gen_Eric Jan 06 '12 at 19:35
  • are you sure??????????? it should not be like this – Shoaib Shaikh Jan 06 '12 at 19:35
  • This is just funny ... Just a little bit ago the same question was posted, but a different user. http://stackoverflow.com/questions/8763362/why-does-parseint09-return-0-but-parseint07-return-7 – John Hartsock Jan 06 '12 at 19:36
  • 3
    Since ages, any number starting with 0 represents OCTAL and 0x represents Hexa-Decimal. I believe this is universal for all languages, but again I may be wrong. – Selvakumar Arumugam Jan 06 '12 at 19:36
  • 3
    FYI: [jsFiddle](http://jsfiddle.net/), is better online JavaScript tester than http://www.w3schools.com/jsref/tryit.asp. – gen_Eric Jan 06 '12 at 19:37
  • 2
    @JohnHartsock Yeh, it's because we were both on this post http://stackoverflow.com/questions/8761997/difference-between-datetimes/8763241#8763241 – savinger Jan 06 '12 at 19:38
  • Thank you for the update. I was confused as to why this was giving me different values in FF and Chrome: alert(parseInt('0123')). Chrome outputs 123, and FF outputs 83. They seem to have different default values for the radix parameter when there's a leading 0. – Itison Apr 30 '13 at 23:53
  • 3
    as of 2015 this behavior (default to octal) is not present in standard modern browsers on Windows. I only managed to reproduce it on Safari 5. – d.raev Apr 14 '15 at 12:01

7 Answers7

191

This is because if a number starts with a '0', it's treated as base 8 (octal).

You can force the base by passing the base as the 2nd parameter.

parseInt("09", 10) // 9

According to the docs, the 2nd parameter is optional, but it's not always assumed to be 10, as you can see from your example.

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
44

Calls to parseInt should always specify a base in the second argument:

parseInt("08", 10);

Earlier versions of JavaScript treat strings starting with 0 as octal (when no base is specified) and neither 08 nor 09 are valid octal numbers.

From the Mozilla documentation:

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.

And from the ECMAScript 3 standard:

When radix is 0 or undefined and the string's number begins with a 0 digit not followed by an x or X, then the implementation may, at its discretion, interpret the number either as being octal or as being decimal. Implementations are encouraged to interpret numbers in this case as being decimal.

The latest version of JavaScript (ECMAScript 5) abandons this behavior, but you should still specify the radix to satisfy older browsers.

Wayne
  • 59,728
  • 15
  • 131
  • 126
16

There is a Radix parameter

parseInt(value, base)

Where base is the radix.

In this case you are evaluating base10 (decimal) numbers, therefore use

parseInt(value, 10);
John Hartsock
  • 85,422
  • 23
  • 131
  • 146
4

This doesn't seem to be completely valid in new browsers. Internet Explorer 9 and 10 will return 8 if you execute 'parseInt("08")' whereas Internet Explorer 8 and previous versions will return 0 (IE10 in quirks mode will also return 0).

The latest version of Chrome also returns 8 so they must have changed the interpretation recently.

Maffelu
  • 2,018
  • 4
  • 24
  • 35
  • Yep, the behavior has changed. I'll update my answer. https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/parseInt#ECMAScript_5_Removes_Octal_Interpretation – Wayne May 15 '13 at 17:13
  • 1
    Yes, Firefox and Chrome latest version doesn't have a problem now. – mythicalcoder Feb 01 '17 at 10:05
3

This issue is deprecated now. But you can still use radix in parseInt to convert number of other bases into base-10. E.g.,

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

returns 17 (which is base-10 of 0010001).

Muhammad Imran
  • 734
  • 7
  • 21
0

Tip: As you now know when default to octal has been deprecated. Here is how you would fix it in legacy browsers

// 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));
}
Endless
  • 34,080
  • 13
  • 108
  • 131
  • P.S.: if you use just a constant number with a leading zero (instead of a string), it is still treated as base 8 in all current browsers. – Agamemnus Mar 05 '15 at 20:59
0

The issue seems to have changed now in most browsers.

Firefox 51.0.1 (64-bit)

parseInt("09")   // 9

Chrome 55.0.2883.95 (64-bit)

parseInt("09")   // 9

Safari 10.0 (12602.1.50.0.10)

parseInt("09")   // 9

=====

Recommended Practice

Having said that, just to be on the safer side and to avoid issues, use the base/radix parameter as suggested in the accepted answer.

parseInt("09", 10)    // 9

Extra test

I just wanted to test this as well, if the argument is not a string. Chrome & Safari gives exact result. Firefox too returns proper result, but with a warning.

parseInt(09)     // 9. (Warning: SyntaxError: 09 is not a legal ECMA-262 octal constant)
Community
  • 1
  • 1
mythicalcoder
  • 3,143
  • 1
  • 32
  • 42
  • If the value starts with 0 and is a number, parseInt will still use base 8. Try parseInt(020) – sirrocco Mar 05 '17 at 05:39
  • Yes. I have even pointed to the suggested answer. And I know best practices and bad features to avoid. So I have given **Recommended practice** as well in my answer. – mythicalcoder Mar 10 '17 at 05:29