二进制运算
基本的二进制运算有 与、或、异或、取反、左移、右移这六种
& 与 运算 :
只有当两位都是1时结果才是1,否则为0。
eg:6&4=4
0110
& 0100
---------
0100
| 或 运算:
两位中只要有1位为1结果就是1,两位都为0,则结果为0。
eg:6|4=6
0110
| 0100
---------
0110
^ 异或 运算:
两个位相同则为 0,不同则为 1
eg:6^4=2
0110
^ 0100
---------
0010
~ 取反 运算:
-
0 则变为 1,1 则变为 0
- 0110
-----------
1001
<< 左移 运算:
向左进行移位操作,高位丢弃,低位补 0
int a = 8;
a << 3;
移位前:00000000000000000000000000001000
移位后:00000000000000000000000001000000
>> 右移 运算:
向右进行移位操作,对无符号数,高位补 0,对于有符号数,高位补符号位
unsigned int a = 8;
a >> 3;
移位前:00000000000000000000000000001000
移位后:00000000000000000000000000000001
int a = -8;
a >> 3;
移位前:11111111111111111111111111111000
移位后:11111111111111111111111111111111
位运算操作技巧
1、判断整数的奇偶性
if((x & 1) == 0) {
// 偶数
} else {
// 奇数
}
只需判断整型的第一位是否是 1 即可,如果是说明是奇数,否则是偶数。
2、判断第n位是否为1
if (x & (1<<n)) {
// 第 n 位设置为 1
}
else {
// 第 n 位设置为 1
}
在上例中我们判断第一位是否为 1,所以如果要判断第 n 位是否 1,只要把 1 左移 n 位再作与运算就ok。
3、 将第 n 位设置为 1
y = x | (1<<n)
思路同第二步,先把 1 移到第 n 位再作或运算,这样第 n 位就肯定为 1。
4、 将第 n 位设置为 0
y = x & ~(1<<n)
先将 1 左移到 第 n 位,再对其取反,此时第 n 位为 0,其他位都为 1,这样与 x 作与运算后,x 的第 n 位肯定为 0。
5、将第 n 位的值取反
y = x ^ (1<<n)
我们知道异或操作是两个数的每一位相同,结果为 0,否则是 1,所以现在把 1 左移到第 n 位,则如果 x 的第 n 位为 1,两数相同结果 0,如果 x 的第 n 位为 0,两数不相同,则为 1。来看个简单的例子
01110101
^ 00100000
------------
01010101
如图示,第五位刚好取反
6、 将最右边的 1 设为 0
y = x & (x-1)
如果说上面的 5 点技巧有点无聊,那第 6 条技巧确实很有意思,也是在 leetcode 经常出现的考点,下文中大部分习题都会用到这个知识点,务必要谨记!掌握这个很重要,有啥用呢,比如我要统计 1 的位数有几个,只要写个如下循环即可,不断地将 x 最右边的 1 置为 0,最后当值为 0 时统计就结束了。
int count = 0
while(x) {
x = x & (x - 1);
count++;
}