ChakraCore icon indicating copy to clipboard operation
ChakraCore copied to clipboard

Add `JsNumberToInt64` function

Open kfarnung opened this issue 6 years ago • 11 comments

Allow the caller to get the integer value for a given number back as a 64-bit integer value.

kfarnung avatar Mar 14 '18 23:03 kfarnung

I had written this up when trying to fix a bug in node-chakracore, but ended up just using a static cast from double to int64_t instead. Looking to see if other people think this would be useful.

kfarnung avatar Mar 14 '18 23:03 kfarnung

Is this only guaranteed to be precise for 52 bit numbers?

MSLaguana avatar Mar 14 '18 23:03 MSLaguana

It's still subject to the significant bit limits of the IEEE754 double-precision numbers. In this case it's 53-bits of integer precision (technically 54 if you count the sign bit).

I can add that remark to the documentation if there's agreement that the function is useful.

kfarnung avatar Mar 14 '18 23:03 kfarnung

@MSLaguana I updated the comment to call out the precision caveat.

kfarnung avatar Mar 15 '18 00:03 kfarnung

@boingoing Can you take another look?

kfarnung avatar Mar 15 '18 02:03 kfarnung

Just saw this PR. Btw there's a new primitive BigInt proposal in TC39 (stage 3 already, pretty close to standardized), which allows representing int64 in JS. It would complicate things a bit if this API also takes BigInt.

liminzhu avatar May 15 '18 23:05 liminzhu

There are some open questions about how this API should handle numbers too large to represent even without considering BigInt. For Int32 we seem to just wrap back around, but for Int64 the default behavior is to return a number indicating the invalid state (some CPUs do this by returning 0x8000000000000000 and we appear to use that ourselves).

I suspect the same sort of issues will occur with BigInt, except that 0x8000000000000000 will be possible to represent exactly with a BitInt when it's not possible to do so using a double.

Any thoughts about what the API should do in cases where the number can't be represented in an Int64 value?

kfarnung avatar May 15 '18 23:05 kfarnung

for Int64 the default behavior is to return a number indicating the invalid state

It would be good to study some prior art. Can you point me to what language/platform use this as a default behavior? I was thinking more along the lines of returning a overflow error code, since you'd be getting that from .NET if you try to convert a bigint too large to int64.

I looked a bit more into BigInt and it looks like the proposal champion wants to set a clear boundary between BigInt and Number by having them as separate primitives and disallowing implicit conversions and ops mix-up, which is an approach I can agree with. This also makes me feel that if we were to expose BigInt natively, we want a different API, and b/c there is no builtin in C corresponding directly to bigint, we'll have to think about that later.

liminzhu avatar May 16 '18 21:05 liminzhu

hey, what is the final decision on this PR? I need to convert a Int64 in .net environment. thanks

alexgwolff avatar Apr 14 '19 21:04 alexgwolff

@kfarnung ??

alexgwolff avatar Apr 25 '19 11:04 alexgwolff

@alexgwolff technically you can just convert the number to a double and then cast to a 64-bit integer. Since JavaScript numbers are all IEEE754, that's essentially what this code does internally.

The problem was that we couldn't find agreement on how to represent invalid conversions, that behavior isn't defined by the standard and V8 seemed to use the value that the base conversion returns (0x8000000000000000), but that's basically an architecture-specific magic number.

kfarnung avatar Apr 25 '19 21:04 kfarnung