Bitwise Operation - tenji/ks GitHub Wiki
什么是位运算?
程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。
位运算就是直接操作二进制数,那么有哪些种类的位运算呢?
常见的运算符有与(&
)、或(|
)、异或(^
)、取反(~
)、左移(<<
)、右移(>>
是带符号右移 >>>
无符号右移动)。下面来细看看每一种位运算的规则。
规则:二进制对应位两两进行逻辑 AND 运算(只有对应位的值都是 1 时结果才为 1, 否则即为 0)即:0 & 0 = 0, 0 & 1 = 0, 1 & 1 = 1
例如:2 & -2
规则:二进制对应位两两进行逻辑或运算(对应位中有一个为 1 则为 1) 即:0 | 0 = 0, 0 | 1 = 1, 1 | 1 = 1
例如:2 | -2
规则:二进制对应位两两进行逻辑 XOR (异或) 的运算(当对应位的值不同时为 1, 否则为 0)即:0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 1 = 0
例如:2 ^ -2
private static String oxr(String hexStrLeft, String hexStrRight) {
// 先通过 Integer.valueOf(String s, int radix) 方法转为十进制数字
int decLeft = Integer.valueOf(hexStrLeft, 16);
int decRight = Integer.valueOf(hexStrRight, 16);
int res = decLeft ^ decRight;
// 使用 Integer.toHexString(int i) 方法将异或计算的结果转成十六进制字符串
return Integer.toHexString(res).toUpperCase();
}
规则:二进制的 0 变成 1,1 变成 0。
左移运算 <<:左移后右边位补 0
右移运算 >>:右移后左边位补原最左位值(可能是 0,可能是 1)
右移运算 >>>:右移后左边位补 0
- 对于左移运算符
<<
没有悬念右侧填个零无论正负数相当于整个数乘以2。 - 而右移运算符就有分歧了,分别是左侧补 0
>>>
和左侧补原始位>>
,如果是正数没争议左侧都是补 0,达到除以 2 的效果;如果是负数的话左侧补 0>>>
那么数值的正负会发生改变,会从一个负数变成一个相对较大的正数。而如果是左侧补原始位(负数补 1)>>
那么整个数还是负数,也就是相当于除以 2 的效果。
正常判断奇数偶数的时候我们会这样写:
if ( n % 2 == 1) {
// n 是个奇数
}
使用位运算可以这么写:
if (n & 1 == 1) {
// n 是个奇数。
}
其核心就是判断二进制的最后一位是否为 1,如果为 1 那么结果加上 2^0 = 1 一定是个奇数,否则就是个偶数。
对于传统的交换两个数,我们需要使用一个变量来辅助完成操作,可能会是这样:
int team = a;
a = b;
b = team;
但是使用位运算可以不需要借助额外空间完成数值交换:
a=a^b; // a = a^b
b=a^b; // b = (a^b)^b = a^0 = a
a=a^b; // a = (a^b)^(a^b^b) = 0^b = 0