Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

64 bit integer #3666

Closed
sm2017 opened this issue Sep 20, 2017 · 6 comments
Closed

64 bit integer #3666

sm2017 opened this issue Sep 20, 2017 · 6 comments

Comments

@sm2017
Copy link

sm2017 commented Sep 20, 2017

According to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER

The Number.MAX_SAFE_INTEGER constant represents the maximum safe integer in JavaScript (2^53 - 1).

The MAX_SAFE_INTEGER constant has a value of 9007199254740991 (9,007,199,254,740,991 or ~9 quadrillion). 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 -(2^53 - 1) and 253 - 1.

So we have problem with 64 bit integers , When I want to open a uint64 field that is larger than (2^53 - 1) it is rounded to another number

unofficial protobuffer library , https://github.com/dcodeIO/ProtoBuf.js/ , uses https://github.com/dcodeIO/long.js and solved problem

Please use long.js for 64 bit integer

As of ECMA-262 5th Edition, "all the positive and negative integers whose magnitude is no greater than 2^53 are representable in the Number type", which is "representing the doubleprecision 64-bit format IEEE 754 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic". The maximum safe integer in JavaScript is 2^53-1.

Example: 2^64-1 is 18446744073709551615 but in JavaScript it evaluates to 18446744073709552000.

Furthermore, bitwise operators in JavaScript "deal only with integers in the range −2^31 through 2^31−1, inclusive, or in the range 0 through 2^32−1, inclusive. These operators accept any value of the Number type but first convert each such value to one of 2^32 integer values."

In some use cases, however, it is required to be able to reliably work with and perform bitwise operations on the full 64 bits. This is where long.js comes into play.

@amelhaoui
Copy link

it has been fixed in 3.4 : https://github.com/google/protobuf/releases
message dummy { uint64 bigInt = 1; [jstype = JS_STRING] }

@SimenB
Copy link

SimenB commented Dec 12, 2018

Any chance of using BigInt?

@jasonxia23
Copy link

Any chance of using BigInt?

Anyone on this?

@shawncao
Copy link

I understand adding [jstype = JS_STRING] is an option, however I concern about the performance when I pass millions of bigint through the field repeated int64 big_values. With this option, I guess we pay unnecessary serde of these values

  • client: it has to convert long[] to string[] to call the REST API (node.js)
  • server: it can get int64_t[] due to the proto declaration, but I guess protobuf pays cost to deserialize strings to int64

So the ideal case is, if protobuf can support bigint (long.js or native bigint if supported), then we can completely remove above conversions, and we don't pay the cost any more.

It will be great if this support can be added.

@jul-sh
Copy link

jul-sh commented Sep 9, 2020

it has been fixed in 3.4 : https://github.com/google/protobuf/releases
message dummy { uint64 bigInt = 1; [jstype = JS_STRING] }

I wouldn't personally consider this to be a fix. Imho the default unsafe conversion of 64 bit integers to JavaScript numbers is a problem. Merely giving developers the option to overwrite this (on an individual field basis) doesn't justify the unsafe default behavior of silently loosing precision. It is also inconsistent with protobuf's JSON mapping which converts these to strings.

@bennyscetbun
Copy link

We just get bitten by the same issue. Silently not converting a uint64 to its full precision is a real issue. Our server is in Golang and using 64bits integer is a basic thing. I understand the JS limitation but maybe we should consider using an open source uint64 library until it s part of the language (if it ever will)
Someone has suggested BigInt.
If you dont want to make BigInt the default for retro compatibility reason. Would you consider adding a new [jstype = JS_BIGINT ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants