大数和按位运算的javascript问题

问题描述 投票:0回答:1

在我的程序中,我根据传入的数字“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 bitwise-operators biginteger bignum bitwise-and
1个回答
0
投票

您遇到的问题是由于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

© www.soinside.com 2019 - 2024. All rights reserved.