today I stumbled on a strange (in my opinion) case in JavaScript. I passed a non-hexadecimal string to the parseInt function with the base of 16 and...I got the result. I would expect the function to throw some kind of exception or at least return NaN, but it succeeded parsing it and returned an int.
My call was:
var parsed = parseInt('dsff66', 16); // note the 's' in the first argument document.write(parsed);
and the result was: 13
.
I noticed that it "stops" parsing with the first character that doesn't belong to the numeral system specified in the 2nd argument, so calling parseInt('fg',16)
I would get 15
as a result.
In my opinion, it should return NaN. Can anyone explain to me why it doesn't? Why would anyone want this function to behave like this (return an integer even if it isn't the precise representation of the string passed) ?
Description. The parseInt function converts its first argument to a string, parses that string, then returns an integer or NaN . If not NaN , the return value will be the integer that is the first argument taken as a number in the specified radix .
parseInt(int i) − This returns an integer, given a string representation of decimal, binary, octal, or hexadecimal (radix equals 10, 2, 8, or 16 respectively) numbers as input.
parseInt will only parse the leading part of the string that defines a whole number ("int" = "integer" = "whole number"), so it stops at the , . parseFloat will parse a decimal number, but only understands .
Returns. The parsed number, or NaN if s does not begin with a valid integer. In JavaScript 1.0, parseInt( ) returns 0 instead of NaN when it cannot parse s .
parseInt
reads input until it encounters an invalid character, and then uses whatever valid input it read prior to that invalid character. Consider:
parseInt("17days", 10);
This will use the input 17
and omit everything after the invalid d
.
From the ECMAScript specification:
If [input string] S contains any character that is not a radix-R digit, then let Z [the string to be integer-ified] be the substring of S consisting of all characters before the first such character; otherwise, let Z be S.
In your example, s
is an invalid base-16 character, so parseInt
uses only the leading d
.
As for why this behavior was included: there's no way to know for sure, but this is quite likely an attempt to reproduce the behavior of strtol
(string to long) from C's standard library. From the strtol(3)
man page:
...the string is converted to a long int value in the obvious manner, stopping at the first character which is not a valid digit in the given base.
This connection is further supported (to some degree) by the fact that both parseInt
and strtol
are specified to ignore leading whitespace, and they can both accept a leading 0x
for hexadecimal values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With