Why parseInt(x,0) is the same as parseInt(x, 10)? - javascript

Why is parseInt('60', 10) the same as parseInt('60', 0)?
What does JavaScript convert that 0 radix to?

From MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt)
If the radix is undefined, 0, or unspecified, JavaScript assumes the following:
If the input string begins with "0x" or "0X" (a zero followed by lowercase or uppercase X), radix is assumed to be 16 and the rest of the string is parsed as a hexidecimal number.
If the input string begins with "0" (a zero), radix is assumed to be 8 (octal) or 10 (decimal). Exactly which radix is chosen is implementation-dependent. ECMAScript 5 clarifies that 10 (decimal) should be used, but not all browsers support this yet. For this reason always specify a radix when using parseInt.
If the input string begins with any other value, the radix is 10 (decimal).
So the result depends on the browser if parsed input starts from '0'.

From the docs
If the radix is undefined, 0, or unspecified, JavaScript assumes the following:
If the input string begins with "0x" or "0X" (a zero followed by lowercase or uppercase X), radix is assumed to be 16 and the rest of the string is parsed as a hexidecimal number.
If the input string begins with "0" (a zero), radix is assumed to be 8 (octal) or 10 (decimal). Exactly which radix is chosen is implementation-dependent. ECMAScript 5 clarifies that 10 (decimal) should be used, but not all browsers support this yet. For this reason always specify a radix when using parseInt.
If the input string begins with any other value, the radix is 10 (decimal).
parseInt(string, radix);
string:
The value to parse. If this argument is not a string, then it is converted to one using the ToString abstract operation. Leading whitespace in this argument is ignored.
radix
An integer between 2 and 36 that represents the radix (the base in mathematical numeral systems) of the string. Be careful — this does not default to 10.

From the ECMAScript® 2018 Language Specification (ECMA-262, 9th edition, June 2018):
If radix is undefined or 0, it is assumed to be 10 except when the number begins with the code unit pairs 0x or 0X, in which case a radix of 16 is assumed. If radix is 16, the number may also optionally begin with the code unit pairs 0x or 0X.
Specifically steps 6, 8 and 9 say:
6 - Let R be ? ToInt32(radix).
8 - If R ≠ 0,...
9 - Else R = 0, Let R be 10.
So when radix == 0, it will always be replaced with 10, assuming a compliant browser.

As per the documentation, if radix is undefined or 0, it is assumed to be 10.
so,
parseInt('60', 10) = (0 * 10 ^ 0) + (6 * 10 ^ 1) = 60
and
parseInt('60', 0) = (0 * 10 ^ 0) + (6 * 10 ^ 1) = 60

Related

I am puzzled when i use parseInt from javascript [duplicate]

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
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 returns NaN.
parseInt(8, 3) means "parse "8" in base 3" (note that it converts the number 8 to a string; details in the spec). But in base 3, the single-digit numbers are just 0, 1, and 2. It's like asking it to parse "9" in octal. Since there were no valid characters, you got NaN.
parseInt(16, 3) is asking it to parse "16" in base 3. Since it can parse the 1, it does, and then it stops at the 6 because it can't parse it. So it returns 1.
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. So parseInt("10x") is 10; the x is ignored. Supports an optional radix (number base) argument, so parseInt("15", 16) is 21 (15 in hex). If there's no radix, assumes decimal unless the string starts with 0x (or 0X), in which case it skips those and assumes hex. (Some browsers used to treat strings starting with 0 as octal; that behavior was never specified, and was specifically disallowed in the ES5 specification.) Returns NaN if no parseable digits are found.
parseFloat(str) - Like parseInt, but does floating-point numbers and only supports decimal. Again extra characters on the string are ignored, so parseFloat("10.5x") is 10.5 (the x is ignored). As only decimal is supported, parseFloat("0x15") is 0 (because parsing ends at the x). Returns NaN 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 leading 0 as octal, but not in strict mode). +"10x" is NaN because the x is not ignored. +"10" is 10, +"10.5" is 10.5, +"0x15" is 21, +"0o10" is 8 [ES2015+]. Has a gotcha: +"" is 0, not NaN 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.)
For the same reason that
>> parseInt('1foobar',3)
<- 1
In the doc, parseInt takes a string. And
If string is not a string, then it is converted to a string
So 16, 8, or '1foobar' is first converted to string.
Then
If parseInt encounters a character that is not a numeral in the specified radix, it ignores it and all succeeding characters
Meaning it converts up to where it can. The 6, 8, and foobar are ignored, and only what is before is converted. If there is nothing, NaN is returned.
/***** Radix 3: Allowed numbers are [0,1,2] ********/
parseInt(4, 3); // NaN - We can't represent 4 using radix 3 [allowed - 0,1,2]
parseInt(3, 3); // NaN - We can't represent 3 using radix 3 [allowed - 0,1,2]
parseInt(2, 3); // 2 - yes we can !
parseInt(8, 3); // NaN - We can't represent 8 using radix 3 [allowed - 0,1,2]
parseInt(16, 3); // 1
//'16' => '1' (6 ignored because it not in [0,1,2])
/***** Radix 16: Allowed numbers/characters are [0-9,A-F] *****/
parseInt('FOX9', 16); // 15
//'FOX9' => 'F' => 15 (decimal value of 'F')
// all characters from 'O' to end will be ignored once it encounters the out of range'O'
// 'O' it is NOT in [0-9,A-F]
Some more examples:
parseInt('45', 13); // 57
// both 4 and 5 are allowed in Radix is 13 [0-9,A-C]
parseInt('1011', 2); // 11 (decimal NOT binary)
parseInt(7,8); // 7
// '7' => 7 in radix 8 [0 - 7]
parseInt(786,8); // 7
// '78' => '7' => 7 (8 & next any numbers are ignored bcos 8 is NOT in [0-7])
parseInt(76,8); // 62
// Both 7 & 6 are allowed '76' base 8 decimal conversion is 62 base 10

Why is it that parseInt(8,3) == NaN and parseInt(16,3) == 1?

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
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 returns NaN.
parseInt(8, 3) means "parse "8" in base 3" (note that it converts the number 8 to a string; details in the spec). But in base 3, the single-digit numbers are just 0, 1, and 2. It's like asking it to parse "9" in octal. Since there were no valid characters, you got NaN.
parseInt(16, 3) is asking it to parse "16" in base 3. Since it can parse the 1, it does, and then it stops at the 6 because it can't parse it. So it returns 1.
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. So parseInt("10x") is 10; the x is ignored. Supports an optional radix (number base) argument, so parseInt("15", 16) is 21 (15 in hex). If there's no radix, assumes decimal unless the string starts with 0x (or 0X), in which case it skips those and assumes hex. (Some browsers used to treat strings starting with 0 as octal; that behavior was never specified, and was specifically disallowed in the ES5 specification.) Returns NaN if no parseable digits are found.
parseFloat(str) - Like parseInt, but does floating-point numbers and only supports decimal. Again extra characters on the string are ignored, so parseFloat("10.5x") is 10.5 (the x is ignored). As only decimal is supported, parseFloat("0x15") is 0 (because parsing ends at the x). Returns NaN 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 leading 0 as octal, but not in strict mode). +"10x" is NaN because the x is not ignored. +"10" is 10, +"10.5" is 10.5, +"0x15" is 21, +"0o10" is 8 [ES2015+]. Has a gotcha: +"" is 0, not NaN 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.)
For the same reason that
>> parseInt('1foobar',3)
<- 1
In the doc, parseInt takes a string. And
If string is not a string, then it is converted to a string
So 16, 8, or '1foobar' is first converted to string.
Then
If parseInt encounters a character that is not a numeral in the specified radix, it ignores it and all succeeding characters
Meaning it converts up to where it can. The 6, 8, and foobar are ignored, and only what is before is converted. If there is nothing, NaN is returned.
/***** Radix 3: Allowed numbers are [0,1,2] ********/
parseInt(4, 3); // NaN - We can't represent 4 using radix 3 [allowed - 0,1,2]
parseInt(3, 3); // NaN - We can't represent 3 using radix 3 [allowed - 0,1,2]
parseInt(2, 3); // 2 - yes we can !
parseInt(8, 3); // NaN - We can't represent 8 using radix 3 [allowed - 0,1,2]
parseInt(16, 3); // 1
//'16' => '1' (6 ignored because it not in [0,1,2])
/***** Radix 16: Allowed numbers/characters are [0-9,A-F] *****/
parseInt('FOX9', 16); // 15
//'FOX9' => 'F' => 15 (decimal value of 'F')
// all characters from 'O' to end will be ignored once it encounters the out of range'O'
// 'O' it is NOT in [0-9,A-F]
Some more examples:
parseInt('45', 13); // 57
// both 4 and 5 are allowed in Radix is 13 [0-9,A-C]
parseInt('1011', 2); // 11 (decimal NOT binary)
parseInt(7,8); // 7
// '7' => 7 in radix 8 [0 - 7]
parseInt(786,8); // 7
// '78' => '7' => 7 (8 & next any numbers are ignored bcos 8 is NOT in [0-7])
parseInt(76,8); // 62
// Both 7 & 6 are allowed '76' base 8 decimal conversion is 62 base 10

Why won't parseInt work on a large number with leading 0's? [duplicate]

