我知道〜是一个按位NOT运算符,但是如何将数字反转两次使它成为Math.floor What does ~~ ("double tilde") do in Javascript?描述了使用Math.floor与按位运算在Javascript中舍入数字之间的区别,但我感兴趣的是如何完全反转这两位来实现这一点。
由于
答案 0 :(得分: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!
答案 1 :(得分:2)
从the spec,按位NOT,~
- 让
expr
成为评估 UnaryExpression 的结果。- 让
oldValue
成为ToInt32(GetValue(expr))
。- 返回将按位补码应用于
醇>oldValue
的结果。结果是带符号的32位整数。
ToInt32
here的定义。
32位整数i
的“补码”是i XOR 0xFFFFFFFF
。
所以把这些放在一起,你有~~i
的含义
ToInt32(i) XOR 0xFFFFFFFF XOR 0xFFFFFFFF
// same as
ToInt32(i) XOR 0x00000000
// same as
ToInt32(i)
请记住负数的舍入方向的差异。
我个人更喜欢使用x | 0
而不是~~x
,因为相同结果的操作较少。
答案 2 :(得分:1)
它本质上相当于truncate函数(在某种意义上它将float转换为一个整数,这正是这样),JavaScript没有。这就是为什么对于负数,行为实际上更接近Math.ceil
。