16

I stumbled upon this issue with parseInt and I'm not sure why this is happening.

console.log(parseInt("16980884512690999"));   // gives 16980884512691000
console.log(parseInt("169808845126909101"));​  // gives 169808845126909100

I clearly not hitting any number limits in JavaScript limits (Number.MAX_VALUE = 1.7976931348623157e+308)

Running Win 7 64 bit if that matters.

What am I overlooking?

Fiddle

Mrchief
  • 75,126
  • 20
  • 142
  • 189

2 Answers2

16

Don't confuse Number.MAX_VALUE with maximum accurate value. All numbers in javascript are stored as 64 bit floating point, which means you can get high (and low) numbers, but they'll only be accurate to a certain point.

Double floating points (i.e. Javascript's) have 53 bits of significand precision, which means the highest/lowest "certainly accurate" integer in javascript is +/-9007199254740992 (2^53). Numbers above/below that may turn out to be accurate (the ones that simply add 0's on the end, because the exponent bits can be used to represent that).

Or, in the words of ECMAScript: "Note that all the positive and negative integers whose magnitude is no greater than 2^53 are representable in the Number type (indeed, the integer 0 has two representations, +0 and −0)."

Update

Just to add a bit to the existing question, the ECMAScript spec requires that if an integral Number has less than 22 digits, .toString() will output it in standard decimal notation (e.g. 169808845126909100000 as in your example). If it has 22 or more digits, it will be output in normalized scientific notation (e.g. 1698088451269091000000 - an additional 0 - is output as 1.698088451269091e+21).

JimmiTh
  • 7,389
  • 3
  • 34
  • 50
  • Both answers are right, however this one explains it in length and also explains what my seemingly abnormal output means. – Mrchief Feb 16 '12 at 03:26
12

From this answer

All numbers in Javascript are 64 bit "double" precision IEE754 floating point.

The largest positive whole number that can therefore be accurately represented is 2^53. The remaining bits are reserved for the exponent.

2^53 = 9007199254740992

Community
  • 1
  • 1
devio
  • 36,858
  • 7
  • 80
  • 143
  • 1
    Yes; also see http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html "What Every Computer Scientist Should Know About Floating-Point Arithmetic" – Doug Currie Feb 15 '12 at 16:57
  • So why do I get `169808845126909100` instead of some overflow error or something else? That is bigger than `9007199254740992` – Mrchief Feb 15 '12 at 16:58
  • 1
    See my answer. Because `1698088451269091` is below that number, and the 0's on the end are part of the exponent (i.e., it can be written as 1698088451269091 x 10^2). It doesn't overflow, because that's the way floating point arithmetic works. It doesn't care that you're looking for integers. – JimmiTh Feb 15 '12 at 17:00