This question already has answers here:
How to parseInt a string with leading 0
(6 answers)
Closed 8 years ago.
avar = "0000013482000000";
t = parseInt(avar);
When I run that, t is 92 for some reason. If I remove the leading 0's, then it works just fine. Why would that be?
Try this:
avar = "0000013482000000";
t = parseInt(avar,10);
Some browsers might assume that it is an octal number if the string starts with 0.
However, ,10 is not required in modern browsers with new ECMAScript standards because they will always be considered as decimal unless specified or starts with 0x (hexadecimal).
Chrome is one of those browsers that has a default radix of 10.
Reference: ECMAScript Language Specification Page 104
The parseInt function produces an integer value dictated by interpretation of the contents of the string
argument according to the specified radix. Leading white space in string is ignored. If radix is undefined or 0,
it is assumed to be 10 except when the number begins with the character pairs 0x or 0X, in which case a radix
of 16 is assumed. If radix is 16, the number may also optionally begin with the character pairs 0x or 0X.
Use the second parameter (radix):
t = parseInt(avar, 10);
To specify that the number should be parsed in base 10.
From the MDN docs:
If radix is undefined or 0 (or absent), JavaScript assumes the following:
If the input string begins with "0x" or "0X", radix is 16 (hexadecimal) and the remainder of the string is parsed.
If the input string begins with "0", radix is eight (octal) or 10 (decimal). Exactly which radix is chosen is implementation-dependent. ECMAScript 5 specifies that 10 (decimal) is used, but not all browsers support this yet. For this reason always specify a radix when using parseInt.
If the input string begins with any other value, the radix is 10 (decimal).
And in reference to ECMAScript 5:
The parseInt function produces an integer value dictated by interpretation of the contents of the string argument according to the specified radix. Leading white space in string is ignored. If radix is undefined or 0, it is assumed to be 10 except when the number begins with the character pairs 0x or 0X, in which case a radix of 16 is assumed. If radix is 16, number may also optionally begin with the character pairs 0x or 0X.
Reference:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/parseInt
Parsing a number with leading zeros causes the number to be treated as octal. To override this you need to set the radix parameter of parseInt to 10 (base 10 as opposed to base 8).
parseInt assumes octal notation if you have a leading zero, so you want to pass in a radix as the second parameter, telling the function to parse the string as a base 10 int.
parseInt(avar, 10)
should fix it.

Behavior difference between parseInt() and parseFloat() [duplicate]

This question already has answers here:
Javascript parseInt() with leading zeros
(7 answers)
Closed 4 years ago.
Why is this behavior difference between parseInt() and parseFloat()?
I have a string that contains 08 in it.
When I write this code:
alert(hfrom[0]);
alert(parseInt(hfrom[0]));
alert(parseFloat(hfrom[0]));
The following output is generated:
08
0
8
Why does parseInt and parseFloat return two different results in this case?
parseInt() assumes the base of your number according to the first characters in the string. If it begins with 0x it assumes base 16 (hexadecimal). Otherwise, if it begins with 0 it assumes base 8 (octal). Otherwise it assumes base 10.
You can specify the base as a second argument:
alert(parseInt(hfrom[0], 10)); // 8
From MDN (linked above):
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).
you should always include the radix param with parseInt() ex parseInt('013', 10) otherwise it can convert it to a different numeric base:
parseInt('013') === 11
parseInt('013', 10) === 13
parseInt('0x13') === 19

parseInt(null, 24) === 23... wait, what?

