【说明:本文参考了网上相关内容,做了补充和修改。】
C++中的位操作包括两种:传统的C语言方式的位操作和C++中利用bitset容器进行的位操作。
****** 一、传统的C方式位操作:******
1.基本操作:
使用一个unsigned int变量来作为位容器。
2.位操作符:
|:按位或操作,result = exp1 | exp2;当exp1和exp2中对应位中有一个为1时,则result中对应位为1,否则为0.
应用特点:与0位“或”相应的位不变,与1位“或”设置相应的位为1.
因此用于:设置某一位为1,而保证其它的位不变。比如:result |= (1<<12)将设置result的第12位为1.
也常用于:给某个位属性值附加上另一个属性值,比如:result |= exp;这里相当于给result附加上exp的属性。
&:按位与操作,result = exp1 & exp2;当exp1和exp2中对应的位都为1时,result中对应的位才为1.
应用特点:与0位“与”相应的位为0,与1位“与”相应的位不变。0与1“与”结果为0,1与1“与”结果为1,所以也就是说bit & 1 = bit,与1进行“与”操作不改变本身。
因此用于:设置某一位为0,而保证其它的位不变。比如:result &= ~(1<<12)将设置result的第12为0.
也常用于:获得某个属性的某一位或某几位。比如:result & 3 将获得result的最低的两位。再比如截取一个32位数字的低8位等等。
也常用于:测试某个属性是否等于或包含特定的值。比如:if(result & exp)...
^:按位异或操作符,result = exp1 ^ exp1;当exp1和exp2中对应位的值不相同时,result对应的位为1
应用特点:1)0与1“异或”结果位1,1与1“异或”结果位0,也就是说bit ^ 1 = ~bit,与1“异或”相当于将特定的位取反。
2)1与0“异或”结果位1,0与0“异或”结果位0,也就是说bit ^ 0 = bit,与0“异或”将保持特定的位不变。
因此用于:将某一特定位取反,而保证其它的位不变。比如:result ^= (1<<12)将result的第12位取反。
也常用于:将自己清0,比如:result ^= reslut;将使result所以位都变成0.
~:反转操作符,将位容器中的所以位都反转,将1变成0,0变成1。
<<:按位左移操作符,exp << n;将容器中的所有位向左移n位,空出的位用0填补。
>>:按位右移操作符,exp >> n;将容器中的所有位向右移n位,空出的位用0填补。
3.C方式位操作总结:
设置特定的位用|;
清除特定的位用&;
取反特定的位用^;
取反所有的位用~;
****** 二、C++中bitset容器来操作位:******
1.头文件:
#include
2.声明一个容器:
(a)声明一个指定位数n所有位都为0的空容器:
bitset bits;
(b)声明一个指定位数n并将用相应值来初始化容器:
bitset bits(int m);
bitset bits(string&);
总结:bitset模板类中类型参数传递容器的位数,而构造函数参数通过一个int或一个string&值来从右至左初始化容器中的相应值。
3.bitset的基本用法:
4.bitset与传统C位操作及字符串的转换:
可以通过to_string()成员函数将容器输出为一个string字符串;
可以通过to_long()成员函数将容器输出到传统的用于C风格的位容器中。
5.bitset支持所有位操作
6.位操作的例子:
将一个32位的整数输出成二进制形式:
- //C的方式:
- int i = 343543;
- for(int j=31; j>=0; --j)
- cout << ((i >> j) & 1);
- //C++的方式:
- int i = 343543;
- bitset<32> intBit(i);
- cout << intBit.to_string() << endl;
- //测试一个数字含有多少个1位:
- int count(int x)
- {
- int n = 0;
- while(x) {
- x &= (x-1); //将x的最右边的1位变成0
- ++n;
- }
- return n;
- }
- //测试一个数字含有多少个0位:
- sizeof(x)*8 - count(x);
- //测试一个数字的奇偶性:
- 只需测试最右位:为0则是偶数;位1则是奇数;if(x & 1)奇数; else 偶数;
- ///检测一个无符号数是不为2的次方:
- if(x & (x-1) == 0) true; else false;
- ///二进制补码运算公式:(摘录自网上资料)
- -x = ~x + 1 = ~(x-1);
- ~x = -x-1;
- ~(-x) = x-1;
- x+y = x - ~y-1 = (x|y)+(x&y);
- x-y = x + ~y + 1 = (x|~y) - (~x&y);
- x^y = (x|y) - (x&y);
- x|y = (x& ~y) + y;
- x&y = (~x|y)- ~x;
- ///x == y:
- ~(x-y|y-x);
- ///x != y:
- x-y|y-x;
- ///x < y:
- (x-y)^((x^y)&((x-y)^x));
- ///x <= y:
- (x|~y)&((x^y)|~(y-x));
- ///x < y:
- (~x&y)|((~x|y)&(x-y)); ///无符号x,y的比较
- ///x <= y:
- (~x|y)&((x^y)|~(y-x)) ///无符号x,y的比较
- ///使用位运算的无分支代码:
- ///计算绝对值:
- int abs(int x)
- {
- int y;
- y = x >> 31;
- return (x^y)-y; ///or:(x+y)^y
- }
- ///符号函数:
- sign(int x)
- {
- return (x>>31)|
- (unsigned(-x))>>31; //x=-2的31次方时失败
- }
- ///三值比较:cmp(x, y) = -1(x<y);0(x==y);1(x>y)
- int cmp(int x, int y)
- {
- return (x>y)-(x-y);
- }
阅读(322) | 评论(0) | 转发(0) |