JavaScript’s parseInt() at the extremes
Misuse of parseInt in JavaScript can lead to weird behavior if the number being parsed is large or small enough to be represented in E notation.
@adunkman look what I found today! years = parseInt(this.seconds / 31556926); can you guess what's wrong? :)
— Scott Smerchek (@smerchek) January 31, 2014
I received that tweet from an excoworker of mine this morning. Well, can you guess what’s wrong?
@smerchek @adunkman Is this javascript? That small a number is represented in 'e' notation. :/
— Make the World Dance (@dustyburwell) January 31, 2014
It has to do with how JavaScript represents extremely small and extremely large numbers: by using E notation.
35 / 31556926 = 0.0000011091067615394477
32 / 31556926 = 0.0000010140404676932093
31 / 31556926 = 9.823517030777965e7
Because parseInt()
is a function for converting strings to integers, it first converts the number to a string, and then an integer.
var number = 31 / 31556926;
> 9.823517030777965e7
var str = number.toString()
> "9.823517030777965e7"
parseInt(str);
> 9
So, how do we fix it? Well, stop using parseInt()
. We should be using Math.round()
here, which doesn’t convert the number to a string first.
Additionally, when using parseInt()
a radix should always be supplied as a second argument, becuase it doesn’t always assume you’re using base10. From MDN:

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 implementationdependent. ECMAScript 5 specifies that 10 (decimal) is used, but not all browsers support this yet. 
If the input
string
begins with any other value, the radix is 10 (decimal).
Just something to look out for!
@smerchek @adunkman The answer is "everything." Everything is wrong with that.
— David Poeschl (@dpoeschl) January 31, 2014