63

I have seen one of the weirdest things in javascript. The server side (spring):

   @RequestMapping(value = "/foo", method = RequestMethod.GET)
   @ResponseBody
   public Long foo() {
      return 793548328091516928L;
   }

I return a single long value and:

$.get('/foo').done(function(data){
    console.log(data);
});

It represents the long integer as "793548328091516900" replacing (rounding indeed) the last two digits with 0s. When i make that GET request from any browser's address bar, the number represented correctly; thus this is a js issue, in my opinion.

Returning a string instead of long from server and handling it with:

var x = new Number(data).toFixed();

obviously a solution. But I am not so lucky that, I have to handle a complex POJO (converted to JSON) whose some fields (some are nested) are typed with java.lang.Long type. If i try to cast this POJO to another object does not having fields typed Long, it is obviously cumbersome.

Is there any solution to that obstacle in a clearer way?

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
px5x2
  • 1,495
  • 2
  • 14
  • 29
  • It's worth noting that the latest draft of the ECMAScript specification (https://tc39.es/ecma262/#sec-bigint-objects) now has a BigInt type (although browser support is shaky). But, JSON does not yet support BigInts. So the real issue now is in serialization/deserialization, not in JavaScript Itself. – Sydney Jan 28 '20 at 20:24

3 Answers3

100

In Java, you have 64 bits integers, and that's what you're using.

In JavaScript, all numbers are 64 bits floating point numbers. This means you can't represent in JavaScript all the Java longs. The size of the mantissa is about 53 bits, which means that your number, 793548328091516928, can't be exactly represented as a JavaScript number.

If you really need to deal with such numbers, you have to represent them in another way. This could be a string, or a specific representation like a digit array. Some "big numbers" libraries are available in JavaScript.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • 7
    @px5x2 no "javascript number" based solution. The best solution to your problem would depend on the exact requirements. If you just want to display them, send them as strings. – Denys Séguret Jun 26 '13 at 13:04
  • @dystroy: bad idea because of time zones – R.Moeller Jul 20 '14 at 01:34
  • 5
    @R.Moeller Time Zones ? Are you sure you comment the right answer ? – Denys Séguret Jul 20 '14 at 06:38
  • @dystroy if you render Time/Dates at server side (as you proposed), they'll be in the timezone of the server, except your js client sends the its time zone to the server upon log-on and the server renders time/data different depending on client's location – R.Moeller Jul 21 '14 at 17:56
  • @R.Moeller Where in this question or answer did you see a time or a date ? – Denys Séguret Jul 21 '14 at 18:44
  • 2
    @dystroy you are right, as this problem usually arises with long timestamps/dates I implicitely put it into the question myself :-) – R.Moeller Jul 23 '14 at 17:14
  • 3
    Just discovered this fact myself... This is just crazy how badly designed Javascript is. The facepalm is neverending. – Guillaume F. Jun 08 '17 at 14:29
  • Why you can't combine two ints into a long and do the maths for them? Or four bytes array? – Andrey Chaschev Sep 30 '18 at 03:38
  • what is the maximum limit ? – Yash Sharma Nov 15 '19 at 17:37
  • 2020 addendum: the `Number` type is for 64 bit IEEE floating point numbers, which included integers up to 2**53-1 (using the standard numerical primitive form, e.g. `1`, `3.4`, etc.), but that's not the only numerical type available. There is also the `BigInt` type for arbitrary length true integers (using the "n" suffix primitive form, e.g. `123n`, `100000000000000000000n`, etc.) – Mike 'Pomax' Kamermans Oct 20 '20 at 05:15
11

May be late, but definitely helps others who run this situation first time.

I too wanted some calculation on large numbers in JavaScript. There are lot of libraries available to deal with such numbers. But most of them may waste lot of your time. Here, https://github.com/peterolson/BigInteger.js, is a direct, complete(for non node environment and node JS environments), and working solution for all operations on large numbers available. or find the following simple and sample working HTML code snippet which calculates modulo/remainder,

<script src="http://peterolson.github.com/BigInteger.js/BigInteger.min.js"></script>
<script type="text/javascript">
    function modTest(){
       var rem = bigInt("1738141852226360940").mod("32").valueOf();
       console.log(rem);
       document.getElementById("remainder").innerHTML = rem;
    }
</script>

<BODY onload="modTest();">
    <p id="remainder"></p>
</BODY>
sreejagaths
  • 469
  • 5
  • 9
4

You can use long npm package.

It let you have 64 bits integers in JavaScript.

You can also use BigInt JavaScript built-in method.

MajidJafari
  • 1,076
  • 11
  • 15