在java的源码中我们会经常看到一些这些特殊的运算,了解这些运算的规则可以帮助我们更好的理解代码的意义。

以下我整理的是一些运算的含义,也是边整理边学习,希望对你们有用,如有错误之处还请各位大佬指正,谢谢。

目录

|(或运算符)

&(与运算符)

^(异或运算符)

|| (或逻辑运算符)

&& (且逻辑运算符)

>> (右移运算)

<<(左移运算)

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

<<< (无此表示符)


|(或运算符)

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

比如:1000 | 101 = 1101 .

下面是一些java代码举例。

| 二进制运算规则和对应的十进制
java十进制运算二进制运算二进制运算结果十进制运算结果
1 | 21 | 10 113
2 | 1 10 | 1113
1 | 3 1 | 11113
2 | 310 | 11113
1 | 41 | 1001015
2 | 410 | 1001106
3 | 411 | 100 1117
1 | 51 | 1011015
2 | 510 | 101 1117
3 | 511 | 1011117
4 | 5100 | 1011015

对于代码中的布尔类型运算,则表示两边有一个为true则结果为true,需要注意的是,运算符两边都会计算的。即使 | 前面是false,也会计算 | 后面的表达式。

例如:

System.out.println(true | false); // true
System.out.println(true | true); // true
System.out.println(false | true); // true
System.out.println(false | false); // false

&(与运算符)

& 是是针对二进制的二目运算符。两个二进制数值如果在同一位上都是1,则结果中该位为1,否则为0 。

比如: 10010 & 110 = 00010 . 

下面是一些java代码举例。

& 二进制运算规则和对应的十进制
java十进制运算二进制运算二进制运算结果十进制运算结果
1 & 21 & 10 000
2 & 1 10 & 1000
1 & 3 1 & 11011
2 & 310 & 11102
1 & 41 & 1000000
2 & 410 & 1000000
3 & 411 & 100 0000
1 & 51 & 1010011
2 & 510 & 101 0000
3 & 511 & 1010011
4 & 5100 & 1011004

对于布尔类型的运算,需要&两边都是true,结果才会是true。

System.out.println(true & false);  // false
System.out.println(true & true);   // true
System.out.println(false & true);  // false
System.out.println(false & false); // false

^(异或运算符)

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

比如: 10100 ^ 101 = 10001 .

下面是一些java代码举例。

^ 二进制运算规则和对应的十进制
java十进制运算二进制运算二进制运算结果十进制运算结果
1 ^ 21 ^ 10 113
2 ^ 1 10 ^ 1113
1 ^ 3 1 ^ 11102
2 ^ 310 ^ 11011
1 ^ 41 ^ 1001015
2 ^ 410 ^ 1001106
3 ^ 411 ^ 100 1117
1 ^ 51 ^ 1011004
2 ^ 510 ^ 101 1117
3 ^ 511 ^ 1011106
4 ^ 5100 ^ 1010011

对于布尔类型运算,因为true=1,false=0,所以如果两边相同则结果为0,也就是false。

System.out.println(true ^ false);  // true
System.out.println(true ^ true);   // false
System.out.println(false ^ true);  // true
System.out.println(false ^ false); // false

|| (或逻辑运算符)

逻辑运算符。当 || 两边有一个表达式结果为true时,结果就为true,反之为false。而且当第一个表达式结果为true时不计算第二个表达式。

&& (且逻辑运算符)

逻辑运算符。当且仅当两边表达式都是true时结果才为true,反义false。如果第一个表达式结果为false,不进行第二个表达式计算。

>> (右移运算)

首先理解一下机器编码(二进制)。各种数值在计算机中表示的形式成为机器数,其特点是采用二进制计数制,数的符号用0和1表示。正负符号在最高位,0:正,1:负。

以8位机器字节长为例,所以十进制0使用机器数表示为0 0000000或者1 0000000,+1为0 0000001,-1为1 0000001 。

机器数的码制分为:原码、反码、补码、移码表示。例如:

+5的四个码制表示法如下:

原码:0 0000101

反码:0 0000101 

补码:0 0000101

移码:1 0000101

-5的四个码制表示法如下:

原码:1 0000101

反码:1 1111010

补码:1 1111011

移码:0 1111011

由上可以看出,正数的原码、反码、补码相同,负数的反码为原码的绝对值求反(也就是符号不变,其余取反),负数的补码为其反码的末位加1 。移码都是其补码的符号取反。

然后说一下位运算。

X >> y:表示将X值右移y位。正数和负数右移的处理过程不同,正数是直接右移,则高位(最左边)补y个0

负数是先求反码,再求补码,然后右移两位,最高位补y个1。再求反码,最后再求其原码。

以32位举例。

正数右移两位:38 >> 2 

38的原码:00000000 00000000 00000000 00100110(首位0代表符号+)

右移两位:_ _ 000000 00000000 00000000 00001001

左边补两个0,得到:00000000 00000000 00000000 00001001

结果为:9(十进制)

负数右移两位:-38 >> 2 

-38的原码:  10000000 0000000 0000000 00100110 (首位1表示负号-)

反码:       11111111   1111111   1111111   11011001 (符号位不变,其余为取反)

补码:       11111111   1111111   1111111   11011010 (反码的末位+1)

右移2位:_ _11111111 11111111 11111111 110110

补码左边添两个1,得到:11111111 1111111 1111111 11110110

反码:11111111    11111111  11111111   11110101 (补码的末位-1)

原码:10000000 00000000 00000000 00001010 (反码的符号位不变,其余为取反)

结果为:-10(十进制)

<<(左移运算)

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

正数向左移3位:38 <<  3 

原码:00000000 0000000 0000000 00100110

向左移三位,右边补三个0:00000 00000000 00000000 00100110 000

结果:304

负数向左移3位:-38 <<  3 

原码:10000000 0000000 0000000 00100110

反码:11111111  11111111  11111111 11011001

补码:11111111  11111111  11111111 11011010

左移三位,右边补三个0

补码:11111   11111111    11111111   11011010  000

反码:11111   11111111    11111111   11011001  111

原码:10000  00000000 00000000  00100110  000

结果:-304

对于10进制来说,左移可以理解为2的幂次方,比如 :

  • 38 << 3 就等于 38 乘以 2的3次方,就等于38 * 8 = 304。
  • 5 << 5   就等于 5 乘以 2的5次方,就等于5 * 32 = 160 。

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

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

正数右移两位:38 >>> 2 

原码: 00000000 00000000 00000000 00100110

右移两位,最左边添两个0:00 00000000 00000000 00000000 001001

结果:9

负数右移两位:-38 >>> 2 

原码:10000000 0000000 0000000 00100110

反码:11111111  11111111  11111111 11011001

补码:11111111  11111111  11111111 11011010

右移两位,左边补充两个0

补码:00 11111111 11111111 11111111 110110

反码:00 11111111 11111111 11111111 110110(因为上个补码符号位是0,为正数,所以对应的反码、原码都一样)

原码:00111111 11111111 11111111 11110110(因为反码符号位是0,为正数,所以原码和反码相同)

最终结果:1073741814

<<< (无此表示符)

不存在 <<< 表示符号。

参考文献:JAVA中 ^、&、|和位运算符的含义详解 (这个文章不错,大家可以参考)

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