位运算的常用操作总结
2016-07-01 10:43
435 查看
位运算是一个神奇的运算,可以很巧妙的解决一些难题,同时速度还非常快。下面将介绍位运算基本的概念,以及位运算的一些常用方法。
这里需要注意的是,位运算的时候全部都是换算成二进制的,一般都是32位的长度。
2.2 判断一个数是不是2的幂次
判断一个数是不是2的幂次,要分析2的次幂的数的二进制表示中,必然只有一个1,其余的都是0,要记住这个性质。而且n&(n-1)这也是一个重要的性质,可以实现把n的最右边的1变成0。
2.3 求一个数的绝对值
对于负数可以采用通过对其取反后加1来得到正数。首先是向右移动31位,如果是正数就会得到0,如果是负数就是得到-1,对于正数可以直接输出,对于负数可以取反加1。
2.4 求一个数的相反数
可以使用取反操作,但需要注意的是取反之后要加1。
2.5 判断一个数的奇偶性
只需要和1进行与操作即可,因为一个奇数的二进制表示中1的个数肯定是偶数,而一个偶数的的二进制表示中1的个数肯定是奇数个。
2.6 、实现加法运算
异或操作可以实现无进位的加法,要实现进位操作的话,需要有一个进位变量记录是否进位。
2.7 实现减法
2.7、实现正数的乘法
原理上还是通过加法计算。将b个a相加。
2.8、实现正数除法
本质上还是进行的减法操作,看看,除数可以减去多少次被除数。
2.9、统计一个数的二进制表示中有多少个1
使用的性质就是一个数和这个数减去1相与的话实现的效果就是把二进制表示中的最后一个1变为0。这样就可以统计次数了,也就是1的个数。
2.10、查找序列中只出现一次的数,其余的数出现了2次
一个数和自己异或操作就是0,这样就可以找出来,需要知道性质就是a^b^c=a^c^b
2.11、反转二进制序列,然后输出整数
原数不断右移一位,然后取出最低位赋给新数的最低位,然后新数左移移位。
2.12、实现两个数的平均数
1、位运算的基本概念
图片来自谷歌。这里需要注意的是,位运算的时候全部都是换算成二进制的,一般都是32位的长度。
2、常用的位运算方法
2.1 交换两个数int x = 1, y = 2; x ^= y; y ^= x; x ^= y;
2.2 判断一个数是不是2的幂次
判断一个数是不是2的幂次,要分析2的次幂的数的二进制表示中,必然只有一个1,其余的都是0,要记住这个性质。而且n&(n-1)这也是一个重要的性质,可以实现把n的最右边的1变成0。
public static boolean mici(int a) { if(a==0) return false; return (a&(a-1))==0; }
2.3 求一个数的绝对值
对于负数可以采用通过对其取反后加1来得到正数。首先是向右移动31位,如果是正数就会得到0,如果是负数就是得到-1,对于正数可以直接输出,对于负数可以取反加1。
int i=-1; int j=i>>31; return (i^j)-j;
2.4 求一个数的相反数
可以使用取反操作,但需要注意的是取反之后要加1。
int a=-1; int b=~a+1;
2.5 判断一个数的奇偶性
只需要和1进行与操作即可,因为一个奇数的二进制表示中1的个数肯定是偶数,而一个偶数的的二进制表示中1的个数肯定是奇数个。
int a=9; return (a&1)==1;
2.6 、实现加法运算
异或操作可以实现无进位的加法,要实现进位操作的话,需要有一个进位变量记录是否进位。
public static int getSum(int a, int b) { while (b != 0) { int c = a ^ b; //无进位加法 b = (a & b) << 1; a = c; } return a; }
2.7 实现减法
//实现减法 a-b public static int jianfa(int a,int b) { return getSum(a, ~b+1); }
2.7、实现正数的乘法
原理上还是通过加法计算。将b个a相加。
public static int Multi(int a, int b) { int ans = 0; while (b > 0) { if ((b & 1) != 0) { ans = getSum(ans, a);//两个数相加 } a = a << 1; b = b >> 1; } return ans; }
2.8、实现正数除法
本质上还是进行的减法操作,看看,除数可以减去多少次被除数。
//实现正数除法 public static int divide(int a,int b) { int res=0; while(a>=b){ a=jianfa(a,b); res++; } return res; }
2.9、统计一个数的二进制表示中有多少个1
使用的性质就是一个数和这个数减去1相与的话实现的效果就是把二进制表示中的最后一个1变为0。这样就可以统计次数了,也就是1的个数。
public int hammingWeight(int n) { int sum=0; while(n!=0){ sum++; n=n&(n-1); } return sum; }
2.10、查找序列中只出现一次的数,其余的数出现了2次
一个数和自己异或操作就是0,这样就可以找出来,需要知道性质就是a^b^c=a^c^b
public int singleNumber(int[] nums) { int r=0; for(int i=0;i<nums.length;i++){ r=r^nums[i]; } return r; }
2.11、反转二进制序列,然后输出整数
原数不断右移一位,然后取出最低位赋给新数的最低位,然后新数左移移位。
private static int rever(int a) { int res=0; for (int i = 0; i < 32; i++) { res=res<<1|(a&1); a>>=1; } return res; }
2.12、实现两个数的平均数
int a=1; int b=9; return (a+b)>>1;
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树