Java 位运算符和移位运算符

在 Java 中,按位运算符对整数数据的单个位进行操作。这里的整数数据包括 byteshortintlong 类型的数据。

Java 中有 7 个运算符用于执行位级操作。


1. Java 按位 OR 运算符

按位 OR | 运算符在至少一个操作数为 1 时返回 1。否则,它返回 0。

以下真值表演示了按位 OR 运算符的工作原理。令 a 和 b 为两个只能取二进制值(即 1 或 0)的操作数。

a b a | b
0 0 0
0 1 1
1 0 1
1 1 1

上表称为按位 OR 运算符的“真值表”。

让我们看一看整数 12 和 25 的按位 OR 操作。

12 = 00001100 (In Binary)
25 = 00011001 (In Binary)

Bitwise OR Operation of 12 and 25
   00001100
 | 00011001
____________
   00011101 = 29 (In Decimal)

示例 1:按位 OR

class Main {
  public static void main(String[] args) {

    int number1 = 12, number2 = 25, result;

    // bitwise OR between 12 and 25
    result = number1 | number2;
    System.out.println(result);    // prints 29
  }
}

2. Java 按位 AND 运算符

按位 AND & 运算符当且仅当两个操作数都为 1 时返回 1。否则,它返回 0。

下表演示了按位 AND 运算符的工作原理。令 a 和 b 为两个只能取二进制值(即 1 和 0)的操作数。

a b a & b
0 0 0
0 1 0
1 0 0
1 1 1

让我们来看一看整数 12 和 25 的按位 AND 操作。

12 = 00001100 (In Binary)
25 = 00011001 (In Binary)

// Bitwise AND Operation of 12 and 25
   00001100
 & 00011001
____________
   00001000 = 8 (In Decimal)

示例 2:按位 AND

 class Main {
  public static void main(String[] args) {

    int number1 = 12, number2 = 25, result;

    // bitwise AND between 12 and 25
    result = number1 & number2;
    System.out.println(result);    // prints 8
  }
}

3. Java 按位 XOR 运算符

按位 XOR ^ 运算符当且仅当其中一个操作数为 1 时返回 1。但是,如果两个操作数都为 0 或都为 1,则结果为 0。

以下真值表演示了按位 XOR 运算符的工作原理。令 a 和 b 为两个只能取二进制值(即 1 或 0)的操作数。

a b a ^ b
0 0 0
0 1 1
1 0 1
1 1 0

让我们看一看整数 12 和 25 的按位 XOR 操作。

12 = 00001100 (In Binary)
25 = 00011001 (In Binary)

// Bitwise XOR Operation of 12 and 25
   00001100
 ^ 00011001
____________
   00010101 = 21 (In Decimal)

示例 4:按位 XOR

class Main {
  public static void main(String[] args) {

    int number1 = 12, number2 = 25, result;

    // bitwise XOR between 12 and 25
    result = number1 ^ number2;
    System.out.println(result);    // prints 21
  }
}

4. Java 按位补码运算符

按位补码运算符是一个一元运算符(仅作用于一个操作数)。它用 ~ 表示。

它将二进制数字 **1** 变为 **0**,将 **0** 变为 **1**。

Java Bitwise complement operator converts 0 to 1 and 1 to 0
Java 按位补码运算符

需要注意的是,任何整数 **N** 的按位补码都等于 **- (N + 1)**。例如,

考虑整数 **35**。根据规则,35 的按位补码应该是 **-(35 + 1)** = **-36**。现在让我们看看是否能得到正确答案。

35 = 00100011 (In Binary)

// using bitwise complement operator
~ 00100011
__________
  11011100

在上面的示例中,我们得到 35 (00100011) 的按位补码是 11011100。这里,如果我们把结果转换为十进制,我们得到 220。

然而,需要注意的是,我们不能直接将结果转换为十进制并得到期望的输出。这是因为二进制结果 11011100 也等同于 -36

为了理解这一点,我们首先需要计算 **-36** 的二进制输出。


2 的补码

在二进制算术中,我们可以使用 2 的补码来计算整数的二进制负数。

1 的补码将 **0** 变为 **1**,将 **1** 变为 **0**。而且,如果我们给 1 的补码结果加 1,我们就得到了原始数字的 2 的补码。例如,

// compute the 2's complement of 36
36 = 00100100 (In Binary)

1's complement = 11011011

2's complement:
 11011011
    +   1
_________
 11011100

在这里,我们可以看到 36(即 **-36**)的 2 的补码是 11011100。这个值等同于 35 的按位补码。

因此,我们可以说 35 的按位补码是 **-(35 + 1) = -36**。


示例 3:按位补码

class Main {
  public static void main(String[] args) {

    int number = 35, result;

    // bitwise complement of 35
    result = ~number;
    System.out.println(result);    // prints -36
  }
}

Java 移位运算符

Java 中有三种移位运算符

  • 带符号左移 (<<)
  • 带符号右移 (>>)
  • 无符号右移 (>>>)

5. Java 左移运算符

左移运算符将所有位向左移动指定的位数。它用 << 表示。

Bits are shifted one position left and 0 is added to the last position
Java 1 位左移运算符

从上图可以看出,我们有一个 4 位数字。当我们在它上面执行 1 位左移操作时,每个单独的位都向左移动 **1** 位。

结果是,最左边的位(最高有效位)被丢弃,最右边的位置(最低有效位)保持空。这个空位用 **0** 填充。


示例 5:左移运算符

class Main {
  public static void main(String[] args) {
    
    int number = 2;
   
    // 2 bit left shift operation 
    int result = number << 2;
    System.out.println(result);    // prints 8
  }
}

5. Java 带符号右移运算符

带符号右移运算符将所有位向右移动指定的位数。它用 >> 表示。

当我们向右移动任何数字时,最低有效位(最右边)被丢弃,最高有效位(最左边)用符号位填充。例如,

// right shift of 8
8 = 1000 (In Binary)

// perform 2 bit right shift
8 >> 2:
1000 >> 2 = 0010 (equivalent to 2)

这里,我们正在进行 8 的右移(即符号为正)。因此,没有符号位。所以最左边的位用 **0** 填充(表示正号)。

// right shift of -8
8 = 1000 (In Binary)

1's complement = 0111

2's complement:

 0111
  + 1
_______
 1000

Signed bit = 1

// perform 2 bit right shift
8 >> 2:
1000 >> 2 = 1110 (equivalent to -2)

在这里,我们使用了带符号位 **1** 来填充最左边的位。


示例 6:带符号右移运算符

class Main {
  public static void main(String[] args) {
    
    int number1 = 8;
    int number2 = -8;
    
    // 2 bit signed right shift
    System.out.println(number1 >> 2);    // prints 2
    System.out.println(number2 >> 2);    // prints -2
  }
}

7. Java 无符号右移运算符

Java 还提供无符号右移。它用 >>> 表示。

这里,空的最左边位置用 **0** 填充,而不是符号位。例如,

// unsigned right shift of 8
8 = 1000

8 >>> 2 = 0010

// unsigned right shift of -8
-8 = 1000 (see calculation above)

-8 >>> 2 = 0010

示例 7:无符号右移

class Main {
  public static void main(String[] args) {
    
    int number1 = 8;
    int number2 = -8;
    
    // 2 bit signed right shift
    System.out.println(number1 >>> 2);    // prints 2
    System.out.println(number2 >>> 2);    // prints 1073741822
  }
}

正如我们所见,带符号和无符号右移运算符对负位返回不同的结果。要了解更多信息,请访问 >> 和 >>> 之间的区别

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战