解释如何使用二元运算符将 JavaScript 中的浮点数强制转换为整数

Explain how binary operators could be used to coerce floating point number to integer number in JavaScript

在 JavaScript 中没有整数值的特殊类型。实际上,所有数字都有一个 Number 类型,即 Double Precision Floating Point Number (IEEE 754)binary64.

JavaScript 中数字运算的一个问题是标准中没有定义 整数除法 运算符或函数。

更新: 实际上,有一个 Math.trunc() 函数,但它比二进制解决方案慢 2-5 倍,并且在 Internet Explorer 中不受支持。

可以使用一些二元运算符来实现所需的结果,例如:

以上所有操作都会产生数字 2,根据我的基准测试,在我的 x64 机器 (Node.js v7.2.1) 上具有相似的性能。

您能否解释一下这些二元运算究竟是如何用于这个确切目的的?有喜欢的吗?

Bit-wise 运算符仅适用于 Javascript 中的整数,因此执行其中任何一个都会将值截断为整数。

(10 / 4) >> 0

执行除法 (10 / 4) 以获得值 2.5,移位 (>>) 仅适用于整数值,因此通过对 2.5 执行 bit-shift,该值被截断为 2。

也是如此
(10 / 4) | 0

除了不是 bit-shift,操作是 bit-wise 或

~~(10 / 4)

执行双重bit-wise否定,第一个截断和否定使2.5变成-3,然后另一个将它转换回正确的符号,2.

您可以在此处阅读有关 bit-wise 运算符的更多信息:http://www.w3schools.com/jsref/jsref_operators.asp

首先,您将数字转换为 signed 32 bit integers,这意味着,与 64 位浮点表示相比,您丢失了一些数字。

你的数字的计算只是给出一个浮点值 2.5 并且操作数首先转换为带符号的 32 位整数,然后进行按位计算。操作数是必需的,因为您在初始对话中需要它。

2 >> 0Sign-propagating right shift >>

的例子
     2 (base 10): 00000000000000000000000000000010 (base 2)
                  --------------------------------
2 >> 0 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)

~~2的示例Bitwise NOT ~

     2 (base 10): 00000000000000000000000000000010 (base 2)
                  --------------------------------
    ~2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
                  --------------------------------
   ~~2 (base 10): 00000000000000000000000000000010 (base 2) =  2 (base 10)

2 | 0 Bitwise OR |

示例
     2 (base 10): 00000000000000000000000000000010 (base 2)
     0 (base 10): 00000000000000000000000000000000 (base 2)
                  --------------------------------
 2 | 0 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)

除了可以将数字转换为整数表示之外,您还可以使用普通的 Math.floor 来达到相同的目的,这会使代码看起来不那么神秘。

这些操作不是将 float 转换为 int 的直接方法。这些是二进制运算,它适用于整数。在这个过程中有自动转换。所以这是一种滥用但将浮点数转换为整数的更快的方法。然而,由于这些操作在 javascript 中非常常用,因此使用它们并没有太大的危害。但是,也可以使用 Math.floor() 或 Math.truncate () 来提高可读性。

这些并不是真正的二元技巧 - 只是使用的所有三个运算符(~>>|)都是 定义的 因为只处理 Number.

的前 32(有符号)位

任何不是整数的(双精度)操作数都将被截断,并且任何超过 1 << 32 的位都会在计算运算之前被丢弃。