位运算
位运算
位运算是基于整数的二进制的运算。计算机内部是以二进制进行存储数据,所以位运算是相当快的。
常见的位运算符有:与(&)、或(|)、异或(^)、取反(~)、左移(<<)、右移(>>)。
描述 | 符号 | 运算法则 |
---|---|---|
与 | & | 只有两个对应位都是1时,结果才为1 |
或 | | | 只有两个对应位都是0时,结果才为0 |
异或 | ^ | 只有两个对应位相同时为0,相异时为1 |
取反 | ~ | 0变1,1变0 |
左移 | << | 各二进制位全部左移若干位,若超过类型范围的高位丢弃,低位补零 |
右移 | >> | 各二进制位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样 |
按位与运算(&)
参与运算的两个数据,按二进制位进行“与”运算。
运算规则:
0 & 0 = 0; 0 & 1 = 0; 1 & 0 = 0; 1 & 1 = 1;
//由此可得到:两个数据只有对应位置都是1时,结果才为1
与运算用途:
判断奇偶性(大多数应用)
我们只要根据最后一位是否是0来决定,为0是偶数,为1时奇数
按位或运算(|)
参与运算的两个数据,按二进制位进行“或”运算。
运算规则:
0 | 0 = 0; 0 | 1 = 1; 1 | 0 = 1; 1 | 1 = 1;
//由此可得到:两个数据只有对应位置都是0时,结果才为0
注意:负数按照补码形式参与按位运算
按位异或运算(^)
参与运算的两个数据,按二进制位进行“异或”运算。
运算规则:
0 ^ 0 = 0; 0 ^ 1 = 1; 1 ^ 0 = 1; 1 ^ 1 = 0;
//由此可得到:两个数据如果对应数位相同为0;反之不相同为为1;
异或运算的运用:
1.交换两个数
void swap(int a, int b){
if(a != b){
a ^= b;
b ^= a;
a ^= b;
}
}
取反运算(~)
参与运算的一个数据,按二进制进行“取反”运算
运算规则:
~1 = 0; ~0 = 1;
//对于一个二进制按位取反,即将0变1,1变0;
左移运算(<<)
参与运算的一个数据,将它的各二进制全部左移若干位,若超过类型范围的高位丢弃,低位补零.若不超过类型范围,则每左移一位相当于该数乘以2。
例如:
如果为正数,则实际移位数=移位数 \(\%\)类型bit的大小
如果为负数,则实际移位数=类型bit的大小\(-\)(一个数的绝对值 % 类型bit的大小)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
while(1){
int n = 3, m;
cin >> m;
n <<= m;
cout << n << endl;
}
return 0;
}
//当m = 32时,输出的结果为3
右移运算(>>)
参与运算的一个数据,将它的各二进制全部右移若干位,正数左边补0,负数左边补1,右边丢弃。
不同长度的数据进行位运算:如果两个不同长度的数据进行位运算时,系统会将二者按右端对齐,然后进行位运算。
如果为正数,则实际移位数=移位数 \(\%\)类型bit的大小
如果为负数,则实际移位数=类型bit的大小\(-\)(一个数的绝对值 % 类型bit的大小)
位运算的应用
1.乘以2的非负整数次幂
int mulpower(int n, int m){
return n << m;
}
2.除以2的非负整数次幂
int divpower(int n, int m){
return n >> m;
}
3.判断符号是否相同
bool isSameSign(int a, int b){
return (x ^ y) >= 0;
}