Java位运算学习 左移位 右移位

本文介绍了Java中的位运算符,重点讲解了左移位(<<)和右移位(>>)运算。左移位运算相当于数字乘以2的指定次方,而右移位运算则等效于数字除以2的指定次方。无符号右移(>>>)会忽略符号位,始终补0。此外,还分享了位移运算的两个法则和常见的应用场景,如快速求幂、判断奇偶性及无临时变量交换数值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java中的位操作符有:

 

&:按位与。

|:按位或。

~:按位非。

^:按位异或。

<<:左移位运算符。

>>:右移位运算符。

<<<:无符号右移运算符。

与或非异或比较简单。

        //按位与( & )
        System.out.println(5 & 7);//输出为5
        System.out.println(5 & 3);// 结果为1
        System.out.println(4 & 1);// 结果为0

        // 按位或( | )
        System.out.println(5 | 3);// 结果为7

        // 按位异或( ^ )  
        System.out.println(5 ^ 3);//结果为6   

        // 按位非( ~ )   
        System.out.println(~5);// 结果为-6  

 

 

 

左移位运算符(<<):

将十进制数字转换为二进制后,整段数字向左移动,高位溢出的需要截断,低位补0。

比如2<<2,即2左移两位

//5左移两位
// 0000 0000 0000 0000 0000 0000 0000 0101 然后左移2位后,低位补0://
// 0000 0000 0000 0000 0000 0000 0001 0100 换算成10进制为20
//相当于5* 2的2次方
System.out.println(5 << 2);

//5左移三位
// 0000 0000 0000 0000 0000 0000 0000 0101 然后左移3位后,低位补0://
// 0000 0000 0000 0000 0000 0000 0010 1000 换算成10进制为40
//相当于5* 2的3次方
System.out.println(5 << 3);

输出结果:

所以,一个数左移多少位相当于这个数乘以2的多少次方。

 

右移位运算符(>>):

将十进制数字转换为二进制后,整段数字向右移动,低位溢出的需要截断,高位补符号位的数字,正数符号位为0补0,负数符号位为1补1。

比如,-6>>2结果为-2

//40右移两位
//0000 0000 0000 0000 0000 0000 0010 1000 初始值右移2位后,高位补符号位的0得:
//0000 0000 0000 0000 0000 0000 0000 1010 换算成10进制为10
//相当于5/ 2的2次方
System.out.println(40 >> 2);

//-40转换成二进制,首先需要写出对应正数40的二进制,然后将符号位置为1,符号位不变,各位取反,再加1,就得到了对应的负数的二进制
// 0000 0000 0000 0000 0000 0000 0010 1000   40的二进制
// 1000 0000 0000 0000 0000 0000 0010 1000   将符号位置为1
// 1111 1111 1111 1111 1111 1111 1101 0111   除符号位外按位取反
// 1111 1111 1111 1111 1111 1111 1101 1000   再加1,得-40的二进制
//-40右移两位
// 1111 1111 1111 1111 1111 1111 1101 1000   初始值右移2位后,高位补符号位的1得:
// 1111 1111 1111 1111 1111 1111 1111 0110   转换为十进制是先减一再按位取反,不看符号位就是其对应的正数,换算成十进制为-10
System.out.println(-40 >> 2);

输出结果:

所以,一个数右移多少位相当于这个数除以2的多少次方。

 

无符号右移(>>>)

将十进制数字转换为二进制后,整段数字向右移动,低位溢出的需要截断,高位补0(不管符号位是什么)

所以说,不管是负数还是正数,无符号右移之后符号位都会变为0,也就是都会变为正数。

无符号右移对于正数来说和不同右移运算符一样。

比如,-1>>>1结果为2147483647,也就是得到了Integer.MAX_VALUE

//1111 1111 1111 1111 1111 1111 1111 1111   -1的二进制,然后右移一位,高位补0
//0111 1111 1111 1111 1111 1111 1111 1111   转换为十进制为2147483647,也就是Integer.MAX_VALUE
System.out.println(-1 >>> 1);
        
//和普通右移运算符一样,得到10
System.out.println(40 >>> 2);

输出结果:

 

两个法则:

 

法则一:任何数左移(右移)32的倍数位等于该数本身。

法则二:在位移运算m<<n的计算中,若n为正数,则实际移动的位数为n%32,若n为负数,则实际移动的位数为(32+n%32),右移,同理。

 

常见使用场景:

 

1.求幂运算时,比如求m*2^n,可以直接写为 m<<n

System.out.println("3*2^3=" + (3<<3));//3*2^3=24

2.判断一个数的奇偶

n&1 == 1?”奇数”:”偶数”

奇数和偶数在二进制中的区别就是最后一位是0还是1,奇数是1,偶数是0。

因为1的二进制前面全是0,只有最后一位是1,那么这个n不管前面几位是什么,只要与0相与就一定是0,所以就保证了只看最后一位。偶数最后一位是0,与1相与就是0,奇数最后一位是1,与1相与就是1。这样就可以判断出来了。

3.不用临时变量交换两个数的值

public static int[] reverse(int[] nums){  
    int i = 0;  
    int j = nums.length-1;  
    while(j>i){  
        nums[i]= nums[i]^nums[j];  
        nums[j] = nums[j]^nums[i];  
        nums[i] = nums[i]^nums[j];  
        j--;  
        i++;  
    }  
    return nums;  
} 

原理:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值