Alright, so I was messing around with parseInt to see how it handles values not yet initialized and I stumbled upon this gem. The below happens for any radix 24 or above.
parseInt(null, 24) === 23 // evaluates to true
I tested it in IE, Chrome and Firefox and they all alert true, so I'm thinking it must be in the specification somewhere. A quick Google search didn't give me any results so here I am, hoping someone can explain.
I remember listening to a Crockford speech where he was saying typeof null === "object" because of an oversight causing Object and Null to have a near identical type identifier in memory or something along those lines, but I can't find that video now.
Try it: http://jsfiddle.net/robert/txjwP/
Edit Correction: a higher radix returns different results, 32 returns 785077
Edit 2 From zzzzBov: [24...30]:23, 31:714695, 32:785077, 33:859935, 34:939407, 35:1023631, 36:1112745
tl;dr
Explain why parseInt(null, 24) === 23 is a true statement.
It's converting null to the string "null" and trying to convert it. For radixes 0 through 23, there are no numerals it can convert, so it returns NaN. At 24, "n", the 14th letter, is added to the numeral system. At 31, "u", the 21st letter, is added and the entire string can be decoded. At 37 on there is no longer any valid numeral set that can be generated and NaN is returned.
js> parseInt(null, 36)
1112745
>>> reduce(lambda x, y: x * 36 + y, [(string.digits + string.lowercase).index(x) for x in 'null'])
1112745
Mozilla tells us:
function parseInt converts its first
argument to a string, parses it, and
returns an integer or NaN. If not NaN,
the returned value will be the decimal
integer representation of the first
argument taken as a number in the
specified radix (base). For example, a
radix of 10 indicates to convert from
a decimal number, 8 octal, 16
hexadecimal, and so on. For radices
above 10, the letters of the alphabet
indicate numerals greater than 9. For
example, for hexadecimal numbers (base
16), A through F are used.
In the spec, 15.1.2.2/1 tells us that the conversion to string is performed using the built-in ToString, which (as per 9.8) yields "null" (not to be confused with toString, which would yield "[object Window]"!).
So, let's consider parseInt("null", 24).
Of course, this isn't a base-24 numeric string in entirety, but "n" is: it's decimal 23.
Now, parsing stops after the decimal 23 is pulled out, because "u" isn't found in the base-24 system:
If S contains any character that is
not a radix-R digit, then let Z be the
substring of S consisting of all
characters before the first such
character; otherwise, let Z be S. [15.1.2.2/11]
(And this is why parseInt(null, 23) (and lower radices) gives you NaN rather than 23: "n" is not in the base-23 system.)
Ignacio Vazquez-Abrams is correct, but lets see exactly how it works...
From 15.1.2.2 parseInt (string , radix):
When the parseInt function is called,
the following steps are taken:
Let inputString be ToString(string).
Let S be a newly created substring of inputString consisting of the first
character that is not a
StrWhiteSpaceChar and all characters
following that character. (In other
words, remove leading white space.)
Let sign be 1.
If S is not empty and the first character of S is a minus sign -, let
sign be −1.
If S is not empty and the first character of S is a plus sign + or a
minus sign -, then remove the first
character from S.
Let R = ToInt32(radix).
Let stripPrefix be true.
If R ≠ 0, then a. If R < 2 or R > 36, then return NaN. b. If R ≠ 16, let
stripPrefix be false.
Else, R = 0 a. Let R = 10.
If stripPrefix is true, then a. If the length of S is at least 2 and the
first two characters of S are either
“0x” or “0X”, then remove the first
two characters from S and let R = 16.
If S contains any character that is not a radix-R digit, then let Z be the
substring of S consisting of all
characters before the first such
character; otherwise, let Z be S.
If Z is empty, return NaN.
Let mathInt be the mathematical integer value that is represented by Z
in radix-R notation, using the letters
A-Z and a-z for digits with values 10
through 35. (However, if R is 10 and Z
contains more than 20 significant
digits, every significant digit after
the 20th may be replaced by a 0 digit,
at the option of the implementation;
and if R is not 2, 4, 8, 10, 16, or
32, then mathInt may be an
implementation-dependent approximation
to the mathematical integer value that
is represented by Z in radix-R
notation.)
Let number be the Number value for mathInt.
Return sign × number.
NOTE parseInt may interpret only a
leading portion of string as an
integer value; it ignores any
characters that cannot be interpreted
as part of the notation of an integer,
and no indication is given that any
such characters were ignored.
There are two important parts here. I bolded both of them. So first of all, we have to find out what the toString representation of null is. We need to look at Table 13 — ToString Conversions in section 9.8.0 for that information:
Great, so now we know that doing toString(null) internally yields a 'null' string. Great, but how exactly does it handle digits (characters) that aren't valid within the radix provided?
We look above to 15.1.2.2 and we see the following remark:
If S contains any character that is
not a radix-R digit, then let Z be the
substring of S consisting of all
characters before the first such
character; otherwise, let Z be S.
That means that we handle all digits PRIOR to the specified radix and ignore everything else.
Basically, doing parseInt(null, 23) is the same thing as parseInt('null', 23). The u causes the two l's to be ignored (even though they ARE part of the radix 23). Therefore, we only can only parse n, making the entire statement synonymous to parseInt('n', 23). :)
Either way, great question!
parseInt( null, 24 ) === 23
Is equivalent to
parseInt( String(null), 24 ) === 23
which is equivalent to
parseInt( "null", 24 ) === 23
The digits for base 24 are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, ..., n.
The language spec says
If S contains any character that is not a radix-R digit, then let Z be the substring of S consisting of all characters before the first such character; otherwise, let Z be S.
which is the part that ensures that C-style integer literals like 15L parse properly,
so the above is equivalent to
parseInt( "n", 24 ) === 23
"n" is the 23-rd letter of the digit list above.
Q.E.D.
I guess null gets converted to a string "null". So n is actually 23 in 'base24' (same in 'base25'+), u is invalid in 'base24' so the rest of the string null will be ignored. That's why it outputs 23 until u will become valid in 'base31'.
parseInt uses alphanumeric representation, then in base-24 "n" is valid, but "u" is invalid character, then parseInt only parses the value "n"....
parseInt("n",24) -> 23
as an example, try with this:
alert(parseInt("3x", 24))
The result will be "3".

Categories

Resources