I'm reading this but I'm confused by what is written in the parseInt with a radix argument chapter
Why is it that parseInt(8, 3)
→ NaN
and parseInt(16, 3)
→ 1
?
AFAIK 8 and 16 are not base-3 numbers, so parseInt(16, 3)
should return NaN
too
For the same reason that
In the doc,
parseInt
takes a string. AndSo
16
,8
, or'1foobar'
is first converted to string.Then
Meaning it converts up to where it can. The
6
,8
, andfoobar
are ignored, and only what is before is converted. If there is nothing,NaN
is returned.This is something people trip over all the time, even when they know about it. :-) You're seeing this for the same reason
parseInt("1abc")
returns 1:parseInt
stops at the first invalid character and returns whatever it has at that point. If there are no valid characters to parse, it returnsNaN
.parseInt(8, 3)
means "parse"8"
in base 3" (note that it converts the number8
to a string; details in the spec). But in base 3, the single-digit numbers are just0
,1
, and2
. It's like asking it to parse"9"
in octal. Since there were no valid characters, you gotNaN
.parseInt(16, 3)
is asking it to parse"16"
in base 3. Since it can parse the1
, it does, and then it stops at the6
because it can't parse it. So it returns1
.Since this question is getting a lot of attention and might rank highly in search results, here's a rundown of options for converting strings to numbers in JavaScript, with their various idiosyncracies and applications (lifted from another answer of mine here on SO):
parseInt(str[, radix])
- Converts as much of the beginning of the string as it can into a whole (integer) number, ignoring extra characters at the end. SoparseInt("10x")
is10
; thex
is ignored. Supports an optional radix (number base) argument, soparseInt("15", 16)
is21
(15
in hex). If there's no radix, assumes decimal unless the string starts with0x
(or0X
), in which case it skips those and assumes hex. (Some browsers used to treat strings starting with0
as octal; that behavior was never specified, and was specifically disallowed in the ES5 specification.) ReturnsNaN
if no parseable digits are found.parseFloat(str)
- LikeparseInt
, but does floating-point numbers and only supports decimal. Again extra characters on the string are ignored, soparseFloat("10.5x")
is10.5
(thex
is ignored). As only decimal is supported,parseFloat("0x15")
is0
(because parsing ends at thex
). ReturnsNaN
if no parseable digits are found.Unary
+
, e.g.+str
- (E.g., implicit conversion) Converts the entire string to a number using floating point and JavaScript's standard number notation (just digits and a decimal point = decimal;0x
prefix = hex;0o
prefix = octal [ES2015+]; some implementations extend it to treat a leading0
as octal, but not in strict mode).+"10x"
isNaN
because thex
is not ignored.+"10"
is10
,+"10.5"
is10.5
,+"0x15"
is21
,+"0o10"
is8
[ES2015+]. Has a gotcha:+""
is0
, notNaN
as you might expect.Number(str)
- Exactly like implicit conversion (e.g., like the unary+
above), but slower on some implementations. (Not that it's likely to matter.)