JavaScript大数位运算还原问题:如何恢复9007199254740991?
问题
我的程序能把数字编码成两段代码,小数字编码后可以正常还原,但处理大数9007199254740991时,还原结果变成了-1。尝试用long.js库但没经验,求正确实现还原的方法。
小数字处理正常示例
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
大数处理异常示例
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
解决方案
问题根源
JavaScript的位操作(<</>>)会把数字强制转换为32位有符号整数处理。65535 << 16会溢出变成-65536,加上65535后结果就是-1。而9007199254740991是JS能精确表示的最大整数(Number.MAX_SAFE_INTEGER),超出了32位范围,导致位操作失效。
方法1:用原生BigInt处理
无需额外库,直接用BigInt支持大数运算:
编码逻辑
const int = 9007199254740991n; // 加n标记为BigInt类型 const code1 = (int >> 16n) & 0xFFFFn; const code2 = int & 0xFFFFn; const myCode = `${code1},${code2}`; // 输出:65535,65535
还原逻辑
const [code1Str, code2Str] = myCode.split(','); const code1 = BigInt(code1Str); const code2 = BigInt(code2Str); const returnInt = ((code1 & 0xFFFFn) << 16n) + (code2 & 0xFFFFn); // 还原结果:9007199254740991n // 若需转回普通Number(确保数值在安全范围内): const safeReturnInt = Number(returnInt);
方法2:用long.js库实现
long.js专门处理64位整数,步骤如下:
安装依赖
npm install long
编码逻辑
const Long = require('long'); const int = 9007199254740991; const longInt = Long.fromNumber(int); const code1 = longInt.shiftRightUnsigned(16).and(Long.fromNumber(0xFFFF)).toNumber(); const code2 = longInt.and(Long.fromNumber(0xFFFF)).toNumber(); const myCode = `${code1},${code2}`; // 输出:65535,65535
还原逻辑
const [code1Str, code2Str] = myCode.split(','); const code1 = Long.fromNumber(parseInt(code1Str, 10)); const code2 = Long.fromNumber(parseInt(code2Str, 10)); const returnLong = code1.shiftLeft(16).or(code2); const returnInt = returnLong.toNumber(); // 还原结果:9007199254740991
内容的提问来源于stack exchange,提问作者smeninick
相关产品推荐
相关产品推荐

