javascript 32 位无符号整数的按位运算?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6798111/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 21:54:22  来源:igfitidea点击:

Bitwise operations on 32-bit unsigned ints?

javascriptbit-manipulation

提问by Delan Azabani

JavaScript converts operands to 32-bit signed ints before doing bitwise operations. It also does the operation with 32-bit signed ints, meaning that the result is a 32-bit signed int.

JavaScript 在执行按位运算之前将操作数转换为 32 位有符号整数。它还使用 32 位有符号整数进行运算,这意味着结果是一个 32 位有符号整数。

Because I'd like to do bitwise operations with 32-bit unsigned ints, I'm wondering if there is a way to use JavaScript's mangled result to find out the intended result.

因为我想对 32 位无符号整数进行按位运算,所以我想知道是否有办法使用 JavaScript 的重整结果来找出预期结果。

To demonstrate my idea, for example, in C, which is the reference as to what I'd like,

为了证明我的想法,例如,在 C 中,这是我想要的参考,

unsigned int a = 3774191835u;
unsigned int b = a >> 2;
/* b == 943547958 */

In JavaScript,

在 JavaScript 中,

 var a = 3774191835;
 var b = a >> 2;
 /* b == -130193866 */

Let's try this with a different operation. In C,

让我们用不同的操作试试这个。在 C 中,

unsigned int a = 1986735448u;
unsigned int b = a << 1;
/* b == 3973470896 */

In JavaScript,

在 JavaScript 中,

 var a = 1986735448;
 var b = a << 1;
 /* b == -321496400 */

Now that JavaScript has evaluated my bitwise operation with the operand as an signed int, we of course, get a different result to what we would in C, where we can properly do bitwise operations on unsigned ints.

既然 JavaScript 已经将我的操作数作为有符号整数进行了按位运算,我们当然会得到与在 C 中不同的结果,在 C 中我们可以正确地对无符号整数进行按位运算。

I know it's possible, but I'm unsure of a way that I can, essentially, turn JavaScript's result into the intended result.

我知道这是可能的,但我不确定我可以从本质上将 JavaScript 的结果转换为预期结果的方法。



Zero-fill right shift the result by zero works for the second case only, but not the first.

零填充将结果右移零仅适用于第二种情况,但不适用于第一种情况。

 var a = 3774191835;
 var b = (a >> 2) >>> 0;
 /* b == 4164773430 */

 var a = 1986735448;
 var b = (a << 1) >>> 0;
 /* b == 3973470896 */

回答by Ernesto Badillo

You only have to follow these rules:

您只需要遵循以下规则:

  1. always end bit wise ops with >>> 0so the result gets interpreted as unsigned.
  2. don't use >>. If the left-most bit is 1 it will try to preseve the sign and thus will introduce 1's to the left. Always use >>>.
  1. 总是以按位操作结束,>>> 0因此结果被解释为无符号。
  2. 不要使用>>. 如果最左边的位是 1,它将尝试保留符号,从而将1's引入左边。始终使用>>>.

Examples:

例子:

C:  (3774191835 >> 2) | 2147483648
js: (3774191835 >>> 2 | 2147483648) >>> 0

C:  1986735448 << 1
js: (1986735448 << 1) >>> 0

C:  3774191835 & 4294967295
js: (3774191835 & 4294967295) >>> 0

Only if the last op is >>>, >>> 0is not necessary.

仅当最后一个操作是 时>>>>>> 0才不是必需的。

回答by Paul

It's ugly, but:

这很丑陋,但是:

var a = 1986735448;
var b = (a << 1) >>> 0;
/* b = 3973470896 */

回答by jswolf19

JavaScript takes care of this problem by offering two bit shift operators, >>and >>>. You want >>>to do a shift without shifting the sign bit.

JavaScript 通过提供两个位移运算符>>>>>. 您想>>>在不移动符号位的情况下进行移位。