一、位移运算基础
位移是对二进制数按指定方向移动指定位数的运算,核心用于高效处理乘除、位标识分配等场景。
1. 左移(<<)
- 规则:二进制位向左移动n位,右侧补0
- 效果:等价于 乘以2的n次方(整数场景)
- 示例:
10 << 1
(10的二进制1010
左移1位→10100
)→ 结果20(10×2¹)10 << 2
→ 结果40(10×2²)
2. 右移(>> / >>>)
-
算术右移(>>):
- 规则:向右移动n位,左侧补与符号位相同的数(正数补0,负数补1)
- 效果:等价于 除以2的n次方(向下取整)
- 示例:
- 正数:
10 >> 1
(1010
→101
)→ 结果5(10÷2¹) - 负数:
-10 >> 1
(二进制补码左补1)→ 结果-5(-10÷2¹)
- 正数:
-
逻辑右移(>>>,部分语言支持如Java):
- 规则:向右移动n位,左侧强制补0(不考虑符号位)
- 结果:始终为非负数
- 示例:
-10 >>> 1
→ 结果为正数(具体值取决于数据位数)
二、位掩码技术(多选状态存储方案)
通过位运算将多个选项的选中状态存储为一个整数,核心是用二进制位的0/1表示未选/已选。
1. 核心步骤
步骤1:分配位标识(用左移)
为每个选项分配唯一的"位标识"(二进制只有1位为1),避免冲突:
- 选项A:
1 << 0 = 1
(二进制0001
,第0位为1) - 选项B:
1 << 1 = 2
(二进制0010
,第1位为1) - 选项C:
1 << 2 = 4
(二进制0100
,第2位为1) - (以此类推,第n个选项用
1 << n
)
步骤2:合并多选结果(用或运算|)
通过按位或(|) 合并选中的选项,结果整数的二进制中"1的位置"即选中项:
- 选A+B:
1 | 2 = 3
(二进制0011
) - 选A+C:
1 | 4 = 5
(二进制0101
) - 选A+B+C:
1 | 2 | 4 = 7
(二进制0111
)
步骤3:查询是否选中(用与运算&)
通过按位与(&) 判断某选项是否选中:
- 结果≠0 → 已选中;结果=0 → 未选中
- 示例(存储值为5,二进制
0101
):- 判断A:
5 & 1 = 1 ≠ 0
→ 选中 - 判断B:
5 & 2 = 0
→ 未选中 - 判断C:
5 & 4 = 4 ≠ 0
→ 选中
- 判断A:
三、与运算(&)和或运算(|)详解
1. 与运算(&)
- 规则:对应位全1则1,有0则0(同1为1,否则0)
- 示例:
3 & 5
(011
&101
=001
)→ 结果1 - 核心用途:
- 判断某一位是否为1(多选场景中判断是否选中)
- 清零特定位(用掩码将指定位置0)
2. 或运算(|)
- 规则:对应位有1则1,全0则0(有1为1,否则0)
- 示例:
3 | 5
(011
|101
=111
)→ 结果7 - 核心用途:
- 合并多个位状态(多选场景中存储选中结果)
- 设置特定位为1(用掩码将指定位置1)
四、优缺点与适用场景
优点
- 存储高效:单个整数存储多个选项,节省空间
- 运算高效:位运算(&、|)速度远快于字符串/数组操作
- 逻辑清晰:每个选项对应唯一二进制位,状态无歧义
缺点
- 数量限制:受整数位数限制(32位最多32个选项,64位最多64个)
- 可读性差:存储的整数无法直接看出对应选项,需代码解析
- 扩展性受限:超过位数限制需重构存储逻辑
适用场景
- 推荐:选项数量固定(≤64)、需高效存储/查询的场景(如用户权限、订单标签)
- 不推荐:选项可能超64个、需人工直接解读存储值的场景
五、代码示例(JavaScript)
// 1. 定义选项位标识
const TYPE_A = 1 << 0; // 1 → 001
const TYPE_B = 1 << 1; // 2 → 010
const TYPE_C = 1 << 2; // 4 → 100// 2. 合并选中项(选A和C)
let selected = TYPE_A | TYPE_C; // 1 | 4 = 5(二进制101)// 3. 判断是否选中
console.log((selected & TYPE_A) !== 0); // true(A选中)
console.log((selected & TYPE_B) !== 0); // false(B未选中)
console.log((selected & TYPE_C) !== 0); // true(C选中)