我不是bitwise运算符的专家,但我经常看到一个模式,在比赛中由256k演示的程序员使用.而不是使用Math.floor()函数,使用双位NOT运算符~~(可能更快?).
像这样:
Math.floor(2.1); // 2 ~~2.1 // 2
2.1 | 0 // 2 2.1 >> 0 // 2
在开发控制台中玩这个时,我注意到了一个我不确定我完全理解的行为.
Math.floor(2e+21); // 2e+21 ~~2e+21; // -1119879168 2e+21 | 0; // -1119879168
引擎盖下发生了什么?
解决方法
正如Felix King所指出的那样,这些数字正被转换为32位有符号整数. 2e9小于signed int的最大正值,因此这适用:
~~(2e9) //2000000000
但是当你转到2e10时,它不能使用所有的位,所以它只需要最低的32位并将其转换为int:
~~(2e10) //-1474836480
您可以通过使用另一个按位运算符并确认它正在获取最低32位来验证这一点:
2e10 & 0xFFFFFFFF // also -1474836480 ~~(2e10 & 0xFFFFFFFF) // also -1474836480
Math.floor是为了解释大数而构建的,所以如果大范围内的准确性很重要,那么你应该使用它.
另外值得注意的是:~~正在进行截断,这与仅为正数的地板相同.它不适用于否定:
Math.floor(-2.1) // -3 ~~(-2.1) // -2