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.
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).
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.
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
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.
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.
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.
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.
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.