如何强制按位运算符产生无符号结果?

问题描述 投票:0回答:2

我正在用 JavaScript 开发 CRC32 算法,对此我还很陌生。 一切似乎都很顺利,直到最后一步:将校验和与 0xFFFFFFFF 进行异或。

1001010100111101101100010001000
 ^ 11111111111111111111111111111111 = -1001010100111101101100010001001

1251924104 ^ 4294967295 = -1251924105

负值似乎是个问题。我可以做什么来解决这个问题?

javascript bit-manipulation bitwise-operators
2个回答
2
投票

Javascript 中的按位运算会将数字强制转换为带符号的 32 位整数,最大值为

2^31-1
。您的号码,
0xFFFFFFFF
,是
2^32-1

但是,如果您使用 BigInts 来代替,它会正常工作:

console.log(0xFFFFFFFF ^ 0)

console.log(String(0xFFFFFFFFn ^ 0n))

注意:我必须使用

String()
,因为 stackoverflow console.log 函数似乎无法处理 BigInts。


1
投票

JavaScript 中的大多数按位运算符都会对带符号的 32 位整数进行运算并返回其结果(只要操作数是普通数字,而不是 bigint)。 然而,有一个运算符不这样做:无符号右移运算符

>>>
,它返回一个 无符号 32 位整数。

您可以使用无符号零右移将有符号 32 位整数强制转换为无符号 32 位整数:

console.log(~0);
console.log(~0 >>> 0);

console.log(1251924104 ^ 0xffffffff);
console.log((1251924104 ^ 0xffffffff) >>> 0);

// since JS bitwise operators work on 32-bit values,
// bitwise negation is equivalent to XORing with 0xffffffff
console.log(~1251924104);
console.log(~1251924104 >>> 0);

从第一个 JavaScript 版本(如 Netscape 2.02)开始就支持

>>>
运算符,这与仅出现在 ECMAScript 2020(ECMA-262 第 11 版)中的 bigint 支持不同。 因此,您应该更喜欢它而不是 bigint,特别是如果您没有使用后者,因为这将确保更好的兼容性。

无论如何,问题大部分是表面上的。 无论这些值被解释为有符号整数还是无符号整数,应用按位运算符产生的位模式都是相同的。 因此,仅在显示结果时,或者在将结果作为操作数输入算术(非按位)运算符之前应用无符号强制就足够了,而这种解释实际上很重要。

© www.soinside.com 2019 - 2024. All rights reserved.