Java位运算的一些用法和操作

本文详细介绍了位运算的基本操作,包括与(&), 或(|), 异或(^), 取反(~), 左移(<<), 右移(>>)等,并通过实例展示了它们在计算、奇偶性判断、数值交换、查找数组中只出现一次的数等方面的应用。此外,还讨论了如何确定转换两个整数所需的位交换次数,以及不同方法的实现。位运算的高效性和灵活性在程序设计中具有重要作用。
摘要由CSDN通过智能技术生成

 使用位运算的目的是位运算速度比较快,因为它更接近机器的运算语言

&(and)与运算:都为1是1其他为0

|(or)或运算:都是0是0其余为1

^(not):取反

~(xor)异或运算:同为0或同为1是0其余为1

<<:左移

>>:右移

 左移右移位运算可以进行乘法除法运算,<<i左移是乘2的i次方,>>i右移是除2的i次方,>>>是无符号右移(符号位也右移,被0替换

举个简单的例子,如图:

代码如下:

public class Testwys {
public static void main(String[] args) {
	int a=-5;
	int b=a<<2;
	int c=4;
	int d=c<<3;
	int e=-6;
	int f=e>>2;
	int g=e>>>2;
	int j=60;
	int h=j>>3;
	int i=j>>>3;
	System.out.println("-5左移<<2==="+b);
	System.out.println("4左移<<3==="+d);
	System.out.println("-6右移>>2==="+f);
	System.out.println("-6无符号右移>>2==="+g);
	System.out.println("60右移>>3==="+h);
	System.out.println("60无符号右移>>>3==="+i);
}
}

结果如图:

我们可以看到<<左移不管正负符号位都不会变,>>右移不管正负符号位也不会变,而使用>>>无符号位移符时符号位不管正负都会变成正的

&与运算可以判断奇偶性,i&1==0时为偶数否则为奇数

原理如下图(因为二进制1的前面位数都为0,与运算后都是0,最后结果只有0和1两种可能):

去掉二进制的最后一个一:i=i&(i-1) 

代码如下:

public class Testa {
	public static void main(String[] args) {
		int i=6;
		i=i&(i-1);
		int a=5;
		a=a&(a-1);
		System.out.println("6的二进制110去掉最后一个一==100=="+i);
		System.out.println("5的二进制101去掉最后一个一==100=="+a);
}
}

结果如下图:

 ^异或运算:判断相同a^b==0异或是相同为0不同为1,所以二进制如果完全相同异或后是0。

交换数:用异或交换两个数的时候不用引入第三个数

int a=2;

int b=4;

a=a^b;//a^b=c,c^b=a,c^a=b,也就是把a赋值为成c的 数

b=a^b;//b=a

a=a^b;//a=b

代码可简写成如下,

public class Testa {
	public static void main(String[] args) {
		int a=2;
		int b=4;
		System.out.println("交换前(a,b)"+"("+a+","+b+")");
		a^=b;
		b^=a;
		a^=b;
		System.out.println("交换前(a,b)"+"("+a+","+b+")");
	}
}

 结果交换成功:

数组中只出现一次的数其他的数都出现过偶数次找出只出现过一次的数

public class Testa {
	public static void main(String[] args) {
		int[] a= {1,1,2,3,3,3,3,4,4};
		int flag=0;
		for(int i=0;i<a.length;i++) {
			flag^=a[i];
		}
		System.out.println(flag);
	}
}

上面知道两个相同的数异或等于0,所以最后flag就等于只出现过一次的数结果如下:

将位运算混合起来使用:例

给定两个整数A, B,写一个方法确定需要几次换位才可以将A变为B。  

比如 A: 11010  B: 01100  输出:3 

我们首先要知道那些位需要替换,我们很容易想到异或这个功能,A^B,相同的位异或为0,不同的位异或为1,所以我们只需要确定异或之后的数有几个1即可。我们需要确定出这几位一,例如A^B = x, 我们让x&(x-1),这个操作清除了x最右边的1,我们通过一个循环确定次数,直到x为0结束。代码如下:

public class Testa {
	public static void main(String[] args) {
		int A=26;//二进制11010  
		int B=12;//二进制01100    
		int a=bitSwapNums(A,B);
		System.out.println(a);
}
	public static int bitSwapNums(int a, int b) {  
	    int count = 0; 
	  //a^b找出二进制不同位,用i= i & (i - 1)去二进制最后一个1,直到去完1,i=0时停止循环
	    for(int i = a ^ b; i > 0; i= i & (i - 1)){
	        count ++;  
	    }  
	    return count;  
	} 
}

结果如图:

 位运算的应用很灵活,我们也可以这样实现 :

 

public class Testa {
	public static void main(String[] args) {
		int A=26;//二进制11010  
		int B=12;//二进制01100    
		int a=bitSwapNums(A,B);
		System.out.println(a);
}
	public static int bitSwapNums(int a, int b) {  
        int count = 0;  
      //a^b找出二进制不同位,右移运算二进制最后一位是1count加一,直到i=0循环结束
        for(int i = a ^ b; i > 0; i = i >> 1) {  
        	count += i & 1; //与运算i&1最后一位是1结果就是1,最后一位是0结果就是0
        }  
        return count;  
	}  
 
}

结果同样为3。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sshm_666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值