Search code examples
h3

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


When in Javascript I do:

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

So does not seem to get me the same result in both directions

Any idea?


Solution

  • This has nothing to do with H3.

    JavaScript’s usual number type is an IEEE-754 double-precision floating point number. A double lives in a 64-bit space in memory and divides it into a sign bit, 11 exponent bits, and 52 significant bits in a fraction; one further significant bit is available implicitly. As a result if you go to the console, you can see:

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

    The gaps between numbers at this point have expanded to the point where the minimum size is 2; adding 1 to that number rounds down. That is ultimately why your bottom 11 bits or so are getting trashed here by rounding.

    A much newer BigInt construct is being added to the language as we speak but does not exist at this time in Edge, Safari, or old browsers like Internet Explorer—but if you are using Node.js or so you might be able to use it reliably. It does not have JSON.parse support even where it exists. But other than that, it does exactly what you are trying to do; in a supporting console:

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

    Otherwise there are libraries like, say, json-bigint (assuming that you need to parse these from JSON, JSON.parse will not work as it will parse all numbers to the built-in number type) which uses a library called bignumber.js to use JS objects to represent larger numbers using smaller numbers.