位运算
# 位运算
# 位运算常用命令
- 与运算(&):对两个操作数的每个对应位执行逻辑与操作,如果两个位都为1,则结果为1,否则为0。
- 或运算(|):对两个操作数的每个对应位执行逻辑或操作,如果两个位中至少有一个为1,则结果为1,否则为0。
- 异或运算(^):对两个操作数的每个对应位执行逻辑异或操作,如果两个位相同,则结果为0,否则为1。
- 非运算(~):对操作数的每个位执行逻辑非操作,将每个位取反。
- 左移运算(<<):将操作数的所有位向左移动指定的位数,右侧用0填充。
- 转换by运算(>>):将操作数的所有位向转换by动指定的位数,左侧用符号位填充。
- 无符号转换by运算(>>>):将操作数的所有位向转换by动指定的位数,左侧用0填充。
# 使用案例
# 获取大于等于x的最小的2的幂次方的值
HashMap 里面有这样一个方法,输入cap,可以计算出大于等于 cap 最小的2的幂次方的值。
static final int MAXIMUM_CAPACITY = 1 << 30;
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
所有正的2的幂次方都只有1个位被设置为1; 而(2的幂次方 - 1)的所有位都被设置为1,但最高位设置为0。 因此,我们可以通过以下步骤找到下一个最大的2的幂次方:
- 减去1
- 设置所有较低位的位为1
- 再加上1 这些位移操作实现了这个过程的第二步,通过"扩散"设置的位。
扩散操作-举例1:
01xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx // 初始值
=> 011xxxxxxxxxxxxxxxxxxxxxxxxxxxxx // 转换by1
=> 01111xxxxxxxxxxxxxxxxxxxxxxxxxxx // 转换by2
=> 011111111xxxxxxxxxxxxxxxxxxxxxxx // 转换by4
=> 01111111111111111xxxxxxxxxxxxxxx // 转换by8
=> 01111111111111111111111111111111 // 转换by16
1
2
3
4
5
6
2
3
4
5
6
扩散操作-举例2:
0000000000000000000001xxxxxxxxxx // 初始值
=> 00000000000000000000011xxxxxxxxx // 转换by1
=> 0000000000000000000001111xxxxxxx // 转换by2
=> 00000000000000000000011111111xxx // 转换by4
=> 00000000000000000000011111111111 // 转换by8
=> 00000000000000000000011111111111 // 转换by16
1
2
3
4
5
6
2
3
4
5
6
参考:HashMap.tableSizeFor(...). How does this code round up to the next power of 2? (opens new window)
编辑 (opens new window)
上次更新: 2024/05/21, 21:29:15