23

Defaulting the radix to 8 (if the string starts with a 0) in JavaScript's parseInt function annoys me, only because I continue to forgot to pass the optional second argument as 10. I'm looking for an answer telling me why it makes sense to have it default to 8.

3 Answers 3

34

It only "defaults" to 8 if the input string starts with 0. This is an unfortunate carryover from C and C++.

You can use Number('0123') instead, or, as you said in the question, parseInt('0123', 10).

How do I work around JavaScript's parseInt octal behavior?


Can you tell me more about this carryover?


Note: ECMAScript strict mode removes octal syntax.

Sign up to request clarification or add additional context in comments.

7 Comments

Can you tell me more about this carryover?
Yes. It is stupid, evil, bad, and obnoxious - a poorly designed "feature" implemented solely because previous languages did it.
A unary + is a better choice than using Number. Unary + ignores octal formats (but still honors hexadecimal formats) and is faster than a function call.
@Reid: the better choice depends on your usage. As for performance, I'm not 100% sure that + is faster (and it almost certainly isn't the same for all browsers). Let's see: jsperf.com/string-to-int-2
Since when has C(++) had parseInt? Surely only this aspect of integer literals is (or was, before it was removed in ECMAScript 5) a carryover, and how parseInt behaves is another matter altogether.
|
9

If a number starts with 0 and contains digits between (and inclusive) 0 to 7, it is interpreted as an octal number (with base 8 instead of 10).

In parseInt however, if a string starts with a 0 it's always interpeted as an octal, and stops searching when it encounters an invalid character (e.g. the digits 8 or 9 or a character like z).

parseInt("070");     //56
parseInt("70");      //70
parseInt("070", 10); //70
parseInt("78");      //78
parseInt("078");     //7, because it stops before 8

If you need to convert a string into a number, and you're sure that it contains no invalid characters or fractional parts, you can multiply it with 1 to make a number of it:

1 * "070";           //70

I personally prefer this approach, and believe it's faster than calling functions.

2 Comments

For those who do not understand what Matt Ball is talking about, the first answer submitted contained the first paragraph only.
All this is out of date now. Previously, an integer literal beginning with 0 was notated as octal, but it is now illegal (see also my comment on Matt's answer). But I'm informed that this behaviour of parseInt was never part of the standard, and nowadays the standard dictates that parseInt with one argument always uses decimal.
6

Now, a couple of years later, parseInt() seems to work fine with numbers starting with 0. Current browsers:

parseInt("019"); // 19 on Firefox 67
parseInt("019"); // 19 on Chrome 75
parseInt("019"); // 19 on Safari 12
parseInt("019"); // 19 on IE 11
parseInt("019"); // 19 on Edge 42

But still, this "fix" must break older scripts that rely on parseInt("019") returning 1 or 0 instead of 19...

3 Comments

Does that hold for Number.parseInt too?
Does it make any difference that 019 wouldn't be a valid octal number anyway, as it contains the digit 9? MDN uses the example of 015, but I don't know whether or not it's significant that all the digits are below 8.
@Tim Even 015 seems to be working as base 10 now on both Firefox and Chrome. And I believe it's a relatively recent change, I was still bitten by it one or two years ago (or maybe it's node.js? It works fine now too on v12.20+).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.