Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I've been a JavaScript developer for years and it's a surprise to me that there's a `Number.MAX_SAFE_INTEGER` and `Number.MIN_SAFE_INTEGER`.

It seems that I've never had the use case where I exceeded the maximum or minimum integer count. I figure there's a good amount of JavaScript developers that have the same experience.

But good article nonetheless.



Anyone who's used the Twitter API from Javascript has probably encountered the integer limit, because Tweet IDs are 64-bit values that often exceed MAX_SAFE_INTEGER.

Their JSON API works around that limitation by returning IDs as both "id" (a number that may not be representable in Javascript) and "id_str" (the same number in JS-friendly string form).


Wow, why would they ever send "id" as a number? Seems like a terrible idea when it doesn't fit in the medium's spec (JSON).


JSON spec doesn't restrict the range of numbers [0], though it does note that because different platforms that may use JSON have different limitations and IEEE 754 doubles are widely supported, valued that aren't representable as IEEE 754 doubles may have interoperability issues.

[0] https://tools.ietf.org/html/rfc8259#section-6


Sure, but why would you ever return an ID as a number? IDs are explicitly a data-type where arithmetic operations or other numeric transformations will not yield meaningful results.

String is the best choice in JSON but ultimately only somewhat less wrong (since string transformations won’t yield meaningful results for an ID either). That’s why GraphQL defines a discrete ID scalar.


I blame RDBMS-centric thinking. Things that look like numbers will perform well in an index, and we get free ID generation, so... why think about hard things, just throw it in there.

In terms of identity an ID is never a number, always a unique value. It should be its own type.


> though it does note that because different platforms that may use JSON hace different limitations and IEEE 754 doubles are widely supported, valued that aren't representable as IEEE 754 doubles may have interoperability issued

Does it note that in the spec? I can't find it.


Yes, in Section 6: “Since software that implements IEEE 754 binary64 (double precision) numbers [IEEE754] is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision. A JSON number such as 1E400 or 3.141592653589793238462643383279 may indicate potential interoperability problems, since it suggests that the software that created it expects receiving software to have greater capabilities for numeric magnitude and precision than is widely available.”


Just in general: your employee ID is likely a 'number', but it's not a number, it's a unique series of digits.... You don't add employee IDs. You don't multiply them by the current month. You don't group employees in ID based sets, find the ID modulus, and do things. They're not numbers, they are an alphanumeric series that should be unique.

And after seeing a hundred systems break when IDs started to overflow the 32 bit max, or struggle to handle a change to guids, or alphanumeric security codes, or a harmonization with another systems IDs, or freak out when their numbers get exposed through a URL and it turns out keeping leading-0 formatting has something to say: ... use a damned string.

"00123" and 123 are different. Just use a string.


Maybe for some other languages which implement JSON libraries (Python comes to mind) with greater than double floating point precision.


First Ajax app I worked on had the same problem and for similar reasons. We configured the JSON emitter to turn them into Strings, and back on inbound requests.


Send 64 bit numbers from the server and you’ll run into trouble sooner or later.

If the numbers are random (like IDs) you’ll hit it about every 1000th ID. Solution: IDs are strings not numbers.


I have run into the issue a few times. I've run into it most frequently when doing binary operations on 64bit numbers. When I first ran into the issue with going over `Number.MAX_SAFE_INTEGER`, it took me a long time to figure out that was the issue.

I can imagine this is an especially important advancement for server side JS. Not something I personally care about tho.


Badly needed for server side development


You may also be interested in learning about Number.EPSILON (the floating point epsilon) which is required when dealing with number equality...

For example, this is an incorrect way to compare numbers:

    > 0.1 + 0.2 === 0.3
    false
This is the proper way to compare numbers:

    a = 0.1 + 0.2
    b = 0.3
    > Math.abs(a - b) < Number.EPSILON
    true
This means the difference is smaller than the smallest quantity that can be represented in floating point number, and every JS number is a floating point number.

Not knowing about this can cause many issues if you deal with values representing currency.


Epsilon is not the smallest quantity that can be represented. Its the smallest amount that can be added to a number between 1 and 2. If its added to 2 the result is 2. We need to add 2 * Number.EPSILON to 2 to add anything. 4 * E to 4, 8 * E to 8, 16 * E to 16 etc.

That kind of equality test should be:

  abs( a-b ) < Number.EPSILON * max( abs(a), abs(b) )
In practice I judge the scale of the quantization noise that may accrue and compare the difference to it.

It may also be possible to kind of caste precision away by adding a trick value. eg.

  a + t == b + t
If a and b are positive, that is somewhat similar to:

  abs( a-b ) < Number.EPSILON * t


Thanks for pointing it out.

A more popular definition is "the smallest number that yields a result different to 1 when added to 1".


Look out - I just now tested those two extra ideas which I added for equality testing and found they dont work.

This version of adding a rounding value seems to though:

  ( a-b + rounder ) == rounder
My apologies, be careful out there :)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: