No encoding support for 64 bit format integers
BurtHarris opened this issue · 5 comments
Looking at encode.js, it appears that there is no support for 64-bit integers. If encoding a large integer value (greater than 0xFFFFFFFF, the encoding logic does not use the option a 9-byte head.
This means, for example, that Number.MAX_SAFE_INTEGER (0x1FFFFFFFFFFFFF on 64-bit platforms) cannot be round-tripped.
These large numbers are encoded as double/float64, to match the representation used by JS. And I believe this is properly encoded as 64-bit and properly round-trips:
Number.MAX_SAFE_INTEGER -> 9007199254740991
let bytes = encode(Number.MAX_SAFE_INTEGER);
bytes.length -> 9;
decode(bytes) -> 9007199254740991
IDK is it related or not. But I faced next problem:
Here is a simple bin data (in hex): 1B00000184B336D838
it is unsigned(1669454026808)
Here is the result of decoding it in node:
d = new Uint8Array('1B00000184B336D838'.match(/../g).map(h=>parseInt(h,16)));
Uint8Array(9)
dd = decode(d)
1669454026808
The same code in browser produces:
d = new Uint8Array('1B00000184B336D838'.match(/../g).map(h=>parseInt(h,16)));
Uint8Array(9)
dd = decode(d)
1669454026808n
I can't understand why? Is it a bug? I tried to play with different options, like:
const cbrxOptions = {
useRecords: false,
int64AsNumber: true,
largeBigIntToFloat: true
};
But seems they all are not applied here.
@KSDaemon With your code, the numbers decode to bigints on node (by default), just like in the browser:
let d = new Uint8Array('1B00000184B336D838'.match(/../g).map(h=>parseInt(h,16)));
let dd = decode(d);
console.log(dd); // 1669454026808n
dd = new CBOR.Decoder({ int64AsNumber: true }).decode(d);
console.log(dd); // 1669454026808
Hm... Seems something goes wrong... Mb cache or smth else. Thnx! I'll recheck again!
My issue has been addressed - by design; I'm marking it closed. @KSDaemon if you think there is still a problem, you should probably create a new issue.
I misunderstood that it would be encoded as major type 7 (rather than major type 0).