2

I have an interesting question, I have been doing some work with javascript and a database ID came out as "3494793310847464221", now this is being entered into javascript as a number yet it is using the number as a different value, both when output to an alert and when being passed to another javascript function.

Here is some example code to show the error to its fullest.

<html><head><script language="javascript">alert( 3494793310847464221);
var rar =  3494793310847464221;
alert(rar);
</script></head></html>

This has completly baffeled me and for once google is not my friend...

btw the number is 179 more then the number there...

Jon 'links in bio' Ericson
  • 20,880
  • 12
  • 98
  • 148

9 Answers9

15

Your number is larger than the maximum allowed integer value in javascript (2^53). This has previously been covered by What is JavaScript's highest integer value that a Number can go to without losing precision?

Community
  • 1
  • 1
dave
  • 989
  • 5
  • 8
  • 3
    This is not really true; there are bigger integers that are "allowed" (as long as they can be represented as a 64-bit float). The relevant information here is that javascript numbers are floating point numbers, as mentioned in the post you link to, and not integers. – mweerden Apr 06 '09 at 17:04
12

In JavaScript, all numbers (even integral ones) are stored as IEEE-754 floating-point numbers. However, FPs have limited "precision" (see the Wikipedia article for more info), so your number isn't able to be represented exactly.

You will need to either store your number as a string or use some other "bignum" approach (unfortunately, I don't know of any JS bignum libraries off the top of my head).

Edit: After doing a little digging, it doesn't seem as if there's been a lot of work done in the way of JavaScript bignum libraries. In fact, the only bignum implementation of any kind that I was able to find is Edward Martin's JavaScript High Precision Calculator.

Ben Blank
  • 54,908
  • 28
  • 127
  • 156
  • I've been working on a JavaScript big integer library, because I couldn't find any existing JS libraries I liked. The code is at http://github.com/silentmatt/javascript-biginteger. – Matthew Crumley Apr 08 '09 at 19:35
4

Use a string instead.

Diodeus - James MacFarlane
  • 112,730
  • 33
  • 157
  • 176
3

179 more is one way to look at it. Another way is, after the first 16 digits, any further digit is 0. I don't know the details, but it looks like your variable only stores up to 16 digits.

Mike Robinson
  • 24,971
  • 8
  • 61
  • 83
2

That number exceeds (2^31)-1, and that's the problem; javascript uses 32-bit signed integers (meaning, a range from –2,147,483,648 to 2,147,483,647). Your best choice is to use strings, and create functions to manipulate the strings as numbers.

I wouldn't be all too surprised, if there already was a library that does what you need.

Henrik Paul
  • 66,919
  • 31
  • 85
  • 96
  • how does this match the statement that javascript numbers are 64bit floats? – xtofl Apr 07 '09 at 13:26
  • @xtofl: double precision floating point values can express the range of 32bit integers exactly; also, the bit-operators are defined using the integer representation of the number, so sometimes JS numbers behave like integers, but the intrinsic type is floating point – Christoph Apr 07 '09 at 14:14
2

One possible solution is to use a BigInt library such as: http://www.leemon.com/crypto/BigInt.html

This will allow you to store integers of arbitrary precision, but it will not be as fast as standard arithmetic.

alumb
  • 4,401
  • 8
  • 42
  • 52
1

"Can't increment and decrement a string easily..."

Really?

function incr_num(x) {
   var lastdigit=Number(x.charAt(x.length-1));
   if (lastdigit!=9) return (x.substring(0,x.length-1))+""+(lastdigit+1);
   if (x=="9") return "10";
   return incr_num(x.substring(0,x.length-1))+"0";
}

function decr_num(x) {
   if(x=="0") return "(error: cannot decrement zero)";
   var lastdigit=Number(x.charAt(x.length-1));
   if (lastdigit!=0) return (x.substring(0,x.length-1))+""+(lastdigit-1);
   if (x=="10") return "9"; // delete this line if you like leading zero
   return decr_num(x.substring(0,x.length-1))+"9";
}
Robert L
  • 1,963
  • 2
  • 13
  • 11
1

Since it's to big to be stored as int, it's converted to float. In JavaScript ther is no explicit integer and float types, there's only universal Number type.

vartec
  • 131,205
  • 36
  • 218
  • 244
0

Just guessing, but perhaps the number is stored as a floating type, and the difference might be because of some rounding error. If that is the case it might work correctly if you use another interpreter (browser, or whatever you are running it in)

Caotic
  • 954
  • 6
  • 4