Marcos Bergamo
Marcos Bergamo

Reputation: 1123

Strange behavior using high number value in Javascript

Just some days ago, I start to write a wrapper to consume an Brazilian Service when I want to send the "product_code" as an number value, but the number is very high. The magic number is 5213372036854743040, this is a high value, but when I receive my first bug saying to me the product is now available for me, I open some support tickets, but the strange is the POSTMan works great, but in my app using Request I ever receive the error message.

Well, open the Node.js console and Chrome's console and put the number 5213372036854743040 the return value is just 5213372036854743000. My first thinking is "well, maybe this number is the max number value" but, the max integer in x64 is 9,223,372,036,854,775,807 and the Number.MAX_VALUE is 1.7976931348623157e+308.

If I sum the number with 100 the return is the same, but if I double the value this works. I think maybe when we got a number with more than 19 algarisms the v8 just round the value to end 000.

Someone here knows what or because this works with this behavior?

Upvotes: 2

Views: 464

Answers (2)

Trott
Trott

Reputation: 70183

Number.MAX_VALUE is the maximum value a floating point number can have. For consecutive integers, you want to check Number.MAX_SAFE_INTEGER.

Number.MAX_SAFE_INTEGER > 5213372036854743000; //false

Or perhaps more succinctly:

Number.isSafeInteger(5213372036854743000); //false

Note that both Number.MAX_SAFE_INTEGERand Number.isSafeInteger() are new in ES 2015 and may not be available in old versions of Node.

A good explanation about safe integers is in MDN docs for Number.MAX_SAFE_INTEGER:

The MAX_SAFE_INTEGER constant has a value of 9007199254740991. The reasoning behind that number is that JavaScript uses double-precision floating-point format numbers as specified in IEEE 754 and can only safely represent numbers between -(253 - 1) and 253 - 1.

Safe in this context refers to the ability to represent integers exactly and to correctly compare them. For example, Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 will evaluate to true, which is mathematically incorrect. See Number.isSafeInteger() for more information.

Because MAX_SAFE_INTEGER is a static property of Number, you always use it as Number.MAX_SAFE_INTEGER, rather than as a property of a Number object you created.

Since you are using Node.js, you may be able to get around this using an npm package like bignum.

Upvotes: 5

Jesse
Jesse

Reputation: 2848

This is how it works unfortunately.

See this article -> Double-precision floating-point format

The format is written with the significand having an implicit integer bit of value 1 (except for special datums, see the exponent encoding below). With the 52 bits of the fraction significand appearing in the memory format, the total precision is therefore 53 bits (approximately 16 decimal digits, 53 log10(2) ≈ 15.955). The bits are laid out as follows:

This means that you only have 16 digits to work with to precision. The remainder of the 64 bits are reserved for the exponent.

Example in chrome console ::

>9999999999999998

9999999999999998

>9999999999999999

10000000000000000

There are a few resources in dealing with large integers in Javascript. Here is one -> Long Numbers - Adding

Upvotes: 0

Related Questions