Java中的位运算符号解读(&、|、^、~、<<、>>、>>>)

 更新时间:2023年08月21日 16:36:42   作者:羽觞醉月11  
这篇文章主要介绍了Java中的位运算符号(&、|、^、~、<<、>>、>>>),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

1. 位运算符号概览

符号描述运算规则
&两个位都为1时,结果才为1
|两个位都为0时,结果才为0
^异或两个位相同为0,不同为1
~取反所有位置0变1,1变0
<<左移各二进位全部左移若干位,高位丢弃,低位补0
>>带符号右移各二进位全部右移若干位,低位丢弃,高位补为符号位
>>>无符号右移各二进位全部右移若干位,低位丢弃,高位补0

还有两个符号,并不是位运算符,但是容易与位运算符混淆,后面将与其相似的位运算符进行一并讲解:

符号描述运算规则
&&逻辑与左右表达式均为true时,运算最终结果才为true
||逻辑非左右表达式只要有一个为true,运算最终结果就为true

2. 一个工具

下面的函数可以帮助我们打印Java中int整型的在底层的32位信息,后面可以使用该工具对程序进行调试:

public static void print(int num) {
    for (int i = 31; i >= 0; i--) {
        System.out.print((num & (1 << i)) == 0 ? "0" : "1");
    }
    System.out.println();
}
// print(1);  -->  00000000000000000000000000000001
// print(-1); -->  11111111111111111111111111111111
// print(Integer.MAX_VALUE);  -->  01111111111111111111111111111111
// print(Integer.MAX_VALUE);  -->  10000000000000000000000000000000

下面开始对每个符号进行介绍。

3. 按位与(&)、逻辑与(&&)

**按位与(&)**的具体运算规则为:

1 & 1 = 1        1 & 0 = 0        0 & 1 = 0        0 & 0 = 0

// 举例:
print(123);		// 00000000000000000000000001111011
print(321);		// 00000000000000000000000101000001
print(a & b);	// 00000000000000000000000001000001
// 任何数与0相与都等于0
// 任何数与自己相与都等于自己

在Java中,(&)不仅可以作为位运算符号,同样也可以作为逻辑与符号,

要注意:(&&)并不是位运算符号,不可以参与位运算!

**逻辑与(&)、逻辑与(&&)**的具体运算规则为:

true & true = true			true & false = false		
false & true = false		false & false = false	
true && true = true			true && false = false		
false && true = false		false && false = false

两者的区别在于:

**逻辑与(&)**在运算时,不论(&)前面的表达式的结果是否为false,(&)后面的表达式都会执行运算;

而**逻辑与(&&)**在运算时,如果(&&)前面的表达式的结果为false,则(&&)后面的表达式就不会执行运算。

4.按位或(|)、逻辑或(||)

**按位与(&)**的具体运算规则为:

1 | 1 = 1        1 | 0 = 1        0 | 1 = 1        0 | 0 = 0        

// 举例:
print(123);		// 00000000000000000000000001111011
print(321);		// 00000000000000000000000101000001
print(a | b);	// 00000000000000000000000101111011
// 任何数与0相或都等于自身
// 任何数与自己相或都等于自己

在Java中,(|)不仅可以作为位运算符号,同样也可以作为逻辑与符号。

要注意:(||)并不是位运算符号,不可以参与位运算!

**逻辑或(|)、逻辑或(||)**的具体运算规则为:

true | true = true			true | false = true		
false | true = true			false | false = false	
true || true = true			true || false = true		
false || true = true		false || false = false

两者的区别在于:

**逻辑或(|)**在运算时,不论(|)前面的表达式的结果是否为true,(|)后面的表达式都会执行运算;

而**逻辑或(||)**在运算时,如果(||)前面的表达式的结果为true,则(||)后面的表达式就不会执行运算。

5. 异或(^)

**异或(^)**的具体运算规则为:

1 ^ 1 = 0        1 ^ 0 = 1        0 ^ 1 = 1        0 ^ 0 = 0    
// 即相同为0,不同为1

// 举例:
print(123);		// 00000000000000000000000001111011
print(321);		// 00000000000000000000000101000001
print(a ^ b);	// 00000000000000000000000100111010
// 任何数与0异或都等于自身
// 任何数与自己异或都为0

6. 取反(~)

**取反(~)**的具体运算规则为:

~1 = 0        ~0 = 1

// 举例:
print(123);		// 00000000000000000000000001111011
print(~a);		// 11111111111111111111111110000100
// 符号位也取反

**取反(~)**可以用来求相反数:

