在我的程序中,我根据传入的数字“int”生成代码。有时我需要做相反的动作,将代码翻译成数字。对于小数字,它工作正常。
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
处理大量数据时会出现问题。在下面的示例中使用什么来再次获取号码 9007199254740991?
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
尝试使用 long.js 库,但失败了,缺乏知识
您遇到的问题是由于JavaScript在处理大于2 ** 53 - 1或Number.MAX_SAFE_INTEGER的数字时受到限制,即9007199254740991。在执行按位运算时,JavaScript首先将操作数转换为32位有符号整数,从而导致较大数字的溢出和精度损失。
您可以使用 ECMAScript 2020 中引入的 BigInt 类型来处理大整数和按位运算。这是使用 BigInt 解决问题的示例:
const int = BigInt(9007199254740991);
const code1 = (int >> BigInt(16)) & BigInt(0xFFFF);
const code2 = int & BigInt(0xFFFF);
const myCode = `${code1},${code2}`; // 262143,65535
const returnInt = (BigInt(code1) << BigInt(16)) + BigInt(code2); // 9007199254740991
如果你更喜欢使用 long.js,你可以执行以下操作:
const Long = require('long');
const int = Long.fromString('9007199254740991');
const code1 = (int.shiftRightUnsigned(16)).and(0xFFFF);
const code2 = int.and(0xFFFF);
const myCode = `${code1},${code2}`; // 262143,65535
const returnInt = (code1.shiftLeft(16)).add(code2); // 9007199254740991