Java位运算

389 阅读4分钟

Java位运算

一. 概述

Java中的位运算符

&   按位与
|   按位或
~   按位非
^   按位异或
<<  左移
>>  右移
>>> 无符号右移

二. 详解

文中例子为了方便统一采用一字节来表示二进制

1. 按位与(&)

规律:两个操作数进行按位与操作时,当且仅当两个操作数都为1时结果才为1,否则结果为0。

a1100
b1010
按位与1000

例如:

  2 & 5
= 0000 0010 & 0000 0101  --正数原码、反码、补码都一样
= 0000 0000
= 0

  -2 & -5
= 1000 0010 & 1000 0101  --原码
= 1111 1101 & 1111 1010  --反码
= 1111 1110 & 1111 1011  --补码
= 1111 1010              --补码
= 1111 1001              --反码
= 1000 0110              --原码
= -6

2. 按位或(|)

规律:两个操作数进行按位或操作时,当且仅当两个操作数都为0是结果才为0,否则结果为1。

a1100
b1010
按位或1110

例如:

  2 | 5
= 0000 0010 | 0000 0101  --正数原码、反码、补码都一样
= 0000 0111
= 7

  -2 | -5
= 1000 0010 | 1000 0101  --原码
= 1111 1101 | 1111 1010  --反码
= 1111 1110 | 1111 1011  --补码
= 1111 1111              --补码
= 1111 1110              --反码
= 1000 0001              --原码
= -1

3. 按位非(~)

规律:对一个操作数进行按位非操作时,该操作数为1则结果为0,该操作数为0则结果为1

a10
按位非01

例如:

  ~ 2
= ~ 0000 0010 --正数原码、反码、补码都一样
= 1111 1101   --补码  
= 1111 1100   --反码
= 1000 0011   --原码
= -3

  ~ -5
= ~ 1000 0101 --原码
= ~ 1111 1010 --反码
= ~ 1111 1011 --补码
= 0000 0100   --补码
= 0000 0100   --反码
= 0000 0100   --原码
= 4

4. 按位异或(^)

规律:两个操作数进行按位异或操作时,当且仅当两个操作数不一样时结果才为1,否则结果为0

a1100
b1010
按位异或0110

例如:

  2 ^ 5
= 0000 0010 ^ 0000 0101 --正数原码、反码、补码都一样
= 0000 0111
= 7

  -2 ^ -5
= 1000 0010 ^ 1000 0101 --原码
= 1111 1101 ^ 1111 1010 --反码
= 1111 1110 ^ 1111 1011 --补码
= 0000 0101             --补码
= 0000 0101             --反码
= 0000 0101             --原码
= 5

5. 左移(<<)

规律:高位舍弃,低位补0 例如:

  2 << 1
= 0000 0010 << 1 --正数原码、反码、补码都一样
= 0000 0100
= 4

  -2 << 1
= 1000 0010 << 1 --原码
= 1111 1101 << 1 --反码
= 1111 1110 << 1 --补码
= 1111 1100      --补码
= 1111 1011      --反码
= 1000 0100      --原码
= -4

6. 右移(>>)

规律:低位舍弃,高位补0,符号位不移动 例如:

  2 >> 1
= 0000 0010 >> 1 --正数原码、反码、补码都一样  
= 0000 0001
= 1

  -2 >> 1
= 1000 0010 >> 1 --原码
= 1111 1101 >> 1 --反码
= 1111 1110 >> 1 --补码
= 1111 1111      --补码
= 1111 1110      --反码
= 1000 0001      --原码
= -1

7. 无符号右移(>>>)

规律:低位舍弃,高位补0,符号位移动 例如:

  2 >>> 1 --正数符号位为0,所以正数无符号右移跟右移结果相同
  
  此例子特殊,java中int为32位
  -2 >>> 1
= 1000 0000 0000 0000 0000 0000 0000 0010 >>> 1 --原码
= 1111 1111 1111 1111 1111 1111 1111 1101 >>> 1 --反码
= 1111 1111 1111 1111 1111 1111 1111 1111 >>> 1 --补码
= 0111 1111 1111 1111 1111 1111 1111 1111       --补码
= 0111 1111 1111 1111 1111 1111 1111 1111       --反码
= 0111 1111 1111 1111 1111 1111 1111 1111       --原码
= 2147483647