如何在 JS 中来回将 H3 ID 从十六进制转换为整数

How do I convert an H3 ID from hex to integer back and forth in JS

在 Javascript 时我会:

h3Int = parseInt("8B2A100D1D98FFF",16) //626740323050688500
h3Int.toString(16).toUpperCase() // 8B2A100D1D99000

所以似乎在两个方向上都没有得到相同的结果

有什么想法吗?

这与H3无关

JavaScript的常用数字类型是IEEE-754双精度浮点数。一个double住在一个64位的space内存中,把它分成一个符号位,11个指数位,52个有效位的小数;另一个有效位隐式可用。结果如果你去控制台,你可以看到:

> 2**53
9007199254740992
> 2**53 - 1
9007199254740991
> 2**53 + 1
9007199254740992

此时数字之间的差距已经扩大到最小尺寸为2;将该数字加 1 向下舍入。这最终就是为什么你的底部 11 位左右被四舍五入弄丢了。

一种更新的 BigInt 构造正在被添加到我们所说的语言中,但目前在 Edge、Safari 或 Internet Explorer 等旧浏览器中不存在——但如果您使用 Node.js 左右您也许可以可靠地使用它。它没有 JSON.parse 支持,即使它存在。但除此之外,它完全符合您的要求;在支持控制台中:

> x = 0x8B2A100D1D98FFFn
626740323050688511n
> x === BigInt('0x' + '8B2A100D1D98FFF')
true
> x.toString(16)
'8b2a100d1d98fff'

否则会有像 json-bigint 这样的库(假设您需要从 JSON 解析这些库,JSON.parse 而不是 工作,因为它会将所有数字解析为内置 number 类型),它使用名为 bignumber.js 的库来使用 JS 对象使用较小的数字表示较大的数字。

您可以在此处查看 h3-js 用于执行此转换的函数:https://github.com/uber/h3-js/blob/9a20295a2377f415ecc3ef6ad50410f948bfbeb2/lib/h3core.js#L84

正如@cr-drost 正确解释的那样,我们不能在 JS 中直接使用 64 位 int,因此我们将其分为高 32 位和低 32 位。这些可以可靠地与 32 位十六进制字符串相互转换。