每天一个劝退小技巧之位操作

3 年前(已编辑)
967
2
这篇文章上次修改于 3 年前,可能部分内容已经不适用,如有疑问可询问作者。

为什么要使用位操作,因为位操作是直接操作二进制数,是所有语言中执行效率最高的运算。

以下代码以 JavaScript 为例,部分代码在所有支持位操作的语言通用。

注:JavaScript 中数值以 IEEE 754 双精度浮点数表示。

快速取整

parseInt(2.2) === ~~2.2 // true
parseInt('1.3') === ~~'1.3' // true
1<<30 === ~~1<<30 // true

Math.floor(1.2) == 1.2 | 0
Math.floor(1.2) == 1.2 ^ 0

Math.floor(-1.2) == -1.2 | 0
Math.floor(-1.2) == -1.2 ^ 0

// HINT

parseInt('4294967296') === ~~4294967296 //false, 越界
parseInt('4294967296') === ~~'4294967296' //false, 越界

快速累加

-~undefined === 1 // true
-~0 === 1 // true
-~1 === 2 // true
-~-1 === 0 // true, -~-1 为 -0

-~2<<30 === 2<<29+1 //false

是否奇数

1 & 1 === 1 // 1 为奇数
2 & 1 === 0 // 0 为偶数
3 & 1 === 1 // etc.

权限

// 比如我有 2 3 4 号权限
permission = 1 << 2 | 1 << 3 | 1 << 4
// 现在判断我有没有 3 号权限
hasPerssion3 = !!(permission & 1 << 3) // res is 8, true
hasPerssion5 = !!(permission & 1 << 5) // res is 0, false
hasPerssion0 = !!(permission & 1 << 0) // res is 0, false

注意最大边界为 1 << 30, 更大需要用 BigInt

获取数组中只出现一次的数字

  1. 交换律:a ^ b ^ c <=> a ^ c ^ b
  2. 任何数于0异或为任何数 0 ^ n => n
  3. 相同的数异或为0: n ^ n => 0
let res = 0
arr.forEach(i => res ^= i)
// return res

0-1互转

0^1 == 1
1^1 == 0

两数中点

left + ((right - left) >> 1) === (left + right) / 2 // int

持续更新,有更好的用法欢迎评论区指出

评论区加载中...