Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将按位操作产生的32位JavaScript数字转换回64位数字_Javascript_Bit Manipulation - Fatal编程技术网

如何将按位操作产生的32位JavaScript数字转换回64位数字

如何将按位操作产生的32位JavaScript数字转换回64位数字,javascript,bit-manipulation,Javascript,Bit Manipulation,我试图理解JavaScript中的逐位操作是如何工作的,更具体地说,是如何将逐位操作产生的32位数字转换回64位JavaScript数字的。当设置32位数字中最左边的位以及操作溢出时,我得到了一些奇怪的结果 例如,使用以下操作: 0x01 << 31 0x02 << 32 数字将溢出,结果值应为0x00。但最终的JavaScript编号是0x02 是否有JavaScript用于位操作的特定规则我不知道?我知道所有逐位操作都是用32位整数执行的,JavaScript数字

我试图理解JavaScript中的逐位操作是如何工作的,更具体地说,是如何将逐位操作产生的32位数字转换回64位JavaScript数字的。当设置32位数字中最左边的位以及操作溢出时,我得到了一些奇怪的结果

例如,使用以下操作:

0x01 << 31
0x02 << 32
数字将溢出,结果值应为
0x00
。但最终的JavaScript编号是
0x02

是否有JavaScript用于位操作的特定规则我不知道?我知道所有逐位操作都是用32位整数执行的,JavaScript数字是64位双精度浮点数,但我不知道在这两者之间转换时额外的填充是从哪里来的

  • 按位运算符的结果是有符号int32,符号位在转换回数字时传播

  • 移位不能超过31位:


  • 也就是说,在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);