为什么 2 ** (1 << 31) == 0?

x70*_*66c 0 javascript algorithm bit-manipulation

在节点 REPL 中运行它,给我:

> 2 ** (1 << 31)
0

Run Code Online (Sandbox Code Playgroud)

我还为此编写了一个小算法,它给了我 1。

> 2 ** (1 << 31)
0

Run Code Online (Sandbox Code Playgroud)

问题:

  1. 为什么 REPL 0 中的实际答案是?
  2. 我上面的算法有什么问题吗?

Poi*_*nty 8

该值1 << 31是一个幅度很大的负数,比标准浮点表示法所能表示的要大得多。因此,0 与实际值差不多。

浮点计算机数学是一门非常复杂的学科。这并不完全是魔术,但它非常复杂。某些语言提供某种“定点”十进制数学系统,以牺牲计算效率为代价实现无限精度。JavaScript 没有这样的内置工具。

至于迭代算法,发生的情况是,当您将负值翻转回正值时,它太大而无法放入整数。第一次>>in 循环发生时,您再次得到负指数,因为 JavaScript 按位运算符强制内部转换为 32 位有符号整数。如果您>>>改为使用,则不会出现该问题。