位运算符作用于整数类型的运算对象,并把运算对象看作是二进制位的集合。
运算符 | 功能 |
---|---|
~ | 位求反 |
<< | 左移 |
>> | 右移 |
& | 位与 |
^ | 位异或 |
| | 位或 |
运算的对象可以是带符号的,也可以是无符号的。如果运算对象是带符号的负值,那么位运算如何处理运算对象的“符号位”依赖于机器,此时的左移操作可能会改变符号位的值,因此是一种未定义的行为。(建议将位运算仅用于处理无符号类型)
bitset类
bitset类位于头文件bitset中。
bitset类是一个类模板,具有固定的大小,当我们定义一个bitset类的时候要声明它具有多少个二进制位,大小必须是常量表达式。
bitset<32> bvec(1U);//32位;低位为1,其他位为0;
从0~31编号,0为低位。
//初始化bitset的方法
bitset<n> b; //b有n位,每一位为0
bitset<n> b(u);//b是unsigned long long值u的低n位拷贝,n过大则高位置0
bitset<n> b(s, pos, m);//b是string s从位置pos开始m个字符的拷贝;s只能包含字符0或1。
bitset<n> b(cp, pos, m);//cp是一个字符数组
bitset<12> b1(0xbeef);//保留低12位
bitset<20> b2(0xbeef);//高4位置0
bitset<64> b3(~0ULL);//0~63位为1,64~127为0
//string下标编号和bitset编号相反,string中下标最大的字符来初始化bitset中的低位
bitset<32> b4("1010");//string初始化bitset对象
string str("111111110000000110011");
bitset<32> b5(str, 5, 4);//使用str[5]开始的四个字符
bitset<32> b6(str, str.size()-4);//使用最后4个字符
//bitset操作
b.any() //b中是否存在置位的二进制位
b.all() //b中所有位都置位了吗
b.none()//b中不存在置位的二进制位吗
b.count()//b中置位的位数
b.size()//b中的位数,constexpr函数
b.test(pos)//pos位置的位是否置位
b.set(pos, v)//将位置pos位设置为bool值v,v默认为true
b.set()//未传参数,将所有位置位
b.reset(pos)//将pos位复位
b.reset()//所有位复位
b.flip(pos)//改变pos位状态
b.flip()//改变所有位的状态
b[pos]//访问pos位
b.to_ulong()//返回一个unsigned long值
b.to_ullong()//返回一个unsigned long long值
b.to_string(zero,one)//返回一个string对象,表示b中的位模式zero和one默认表示0和1
os << b //将b中二进制打印为字符1和0,打印到流os
is >> b //从is读取字符存入b。
//bitset使用
bitset<32> b(1U); //32位,仅低位为1
bool is_set = b.any();//is_set == true,因为有一位置位
bool is_not_set = b.none();//is_not_set == false
bool all_set = b.all();//all_set == false,只有一位置位
size_t on_bits = b.count();//on_bits == 1
size_t sz = b.size();
b.flip();//翻转b中所有位,即取反
b.flip(0);//翻转0位置处
b.reset();//将所有位复位(置为0)
b.reset(0);
b.set();//将所有位置位(置为1)
b.set(b.size()-1);//置位最后一位
b.test(31);//返回true,最后一位置位的
b[0] = 0;//0位置复位
b[30] = b[0];//30位置置为和0位置一样
b[0].flip();//等价于b.flip(0);
~b[0];//等价上一语句
bool b = b[0];//取出0位的值转化为bool类型
bitset<16> bi;
cin >> bi;//从cin最多读取16个0或1
cout << bi << endl;//打印bi