Java运算符

|= (a = a | b)位或

描述:

两个二进制对应位为0时,该位为0,否则为1。拿5的二进制0000 0101和3的二进制0000 0011进行|运算,后三位的对应位都不是同时等于0,所以最终结果为0000 0111也就是7的二进制。

代码示例如下:

1
2
3
4
5
6
private static void test() {
int a = 5;//0000 0101
int b = 3;//0000 0011
a |= b;//0000 0111
System.out.println(a);
}

&= (a = a & b)位与

描述:

两个二进制对应位都为1时,结果为1,否则结果都是0。拿5的二进制0000 0101和3的二进制0000 0011进行&运算,只有最后一位都是1,则最终结果为0000 0001也就是1的二进制。

代码示例:

1
2
3
4
5
6
private static void test1() {
int a = 5;//0000 0101
int b = 3;//0000 0011
a &= b;//0000 0001
System.out.println(a);
}

^= (a = a ^ b)异或运算符

描述:

两个二进制对应位相同时,结果为0,否则结果为1。拿5的二进制0000 0101和3的二进制0000 0011进行^运算,1-5位对应位都是0,所以1-5位都是0,第8位都为1所以第8位也为0,其他的对应位都不相等所以为1,则最终结果为0000 0110也就是6的二进制。

代码示例:

1
2
3
4
5
6
private static void test2() {
int a = 5;//0000 0101
int b = 3;//0000 0011
a ^= b;//0000 0110
System.out.println(a);
}

总结:

  • |=:两个二进制对应位都为0时,结果为0,否则结果为1;
  • &=:两个二进制的对应位都为1时,结果为1,否则结果等于0;
  • ^=:两个二进制的对应位相同时,结果为0,否则结果为1。

~ (取反运算符)

描述:

把数字转为二进制,然后取反,就是1变0,0变1

代码示例:

1
2
3
4
5
6
7
// ~
private static void test6() {
//4 0000 0000 0000 0000 0000 0000 0000 0100
// 1111 1111 1111 1111 1111 1111 1111 1011
System.out.println(Integer.parseInt("-1111111111111111111111111111011",2));
System.out.println(~4);
}

>> (带符号右移)

描述:

符号前面的数字的二进制数,向右移动符号右边的数字位数,正数高位用0补,负数高位用1补。

代码示例:

1
2
3
4
5
6
7
8
private static void test3() {
//4 0000 0000 0000 0000 0000 0000 0000 0100
// 00000 0000 0000 0000 0000 0000 0000 010
System.out.println(4>>1);
//-4 1111 1111 1111 1111 1111 1111 1111 1100
// 11111 1111 1111 1111 1111 1111 1111 110
System.out.println(-4>>1);
}

<< (带符号左移)

描述:

符号前面的数字的二进制数,向左移动符号右边的数字位数,正数高位用0补,负数高位用1补。

代码示例:

1
2
3
4
5
6
7
8
private static void test4() {
//4 0000 0000 0000 0000 0000 0000 0000 0100
// 000 0000 0000 0000 0000 0000 0000 01000
System.out.println(4<<1);
//-4 1111 1111 1111 1111 1111 1111 1111 1100
// 111 1111 1111 1111 1111 1111 1111 11011
System.out.println(-4<<1);
}

>>> (无符号右移)

描述:

符号前面的数字的二进制数,向右移动符号右边的数字位数,正数高位用0补,负数忽略符号高位也用0补。

1
2
3
4
5
6
7
8
9
// >>>
private static void test5() {
//4 0000 0000 0000 0000 0000 0000 0000 0100
// 00000 0000 0000 0000 0000 0000 0000 010
System.out.println(4>>>1);
//-4 1111 1111 1111 1111 1111 1111 1111 1100
// 01111 1111 1111 1111 1111 1111 1111 110
System.out.println(-4>>>1);
}

负数取值

Java中负数是以原码的补码形式表达的。

原码:

  • 一个正数,按照绝对值大小转换成的二进制;
  • 一个负数,按照绝对值大小转换成二进制,然后最高位补1,称为原码。

比如Java中Integer是32位,所以5的二进制为:0000 0000 0000 0000 0000 0000 0000 0101
5的原码是:0000 0000 0000 0000 0000 0000 0000 0101
所以,对应的-5的原码是:1000 0000 0000 0000 0000 0000 0000 0101

反码:

  • 正数的反码与原码相同,负数的反码为该数的原码除符号位外其他位取反;
  • 取反操作指:原为1,得0,原为0,得1,;(1变0,0变1)

比如正数5的反码还是:0000 0000 0000 0000 0000 0000 0000 0101
负数-5,1000 0000 0000 0000 0000 0000 0000 0101的反码是:1111 1111 1111 1111 1111 1111 1111 1010
称1000 0000 0000 0000 0000 0000 0000 0101和1111 1111 1111 1111 1111 1111 1111 1010互为反码

补码:

  • 正数的补码与原码相同
  • 负数的补码为该数的反码然后在最后一位加1

比如,1000 0000 0000 0000 0000 0000 0000 0101的反码是1111 1111 1111 1111 1111 1111 1111 1010
那么补码为:
1111 1111 1111 1111 1111 1111 1111 1010 + 1 = 1111 1111 1111 1111 1111 1111 1111 1011

所以-5在Java中表达为:1111 1111 1111 1111 1111 1111 1111 1011

如-1在java中的表示:

  • 先取-1的原码:1000 0000 0000 0000 0000 0000 0000 0001
  • 取反码:1111 1111 1111 1111 1111 1111 1111 1110
  • 补码:1111 1111 1111 1111 1111 1111 1111 1111