~~如何作为math.floor工作?

mal*_*cky 5 javascript double

我知道〜是一个按位NOT运算符,但如何将数字上的位反转两次使其作为Math.floor运行 在Javascript中做什么~~("双波浪")?描述了使用Math.floor与按位运算在Javascript中舍入数字之间的区别,但我感兴趣的是如何完全反转这两位来实现这一点.

谢谢

Nik*_* B. 5

~强制操作数转换为整数.这是一个解决浮点数和整数值之间没有直接投射方式这一事实的技巧.事实上,Javascript并没有正式的整数类型,但实现可能会在内部使用整数来提高性能.

所以~x是按位逆castToInt(x).然后你再次反转这些位得到的castToInt(x).

碰巧将浮点数转换为整数的行为几乎就像Math.floor.最值得注意的差异是向零舍入,而Math.floor朝向负无穷大舍入.还有一些其他差异:

js> ~~(-4.5)
-4
js> Math.floor(-4.5)
-5
js> ~~Infinity
0
js> Math.floor(Infinity)
Infinity
js> ~~NaN
0
js> Math.floor(NaN)
NaN
js> Math.floor(1e12)
1000000000000
js> ~~1e12 
-727379968      // <- be aware of integer overflows!
Run Code Online (Sandbox Code Playgroud)


Pau*_* S. 4

规范来看,按位非,~

  1. 让为UnaryExpressionexpr的计算结果。
  2. oldValue这样吧ToInt32(GetValue(expr))
  3. 返回对 进行按位求补的结果oldValue。结果是一个带符号的 32 位整数。

ToInt32 这里的定义。

32 位整数的“补码”ii XOR 0xFFFFFFFF

所以把这一切放在一起你就有了~~i意义

ToInt32(i) XOR 0xFFFFFFFF XOR 0xFFFFFFFF
// same as 
ToInt32(i) XOR 0x00000000
// same as
ToInt32(i) 
Run Code Online (Sandbox Code Playgroud)

请记住负数舍入方向的差异。


就我个人而言,我更喜欢使用x | 0over ~~x,因为它需要更少的操作来获得相同的结果。