需要JavaScript / ecma262 ToInt32算法说明

问题描述

我试图了解JS引擎如何将JS编号(Float64)转换为32位带符号整数。我读到可以使用按位OR迅速将64位浮点数转换为32位有符号整数:

-8589934590 | 0 // which gives 2

我不明白2的来源。根据{{​​3}},ToInt32算法可以做到这一点(粗体字是我的,不是规范的):

  1. number 是? ToNumber(参数): -8589934590已经是一个数字
  2. 如果 number 为NaN,+ 0,-0,+∞或-∞,则返回+0 。:
  3. int 为与数字相同的符号,其大小为floor(abs(number))的Number值: -8589934590已经是整数
  4. int32bit int 模2³²由于2³²为正,结果也应为正。在JS中,余数运算符使用左操作数的符号,因此,在这种情况下(-8589934590为负数)取模,我们将其取反: let int32bit = 8589934590 % 2**32 // 4294967294 which has 32 bit length 0b11111111111111111111111111111110
  5. 如果 int32bit ≥2³¹,则返回 int32bit -2³²;否则返回 int32bit int32bit小于2³¹(因为它为负数),所以我使用 int32bit 等于 -2即使我们考虑 0b11111111111111111111111111111110 无符号整数,则它大于2³¹,而 int32bit -2³²仍等于 -2

有人可以解释一下,我是否正确理解ToInt32算法和按位OR运算符?

解决方法

您的步骤4错误。规范将模数定义为:

符号“ x模y”(y必须是有限且非零)可计算与y(或零)具有相同符号的值k,使得abs(k)

因此-8589934590是我们的x,而2 ** 32是我们的y,由此我们也知道k必须为正。如果选择q = -1,则可以将方程求解为k = -4294967294。但是,这不是有效的解决方案,因为k(负数)与y(正数)的符号不同。如果选择q = -2,则得到k = 2。

因此,对于负数x和正数y,要使k为正数,q * y总是必须比x小 个数。因此,如果我们将其转换为正数(如您所做的那样),我们将寻找数字的较大倍数,而不是较小的 。例如。如果我们取2%3,则将返回2(2-2 = 3 * 0),而-2模3将返回1(-2 -1 = 3 * -1)。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...