如何将按位操作产生的32位JavaScript数字转换回64位数字
我试图理解JavaScript中的逐位操作是如何工作的,更具体地说,是如何将逐位操作产生的32位数字转换回64位JavaScript数字的。当设置32位数字中最左边的位以及操作溢出时,我得到了一些奇怪的结果 例如,使用以下操作:如何将按位操作产生的32位JavaScript数字转换回64位数字,javascript,bit-manipulation,Javascript,Bit Manipulation,我试图理解JavaScript中的逐位操作是如何工作的,更具体地说,是如何将逐位操作产生的32位数字转换回64位JavaScript数字的。当设置32位数字中最左边的位以及操作溢出时,我得到了一些奇怪的结果 例如,使用以下操作: 0x01 << 31 0x02 << 32 数字将溢出,结果值应为0x00。但最终的JavaScript编号是0x02 是否有JavaScript用于位操作的特定规则我不知道?我知道所有逐位操作都是用32位整数执行的,JavaScript数字
0x01 << 31
0x02 << 32
数字将溢出,结果值应为0x00
。但最终的JavaScript编号是0x02
是否有JavaScript用于位操作的特定规则我不知道?我知道所有逐位操作都是用32位整数执行的,JavaScript数字是64位双精度浮点数,但我不知道在这两者之间转换时额外的填充是从哪里来的
也就是说,在JavaScript中,所有数字都用53位表示。JavaScript使用浮点表示在内部存储所有数字,这意味着整数存储为浮点数字(尾数有53位)。这篇博文是关于这个主题的好文章 所以用53位,我们可以表示最大值2^53=9007199254740992 与C、C#等其他语言不同,在JavaScript中,不能使用右移和二进制操作从53位数字中提取低32位和高21位 原因是当我们对任何数字应用二进制运算符时——JavaScript首先将该数字转换为32位有符号数字,应用二进制运算并返回结果。这意味着位于高于32的位置的任何位都将被丢弃
我使用了下面的方法从正数中提取较高(21位)和较低(32位)部分,以下是规范的说明:。有很多更好的方法
var bigNumber = Math.pow(2, 53); // 9007199254740992
var bigNumberAsBinaryStr = bigNumber.toString(2); // '100000000000000000000000000000000000000000000000000000'
// Convert the above binary str to 64 bit (actually 52 bit will work) by padding zeros in the left
var bigNumberAsBinaryStr2 = '';
for (var i = 0; i < 64 - bigNumberAsBinaryStr.length; i++) {
bigNumberAsBinaryStr2 += '0';
};
bigNumberAsBinaryStr2 += bigNumberAsBinaryStr;
var lowInt = parseInt(bigNumberAsBinaryStr2.substring(0, 32), 2);
var highInt = parseInt(bigNumberAsBinaryStr2.substring(32), 2);
Assert((lowInt * Math.pow(2, 32) + highInt) === bigNumber);