Javascript中的按位AND和64位整数

Javascript中的按位AND和64位整数,javascript,64-bit,integer,bit-manipulation,Javascript,64 Bit,Integer,Bit Manipulation,我正在寻找一种在JavaScript中对64位整数执行按位AND的方法 JavaScript将其所有双精度值转换为有符号的32位整数,以执行逐位运算()。JavaScript将所有数字表示为64位(请参阅,第8.5节)。所有最大为2^53的正整数都可以精确编码。较大的整数得到其最低有效位的剪裁。这就留下了一个问题:如何在Javascript中表示64位整数——本机数字数据类型显然不能精确地表示64位整数 下面说明了这一点。尽管javascript似乎能够解析表示64位数字的十六进制数字,但底层数

我正在寻找一种在JavaScript中对64位整数执行按位AND的方法


JavaScript将其所有双精度值转换为有符号的32位整数,以执行逐位运算()。

JavaScript将所有数字表示为64位(请参阅,第8.5节)。所有最大为2^53的正整数都可以精确编码。较大的整数得到其最低有效位的剪裁。这就留下了一个问题:如何在Javascript中表示64位整数——本机数字数据类型显然不能精确地表示64位整数

下面说明了这一点。尽管javascript似乎能够解析表示64位数字的十六进制数字,但底层数字表示并不包含64位。在浏览器中尝试以下操作:

<html>
  <head>
    <script language="javascript">
      function showPrecisionLimits() {
        document.getElementById("r50").innerHTML = 0x0004000000000001 - 0x0004000000000000;
        document.getElementById("r51").innerHTML = 0x0008000000000001 - 0x0008000000000000;
        document.getElementById("r52").innerHTML = 0x0010000000000001 - 0x0010000000000000;
        document.getElementById("r53").innerHTML = 0x0020000000000001 - 0x0020000000000000;
        document.getElementById("r54").innerHTML = 0x0040000000000001 - 0x0040000000000000;
      }
    </script>
  </head>
  <body onload="showPrecisionLimits()">
    <p>(2^50+1) - (2^50) = <span id="r50"></span></p>
    <p>(2^51+1) - (2^51) = <span id="r51"></span></p>
    <p>(2^52+1) - (2^52) = <span id="r52"></span></p>
    <p>(2^53+1) - (2^53) = <span id="r53"></span></p>
    <p>(2^54+1) - (2^54) = <span id="r54"></span></p>
  </body>
</html>

那你能做什么呢

如果您选择将64位整数表示为两个32位数字,则对低32位和高32位“字”应用按位AND与应用2位AND一样简单

例如:

var a = [ 0x0000ffff, 0xffff0000 ];
var b = [ 0x00ffff00, 0x00ffff00 ];
var c = [ a[0] & b[0], a[1] & b[1] ];

document.body.innerHTML = c[0].toString(16) + ":" + c[1].toString(16);
让你:

ff00:ff0000

闭包库具有按位
add()
方法。

Javascript不支持开箱即用的64位整数。这就是我最后做的:

  • 在github上找到了一个自包含的长实现
  • 将表示64位数字的字符串值转换为
  • 提取高和低32位值
  • 分别在高位<强>和低位<强>之间执行32位按位and运算
  • 从低位和高位初始化新的64位
    Long
  • 如果数值大于0,则两个数值之间存在相关性
  • 注意:对于下面的代码示例,您需要加载

    控制台输出:

    2^3

    0000000000000000000000000000000000000000000000000000000000000000001000

    2^3+2^63

    0010000000000000000000000000000000000000000000000000000000000000001000

    2^3&(2^3+2^63)

    0000000000000000000000000000000000000000000000000000000000000000001000

    val1和val2之间的相关性

    真的


    这是和int64数字的代码,您可以用其他位操作替换和

    function and(v1, v2) {
        var hi = 0x80000000;
        var low = 0x7fffffff;
        var hi1 = ~~(v1 / hi);
        var hi2 = ~~(v2 / hi);
        var low1 = v1 & low;
        var low2 = v2 & low;
        var h = hi1 & hi2;
        var l = low1 & low2;
        return h*hi + l;
    }
    

    现在可以使用新的BigInt内置数字类型来完成此操作。BigInt目前(2019年7月)仅在某些浏览器中可用,有关详细信息,请参阅以下链接:


    我已经在Chrome67中使用bigint测试了按位操作,并且可以确认它们在高达64位的值下可以按预期工作

    谢谢。在本例中,我实际上是在读取一个包含64位值的二进制字符串。所以我可以将其转换成两个32位的数字,并使用我自己的内部表示来管理这些数据;你说的二进制字符串是什么意思?如果这是一个字符序列,每个字符相当于一个8位字节,则可以执行以下操作:var a=[s.charCodeAt(0)+(s.charCodeAt(1)@Orent Trutner:这里要小心:使用Unicode时,字符代码可能超过255。我认为一旦其中一个字节设置为高位,您的代码就会失败。确实如此。到目前为止,我仍然不清楚OP的64位数字最初是如何表示的。“一个二进制字符串”,如第一条注释中所示,可能表示8位字符、16位字符,甚至是64个“0”和“1”字符的字符串。如果将javascript与WinRT一起使用,下面是一些详细信息:Windows运行时Int64是有符号的64位整数,如果在[-2^53,2^53]范围内,则表示为标准数字.Hooking注意,要使用另一个按位操作,您可以替换
    h
    l
    表达式中的
    &
    。这很好,左/右移位如何?@vanowm示例:10>3可以编写Math.floor(10/(2**3))
    // Handy to output leading zeros to make it easier to compare the bits when outputting to the console
    function zeroPad(num, places){
        var zero = places - num.length + 1;
      return Array(+(zero > 0 && zero)).join('0') + num;
    }
    
    // 2^3 = 8
    var val1 = Long.fromString('8', 10);
    var val1High = val1.getHighBitsUnsigned();
    var val1Low = val1.getLowBitsUnsigned();
    
    // 2^61 = 2305843009213693960
    var val2 = Long.fromString('2305843009213693960', 10);
    var val2High = val2.getHighBitsUnsigned();
    var val2Low = val2.getLowBitsUnsigned();
    
    console.log('2^3 & (2^3 + 2^63)')
    console.log(zeroPad(val1.toString(2), 64));
    console.log(zeroPad(val2.toString(2), 64));
    
    var bitwiseAndResult = Long.fromBits(val1Low & val2Low, val1High & val2High, true);
    
    console.log(bitwiseAndResult);
    console.log(zeroPad(bitwiseAndResult.toString(2), 64));
    console.log('Correlation betwen val1 and val2 ?');
    console.log(bitwiseAndResult > 0);
    
    function and(v1, v2) {
        var hi = 0x80000000;
        var low = 0x7fffffff;
        var hi1 = ~~(v1 / hi);
        var hi2 = ~~(v2 / hi);
        var low1 = v1 & low;
        var low2 = v2 & low;
        var h = hi1 & hi2;
        var l = low1 & low2;
        return h*hi + l;
    }