Javascript 中的按位 AND 与 64 位整数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2983206/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
bitwise AND in Javascript with a 64 bit integer
提问by Toby Hede
I am looking for a way of performing a bitwise AND on a 64 bit integer in JavaScript.
我正在寻找一种在 JavaScript 中对 64 位整数执行按位 AND 的方法。
JavaScript will cast all of its double values into signed 32-bit integers to do the bitwise operations (details here).
JavaScript 会将其所有双精度值转换为有符号的 32 位整数以执行按位运算(详情请点击此处)。
回答by Oren Trutner
Javascript represents all numbers as 64-bit double precision IEEE 754 floating point numbers(see the ECMAscript spec, section 8.5.) All positive integers up to 2^53 can be encoded precisely. Larger integers get their least significant bits clipped. This leaves the question of how can you even represent a 64-bit integer in Javascript -- the native number data type clearly can't precisely represent a 64-bit int.
Javascript 将所有数字表示为 64 位双精度 IEEE 754 浮点数(请参阅ECMAscript 规范,第 8.5 节。)所有高达 2^53 的正整数都可以精确编码。较大的整数会剪掉它们的最低有效位。这留下了一个问题,即如何在 Javascript 中表示 64 位整数——本机数字数据类型显然无法精确表示 64 位整数。
The following illustrates this. Although javascript appearsto be able to parse hexadecimal numbers representing 64-bit numbers, the underlying numeric representation does not hold 64 bits. Try the following in your browser:
下面说明了这一点。尽管 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>
In Firefox, Chrome and IE I'm getting the following. If numbers were stored in their full 64-bit glory, the result should have been 1 for all the substractions. Instead, you can see how the difference between 2^53+1 and 2^53 is lost.
在 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
So what can you do?
所以,你可以做什么?
If you choose to represent a 64-bit integer as two 32-bit numbers, then applying a bitwise AND is as simple as applying 2 bitwise AND's, to the low and high 32-bit 'words'.
如果您选择将 64 位整数表示为两个 32 位数字,那么应用按位 AND 就像将 2 个按位 AND 应用于低位和高位 32 位“字”一样简单。
For example:
例如:
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);
gets you:
让你:
ff00:ff0000
回答by Andrey
Here is code for AND int64 numbers, you can replace AND with other bitwise operation
这是AND int64数字的代码,您可以用其他按位运算替换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;
}
回答by bounav
Javascript doesn't support 64 bit integers out of the box. This is what I ended up doing:
Javascript 不支持开箱即用的 64 位整数。这就是我最终做的:
- Found long.js, a self contained Long implementation on github.
- Convert the string value representing the 64 bit number to a
Long. - Extract the high and low 32 bit values
- Do a 32 bit bitwise andbetween the high andlow bits, separately
- Initialise a new 64 bit
Longfrom the low and high bit - If the number is > 0 then there is correlation between the two numbers
- 在 github 上找到了long.js,一个自包含的 Long 实现。
- 将表示 64 位数字的字符串值转换为
Long. - 提取高低 32 位值
- 做32位按位和高之间和低位,分别
Long从低位和高位初始化一个新的64位- 如果数字 > 0,则两个数字之间存在相关性
Note: for the code example below to work you need to load long.js.
注:下面工作的代码示例,你需要负载 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);
Console output:
控制台输出:
2^3
0000000000000000000000000000000000000000000000000000000000001000
2^3 + 2^63
0010000000000000000000000000000000000000000000000000000000001000
2^3 & (2^3 + 2^63)
0000000000000000000000000000000000000000000000000000000000001000
Correlation between val1 and val2?
true
2^3
00000000000000000000000000000000000000000000000000000000001000
2^3 + 2^63
00100000000000000000000000000000000000000000000000000000001000
2^3 & (2^3 + 2^63)
00000000000000000000000000000000000000000000000000000000001000
val1 和 val2 之间的相关性?
真的
回答by Gav G
This can now be done with the new BigInt built-in numeric type. BigInt is currently (July 2019) only available in certain browsers, see the following link for details:
现在可以使用新的 BigInt 内置数字类型来完成。BigInt 目前(2019 年 7 月)仅在某些浏览器中可用,详情请参见以下链接:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt
I have tested bitwise operations using BigInts in Chrome 67 and can confirm that they work as expected with up to 64 bit values.
我已经在 Chrome 67 中使用 BigInts 测试了按位运算,并且可以确认它们在最多 64 位值的情况下按预期工作。
回答by Janus Troelsen
The Closure library has goog.math.Longwith a bitwise add()method.
Closure 库具有goog.math.Long按位add()方法。