// 一个32整数,取反再+1,就是该数的相反数,效果等同于加负号(-)
int a = 123;
System.out.println(a);		// 123
System.out.println(~a+1);	// -123

说明:

由于Java中int类型的整数范围为 − 2 31 ∼ 2 31 − 1 -2^{31}\sim2^{31}-1 −231∼231−1,负数的个数比正数多一个,这样就导致,所有的正数都有相应的负的相反数,但是并不是所有的负数都有正的相反数:

a = Integer.MIN_VALUE;
System.out.println(a);		// -2147483648
print(a);					// 10000000000000000000000000000000
System.out.println(~a+1);	// -2147483648
print(~a + 1);				// 10000000000000000000000000000000
// Java中int整数最小值的相反数还是其自身
// 如果一定需要对int整数最小值求相反数,请将int类型换为long类型

7. 左移(<<)

左移表示的是某数的各二进位全部左移若干位,高位丢弃,低位补0

// 举例:
print(123);			// 00000000000000000000000001111011
print(123 << 1);	// 00000000000000000000000011110110	
// 整体左移1位,高位丢弃,低位补0

应用:

// 左移1位相当于在原数的基础上乘以2
System.out.println(123);	// 123
System.out.println(123<<1);	// 246
// 左移2位相当于在原数的基础上乘以4
System.out.println(2);		// 2
System.out.println(2<<2);	// 8
// 左移3位、4位...以此类推

8. 带符号右移(>>)、无符号右移(>>>)

**带符号右移(>>)**指的是各二进位全部右移若干位,低位丢弃,高位补为符号位

**无符号右移(>>>)**指的是各二进位全部右移若干位,低位丢弃,高位补0

int a = 123;	
print(a);		// 00000000000000000000000001111011
print(a>>2);	// 00000000000000000000000000011110
print(a>>>2);	// 00000000000000000000000000011110
int b = -123;
print(b);		// 11111111111111111111111110000101
print(b>>2);	// 11111111111111111111111111100001
print(b>>>2);	// 00111111111111111111111111100001
// 区别就在于:一个高位用符号位补,一个高位用0补

Java中没有(<<<)符号!!!

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Activiti开发环境的搭建过程详解

    Activiti开发环境的搭建过程详解

    这篇文章主要介绍了Activiti开发环境的搭建过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Javaweb使用cors完成跨域ajax数据交互

    Javaweb使用cors完成跨域ajax数据交互

    本文由跨域、cors的概念开始,进而向大家介绍了Javaweb使用cors完成跨域ajax数据交互的相关内容,需要的朋友可以了解下。
    2017-09-09
  • Mybatis中实体类属性与数据列表间映射方法介绍

    Mybatis中实体类属性与数据列表间映射方法介绍

    这篇文章主要介绍了Mybatis中实体类属性与数据列表间映射方法介绍,一共四中方法,供大家参考。
    2017-10-10
  • JAVA中compareTo方法的使用小结

    JAVA中compareTo方法的使用小结

    compareTo方法的目的是用来比较两个对象的大小的,本文主要介绍了JAVA中compareTo方法的使用小结,具有一定的参考价值,感兴趣的可以了解一下
    2024-07-07
  • 使用Springboot搭建OAuth2.0 Server的方法示例

    使用Springboot搭建OAuth2.0 Server的方法示例

    这篇文章主要介绍了使用Springboot搭建OAuth2.0 Server的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 透彻理解Java中Synchronized(对象锁)和Static Synchronized(类锁)的区别

    透彻理解Java中Synchronized(对象锁)和Static Synchronized(类锁)的区别

    这篇文章主要介绍了Java中Synchronized(对象锁)和Static Synchronized(类锁)的区别,希望对大家有所帮助,一起跟随小编过来看看吧
    2018-05-05
  • Java设计模式中的工厂模式详解

    Java设计模式中的工厂模式详解

    这篇文章主要介绍了Java设计模式中的工厂模式详解,工厂方法模式(Factory Method Pattern):创新型模式之一,简称工厂模式,通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象,需要的朋友可以参考下
    2023-09-09
  • Spring @Bean注解深入分析源码执行过程

    Spring @Bean注解深入分析源码执行过程

    随着SpringBoot的流行,我们现在更多采用基于注解式的配置从而替换掉了基于XML的配置,所以本篇文章我们主要探讨基于注解的@Bean以及和其他注解的使用
    2023-01-01
  • 解决Spring使用@MapperScan问题

    解决Spring使用@MapperScan问题

    这篇文章主要介绍了解决Spring使用@MapperScan问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Java实现花卉管理系统

    Java实现花卉管理系统

    这篇文章主要为大家详细介绍了Java实现花卉管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06

最新评论