一、运算符:
(1)“&”:0跟任何数字与的时候都是0,1和某位与的时候不改变它
(2)“|” : 0跟任何数字或的时候不变,1和数字或的时候把它变成1
(3)“^” :0跟某位异或不改变,1和某位异或的时候取反
(4)“>>”:最右边的位被抛弃(以1个字节为例说)
正数:最左边添0;00001010>>3=00000001 ;
负数:最左边添1;10001010>>3=11110001
(5)“<<”:最左边的位被抛弃,最右边统一添0;
(正数)00001010<<3=01010000
(负数)10001010<<3=01010000
二、位运算的几种题型:
题型一:
下面这种类型的题遵守三个规则:(1)定符号 (2)定数字 (3)构造数字
1、去掉最后一位 |(101101->10110)| 即:右移一位即可
2、在最后加一个0 |(101101->1011010)| 即:左移一位
3、在最后加一个1 |(101101->1011011)| 即:先左移一位再或上1
4、把最后一位变成1 |(101100->101101)| 即:直接或上1
5、把最后一位变成0 |(101101->101100)| 即:右移再左移(不太可靠),不能异或(如果本身就是0呢)。定符号:“&”,定数字 0,构造数字:~1(111110)
6、最后一位取反 |(101101 -> 101100)| 即:按位异或1 定符号 “^”,定数字“1”,构造数字 :1
7、把右数第k位变成1 |(101001->101101,k=3)| 即: “|” 1 构造数字:1<<(k-1)位 100
8、把右数第k位变成0 |(101101->101001,k=3)| 即:“&” 0 构造数字:~(1<<(k-1))
9、右数第k位取反 |(101001->101101, k=3)| 即:"^" 1 构造数字:(1<<(k-1))
10、取末三位 |(1101101 ->101)| 即:不可以左移四位再右移四位,因为它不止7位, 即: & 1 7(111)
11、取末k位 |(1101101->1101,k=4)| 即:& 1 构造:(1<<k)-1 注:先左移,再减1
12、取右数第k位 |(1101101->1,k=4)| 即:(x>>(k-1))&1
题型二:
13、把右边连续的1变成0 |(100101111->100100000)| 即:x&(x+1)
14、把右边起第一个0变成1 |(100101111->100111111)| 即:x|(x+1)
15、把右边连续的0变成1 |(11011000->11011111)| 即:x|(x-1)
题型三、
1、求一个二进制数中 1 的个数:
方法一:循环32次
int Bits1(unsigned char n)
{
int count = 0;
while(n)
{
if(n&1)
{
count++;
}
n = n>>1;
}
return count;
}
int Bits1(unsigned char n)
{
int count = 0;
int flag = 1;
while(flag)
{
if(n&flag)
{
count++;
}
flag = flag<<1;
}
return count;
}
方法一的第二种写法:可以解决负数
int Bits(int n)
{
int count = 0;
int flag = 1;
while(flag )
{
if(flag & n)
{
count++;
}
flag = flag <<1;
}
return count;
}
方法二:循环1的个数次
int Bits2(unsigned char n)
{
int count = 0;
while(n)
{
n = n & (n-1);
count++;
}
return count;
}
题型四:
1、将二进制逆置
unsigned int Reverse_bit(unsigned int n)
{
unsigned int m = 0;
//while(n != 0)
for(int i=0; i<32; i++)
{
//n & 1; 得到最右边的一位
m = (m<<1) | (n & 1); //取个位,将各位变成左数第一位,再丢个位的原理
n >>= 1;
}
return m;
}
2、输入两个整数m和n,计算需要改变m二进制中的多少位才能得到n;
如:10:1010;13:1101,则需要改变10的二进制的后三位才能得到1101;
int Fun1(int n, int m)
{
int count = 0;
int k = n^m; //两个数按位异或,将相同的全部变为0,不同的全部变为1,1的个数就是需要改变的位数
while(k)
{
k = k & (k-1);
count++;
}
return count;
}
3、判断一个整数是不是2的正数次方
分析:一个整数如果是2的正数次方,那么这个正数的二进制位中只有一个1;
只需要一句语句就可以判断:假设这个正数为n:只需判断n&(n-1)是否为0;
bool Fun(int n)
{
if(n & (n-1)) //为0则代表是
{
return false;
}
else
return true;
}