web-dev-qa-db-ja.com

64ビット整数のJavascriptでのビット単位のAND

JavaScriptで64ビット整数に対してビット単位のANDを実行する方法を探しています。

JavaScriptは、すべてのdouble値を符号付き32ビット整数にキャストして、ビット単位の演算を実行します( 詳細はこちら )。

32
Toby Hede

Javascriptは、すべての数値を64ビットとして表します 倍精度IEEE 754浮動小数点数ECMAscript仕様 、セクション8.5を参照してください。)2 ^ 53までのすべての正の整数をエンコードできます。正確に。整数が大きいほど、最下位ビットがクリップされます。これにより、Javascriptで64ビット整数をどのように表現できるかという疑問が残ります。ネイティブの数値データ型では、64ビット整数を正確に表現できないことは明らかです。

以下にこれを示します。 javascriptは64ビットの数値を表す16進数を解析できるように見えますが、基になる数値表現は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ビット整数を2つの32ビット数値として表すことを選択した場合、ビット単位のANDを適用するのは、下位および上位の32ビットの「ワード」に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
31
Oren Trutner

ANDint64数値のコードは次のとおりです。ANDを他のビット演算に置き換えることができます

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;
}
10
Andrey

Javascriptは、そのままでは64ビット整数をサポートしていません。これは私がやったことです:

  1. 見つかった long.js 、githubでの自己完結型のLong実装。
  2. 64ビットの数値を表す文字列値をLongに変換します。
  3. 上位32ビット値と下位32ビット値を抽出します
  4. 上位下位ビットの間でビット単位およびを32ビット実行します別々に
  5. 下位ビットと上位ビットから新しい64ビットLongを初期化します
  6. 数値が> 0の場合、2つの数値の間に相関関係があります

:以下のコード例を機能させるには、 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

0000000000000000000000000000000000000000000000000000000000001000

2 ^ 3 + 2 ^ 63

0010000000000000000000000000000000000000000000000000000000001000

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

0000000000000000000000000000000000000000000000000000000000001000

Val1とval2の間の相関?

true

7
bounav

クロージャーライブラリには _goog.math.Long_ ビット単位のadd()メソッドがあります。

4
Janus Troelsen

これは、新しいBigInt組み込み数値型を使用して実行できるようになりました。 BigIntは現在(2019年7月)特定のブラウザでのみ利用可能です。詳細については、次のリンクを参照してください。

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

Chrome 67でBigIntsを使用してビット演算をテストし、最大64ビット値で期待どおりに機能することを確認できます。

1
Gav G