位运算

一、运算符:

(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;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值