java 位操作符
2016-09-22 16:18
344 查看
位运算的应用场景:
因为位运算的运算效率比直接对数字进行加减乘除高很多,所以当出现以下情景且对运算效率要求较高时,可以考虑使用位运算。
情况1:
输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数。例如输入5,因为5 的二进制表示为101,所以输出为2.
解题思路:普通方法是将5转换成二进制的形式,然后再遍历该二进制字符串,如果是1,则计数count加1
public static int toBinary(int m){
int count = 0;
String s = Integer.toBinaryString(m);
for(int i = 0; i < s.length();i++){
if(s.charAt(i) == '1'){
count++;
}
}
return count;
}
如果用位运算,则数字在内存中 ,被转化为二进制。例如7表示为0111,n&(n-1) 即(0111)&(0110)== 0110 就是 n去除了最后一个1
;几个1 就可以在几次内 去除几个1;
情况2;
两个int32整数m和n的二进制表达,有多少个位(bit)不同么? 例如输入为1999和 2299,因为两个的二进制分别表示为
11111001111和1000011111011,所以输出为7.
思路1:是两个数转换成二进制之后,位数若不相等,则短的那个前面补0,使两个二进制的位数相等,然后在依次判断每一位上的数字是否相等,若相等则count加1;
思路2: 使用异或运算。异或运算符是用符号“^”表示的,其运算规律是:两个操作数的位中,相同则结果为0,不同则结果为1。
将两个数进行异或操作后的结果转换成二进制形式,然后计算该二进制有多少个1,即有多少位不同
其他操作:参考http://blog.csdn.net/linbilin_/article/details/50608757
1.
判断int型变量a是奇数还是偶数
a&1 = 0 偶数
a&1 = 1 奇数
2. 求平均值,比如有两个int类型变量x、y,首先要求x+y的和,再除以2,但是有可能x+y的结果会超过int的最大表示范围,所以位运算就派上用场啦。
(x&y)+((x^y)>>1);
3. 对于一个大于0的整数,判断它是不是2的几次方
((x&(x-1))==0)&&(x!=0);
4. 比如有两个int类型变量x、y,要求两者数字交换,位运算的实现方法:性能绝对高效
x ^= y;
y ^= x;
x ^= y;
5. 求绝对值
int abs( int x )
{
int y ;
y = x >> 31 ;
return (x^y)-y ; //or: (x+y)^y
}
6. 取模运算,采用位运算实现:
a % (2^n) 等价于 a & (2^n - 1)
7. 乘法运算 采用位运算实现
a * (2^n) 等价于 a << n
8. 除法运算转化成位运算
a / (2^n) 等价于 a>> n
9. 求相反数
(~x+1)
10 a % 2 等价于 a & 1
因为位运算的运算效率比直接对数字进行加减乘除高很多,所以当出现以下情景且对运算效率要求较高时,可以考虑使用位运算。
情况1:
题目描述
输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数。例如输入5,因为5 的二进制表示为101,所以输出为2.解题思路:普通方法是将5转换成二进制的形式,然后再遍历该二进制字符串,如果是1,则计数count加1
public static int toBinary(int m){
int count = 0;
String s = Integer.toBinaryString(m);
for(int i = 0; i < s.length();i++){
if(s.charAt(i) == '1'){
count++;
}
}
return count;
}
如果用位运算,则数字在内存中 ,被转化为二进制。例如7表示为0111,n&(n-1) 即(0111)&(0110)== 0110 就是 n去除了最后一个1
;几个1 就可以在几次内 去除几个1;
public class Main { public static void main(String[] args) { Scanner sc=new Scanner(System.in); while (sc.hasNext()){ int n=sc.nextInt(); int count=0; while (n!=0){ count++; n=n&(n-1); } System.out.println(count); } } }
情况2;
题目描述
两个int32整数m和n的二进制表达,有多少个位(bit)不同么? 例如输入为1999和 2299,因为两个的二进制分别表示为11111001111和1000011111011,所以输出为7.
思路1:是两个数转换成二进制之后,位数若不相等,则短的那个前面补0,使两个二进制的位数相等,然后在依次判断每一位上的数字是否相等,若相等则count加1;
public static int countBitDiff(int m, int n) { String ms = Integer.toBinaryString(m); String ns = Integer.toBinaryString(n); int count = 0; int diff = Math.abs(ms.length() - ns.length()); //如果两个数转换成二进制形式之后位数不相等,则在短的那个数前面加0,直到长度相等 while (diff > 0) { if (ms.length() < ns.length()) { ms = "0"+ ms; } if (ms.length() > ns.length() ) { ns = "0"+ns; } diff--; } //转换成数组,然后每个位进行比较 char[] sm = ms.toCharArray(); char[] sn = ns.toCharArray(); for (int i = 0; i < sn.length; i++) { if (sm[i] != sn[i]) { count++; } } return count; }
思路2: 使用异或运算。异或运算符是用符号“^”表示的,其运算规律是:两个操作数的位中,相同则结果为0,不同则结果为1。
将两个数进行异或操作后的结果转换成二进制形式,然后计算该二进制有多少个1,即有多少位不同
public static int count(int m, int n){ int count = 0; String res = Integer.toBinaryString(m^n); for (int i = 0; i < res.length(); i++) { if (res.charAt(i) == '1') { count++; } } return count; }
其他操作:参考http://blog.csdn.net/linbilin_/article/details/50608757
1.
判断int型变量a是奇数还是偶数
a&1 = 0 偶数
a&1 = 1 奇数
2. 求平均值,比如有两个int类型变量x、y,首先要求x+y的和,再除以2,但是有可能x+y的结果会超过int的最大表示范围,所以位运算就派上用场啦。
(x&y)+((x^y)>>1);
3. 对于一个大于0的整数,判断它是不是2的几次方
((x&(x-1))==0)&&(x!=0);
4. 比如有两个int类型变量x、y,要求两者数字交换,位运算的实现方法:性能绝对高效
x ^= y;
y ^= x;
x ^= y;
5. 求绝对值
int abs( int x )
{
int y ;
y = x >> 31 ;
return (x^y)-y ; //or: (x+y)^y
}
6. 取模运算,采用位运算实现:
a % (2^n) 等价于 a & (2^n - 1)
7. 乘法运算 采用位运算实现
a * (2^n) 等价于 a << n
8. 除法运算转化成位运算
a / (2^n) 等价于 a>> n
9. 求相反数
(~x+1)
10 a % 2 等价于 a & 1
相关文章推荐
- JavaSE 集合框架(1)- 集合框架基础以及List集合
- eclipse配置gradle
- eclipse配置gradle
- spring classPath加载配置多个
- SSH整合开发
- java 数据库连接池
- springAOP之framework包的解读(四)
- springAOP之framework包的解读(三)
- Java 内层for循环控制外层for循环
- Spring-JDK与CGlib代理实现AOP简单实例
- Java垃圾回收机制
- Java中byte相加的问题.
- Java日期时间使用总结
- java API 知识:截取特殊标识之前的字符串
- Java的printf方法
- SpringMVC日期类型转换问题三大处理方法归纳
- Java之匿名内部类
- java api文档的阅读技巧
- Hadoop环境搭建(三、安装JDK)
- Eclipse工程导入到AndroidStudio实战总结