标签:acm
写这篇文章的主要目的就是一个不断积累的过程,
文中提到的方法其实平时很少用到,就当做是知识扩展吧
位运算中常见的一个操作 与& , 或| , 非~ 异或 ^ 左移位<< 又移位>>
定义我就不说了,记录几个用法直接上代码了
1,求两个数的平均值(有效防止溢出的位运算方法)
int ave(int a,int b) { reutrn (a&b) + ((a^b)>>1) }
解释下,(a&b)表示a,b二进制中都为1的部分(既然是公共的部分就不需要除以2),a^b 的结果是把余下的 a,b中仅有一个对应位为1的相加的结果
(由于不是共有的当然要除以2了) >>1就是除以2
2,不用临时变量交换两个整数的值
int change(int a,int b) { a^=b; b^=a; a^=b; }
补充下,我只是说下这个用法,不要较真说我没用指针根本就无法交换就好。
3,求一个整数的绝对值
int abs(int a) { int i=a>>31; return (a^i ) -i; }
解释下,这里int 是32位整数, a>>31 的结果分两种情况,如果a>=0 那么右移31位答案一定是零,
如果a是负数 那么右移31位的补符号位,结果是-1,二进制表示就是全为1. 而一个数与-1 异或的结果就是对其取反(异或定义)
所以(a^i) - i 的结果就是 取反加一,你懂的。
4,如果判断一个自然数是不是2的整数幂
int chk(int a) { return (a&(a-1)==0) &&(a!=0) }
这个很好理解,由此启发我们可以得到一个判断一个整数2进制表示里面1的个数的方法
int num1(int a) { int ans=0; while(a) { a&=a-1; ans++; } return ans; }
以后再补充。。。
标签:acm
原文地址:http://blog.csdn.net/u012317281/article/details/38391423