JAVA中 ^、&、|和位运算符的含义详解

原文地址:https://blog.csdn.net/kaaryachen/article/details/85082158/

1. ^(异或运算符)

^是针对二进制的二目运算符。运算规则:两个二进制数值如果在同一位上相同,则结果中该位为0,否则为1,比如1011 & 0010 = 1001。

2. |(或运算符)

|是针对二进制的二目运算符。运算规则:两个二进制数值如果在同一位上至少有一个1,则结果中该位为1,否则为0,比如1011 & 0010 = 1011。

3. &(与运算符)

&是是针对二进制的二目运算符。需要注意的是&&是java中判断条件之间表示“和”的标识符,&是一个二目运算符,两个二进制数值如果在同一位上都是1,则结果中该位为1,否则为0,可以认为两个都是true(1),结果也为true(1),比如1011 & 0110 = 0010。

&还有一个比较重要的地方,也是面试中经常出现的问题,即该运算符可以计算余数。我们知道四则运算中速度最慢的就是除,而取余操作更加慢,因此可以通过&来快速的求两个数的余数,来看例子:

public ModTest{
    public static void main(String[] args){
        System.out.println(45 & 11);
        System.out.println(45 & 7);
    }
    /**result:3, 5*/
}

给定x, y两个数值,想求x与y的余数,只需要x & (y-1)即可,如上面例子所示,想求45和12(45和8)的余数,只要求45 & 11(45 & 7)。


以下三种运算符都是位运算符

>>x(常数): 向右移动x位(顶点在哪个方向就往哪个方向移动),如果该数是正数,则高位(最左边)补x个0,如果是负数,则最高位补x个1。

<<x(常数): 向左移动x位(顶点在哪个方向就往哪个方向移动),无论正负数低位(最右边)都补x个0。

<<<: 无该表示方式。

>>>x(常数): 表示无符号右移x位,所谓无符号是与>>x对比,该操作在移动后,无论正负数高位(最左边)都补0。

4. <<(左移运算符)

举例1:-20<<2

原码:10000000 00000000 00000000 00010100

反码: 11111111   11111111   11111111  11101011(符号位不变,其他位取反)

补码: 11111111   11111111   11111111  11101100(反码 + 1)

左移两位(最右边两位添0)

补码: 11111111   11111111   11111111  10110000

反码: 11111111   11111111   11111111  10101111(补码 - 1)

原码: 10000000 00000000 00000000 01010000(符号位不变,其他位取反)

结果:-80

举例2:20<<2

原码(反码,补码):00000000 00000000 00000000 00010100

左移两位(最右边两位添0)

原码(反码,补码):00000000 00000000 00000000 01010000

结果:80

5. >>(右移运算符)

举例1:-20>>2

原码:10000000 00000000 00000000 00010100

反码: 11111111   11111111   11111111  11101011(符号位不变,其他位取反)

补码: 11111111   11111111   11111111  11101100(反码 + 1)

右移两位(最左边两位添1)

补码: 11111111   11111111   11111111  11111011

反码: 11111111   11111111   11111111  11111010(补码 - 1)

原码: 10000000 00000000 00000000 00000101(符号位不变,其他位取反)

结果:-5

举例2:20>>2

原码(反码,补码):00000000 00000000 00000000 00010100

右移两位(最左边两位添0)

原码(反码,补码):00000000 00000000 00000000 00000101

结果:5

6. >>>(无符号右移运算符)

举例1:-2>>>1

原码:10000000 00000000 00000000 00000010

反码: 11111111  11111111   11111111  11111101(符号位不变,其他位取反)

补码: 11111111  11111111   11111111  11111110(反码 + 1)

右移1位(无符号位运算符,最左边一位只添0)

补码: 01111111  11111111   11111111  11111111

反码: 01111111  11111111   11111111  11111111(高位为0,正数)

原码: 01111111  11111111   11111111  11111111(与反码相同)

结果:2147483647

举例2:2>>>1

原码(反码,补码):00000000 00000000 00000000 00000010

右移一位(最左边一位添0)

原码(反码,补码):00000000 00000000 00000000 00000001

结果:1

7.额外知识

^=、|=、&=、<<=、>>=、>>>=与不加等号差不多,只是加入了赋值操作,以>>=为例:

public class Test {
	public static void main(String[] args) {
		int num = 2;
		System.out.println(num>>=1);
        System.out.println(num);
	}
    /**result:1  1
}

注意:既然有赋值操作,那么运算符左边不能是一个常数,比如2>>=1就会报错。

计算中储存数据是用补码的形式

 

参考文献:

https://www.cnblogs.com/liaopeng/p/8436155.html

http://www.cnblogs.com/chuijingjing/p/9405598.html

https://blog.csdn.net/tianyeshiye/article/details/80261622

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值