Java Bitwise Operators – Java位操作符

最后修改: 2019年 1月 31日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Operators are used in the Java language to operate on data and variables.

操作符在Java语言中被用来对数据和变量进行操作。

In this tutorial, we’ll explore Bitwise Operators and how they work in Java.

在本教程中,我们将探讨Bitwise操作符以及它们在Java中的工作原理。

2. Bitwise Operators

2 位数运算法则

Bitwise operators work on binary digits or bits of input values. We can apply these to the integer types –  long, int, short, char, and byte.

比特运算符对输入值的二进制数字或比特进行运算。我们可以将这些运算符应用于整数类型–long、int、short、char、byte。

Before exploring the different bitwise operators let’s first understand how they work.

在探索不同的位运算符之前,让我们首先了解它们的工作原理。

Bitwise operators work on a binary equivalent of decimal numbers and perform operations on them bit by bit as per the given operator:

位操作符对十进制数字的二进制等价物进行操作,并根据给定的操作符逐位进行操作:

  • First, the operands are converted to their binary representation
  • Next, the operator is applied to each binary number and the result is calculated
  • Finally, the result is converted back to its decimal representation

Let’s understand with an example; let’s take two integers:

让我们通过一个例子来理解;让我们拿两个整数:

int value1 = 6;
int value2 = 5;

Next, let’s apply a bitwise OR operator on these numbers:

接下来,让我们在这些数字上应用一个位数OR运算。

int result = 6 | 5;

To perform this operation, first, the binary representation of these numbers will be calculated:

为了进行这一操作,首先,将计算这些数字的二进制表示。

Binary number of value1 = 0110
Binary number of value2 = 0101

Then the operation will be applied to each bit. The result returns a new binary number:

然后,操作将被应用于每个比特。结果返回一个新的二进制数。

0110
0101
-----
0111

Finally, the result 0111 will be converted back to decimal which is equal to 7:

最后,结果0111将被转换回十进制,等于7

result : 7

Bitwise operators are further classified as bitwise logical and bitwise shift operators. Let’s now go through each type.

位操作符又被分为位逻辑操作符和位移操作符。现在让我们来看看每种类型。

3. Bitwise Logical Operators

3.位数逻辑运算法则

The bitwise logical operators are AND(&), OR(|), XOR(^), and NOT(~).

位逻辑运算符是AND(&), OR(|), XOR(^), 和NOT(~)。

3.1. Bitwise OR (|)

3.1 位法OR (|)

The OR operator compares each binary digit of two integers and gives back 1 if either of them is 1.

OR运算符对两个整数的每个二进制数字进行比较,如果其中一个是1,则返回1。

This is similar to the || logical operator used with booleans. When two booleans are compared the result is true if either of them is true. Similarly, the output is 1 when either of them is 1.

这与用于布尔运算的||逻辑运算符相似。当两个布尔运算进行比较时,如果其中一个是true,那么结果就是true。同样,如果其中一个是1,那么输出就是1。

We saw an example of this operator in the previous section:

我们在上一节中看到了这个运算符的一个例子。

@Test
public void givenTwoIntegers_whenOrOperator_thenNewDecimalNumber() {
    int value1 = 6;
    int value2 = 5;
    int result = value1 | value2;
    assertEquals(7, result);
}

Let’s see the binary representation of this operation:

让我们看看这个操作的二进制表示。

0110
0101
-----
0111

Here, we can see that using OR, 0 and 0 will result in 0, while any combination with at least a 1 will result in 1.

在这里,我们可以看到,使用OR,0和0的结果是0,而任何至少有1的组合将导致1。

3.2. Bitwise AND (&)

3.2 位法AND (&)

The AND operator compares each binary digit of two integers and gives back 1 if both are 1, otherwise it returns 0.

AND运算符对两个整数的每个二进制数字进行比较,如果都是1则返回1,否则返回0。

This is similar to the && operator with boolean values. When the values of two booleans are true the result of a && operation is true.

这与boolean值的&&操作类似。当两个booleans的值都是true时,&&操作的结果是true。

Let’s use the same example as above, except now using the & operator instead of the | operator:

让我们使用与上面相同的例子,只是现在使用&操作符而不是|操作符。

@Test
public void givenTwoIntegers_whenAndOperator_thenNewDecimalNumber() {
    int value1 = 6;
    int value2 = 5;
    int result = value1 & value2;
    assertEquals(4, result);
}

Let’s also see the binary representation of this operation:

我们也来看看这个操作的二进制表示。

0110
0101
-----
0100

0100 is 4 in decimal, therefore, the result is:

01004的小数,因此,结果是。

result : 4

3.3. Bitwise XOR (^)

3.3.位数XOR (^)

The XOR operator compares each binary digit of two integers and gives back 1 if both the compared bits are different. This means that if bits of both the integers are 1 or 0 the result will be 0; otherwise, the result will be 1:

