前言
位运算在业务代码中已经很少用了,但面试刷题经常会用到,这里复习下
一、基础位运算操作
1. 按位与 (&)
规则:两位都是1,结果才是1,否则为0
---
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
示例:
1010 (10)
& 1100 (12)
------
1000 (8)
2. 按位或 (|)
规则:两位有一个是1,结果就是1
---
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
示例:
1010 (10)
| 1100 (12)
------
1110 (14)
3. 按位异或 (^)
规则:两位不同为1,相同为0
---
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
示例:
1010 (10)
^ 1100 (12)
------
0110 (6)
特性:
a ^ a = 0
a ^ 0 = a
a ^ b ^ b = a (异或两次等于本身)
满足交换律和结合律
4. 按位取反 (~)
规则:0变1,1变0
---
~ 1010 = 0101
注意:Go中的取反
~1 => ^1 // Go中没有使用~符,其等价于 ^(-1)
5. 左移 (<<)
规则:左边补0,相当于 ×2^n
---
1010 << 1 = 10100 (10 << 1 = 20 = 10 × 2^1)
1010 << 2 = 101000 (10 << 2 = 40 = 10 × 2^2)
常见要点
6. 右移 (>>)
规则:右边移出,左边补符号位,相当于 ÷2^n
---
1010 >> 1 = 0101 (10 >> 1 = 5 = 10 ÷ 2^1)
1010 >> 2 = 0010 (10 >> 2 = 2 = 10 ÷ 2^2)
二、常用位运算技巧
1. 判断奇偶
// 判断 n 是否为偶数
if n & 1 == 0 {
// 偶数
}
// 判断 n 是否为奇数
if n & 1 == 1 {
// 奇数
}
原理: 二进制最后一位是1表示奇数,0表示偶数
2. 取最低位的1
// 获取 n 最低位的1
lowbit := n & (-n)
// 移除 n 最低位的1
n = n & (n - 1)
示例:
n = 12 = 1100
-n = -12 = (补码表示)
n & (-n) = 100 = 4 // 最低位的1
n = 14 = 1110
n & (n-1) = 14 & 13 = 1110 & 1101 = 1100 // 移除最低位1
3. 判断2的幂
// 判断 n 是否是2的幂
if n > 0 && (n & (n-1)) == 0 {
// 是2的幂 (1, 2, 4, 8, 16, ...)
}
原理: 2的幂二进制只有1个1
4. 获取第i位
// 获取第i位(最低位为第0位)
bit := (n >> i) & 1
// 设置第i位为1
n = n | (1 << i)
// 设置第i位为0
n = n & (^(1 << i))
5. 交换两数
// 不使用临时变量交换
a = a ^ b
b = a ^ b // b = (a^b)^b = a
a = a ^ b // a = (a^b)^a = b