简体   繁体   English

需要一个 JavaScript/ecma262 ToInt32 算法解释

[英]Need for a JavaScript/ecma262 ToInt32 algorithm explanation

I'm trying to understand how JS engines convert a JS Number (Float64) to a 32-bit signed integer.我试图了解 JS 引擎如何将 JS Number (Float64) 转换为 32 位有符号整数。 I read that one can quickly convert a 64 bit float to a 32 bit signed integer with the bitwise OR like:我读到可以使用按位 OR 将 64 位浮点数快速转换为 32 位有符号整数,例如:

-8589934590 | 0 // which gives 2

I can't understand where does the 2 come from.我无法理解 2 来自哪里。 According to the spec , the ToInt32 algorithm does this (the bold text is mine, not the spec's):根据规范,ToInt32 算法执行此操作(粗体文本是我的,而不是规范的):

  1. Let number be ?数字是? ToNumber(argument): -8589934590 is already a Number ToNumber(argument): -8589934590 已经是一个数字
  2. If number is NaN, +0, -0, +∞, or -∞, return +0.: No如果number是 NaN、+0、-0、+∞ 或 -∞,则返回 +0。:
  3. Let int be the Number value that is the same sign as number and whose magnitude is floor(abs(number)): -8589934590 is already an integerint是与 number 符号相同且大小为 floor(abs(number)) 的 Number 值: -8589934590 已经是整数
  4. Let int32bit be int modulo 2³² Since 2³² is positive the result should also be positive.int32bitint modulo 2³²由于 2³² 为正,结果也应为正。 In JS the remainder operator uses the sign of the left operand, so to get a modulo in this case (where -8589934590 is negative), we negate it: let int32bit = 8589934590 % 2**32 // 4294967294 which has 32 bit length 0b11111111111111111111111111111110在 JS 中,余数运算符使用左操作数的符号,因此为了在这种情况下获得模数(其中 -8589934590 为负),我们将其取反: let int32bit = 8589934590 % 2**32 // 4294967294 which has 32 bit length 0b11111111111111111111111111111110
  5. If int32bit ≥ 2³¹, return int32bit - 2³²;如果int32bit ≥ 2³¹,则返回int32bit - 2³²; otherwise return int32bit .否则返回int32bit int32bit is smaller 2³¹ (since it's negative), so I use int32bit which equals -2 ( Even if we consider 0b11111111111111111111111111111110 an unsigned integer, then it's greater 2³¹ and int32bit - 2³² still equals -2 int32bit较小2³¹(因为它的负),所以我用int32bit这等于-2即使我们考虑0b11111111111111111111111111111110一个无符号整数,那么它的更大2³¹和int32bit - 2³²仍然等于-2

Could someone, please, explain, do I correctly understand the ToInt32 algorithm and the bitwise OR operator?有人可以解释一下,我是否正确理解 ToInt32 算法和按位 OR 运算符?

Your step 4 is wrong.你的第 4 步是错误的。 Modulo is defined by the spec as:模数由规范定义为:

The notation “x modulo y” (y must be finite and nonzero) computes a value k of the same sign as y (or zero) such that abs(k) < abs(y) and xk = q × y for some integer q.符号“x modulo y”(y 必须是有限且非零的)计算与 y(或零)相同符号的值 k,使得 abs(k) < abs(y) 并且 xk = q × y 对于某个整数 q .

So -8589934590 is our x, and 2**32 is our y, from that we also know that k must be positive.所以 -8589934590 是我们的 x,而 2**32 是我们的 y,由此我们也知道 k 必须是正的。 If we choose q = -1 we can solve the equation to k = -4294967294.如果我们选择 q = -1,我们可以将方程求解为 k = -4294967294。 That is however not a valid solution , as k (negative) does not have the same sign as y (positive).然而,这不是一个有效的解决方案,因为 k(负)与 y(正)的符号不同。 If we choose q = -2 instead, we get k = 2.如果我们选择 q = -2,我们得到 k = 2。

So for negative numbers x and positive numbers y, q * y will always have to result in a smaller number than x for k to be positive.因此,对于负数 x 和正数 y,q * y 总是必须产生比 x小的数才能使 k 为正数。 Thus if we are transforming that to positive numbers (like you did), we are looking for the larger multiple of the number not the smaller one .因此,如果我们将其转换为正数(就像您所做的那样),我们正在寻找数字的较大倍数而不是较小的倍数 Eg if we take 2 % 3, that'll return 2 (2 - 2 = 3 * 0), whereas -2 modulo 3 will return 1 (-2 -1 = 3 * -1).例如,如果我们取 2 % 3,那将返回 2 (2 - 2 = 3 * 0),而 -2 modulo 3 将返回 1 (-2 -1 = 3 * -1)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM