代码之家  ›  专栏  ›  技术社区  ›  Toby Hede

Javascript中的位“与”具有64位整数

  •  26
  • Toby Hede  · 技术社区  · 15 年前

    JavaScript将其所有的双精度值转换成有符号的32位整数来执行逐位操作( details here ).

    4 回复  |  直到 15 年前
        1
  •  36
  •   Michael Gaskill Surya    9 年前

    Javascript将所有数字表示为64位 double precision IEEE 754 floating point numbers ECMAscript spec ,第8.5节)所有小于等于2^53的正整数都可以精确编码。较大的整数将其最低有效位截断。这就留下了一个问题:如何在Javascript中表示64位整数——本机数字数据类型显然不能精确地表示64位整数。

    出现 为了能够解析表示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>
    

    在Firefox、Chrome和IE中,我得到了以下信息。如果数字以64位格式存储,则所有减法的结果应该是1。相反,您可以看到2^53+1和2^53之间的差异是如何消失的。

    (2^50+1) - (2^50) = 1
    (2^51+1) - (2^51) = 1
    (2^52+1) - (2^52) = 1
    (2^53+1) - (2^53) = 0
    (2^54+1) - (2^54) = 0
    

    那你能做什么呢?

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

    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
    
        2
  •  14
  •   Andrey    8 年前

    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;
    }
    
        3
  •  8
  •   Gav G    6 年前

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

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt

        4
  •  6
  •   bounav geekonaut    9 年前

    1. 找到 long.js
    2. 将表示64位数字的字符串值转换为 Long
    3. 提取高32位和低32位值
    4. 按32位执行 在高处之间
    5. 从低到高
    6. 如果编号为>那么这两个数字之间就有相关性了

    注意 long.js

    // 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);
    

    控制台输出:

    2^3

    2^3 + 2^63

    0010000000000000000000000000000000000000000000000000000000001000

    2^3和(2^3 + 2^63)

    是的

        5
  •  4
  •   Jesse Hosain Ahmed    7 年前

    闭包库 goog.math.Long 以位为单位 add() 方法。

    推荐文章