I was debugging some strange errors in a date conversion function I was writing, and I stumbled upon something that amazed me... a strange bug in parseInt
Clearly for the strings '08' and '09' parseInt fails to return the right value. One workaround is easy, use parseFloat.
Why does this happen and where should I report this? I find it extremely odd that it happens in both Firefox and Internet Explorer 6 & 7; there must be some explanation right?
You can test it out for yourself using the FireBug javascript console), or by using one of these two links
alert(parseInt('07')+' == 7 ?')
alert(parseInt('08')+' == 8 ?')
Ok, Ok, so now that I explained how you would expect it to work (and clearly how I expected it to work) I'm going to answer my own question (yes I hate it when I do that too)
The problem is with how parseInt guesses the base of your number. Read the parseInt spec. Instead of always defaulting to base 10, it tries to guess, and if the first character is '0' it thinks you want to parse as an octal number, and if it starts with '0x' it thinks you want hexadecimal.
So, the solution is either to use parseFloat or to always specify your base.
Defaults that change on their own can't be trusted.
2 years, 10 months ago
It’s not broken. The parseInt function allways gueses if you don’t add the base/radix! That’s why I allways pass the base 10 to the function.
2 years, 10 months ago
I know it’s not “broken”, my point was that because it guesses instead of always defaulting to the same base, you can’t reliably use the default (which is exactly what you expect to be able to do)
I am also comparing it to python in my head thinking it would be ridiculous to assume that
int()would not convert'08'to an integer. If you want hex conversions you specify that explicitly.2 years, 10 months ago
for a second i looked quickly at your title and thought you were talking about parseltongue.
2 years, 9 months ago
use
parseInt('09',10)instead ; see the spec.It seems to work OK.
2 years, 9 months ago
@jv: did you read what i posted? clearly using
parseInt('09',10)is exactly what i said people need to do all the time! I was trying to make a strong case that the default functionality was poorly chosen, and causes the function to be broken.2 years, 8 months ago
Jehiah, I got what you were posted. Great stuff, I’ve never known about the unreliability of the supposed default, I’ll specify base10 from now on.
This is a very surprising feature of JavaScript – surprising in a very bad way. Everyone knows that base 10 numbers are often padded with 0’s. It makes me wonder what someone was thinking when they made this decision.
2 years, 8 months ago
[...] After randomly searching for this problem (how do you search for something when you don’t really know what to search for?), I stumbled on this blog entry that explained it all: [...]
2 years, 7 months ago
Wow! I can’t believe how much time I just wasted on this! Do the people who write specifications not understand what “default” means? It is not readily interchangeable with “arbitrary”.
2 years, 3 months ago
That was very helpful, I had no clue what was going on with my JS… thanks!
2 years, 2 months ago
It’s not broken. According to the ECMAScipt Specification (JavaScript is a version of ECMAScript), strings with leading 0’s may be interpreted, at the implementation’s discretion, as either octal or decimal, if a radix of 0 or undefined is specified. implementations are encouraged to interpret as decimal, but it is not required.
Being a programmer that is used to working with octal, decimal, and hexadecimal on a daily basis, I automatically interpret numbers with leading 0’s as octal and consider ‘08′, and ‘09′ to be invalid numbers unless I have a spec that tells me that decimals are left padded with 0’s.
2 years, 2 months ago
@Paul-Joseph, I am not saying you should not be able to do one or the other at will when converting strings to one form or another, what i am arguing is that the default that the parseInt function uses should not change based upon the input, because integer values left padded with ‘0’s are not invalid and so one should not expect those integer values to be converted differently based on the default base 10 setting.
2 years, 2 months ago
I was having the same problem and your article really saves my day…Thanks
2 years, 2 months ago
Another reason why I like opera.
2 years, 2 months ago
A simpler (but probably unsupported) fix is to pre-fix the input stng with a ‘+’ e.g. parseInt(“+08″)
Anyway here is a more interesting one. While trying to round numeric values to 2 decimal places I tried -
this.rawValue = (parseInt(this.rawValue * 100) / 100)
Probably not great code, I’m new to js, but it works UNTILL you input a value of EXACTLY 4.31
It then returns 4.30 !!!!
I have found no other number that does this – anyone got any ideas ?
2 years, 1 month ago
Just use Number. parseInt is a special-purpose function for parsing numbers from random strings, the fact that everyone is using it as a string->number conversion function is a historic accident. Number(“08″) is the recommended way to convert decimal numeric strings to numbers.
2 years, 1 month ago
@Reggie Good point about using
Numberto convert from string to int.parseInt()still has a few capabilities that I don’t see inNumberand you hinted at one of themNumberonly converts base 10 strings to numeric representationparseIntconverts any base string to numeric base 10 representationparseIntconverts to integer, dropping decimal values, Number does not. Sometimes that is desired.2 years, 1 month ago
I’d just like to leave this for those getting a total “hard-on” dropping their “I am so leet and you are an idiot” comments.
I develop in 13 (Yes, that’s a 1 and a 3) different languages. Some of them I know very well while others I know little. I (and I’m sure many other 16 hour day coders out there) simply don’t have the time to wade through thousands of lines of documentation when moving to a new language. We’re cowboys, we jump in and we start coding, we most likely never reach guru status unless the language becomes one of max 3 of our mosts used languages. So drop your holier than thou attitudes and support those who are kind enough to post findings like the OP did here. My 20k USD per month “all round coder” paycheck far outweighs your “guru” comments!
As for the OP, many thanks, I just hit this bug now and was wondering what was causing it, many thanks for you short description into the problem (read feature) too. Always helps to have an idea of what is causing the issue.
2 years, 1 month ago
Thanx for such kind of help.
2 years ago
Thanks for posting this. It’s helpful regardless of the reasoning behind it. I really don’t care why. I just need to get the code working!
1 year, 5 months ago
RTFM people. Paul-Joseph got it right. If the string begins with a zero, parseInt assumes it represents a number in octal. This is documented on the w3schools.com site, the first link when you Google ‘parseInt’.
1 year, 5 months ago
Thanks for your article. I got the answer to my problem, why ‘08′ or ‘09′ are not considered as integers in javascript.
1 year, 3 months ago
Good article, explained everything. Cheers!
1 year, 1 month ago
Thanks… I put the radix and now works fine….
1 year, 1 month ago
It does not mean that it’s “broken” just because it’s against YOUR interpretation of what should be default. The document clearly indicates the behavior and it also warns that it’s implementation dependent.
You can claim that it’s another annoying idiosyncrasy of JavaScript. But it’s not broken…
RTFM, my friend. RTFM.
1 year, 1 month ago
Hey, Anonymous, and everyone who says it’s not broken.
If you all go and “RTFM” as many of the defensors of the “not broken” say, you will actually see it IS BROKEN indeed.
I’ve blogged about it, with excerpts from the ECMA-262 standard, THE authoritative information source for JavaScript (who says w3schools.com is authoritative? who says it is reliable?).
Take a look: http://brunoreis.com/tech/old-javascript-implementation-bug-parsein/
Quoting someone: “RTFM, my friend. RTFM.” But RTFAM, read the ** AUTHORITATIVE manual :-)
Bruno
11 months, 1 week ago
I did RTFM and it is not broken, read 15.1.2.2 steps 11 & 12. They state:
So, setting the radix to 8 and interpretting the string as octal is perfectly valid.