一、位运算的概念
逻辑位运算符
& 位与
| 十进制 | 二进制 |
|---|---|
| 12 | 1100 |
| & | & |
| 10 | 1010 |
位与 是二元运算符,两个数进行 位与 运算,先转化为二进制,然后从低到高按位运算,
1100
& 1010
-------
1000 --> 8
对于每个 位 而言,只有当两个 位 都为 1 的时候,结果才为 1,否者为 0 。再把二进制数转化为十进制,就可以看到两个数 位与 的结果了。
| 位或
| 十进制 | 二进制 |
|---|---|
| 12 | 1100 |
| | | | |
| 10 | 1010 |
位或 也是二元运算符,两个数进行 位或 运算,先转化为二进制,然后从低到高按位运算,
1100
| 1010
-------
1110 --> 14
对于每个 位 而言,只有当两个 位 都为 0 的时候,结果才为 0,否者为 1 。再把二进制数转化为十进制,就可以看到两个数 位或 的结果了。
^ 异或
| 十进制 | 二进制 |
|---|---|
| 12 | 1100 |
| 10 | 1010 |
异或 也是二元运算符,两个数进行 异或 运算,先转化为二进制,然后从低到高按位运算,
1100
^ 1010
-------
0110 --> 6
对于每个 位 而言,只有当两个 位 不同 的时候,结果才为 1,否者为 0 。再把二进制数转化为十进制,就可以看到两个数 异或 的结果了。
~ 按位取反
按位取反 是一元运算符,当前数字转化为二进制以后,0 变 1,1 变 0 。
8位整数
~ 1010
= 11110101
16位整数
~ 1010
= 1111111111110101
- 高位不足位数默认为零
位移运算符
<< 左移
左移 是二元运算符
x << y x 左移 y 位
x 转化为 二进制,
| 十进制 | 二进制 |
|---|---|
| 12 | 1100 |
然后对它的所有位 向左偏移 y 位,末尾 y 位补 0

当 y = 3
1100 << 3
----------------
1100000
所以左移一位可以看作是对 x 乘以 2
>> 右移
右移 也是二元运算符
x >> y x 右移 y 位
x 转化为 二进制,
| 十进制 | 二进制 |
|---|---|
| 12 | 1100 |
然后对它的所有位 向右偏移 y 位。如果 x 是非负数,则高位补 0;如果 x 是负数,则高位补 1

当 y = 3
1100 >> 3
----------------
1
所以右移一位,可以看作是对 x 除以 2,并且向下取整
二、位运算的应用
身边的位运算的例子
比如B站的视频
- 点赞按钮有两种状态(点赞、不点赞)
- 投币按钮有三种状态(不投币、投一个币、投两个币)
- 收藏按钮有两种状态(收藏、不收藏)
如何用一个整数来表示每个用户对这个视频操作的所有情况呢?
-
两种状态可表示为
01,也就是用一个位就能表示 -
三种状态只能用两个位
0110
位 3 2 1 0
X X X X
↑ ↑ ↑ ↑
第0位表示点赞,第1到第2位表示投币,第3位表示收藏,总共4个比特位就够了
一开始没有三连,状态就是
位 3 2 1 0
0 0 0 0
点赞一下
位 3 2 1 0
0 0 0 1
投一个币
位 3 2 1 0
0 0 1 0
投两个币
位 3 2 1 0
0 1 0 0
收藏
位 3 2 1 0
1 0 0 0
如果一键三连就是
位 3 2 1 0
1 1 0 1
我们发现,点赞投币收藏 用到的比特位都是相互独立的,所有我们用 位或 运算符对它们进行组合运算
一开始的状态。 0 0 0 0
点赞。 & 0 0 0 1
----------
0 0 0 1
投两个币。 & 0 1 0 0
----------
0 1 0 1
收藏。 & 1 1 0 1
----------
1 1 0 1
三、位运算的算法题
從易到難 来刷题
简单题 - 中等题 - 困难题
通过率高的题一般比较简单,先刷