我是黑洞极客,欢迎来到算法竞赛系列!(先赞再看,养成习惯!)
位运算
众所周知,计算机中使用的是二进制编码,而在二进制中使用的逻辑运算被称作位运算。这些运算只能对数字进行操作。
布尔值运算:与(&&),或(||),非(!),
二进制运算:按位与(&),按位或(|),取反(~),按位异或(^),左移(<<),右移(>>)
按位与(&)
计算规则:对于两个数的每一位(没有的补零代替),如果两个数字都为1,则结果为1,否则为0
举例说明:对于6和10,二进制为110和1010(下方)。故结果为2。
0 1 1 0
1 0 1 0
0 0 1 0
代码格式:c = a & b;
其他信息:任何数与上0都等于0。
算法应用:
判断是否为2的整数次幂(2的整数次幂形如100...0,2的整数次幂-1形如11...1,与后结果为0)
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
if (n & (n-1)) cout << "NO";
else cout << "Yes";
return 0;
}
统计二进制中1的个数(当一个数结尾是1时,-1后就为零,再与一次就变成零,如此直到没有1)
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n, ans = 0;
cin >> n;
while (n)
{
n = n & (n - 1);
ans++;
}
cout << ans;
return 0;
}
按位或(|)
计算规则:对于两个数的每一位(没有的补零代替),如果两个数字有一个为1,则结果为1,否则为0。
举例说明:对于6和10,二进制为110和1010(下方)。故结果为14。
0 1 1 0
1 0 1 0
1 1 1 0
代码格式:c = a | b;
取反(~)
计算规则:对于一个数的每一位从0变为1或从1变为0,并还原为原码。
举例说明:对于21,二进制为10101(下方)。
0 0 0 1 0 1 0 1 <原数
1 1 1 0 1 0 1 0 <补码
1 1 1 0 1 0 0 1 <反码
1 0 0 1 0 1 1 0 <原码
代码格式:b = ~a;
按位异或(^)
计算规则:对于两个数的每一位(没有的补零代替),如果两个数字不同,则结果为1,否则为0。(tip:异或可以理解为不进位的加法)
举例说明:对于6和10,二进制为110和1010(下方)。故结果为12。
0 1 1 0
1 0 1 0
1 1 0 0
代码格式:c = a ^ b;
其他信息: 一个数异或一个由n个1组成的数(如1111),可以让其后n位反转,如1001^011=1110
左移(<<)
计算规则:对于一个数,将每一位向左移n的位数,溢出的直接舍去,空出来的补零。
(tip:等价于乘2的n次方)
举例说明:对于6左移3位,二进制为110(下方)。故结果为48。
1 1 0
1 1 0 0 0 0
代码格式:b = (a << 1)
右移(>>)
计算规则:对于一个数,将每一位向右移n的位数,溢出的直接舍去,空出来的补零。
举例说明:对于21右移3位,二进制为10101(下方)。故结果为5。
1 0 1 0 1
0 0 1 0 1
代码格式:b = (a >> 1)
注意事项
1、位运算符优先级低于数字运算符,注意加括号。
2、在符号后加上“=”,就变成了赋值运算符。(例如:a >>= 1; b &= a;)
恭喜你成功GET到了位运算,下次见,拜拜!