XOR运算符对两个整数的每个二进制数字进行比较,如果比较的位数不同,则返回1。这意味着,如果两个整数的位数都是1或0,结果将是0;否则,结果将是1。

@Test
public void givenTwoIntegers_whenXorOperator_thenNewDecimalNumber() {
    int value1 = 6;
    int value2 = 5;
    int result = value1 ^ value2;
    assertEquals(3, result);
}

And the binary representation:

以及二进制表示法。

0110
0101
-----
0011

0011 is 3 in decimal, therefore, the result is:

0011 是十进制的3,因此,结果是。

result : 3

3.4. Bitwise COMPLEMENT (~)

3.4.Bitwise COMPLEMENT (~)

Bitwise Not or Complement operator simply means the negation of each bit of the input value. It takes only one integer and it’s equivalent to the ! operator.

Bitwise Not或Complement运算符简单地说就是对输入值的每一个比特进行否定。它只需要一个整数,相当于!操作符。

This operator changes each binary digit of the integer, which means all 0 become 1 and all 1 become 0. The ! operator works similarly for boolean values: it reverses boolean values from true to false and vice versa.

这个操作符改变了整数的每个二进制数字,这意味着所有的0都变成了1,所有的1都变成了0。操作符对boolean值的作用类似:它将boolean值从true逆转为false,反之亦然。

Now let’s understand with an example how to find the complement of a decimal number.

现在让我们通过一个例子来了解如何找到一个十进制数的补数。

Let’s do the complement of value1 = 6:

我们来做value1=6的补数。

@Test
public void givenOneInteger_whenNotOperator_thenNewDecimalNumber() {
    int value1 = 6;
    int result = ~value1;
    assertEquals(-7, result);
}

The value in binary is:

二进制的值是。

value1 = 0000 0110

By applying the complement operator, the result will be:

通过应用补数运算,结果将是。

0000 0110 -> 1111 1001

This is the one’s complement of the decimal number 6. And since the first (leftmost) bit is 1 in binary, it means that the sign is negative for the number that is stored.

这是十进制数字6的一补。由于第一个(最左边)位在二进制中是1,这意味着所存储的数字的符号是负的。

Now, since the numbers are stored as 2’s complement, first we need to find its 2’s complement and then convert the resultant binary number into a decimal number:

现在,由于数字是以2的补数形式存储的,首先我们需要找到它的2的补数,然后将所得的二进制数转换成十进制数。

1111 1001 -> 0000 0110 + 1 -> 0000 0111

Finally, 0000 0111 is 7 in decimal. Since the sign bit was 1 as mentioned above, therefore the resulting answer is:

最后,0000 0111是十进制的7。由于上面提到的符号位是1,因此得出的答案是:。

result : -7

3.5. Bitwise Operator Table

3.5 位操作符表

Let’s summarize the result of the operators we’ve seen to so far in a comparison table:

让我们用一个比较表来总结一下我们到目前为止所看到的运算符的结果。

A	B	A|B	A&B	A^B	~A
0	0	0	0	0	1
1	0	1	0	1	0
0	1	1	0	1	1
1	1	1	1	0	0

4. Bitwise Shift Operators

4 位数移位操作符

Binary shift operators shift all the bits of the input value either to the left or right based on the shift operator.

二进制移位运算符根据移位运算符将输入值的所有位向左或向右移。

Let’s see the syntax for these operators:

让我们看看这些运算符的语法。

value <operator> <number_of_times>

The left side of the expression is the integer that is shifted, and the right side of the expression denotes the number of times that it has to be shifted.

表达式的左边是被移位的整数,表达式的右边表示它要被移位的次数。

Bitwise shift operators are further classified as bitwise left and bitwise right shift operators.

位数移位运算符又被分为位数左移和位数右移运算符。

4.1. Signed Left Shift [<<]

4.1.有符号的左移 [<<]

The left shift operator shifts the bits to the left by the number of times specified by the right side of the operand. After the left shift, the empty space in the right is filled with 0.

左移运算符将比特向左移,移的次数由操作数的右边指定。左移后,右边的空位被填充为0.

Another important point to note is that shifting a number by one is equivalent to multiplying it by 2, or, in general, left shifting a number by n positions is equivalent to multiplication by 2^n.

另一个需要注意的要点是,将一个数字移1相当于乘以2,或者,一般来说,将一个数字左移n位相当于乘以2^n

Let’s take the value 12 as the input value.

让我们把值12作为输入值。

Now, we will move it by 2 places to the left (12 <<2) and see what will be the final result.

现在,我们将向左移动2位(12<<2),看看最后的结果是什么。

The binary equivalent of 12 is 00001100. After shifting to the left by 2 places, the result is 00110000, which is equivalent to 48 in decimal:

12的二进制等价物是00001100。向左移动2位后,结果是00110000,相当于十进制的48。

@Test
public void givenOnePositiveInteger_whenLeftShiftOperator_thenNewDecimalNumber() {
    int value = 12;
    int leftShift = value << 2;
    assertEquals(48, leftShift);
}

This works similarly for a negative value:

这对负值也有类似的作用。

@Test
public void givenOneNegativeInteger_whenLeftShiftOperator_thenNewDecimalNumber() {
    int value = -12;
    int leftShift = value << 2;
    assertEquals(-48, leftShift);
}

4.2. Signed Right Shift [>>]

4.2.有符号的右移 [>>]

The right shift operator shifts all the bits to the right. The empty space in the left side is filled depending on the input number:

右移运算符将所有的位向右移。左边的空位根据输入的数字来填充。

  • When an input number is negative, where the leftmost bit is 1, then the empty spaces will be filled with 1
  • When an input number is positive, where the leftmost bit is 0, then the empty spaces will be filled with 0

Let’s continue the example using 12 as input.

让我们继续使用12作为输入的例子。

Now, we will move it by 2 places to the right(12 >>2) and see what will be the final result.

现在,我们将向右移动2位(12>2),看看最后的结果如何。

The input number is positive, so after shifting to the right by 2 places, the result is 0011, which is 3 in decimal:

输入的数字是正数,所以向右移动2位后,结果是0011,也就是十进制的3。

@Test
public void givenOnePositiveInteger_whenSignedRightShiftOperator_thenNewDecimalNumber() {
    int value = 12;
    int rightShift = value >> 2;
    assertEquals(3, rightShift);
}

Also, for a negative value:

另外,对于一个负值。

@Test
public void givenOneNegativeInteger_whenSignedRightShiftOperator_thenNewDecimalNumber() {
    int value = -12;
    int rightShift = value >> 2;
    assertEquals(-3, rightShift);
}

4.3. Unsigned Right Shift [>>>]

4.3.无符号右移 [>>>]

This operator is very similar to the signed right shift operator. The only difference is that the empty spaces in the left are filled with 0 irrespective of whether the number is positive or negative. Therefore, the result will always be a positive integer.

这个运算符与有符号右移运算符非常相似。唯一的区别是,无论数字是正数还是负数,左边的空位都会被填上0。因此,结果总是一个正整数。

Let’s right shift the same value of 12:

让我们把同样的12的值右移。

@Test
public void givenOnePositiveInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber() {
    int value = 12;
    int unsignedRightShift = value >>> 2;
    assertEquals(3, unsignedRightShift);
}

And now, the negative value:

而现在,负值。

@Test
public void givenOneNegativeInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber() {
    int value = -12;
    int unsignedRightShift = value >>> 2;
    assertEquals(1073741821, unsignedRightShift);
}

5. Difference Between Bitwise and Logical Operators

5.位操作符和逻辑操作符之间的区别

There are a few differences between the bitwise operators we’ve discussed here and the more commonly known logical operators.

我们在这里讨论的位运算符和更常见的逻辑运算符之间有一些区别。

First, logical operators work on boolean expressions and return boolean values (either true or false), whereas bitwise operators work on binary digits of integer values (long, int, short, char, and byte) and return an integer.

首先,逻辑运算符对boolean表达式工作,并返回boolean值(要么true,要么false),而bitwise运算符对整数值的二进制数字工作(long, int, short, char, byte)并返回一个字节。

Also, logical operators always evaluate the first boolean expression and, depending on its result and the operator used, may or may not evaluate the second. On the other hand, bitwise operators always evaluate both operands.

另外,逻辑运算符总是评估第一个boolean表达式,并且根据其结果和使用的运算符,可能评估也可能不评估第二个。另一方面,bitwise运算符总是评估两个操作数

Finally, logical operators are used in making decisions based on multiple conditions, while bitwise operators work on bits and perform bit by bit operations.

最后,逻辑运算符用于根据多个条件进行决策,而位运算符则对位进行工作,并进行逐位操作。

6. Use Cases

6.使用案例

Some potential use cases of bitwise operators are:

比特运算符的一些潜在用例是。

  • Communication stacks where the individual bits in the header attached to the data signify important information
  • In embedded systems to set/clear/toggle just one single bit of a specific register without modifying the remaining bits
  • To encrypt data for safety issues using the XOR operator
  • In data compression by converting data from one representation to another, to reduce the amount of space used

7. Conclusion

7.总结

In this tutorial, we learned about the types of bitwise operators and how they’re different from logical operators. We also saw some potential use cases for them.

在本教程中,我们了解了位运算符的类型以及它们与逻辑运算符的区别。我们还看到了它们的一些潜在用例。

All the code examples in this article are available over on GitHub.

本文中的所有代码示例都可以在GitHub上找到