位运算技巧与应用

来源:互联网 发布:淘宝网孕妇保暖上衣 编辑:程序博客网 时间:2024/03/29 19:40

位运算是把数字用二进制表示之后,对每一位上的0或者1的运算。运算包括与、或、异或,非。熟练掌握位运算技巧,能给我们解决问题提供一些巧妙的方法。

一、逻辑运算符

1、与运算

位与运算的实质是将参与运算的两个数据,按对应的二进制数逐位进行逻辑与运算,1&1=1,1&0=0, 0&0=0。性质是“与0与为0,与1与保留原数”。因此,常用于清零,保留特定位,获取特定为等。

2、或运算

位或运算的实质是将参与运算的两个数据,按对应的二进制数逐位进行逻辑或运算。1|1=1,1|0=1,0|0=0。因此可用于将某些位置为1等操作。

3、异或运算

位异或运算的实质是将参与运算的两个数据,按对应的二进制数逐位进行逻辑异或运算。相同位0,相异为1。因此常用语定位翻转,数字交换等。

4、非运算

位非运算的实质是将参与运算的两个数据,按对应的二进制数逐位进行逻辑非运算。

来吧,看看都有哪些技巧:

二、位运算技巧

我是从大神博客摘抄的:优秀程序员不得不知道的20个位运算技巧,我觉得这几个比较重要,因此摘录了过来,想了解更过可以去大神博客看看。

1、乘2除2

n=n<<1; //乘2n=n>>1; //除2

乘以除以2的m次方

n=n<<m; //乘以2的m次方n=n>>m; //除以2的m次方

2、判断奇偶

(n&1)==1

3、交换两个数(不用临时变量)

a=a^b;b=b^a;a=a^b;

当然也可以这样:

a=a+b;b=a-b;a=a-b;

4、对某个特定位操作

//从低位到高位,取n的第m位(n >> (m-1)) & 1//从低位到高位.将n的第m位置1n | (1 << (m-1));   /*将1左移m-1位找到第m位,得到000...1...000 n在和这个数做或运算*/ //从低位到高位,将n的第m位置0n & ~(1 << (m-1));  /* 将1左移m-1位找到第m位,取反后变成111...0...1111 n再和这个数做与运算*/  

三、位运算应用

二进制中1的个数

int NumberOf1(int n){   int count=0;   while(n)   {      ++count;      n=(n-1)&n;   }  }

能理解为什么这么做吗?
看个简单例子吧,今年2017年,2017的二进制是111 1110 0001 ,2017减1后为2016,111 1110 0000:
n=n&(n-1)=111 1110 0001 & 111 1110 0000=111 1110 0000
n=n&(n-1)=111 1110 0000 & 111 1101 1111=111 1100 0000
…….
…….
…….
看出什么端倪了吗?1的个数会逐渐减少,最终一个都没有了。

同理,我们可以写出求二进制中0的个数:

int NumberOf1(int n){   int count=0;   while(n)   {      ++count;      n=(n-1)|n;   }     return count;}

这个是n中的0逐渐都会变成1,直到溢出,这样就可以统计出0的个数。

当然也有其他常规解法,比如每次判断最后一位是不是1,然后右移一位,再判断….

int NumberOf1(int n){   int count=0;   while(n)   {      if(n&1)        count++;      n=n>>1;   }     return count;}

上述办法,注意对于负数会有问题,那么我们不移动n,移动1好了。

int NumberOf1(int n){   int count=0;   unsigned flag=1;   while(flag)   {      if(n&flag)        count++;      flag=flag<<1;   }     return count;}

这个方法,会循环32次,也就是int的位数。

参考资料:
优秀程序员不得不知道的20个位运算技巧
位运算及其应用详解

0 0
原创粉丝点击