一 、位运算实例
1、用一个表达式,判断一个数X是否是2的N次方(2,4,8,16.....),不可用循环语句。
X:2,4,8,16转化成二进制是10,100,1000,10000。如果减1则变成01,011,0111,01111。两者做按位与运算,结果如果为0,则X是2的N次方。
2、统计一个整数的二进制中1的个数
int CountNumberOfOne(int number)
{
int counter = 0;
while (number)
{
counter++;
number &= number - 1 ;
}
return counter;
}
二、位运算基础
很多高级的动态规划题目或者一些基础的运算往往需要较高的执行效率和较低的空间需求,或者需要表示一些状态集合,而位运算刚好能满足这一切。
很多的时候,恰当的位运算使用也能使程序变得更加简洁和优美。
1、位运算法则
位运算是各位互不影响的,比如A为1010而B为1100,那么有
A&B=1000
A|B=1110
A^B=0110
~A=11110101 (1的个数是取决于A的类型的,这里认为A的类型是8位整型)
另外两种位运算是位移运算a<>b。前者表示将a的所有位向左移动b位,后者则表示将a的所有位向右移动b位。对于非负整数(往往这也是我们最关心的),新空出的位将会被0取代。
比如A为1001,而B为3,那么A<>B则为1。
大多数情况下可以简单地认为左移b位就是乘以2^b,而右移b位则是除以(整除)2^b。当然这是存在例外的——对于负数是不能这么简单认为的:比如在GNU
GCC/G++
编译条件下,若A=-1,你会发现对于任何位移运算A>>B,无论B的取值如何,其结果均为-1。因此请注意,在位移运算下务必确保对非负整数进行运算,以免发生不必要的问题。
对于位移运算最常用的操作就是取一个特定的位——比如1<<