java 位操作符

位运算的应用场景:

因为位运算的运算效率比直接对数字进行加减乘除高很多,所以当出现以下情景且对运算效率要求较高时,可以考虑使用位运算。

情况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 



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值