javascript - 与 0b 的按位或运算将给定数字转换为负数

标签 javascript bit-manipulation bitwise-operators bit-shift bitwise-and

我需要使用按位运算符执行某些操作,假设我们有这个 40 位无符号整数:

1071698660929当我申请时 OR运算符和无符号右移运算符我得到了这个负整数

输入:(1071698660929 >>> 0) | 0b0

输出:-2043163071

我注意到只要数字是 31 位长,添加 0B0 就没有任何问题。但是当数字大于 31 位时,即使我使用无符号右移运算符,它也会变为负数:

32位二进制返回-1 :(0b11111111111111111111111111111111 >>> 0) | 0

31位二进制返回2147483647 :(0b1111111111111111111111111111111 >>> 0) | 0

所以我有几个问题:

  1. 如果我使用右移运算符,为什么上面的数字会变成负数?我的理解是 javascript 中的 MAX 安全整数是 53 位长 Number.MAX_SAFE_INTEGER.toString(2).length所以我在整数安全边界内。
  2. 我该怎么做才能做到这一点(1071698660929 >>> 0) | 0b0返回 1071698660929而不是-2043163071

最佳答案

按位运算符将其操作数隐式转换为 32 位整数(有符号或无符号,取决于运算符)。在此过程中,超过 32 位的数字将获得其最高有效位 discarded :

Before: 11100110111110100000000000000110000000000001
After:              10100000000000000110000000000001

此规则的唯一异常(exception)是(相对)原始 block 上的新 child ,BigInt类型:所有按位操作(&|^)和几乎所有移位都是 overloaded对于该类型。

这为您的问题开辟了一条出路:只需使用 BigInt 而不是普通的 number,或者显式地使用,如下所示:

const bigIntee = BigInt(1071698660929); // note no `new` here!

...或者,如果您实际上必须使用文字,请在其后面附加 n:

const bigIntee = 1071698660929n; // also works

请注意,如果一个操作数是 BigInt,则另一个操作数也应该是 BigInt。所以这...

bigIntee | 0

...会让 JS 对你试图回到 90 年代快乐的类型无政府时代的可悲尝试感到愤怒。更具体地说,你会收到一个 TypeError 错误:

Cannot mix BigInt and other types, use explicit conversions

不过,这很容易解决:只需将上述转换技巧也应用于第二个操作数即可。

bigIntee | 0n 
// or bigIntee | BigInt(0)

两者都有效。忽略 0 并不是真正的 Biggus Integerus 类型;类型安全在这里占主导地位。

仍然存在一个问题:>>>(无符号右移运算符)不能在 BigInt 上使用。如果您尝试这样做,您将收到一个非常具体的错误:

bigIntee >>> 0n
// Uncaught TypeError: BigInts have no unsigned right shift, use >> instead

...这完全有道理(我们希望 JS 抛出的所有错误都是特定的)。

关于javascript - 与 0b 的按位或运算将给定数字转换为负数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73169169/

相关文章:

javascript - 如何为单个类设置原型(prototype)对象的属性

javascript - 基本理解题 : objects scope

go - 在 Go 中解压 redis 设置位字符串

java - 什么是按位运算?

c# - 使用 MongoDB 的官方 C# 驱动程序的按位枚举(标志)查询

javascript - angularjs,browserify + 下划线

c++ - for循环的增量语句中的奇数位运算符

c++ - 连接 4 位整数

c - 位操作困难

javascript - 如何显示来自 XML 的数据?