Home

 › 

Articles

 › 

Concepts

 › 

Understanding Bitwise Operator in Java, With Examples

OOPs in Java

Understanding Bitwise Operator in Java, With Examples

Key Points

  • Bitwise operators allow for manipulation of data at the bit level, providing greater control over specific bits.
  • The AND operator returns a 1 only if both bits in the operands are 1’s, making it useful for checking if specific bits are set.
  • The OR operator returns a 1 if either bits in the operands are 1’s or if both of them are 1’s, making it useful for setting specific bits.
  • The XOR operator returns a 1 if either of the bits in the operands are 1’s, but not if both of them are 1’s, making it useful for toggling specific bits.

Understanding the bitwise operator in Java can prove helpful in numerous situations, especially when dealing with lower-level operations. There are multiple bitwise operators to consider, but they are all rather simple.

Although bitwise operators are not often necessary, it’s important for you to understand them if you want to have a solid grasp of Java programming. So, let’s get into it!

What are Bitwise Operators?

Bitwise operators allow a programmer to act on data at the bit level, making it possible to extract or manipulate specific bits. You may wish to leverage this for a number of reasons, but first, let’s review what bits are.

Bit Review

As you likely know, a computer operates on electrical signals, and the presence or absence of electricity is often represented as binary, or base two. Even though most of the details are abstracted away, this principle carries over to Java. 

Data is represented as a certain number of bits, or binary digits. For example, an integer in Java is 32 bits. This normally allows you to represent numbers up to 2,147,483,647 (when one bit is used as the sign bit, indicating if it is positive or negative.) For the purposes of this article, however, we will mostly use numbers that can be represented as 8 bits.

AND Operator (&)

The AND operator will perform a bitwise AND operation on two numbers. This means that for each bit in the resulting number, it will only be a 1 if both of the bits in the operands are 1’s, and a 0 otherwise. Here’s an example:

int num1 = 10;      // binary: 00001010
int num2 = 6;       // binary: 00000110

int result = num1 & num2;
// The bitwise AND operator will perform the AND operation on each corresponding pair of bits:
//    00001010   (num1)
//  & 00000110   (num2)
//  __________
//    00000010   (result)

One example where you might use the bitwise AND operator is when you are trying to find the parity of a number (whether it is even or odd). You can do this by AND’ing it with 1. If the result is 0, then the number is even.

int number = 13;
boolean isEven = (number & 1) == 0;  // Result: false
bitwise operator in java AND example
Example of a Java class that demonstrates the use of the bitwise AND operator to determine if a number is even or odd.

OR Operator (|)

The OR operator will perform a bitwise OR operation on two numbers. When used, for each bit in the resulting number, it will be a 1 if either bits in the operands are 1’s or if both of them are 1’s, and it’s a 0 otherwise. This is also known as an inclusive OR operation. Here’s an example:

int num1 = 10;     // binary: 00001010
int num2 = 6;      // binary: 00000110

int result = num1 | num2;
// The bitwise OR operator will perform the OR operation on each corresponding pair of bits:
//    00001010   (num1)
//  | 00000110   (num2)
//  __________
//    00001110   (result)

A use for the bitwise OR operator is to combine permissions. Often in operating systems, files or processes will have permissions that define what certain users or groups are allowed to do. 

Since a person can either have a permission or not have it, each one can be represented using a bit. As such, the bitwise OR operator can be used to easily combine permissions as a single number so that parsing it later is easier. Note that in Java, binary numbers can be written by prefixing them with 0b. Something like this would be quite common:

int readPermission = 0b00000001;    int writePermission = 0b00000010;
// Combine the read and write permissions
int combinedPermissions = readPermission | writePermission; // Result: 0b00000011

XOR Operator (^)

The XOR operator will perform a bitwise XOR operation on two numbers. For each bit in the resulting number, it will be a 1 if either of the bits in the operands are 1’s, but not if both of them are 1’s, and it will be a 0 otherwise. Since we ignore the case in which both bits are 1’s, this is known as an exclusive OR operation. Here’s an example:

int num1 = 10;     // binary: 00001010
int num2 = 6;      // binary: 00000110

int result = num1 ^ num2;
// The bitwise XOR operator will perform the XOR operation on each corresponding pair of bits:
//    00001010   (num1)
//  ^ 00000110   (num2)
//  __________
//    00001100   (result)

XOR does have an interesting property: when you xor two numbers, let’s say A and B, you can XOR the result with A to get B, and vice versa. In other words, XOR is reversible. This can be taken advantage of to easily swap two numbers without creating an extra variable. Using that property, swapping two numbers might look like:

int a = 5;
int b = 3;

// Swap the values of a and b
a = a ^ b;
b = a ^ b;
a = a ^ b;
bitwise operator in java XOR example
Example of a Java class that demonstrates the use of the bitwise XOR operator (^) to toggle a binary switch.

Bitwise Complement Operator (~)

When used, the bitwise complement operator takes each bit in a number and flips it, meaning 0’s become 1’s, and 1’s become 0’s. We show the full 32 bits in this demonstration, as all of them contribute to the integer’s value. Here’s an example:

