操作二进制位串的工具
一.位运算符
- 位运算符作用于整数类型的对象,并把运算对象看成是二进制位的集合。
- 它提供检查和设置二进制位的功能。
运算符 | 功能 | 用法 |
---|
~ | 位求反 | ~expr |
<< | 左移 | expr1 << expr2 |
>> | 右移 | expr1 >> expr2 |
& | 位与 | expr1 & expr2 |
^ | 位异或 | expr1 ^ expr2 |
| | 位或 | expr1 |
- 符号位的处理没有规定,因此建议仅用于处理无符号类型
- 一般来说,如果运算对象是”小整型“,则它的值会被自动提升成较大的整数类型。运算对象可以是带符号的,且为负,则如何处理”符号位“依赖于机器。而且此时左移可能会改变符号位的值,是一种未定义行为。
- 整型提升:任何使用了char,short,整型位域或者枚举类型的表达式,(bool、char、signed char、unsigned char、short、unsigned short等小于int的类型),如果装得下,都会被提升成int类型;否则提升为unsigned int。较大的char(wchar_t、char_16_t、char_32_t)则提升为int–unsigned long long中刚好能装下其所有可能的一种
移位运算符
对运算对象执行基于二进制的移动操作
unsigned char bits = 0233;// 0233是八进制的字面值
0X12342 | 0X12343 | 0X12344 | 0X12345 |
---|
其 余 的 数 据 | 其 余 的 数 据 | 其 余 的 数 据 | 1 0 0 1 1 0 1 1 |
bits << 8;
0X12342 | 0X12343 | 0X12344 | 0X12345 |
---|
0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 1 0 0 1 1 0 1 1 | 0 0 0 0 0 0 0 0 |
bits << 31;
0X12342 | 0X12343 | 0X12344 | 0X12345 |
---|
1 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 |
bits >> 3;
0X12342 | 0X12343 | 0X12344 | 0X12345 |
---|
0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 1 0 0 1 1 |
左移运算符在右侧插入0。右移运算符的行为依赖于左侧的运算对象的类型,这里操作的是无符号类型,在左侧插入0,如果运算对象是带符号类型,在左侧插入符号位的副本或0,如何选择视情况而定
位求反运算符
将运算对象逐位求反后生成一个新值
~bits;
0X12342 | 0X12343 | 0X12344 | 0X12345 |
---|
1 1 1 1 1 1 1 1 | 1 1 1 1 1 1 1 1 | 1 1 1 1 1 1 1 1 | 0 1 1 0 0 1 0 0 |
位与、位或、位异或运算符
&、|、^在两个运算对象上执行相应的逻辑操作
unsigned char b1 = 0145;
0X12342 | 0X12343 | 0X12344 | 0X12345 |
---|
其 余 的 数 据 | 其 余 的 数 据 | 其 余 的 数 据 | 0 1 1 0 0 1 0 1 |
unsigned char b2 = 0257;
0X12342 | 0X12343 | 0X12344 | 0X12345 |
---|
其 余 的 数 据 | 其 余 的 数 据 | 其 余 的 数 据 | 1 0 1 0 1 1 1 1 |
b1 & b2
0X12342 | 0X12343 | 0X12344 | 0X12345 |
---|
0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 1 0 0 1 0 1 |
b1 | b2
0X12342 | 0X12343 | 0X12344 | 0X12345 |
---|
0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 1 1 1 0 1 1 1 1 |
b1 ^ b2
0X12342 | 0X12343 | 0X12344 | 0X12345 |
---|
0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 1 1 0 0 1 0 1 0 |
二.bitset
- #include < bitset >
- 位串可以作为开关(0/1)的集合
- 位运算符同样可以作用于bitset
- 二进制位串从0开始编号,从右至左,低位到高位。
bitset的初始化
bitset类是一种类模板;而与vector不一样的是bitset类型对象的区别仅在其长度而不在其类型。在定义bitset时,要明确bitset含有多少位,须在尖括号内给出它的长度值:
bitset<8> bitvec(1U); // 8位;低位为1,其余为0:00000001;
构造函数 | 介绍 |
---|
bitset<n> b; | b有n位,默认为0 |
bitset<n> b(u); | b是u低n位的拷贝,若n>u的长度,则b高位置0 |
bitset<n> b(s); | b是string对象s中含有的位串的副本 |
bitset<n> b(s,pos,n); | b是s中从位置pos开始的n个位的副本 |
bitset<n> b(s,pos,m,zero,one); | 同上,但s只能包含0或1 |
bitset<n> b(cp,pos,m,zero,one); | cp是指向字符数组或者c风格字符串的指针 |
接受string或字符指针的构造函数是explicit(只能直接初始化)
zero和one可以替换为其他char型字符
bitset的操作
bitset操作定义了多种检测或设置一个或多个二进制位的方法,同时bitset还支持位运算符(将bitset对象看做一个unsigned数)。
操作 | 介绍 |
---|
b.any() | b中是否存在置为1的二进制位? |
b.all() | b中所有位都置为1了吗? |
b.none() | b中不存在置为1的二进制位吗? |
b.count() | b中置为1的二进制位的个数 |
b.size() | 返回b中二进制位的个数 |
b[pos] | 访问b中在pos处的二进制位 |
b.test(pos) | b中在pos处的二进制位是否为1? |
b.set() | 把b中所有二进制位都置为1 |
b.set(pos,v) | 把b中在pos处的二进制位置为bool值v,v默认为true |
b.reset() | 把b中所有二进制位都置为0 |
b.reset(pos) | 把b中在pos处的二进制位置为0 |
b.flip() | 把b中所有二进制位逐位取反 |
b.flip(pos) | 把b中在pos处的二进制位取反 |
b.to_ulong() | 用b中同样的二进制位返回一个unsigned long值,如果b中的位模式不能放入指定结果类型,则抛出overflow_error |
b.to_string(zero,one) | 返回一个string,表示b中的位模式。zero和one默认为0,1 |
os << b | 把b中的位集输出到os流 |
is >> b | 从is读取字符存入b。当下一个字符不是1或0,或已经读b.size()个,读取停止 |
example
#include <iostream>
#include <bitset>
#include <string>
int main()
{
char zero = 0;
std::bitset<8> bits(zero);
if (bits.none())
std::cout << " no 1 in bits: " << bits << std::endl;
else
std::cout << " have 1 in bits: " << bits << std::endl;
bits[7] = 1;
std::cout << bits.to_string('1','2')<<std::endl;
char key = 0;
if (bits.none())
std::cout << " no 1 in bits: " << bits << std::endl;
else
{
std::cout << " have 1 in bits: " << bits << " as a integer is: " << bits.to_ulong() << std::endl;
key = bits.to_ulong();
}
char compare = -128;
std::cout << key << compare << std::endl;
system("pause");
return 0;
}