In my program I generate the code from the incoming number "int". Sometimes I need to do the reverse action, translate the code into a number. With small numbers, it works fine.
const int = 10203040
const code1 = (int >> 16) & 0xFFFF
const code2 = int & 0xFFFF
const myCode = `${code1},${code2}` // 155,44960
const returnInt = ((code1 & 0xFFFF) << 16) + (code2 & 0xFFFF) // 10203040
Problems arise when working with large numbers. What to use to get the number 9007199254740991 again in the example below?
const int = 9007199254740991
const code1 = (int >> 16) & 0xFFFF
const code2 = int & 0xFFFF
const myCode = `${code1},${code2}` // 65535,65535
const returnInt = ((code1 & 0xFFFF) << 16) + (code2 & 0xFFFF) // -1
Tried to work with the library long.js, but failed, lack of knowledge
2
Answers
The problem here is that two 16-bit chunks are not enough to store a 53-bit number. In order to store a number as large as 9007199254740991, you would need at least three 16-bit chunks.
Using Long
Your code is splitting the input number into two 16-bit chunks (by masking it with
0xFFFF
, which has 16 bits set). In two 16-bit chunks, you can store a 32-bit (integer) number.9007199254740991
is a 53-bit number, so two 16-bit chunks are not enough to store it.Another issue is that the bitwise operators in JavaScript implicitly truncate their inputs to 32 bits. That’s the part where using BigInts helps — but you’ll still have to use more than two 16-bit chunks.
For example, you could use four 16-bit chunks, then you can store up to 64-bit numbers. That would look like this:
(You don’t need to mask the chunks again when computing
returnInt
.)