位操作
来源:互联网 发布:软件对比分析 编辑:程序博客网 时间:2024/05/29 15:39
& 与运算
| 或运算
^ 异或运算
~ 非运算(求补)
>> 右移运算
<< 左移运算
1、& 与运算
双目运算,两者为1才为1。
2、| 或运算
双目运算,两者有1即为1。可用于合并标志位。
3、^异或运算
双目运算,相同为0,不同为1。可用于翻转某一位,例如0011^0010=0001 就是把第二位翻转。
4、>>右移运算
双目运算,相当于除以2的n次幂
5、<<左移运算
双目运算,相当于乘以2的n次幂
位运算应用:
1、异或运算交换两个数的值。
例如a=3(0011),b=4(0100)
a = a ^ b;(a=0111)
b = b ^ a;(b=0011) //
a = a ^ b;(a=0100)
公式分析:
异或运算满足结合律和交换律。
因此上式2展开等价于 b=b^a^b=a^(b^b)=a^(0000)=a;
式3中展开 a=(a^b)^(b^a^b)=a^b^a=b;
内存角度上分析:
初始a地址存放3,b地址存放4;然后将a地址存放3与4的差别,此时b仍然存放4;然后4与3和4的差别异或运算,有差异的位为1,其余为0,那么相当于把b中所以存在差异的位翻转,无差异的位不变,显然结果为初始a地址的值3;此时b地址存放的值为3,a仍然存放3与4的差异,那么同样将差异与b中的值3异或运算将得到4,并放入a。因此完成了交换运算。
#define SWAP(a,b) a=a^b;\ b=b^a;\ a=a^b;\2、判断整数奇偶性:
判断整数的奇偶性,常规的整数奇偶性判断是使用取余数操作,例如:
#define PARITY(value) (value%2==1)
而实际上有这样一个规律,基数的最低位总是为1,偶数最低位总是为0,因此可以这样判断奇偶性:
#define PARITY(value) (value&1)
3、判断整数是否为2的整数幂
即整数只有一位为1,其余为0,例如 2、4、8、.....
常规操作:遍历2的整次幂并比较是否相同
#include "math.h" template<class Type>bool IsPowerOfTwo(Type value){for(int i = 0,l = 8*sizeof(value); i < l ;i++){if(pow(2,i) == value){return true;}} return false;}而这类数据有这样的规律:n&(n-1)总是为0,1是特殊情况,因此上式简化为
#defineISPOWEROFTWO(n) ((!(n&(n-1)) ) && n)4、统计n中1的个数
常规办法:判断n的奇偶性,为奇数则统计个数加1,然后n右移1位,只到n为0。
template<class Type>inline bool Parity(Type value){return (value % 2 != 0);}template<class Type>inline int CountOne(Type value){if(value != 0){return Parity(value) + CountOne(value >> 1);}return 0;}优化方法:
考虑2位整数 n=11,里边有2个1,先提取里边的偶数位10,奇数位01,把偶数位右移1位,然后与奇数位相加,因为每对奇偶位相加的和不会超过“两位”,所以结果中每两位保存着数n中1的个数;
相应的如果n是四位整数 n=0111,先以“一位”为单位做奇偶位提取,然后偶数位移位(右移1位),相加;再以“两位”为单位做奇偶提取,偶数位移位(这时就需要移2位),相加,因为此时没对奇偶位的和不会超过“四位”,所以结果中保存着n中1的个数;
依次类推可以得出更多位n的算法。整个思想类似分治法。
int CountOne(unsigned long n){ //0xAAAAAAAA,0x55555555分别是以“1位”为单位提取奇偶位 n = ((n & 0xAAAAAAAA) >> 1) + (n & 0x55555555); //0xCCCCCCCC,0x33333333分别是以“2位”为单位提取奇偶位 n = ((n & 0xCCCCCCCC) >> 2) + (n & 0x33333333); //0xF0F0F0F0,0x0F0F0F0F分别是以“4位”为单位提取奇偶位 n = ((n & 0xF0F0F0F0) >> 4) + (n & 0x0F0F0F0F); //0xFF00FF00,0x00FF00FF分别是以“8位”为单位提取奇偶位 n = ((n & 0xFF00FF00) >> 8) + (n & 0x00FF00FF); //0xFFFF0000,0x0000FFFF分别是以“16位”为单位提取奇偶位 n = ((n & 0xFFFF0000) >> 16) + (n & 0x0000FFFF); return n;}看起来似乎采用位运算的代码比朴素方法代码要复杂的多,但是在性能上有着朴素方法无法比拟的优越性,只要四步简单的运算就能达到目的,而朴素方法不是用循环就是递归,这大大降低了CPU的运算性能。
5、正整数的模运算(负整数不适用)
6、循环位移
例如数n,循环左移k位:a=a<<k|a>>sizeof(a)-k;
循环右移k位:a=a>>k|a<<sizeof(a)-k;
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- Android四大组件
- c# 短信猫池移动空充程序
- Android的小菜鸟
- 5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
- android 选择图片拍照并剪切照片上传到服务器
- 位操作
- 【学习ios之路:Objective-C】字典.集合.
- JQuery之表单的reset()方法
- ReflectionMethod执行类中的方法
- 一个通用的Android App架构
- 2014年总结之dm组数据仓库设计总结
- 基于像素的碰撞检测(移植到cocos2dx 3.x)
- Unicode与汉字的转换
- oracle中比较两表表结构差异和数据差异的方法