int num = 42;       // binary: 00000000000000000000000000101010

int result = ~num;
// The bitwise complement operator will flip the bits of the number:
//    00000000000000000000000000101010   (num)//  ~
//  ___________________________________
//    11111111111111111111111111010101   (result)

Left Shift Operator (<<)

The left shift operator, as you may have guessed, shifts all the bits in a number to the left by a given number of positions. Since we are working in base 2, for every shift to the left, we are effectively multiplying the number by 2. Here’s an example.

int num = 5;       // binary: 00000101

int result = num << 2;
// The left shift operator will shift the bits of the number to the left by the specified number of positions:
//    00000101   (num)
//  << 2
//  __________
//    00010100   (result)

Remember that integers in Java are always 32 bits. This means that if you want to store multiple smaller numbers within a larger integer, you can do so. For example:

int x = 3;   // Binary: 00000011
int y = 5;   // Binary: 00000101

// Pack x and y into a single variable
int packed = (x << 8) | y;  // Result: 771 (Binary: 0000001100000101)

Then, to get y back, we can bitwise AND the integer with a binary value of 11111111 (this is sometimes called a “mask”). 

int retrievedY = packed & 0b11111111;

Read on to see how we can retrieve x.

Right Shift Operator (>>)

Similar to the left shift operator, the right shift operator shifts all the bits in a number to the right by a given number of positions. Note again that since we are working in base 2, for every shift to the right, we are halving the number. 

When the right shift operator is applied, the empty spaces on the left are filled with the sign bit (first bit), which is why it is also called the signed right shift operator. Here’s an example:

int num = -42;      // binary: 11111111111111111111111111010110

int result = num >> 2;
// The right shift operator will shift the bits of the number to the right by the specified number of positions, padding with sign bit:
//    11111111111111111111111111010110   (num)
//  >> 2
//  __________
//    11111111111111111111111111110101   (result)

In our demonstration of using the left shift operator, we packed two numbers x and y into one integer. We know how to get y back using a mask, but we can also easily get x back with the right shift operator like so:

int retrievedX = packed >> 8;

Unsigned Right Shift Operator (>>>)

The unsigned right shift operator works exactly the same as the normal right shift operator, except that instead of filling the empty bits on the left with the sign bit, they will always be filled with 0’s. This means when you use the unsigned right shift operator on a number, it will always be positive. Here’s an example:

int num = -42;      // binary: 11111111111111111111111111010110

int result = num >>> 2;
// The signed right shift operator will shift the bits of the number to the right by the specified number of positions, padding with 0:
//    11111111111111111111111111010110   (num)
//  >> 2
//  __________
//    00111111111111111111111111110101   (result)

Logical Operators vs. Bitwise Operators

When programming, you’ve likely common across a statement like this:

if ([expression1] && [expression2]) {
    doSomething();
}

Or

if ([expression1] || [expression2]) {
    doSomething();
}

In programming, these are called logical operators. As opposed to bitwise operators, logical operators are meant to act on booleans or expressions that evaluate to a boolean. That being said, the principle is the same. A true statement can be thought of as a 1, and 0 for a false statement. 

When using logical OR (||), either or both of the expressions must be true for the

condition to pass. For logical AND (&&), both of the expressions must be true for the condition to pass. Although they are used in different ways, logical and bitwise operators are very similar at a basic level.

Wrapping Up

When used correctly, bitwise operators can save you time and allow you to write cleaner code. Although we only used integers, bitwise operators can be used on any primitive type in Java, and as such, they can be leveraged in many clever ways. 

Whether you are writing low-level code or using bit manipulation tricks, bitwise operators are very useful tools. Now, let’s answer some frequently asked questions.

Frequently Asked Questions

Can bitwise operators be used with floating-point numbers in Java?

No, bitwise operators can’t be used directly with floating-point numbers in Java. They can only be used with integer types (byte, short, int, long). If you need to perform bitwise operations on floating-point numbers, you’ll have to convert them to an integer type first, perform the operation, and then convert them back.

What does it mean when we say bitwise operators work at the bit level?

When we say bitwise operators work at the “bit level”, it means they directly manipulate the individual bits (the 0s and 1s) that make up a data value. This is different from higher-level operations like addition or multiplication, which work with the data value as a whole.

What is the difference between signed and unsigned right shift operators in Java?

The signed right shift operator (>>) shifts the bits to the right and fills the leftmost bits with the sign bit. The sign bit is 0 for positive numbers and 1 for negative numbers. On the other hand, the unsigned right shift operator (>>>) always fills the leftmost bits with 0, regardless of the original number’s sign. This can have different results if the number is negative.

Can I use bitwise operators with boolean values?

Yes, you can use bitwise operators with boolean values in Java. However, these operators function differently with booleans compared to integers. For example, the bitwise AND (&) operator with booleans will return true if and only if both operands are true, while the bitwise OR (|) operator will return true if at least one of the operands is true. The bitwise XOR (^) operator will return true if exactly one operand is true.

To top