按位运算符允许按照位来操作整型变量,按位运算符可以应用于signed和unsigned整型,但是通常应哟你于unsigned类型。
按位运算符的一个常见的应用是在整型变量中使用单个的位来存储信息,该位有两种状态
移位运算符
移位运算符可以把整型变量中的内容向左或者向右移动指定的位数,>>向右移动 <<向左移动 移动变量两端的位被舍弃
向左移动相当于乘以2 向右移动相当于除以2
位操作只适用于整型数据,对于float和double类型进行位操作会报错
比如说有个number
number<<2 左移动2位
number>>2 右移动2位
number<<=2相当于number=number<<2
number>>=2相当于number=number>>2
输出的时候需要加括号限制,否则会有异常错误:
cout<<(number<<2);
cout<<(number>>2);
一般位操作都是操作无符号的数,但是有时候需要操作带符号的数:
而对于带符号操作取决于编译器的实现,下面通过一个例子来看看:
signed char value=-104; //10011000
value<<2; //
value>>2; //11100110
常用的按位运算符:
~ 按位求反
& 按位与
^ 按位异或 相同为0不同1
| 按位或
位操作的应用:
1 判断奇偶
根据最后一位是0/1来判断,是0为偶数,是1为奇数
for(i=0;i<100;i++)
if(i&1)
cout<<"奇数:"<<i<<endl;
上述循环可以输出100以内所有的奇数
2 交换两数
void swap(int& a,int& b){
if(a!=b){
a^=b;
b^=a;
a^=b;
}
}
可以将上述if函数体内的表达式合并:
首先需要知道^满******换律
a^=b; a=a^b;
b^=a; b=b^a=b^(a^b);
a^=b; a=a^b=(a^b)^(b^(a^b));
3 变换符号
正数变负数 负数变正数
取反加1就可以得到负数
int reversal(int a){
return ~a+1;
}
4 取绝对值
负数取反加1得到正数
正数直接返回,因此关键在于判断数的正负
int my_abs(int a){
int i=a>>31;
return i==0?a:(~a+1);
}
还有另外一种劲爆的方法:
int my_abs(int a){
int i=a>>31;
return ((a^i)-i);
}
好吧 来个笔试的例子:
写个函数,该函数可以得到一个字节内1的个数,用两种方法来实现
unsigned int onenum(char log){
int i;
unsigned int num=0,val;
for(i=0;i<8;i++){
val=log>>i;
val&=1;//和1与
if(val)
num++;
}
return num;
}
unsigned int onetest(char log){
int i;
unsigned int num=0,val;
for(i=0;i<8;i++){
val=(~log)>>i;
val&=0;
if(!val)
num++;
}
return num;
}
位操作有很多有趣的应用,这里我们总结下高低位交换
给出一个16位无符号的整数,将前8位后8位转换下
方法:左移8位|右移8位即可
#include <iostream>
template<class T>
void PrintBinary(T a){
itn i;
for(i=sizeof(a)*8-1;i>=0;i--){
if(a>>i&1)
cout<<"1";
else
cout<<"0";
if(i%8)
cout<<" ";
}
cout<<endl;
}
int main(){
unsigned short a=3344520;
PrintBinary(a);
a=(a>>8)|(a<<8);
PrintBinary(a);
return 0;
}
参加运算的两个数据,按二进位进行“与”运算。如果两个相应的二进位都为1,则该位的结果值为1,否则为0。即
0&0=0;0&1=0;1&0=0;1&1=1;
例如: 3&5 并不等于8,应该是按位与。
因此,3&5的值得1。如果参加&是负数运算的是负数(如-3 & -5),则以补码形式表示为二进制数,然后按位进行“与”运算。
按位与有一些特殊的用途:
(1)清零。 如果想将一个单元清零,即使其全部二进位为0,只要找一个二进制数,其中各个位符合以下条件:原来的数中为1的位,新数中相应位为0。然后使二者进行&运算,即可达到清零目的。
如:原有数为00101011,另找一个数,设它为10010100,它符合以上条件,即在原数为1的位置上,它的位值均为0。将两个数进行&运算:
00101011
00000000
其道理是显然的。
当然也可以不用10010100这个数而用其他数(如01000100)也可以,只要符合上述条件即可。
(2)取一个数中某些指定位。如有一个整数a(2个字节),想要其中的低字节。
只需将a与(737)8按位与即可。