Bitwise operators in Java allow you to manipulate individual bits of data. These operators perform actions directly on the binary representations of integers. While bitwise operations might seem complex at first, they are efficient for low-level programming tasks like data compression, encryption, or handling binary protocols. By learning the bitwise operators, you can improve your overall understanding of data management in the available memory.

In this blog, we will explain bitwise operators in detail. We’ll cover their types, bit-shift operators, and how they differ from logical operators. We will also explore some useful tricks, use cases, and practice problems.

What are Bitwise Operators?

With Bitwise operators, it is possible to manipulate the data at a very low level – a bit level. The Bitwise operators work directly with the binary forms of numbers, performing operations like AND, OR, XOR, and NOT on individual bits. These operators work at the lowest level, so they are quite faster than the normal arithmetic operations and highly useful in direct binary data manipulation.

Here are a few reasons why Bitwise operators are important in programming.

They allow for efficient data manipulation.

Useful in low-level programming tasks such as encryption, compression, and networking.

Help in optimising performance in memory-constrained environments.

Enable easy bit masking and bit shifting, which is common in hardware programming.

Get curriculum highlights, career paths, industry insights and accelerate your technology journey.

Download brochure

Types of Bitwise Operators

In Java, bitwise operators work directly on bits and perform bit-level operations. They are primarily used in low-level programming tasks, like manipulating flags or working with binary data. Java offers several bitwise operators that can be applied to integers, enabling efficient data processing and manipulation.

If you operate the bitwise AND operator, it’s going to compare every bit of numbers and continually returns 1 if each of the corresponding bits is 1. If you no longer place each corresponding bit to one, the answer could be 0 in every different feasible case.

This operator is typically used for masking and filtering out bits.

Truth Table for AND

a

b

a&b

0

0

0

0

1

0

1

0

0

1

1

1

The truth table shows that the AND operation results in 1 only when both a and b are 1.

Example with Two Numbers

Let’s look at the bitwise AND operation of two integers 8 and 10:

8 = 00001000 (In Binary)

10 = 00001010 (In Binary)

Bitwise AND Operation of 8 and 10

00001000

& 00001010

____________

00001000 = 8 (In Decimal)

Code Example

public class BitwiseExample {
public static void main(String[] args) {
int num1 = 8; // 00001000 in binary
int num2 = 10; // 00001010 in binary
// Perform bitwise AND
int result = num1 & num2;
// Output the result
System.out.println("Bitwise AND of 8 and 10: " + result); // Output will be 8
}
}

Output

Bitwise AND of 8 and 10: 8

Bitwise OR (|)

You can use the bitwise OR operator to compare each bit of two numbers and it will return 1 only if at least one of the bits is 1. This operation is useful for setting specific bits to 1.

The truth table shows that the OR operation results in 1 if either a or b is 1.

Example with Two Numbers

Let’s look at the bitwise OR operation of two integers 8 and 10:

8 = 00001000 (In Binary)

10 = 00001010 (In Binary)

Bitwise OR Operation of 8 and 10

00001000

| 00001010

____________

00001010 = 10 (In Decimal)

Code Example

public class BitwiseExample {
public static void main(String[] args) {
int num1 = 8; // 00001000 in binary
int num2 = 25; // 00001010 in binary
// Perform bitwise OR
int result = num1 | num2;
// Output the result
System.out.println("Bitwise OR of 8 and 20: " + result); // Output will be 10
}
}

Output

Bitwise OR of 8 and 10: 10

Bitwise XOR (^)

This operator is simple and when you compare both corresponding bits, the XOR operator returns 1 if both bits are different and returns 0 if both bits are the same. There are many uses of XOR and it is most commonly used in cryptography and to toggle specific bits.

Truth Table for OR

a

b

a|b

0

0

0

0

1

1

1

0

1

1

1

0

The truth table shows that the XOR operation results in 1 only when the two bits are different.

Example with Two Numbers

Let’s look at the bitwise XOR operation of two integers 8 and 10:

8 = 00001000 (In Binary)

10 = 00001010 (In Binary)

Bitwise XOR Operation of 8 and 10

00001000

^ 00001010

____________

00000010 = 2 (In Decimal)

Code Example

public class BitwiseExample {
public static void main(String[] args) {
int num1 = 8; // 00001000 in binary
int num2 = 10; // 00001010 in binary
// Perform bitwise XOR
int result = num1 ^ num2;
// Output the result
System.out.println("Bitwise XOR of 8 and 10: " + result); // Output will be 2
}
}

Output

Bitwise XOR of 8 and 10: 2

Bitwise Complement Operator (~)

The bitwise complement operator simply flips each bit of its operand, changing all the 1s to 0s and all the 0s to 1s. The result is simply the 2’s complement of the number-that is, simply -(N+1) for any integer N. Such operations prove useful in positive degree manipulations in Java.

Example

Let’s take the integer 20 and find its bitwise complement:

20 = 00010100 (In Binary)

// using bitwise complement operator

~ 00010100

__________

11101011

Here, the binary representation of 20 is 00010100. After applying the bitwise complement, the result is 11101011. If we convert this directly to decimal, it gives 235. However, because the first bit is 1, the number is negative in the two’s complement system, which is why we get -21 (as ~20 = -(20 + 1)).

Why Two’s Complement?

We use two’s complement to represent any negative number in binary. In two’s complement, the primary bit represents the sign (0 for positive, 1 for bad). When the first bit is 1, we can’t directly convert it to decimal. Instead, we find the two’s complement to determine the actual negative value.

2’s Complement Calculation

To find the two’s complement, we flip all bits (1’s complement) and add 1:

21 = 00010101 (In Binary)

1’s complement = 11101010

2’s complement:

11101010

+ 1

_________

11101011

This shows that the two’s complement of 21 is 11101011, which gives us -21.

Code Example

public class BitwiseComplementExample {
public static void main(String[] args) {
int num = 20; // 00010100 in binary
// Perform bitwise complement
int result = ~num;
// Output the result
System.out.println("Bitwise Complement of 20: " + result); // Output will be -21
}
}

Output

Bitwise Complement of 20: -21

Java Bit-Shift Operators

Bit-shift operators in Java are used to shift the bits of a number left or right. These operators move bits in the binary representation of numbers, either to the left or right, depending on the operator. They are useful for tasks like multiplying or dividing by powers of two and manipulating specific bits in low-level programming.

There are three types of bit-shift operators in Java:

Left Shift (<<)

Right Shift (>>)

Unsigned Right Shift (>>>)

Let’s go through each of these in detail.

Left Shift (<<)

The left shift operator shifts the bits of a number to the left by means of an exact number of positions. Each left shift operation doubles the number. The empty positions on the right are filled with zeros. This is equal to multiplying the number via 2^n, in which n is the number of shifts.

Example

Let’s look at the left shift operation of the number 8:

8 = 00001000 (In Binary)

8 << 2

00001000 << 2 = 00100000 = 32 (In Decimal)

Code Example

public class BitShiftExample {
public static void main(String[] args) {
int num = 8; // 00001000 in binary
// Perform left shift by 2 positions
int result = num << 2;
// Output the result
System.out.println("8 << 2 = " + result); // Output will be 32
}
}

Output

8 << 2 = 32

Right Shift (>>)

The right shift operator shifts the bits of a number to the right through a certain range of positions. The leftmost bits are full of the sign bit (0 for positive numbers and 1 for negative numbers). This is equal to dividing the number by 2^n, where n is the number of shifts.

Example

Let’s look at the operation of the number 16:

16 = 00010000 (In Binary)

16 >> 2

00010000 >> 2 = 00000100 = 4 (In Decimal)

Code Example

public class BitShiftExample {
public static void main(String[] args) {
int num = 16; // 00010000 in binary
// Perform right shift by 2 positions
int result = num >> 2;
// Output the result
System.out.println("16 >> 2 = " + result); // Output will be 4
}
}

Output:

16 >> 2 = 4

Unsigned Right Shift (>>>)

The unsigned right shift operator shifts the bits of a number to the right, just like the regular right shift, but it fills the leftmost bits with 0, regardless of the sign of the number. This ensures that negative numbers are not preserved.

Example

Let’s look at the unsigned right shift operation of the number -16:

-16 = 11110000 (In Binary)

-16 >>> 2

11110000 >>> 2 = 00111100 = 1073741820 (In Decimal, because of unsigned shift)

Code Example

public class BitShiftExample {
public static void main(String[] args) {
int num = -16; // 11110000 in binary (for simplicity in this example)
// Perform unsigned right shift by 2 positions
int result = num >>> 2;
// Output the result
System.out.println("-16 >>> 2 = " + result); // Output will be 1073741820
}
}

Bitwise operators are commonly used in various low-level programming tasks where direct manipulation of bits is required. Below are some of the common use cases of using bitwise operators in Java:

Setting or Clearing Specific Bits (Flags)

Bitwise operators can be used to toggle, set, or clear specific bits in a number. For example, enabling or disabling specific features using flags.

Example:

int flags = 0b0101; // Initial flags
int mask = 0b0010; // Flag to enable/disable
// Setting a flag (OR operation)
flags = flags | mask; // Result: 0b0111

Checking if a Number is Even or Odd

The bitwise AND operator can check if a number is even or odd by checking the least significant bit.

Example

int num = 5;
boolean isOdd = (num & 1) == 1; // If the least significant bit is 1, it's odd

Swapping Two Numbers Without a Temporary Variable

XOR can be used to swap two numbers without using a temporary variable.

Example

int a = 5;
int b = 3;
a = a ^ b;
b = a ^ b;
a = a ^ b;
// Now a is 3 and b is 5

Efficient Multiplication or Division by Powers of Two

Left and right bit shifts can be used to multiply or divide efficiently by powers of two.

Example

int num = 8;
int result = num << 1; // Left shift by 1 is equivalent to multiplying by 2 (Result: 16)

Working with Masks for Permissions

Bitwise operations are often used to manage permissions or flags in systems where each bit represents a specific permission or feature.

Example

int permissions = 0b1100; // Read and Write permissions
int writePermission = 0b0100;
// Checking if write permission is enabled
boolean canWrite = (permissions & writePermission) != 0;

Benefits of Using Bitwise Operators in Java

Performance: Bitwise operations are quicker than arithmetic operations, which can enhance performance in applications that deal with massive data sets or require frequent bit manipulations.

Memory Efficiency: They allow for more compact code, especially when working with flags, settings, or binary data.

Direct Hardware Interaction: Useful in low-level programming tasks where direct interaction with hardware or binary protocols is required.

Some Practice Problems on Bitwise Operators

In this section, we can cover some exercise issues to help you understand how to use bitwise operators in Java successfully. These problems involve operations that you may remedy using the information received so far about bitwise operators.

Problem 1: Check if a Number is the Power of Two

Problem Statement: Write a program to check if a given integer is a power of two using bitwise operators.

Solution Explanation

A number is a power of two if it has the simplest one-bit set to 1 in its binary representation. To take a look at this, we will use the expression (n & (n – 1)) == 0. This works because subtracting 1 from a number will flip all bits from the rightmost 1 to the end, and the AND operation among that number and one less than it will ultimately result in 0 if there is only 1 bit.

Code

public class PowerOfTwo {
public static void main(String[] args) {
int num = 16; // Example number
// Check if the number is a power of two
boolean isPowerOfTwo = (num > 0) && ((num & (num - 1)) == 0);
System.out.println(num + " is power of two: " + isPowerOfTwo); // Output will be true
}
}

Output

16 is power of two: true

Problem 2: Count the Number of 1 Bits in an Integer

Problem Statement: Write a program to count the number of 1 bits (also known as Hamming weight) in the binary representation of a given integer.

Solution Explanation

You can use the bitwise AND operator to check each bit of the given number. You just have to apply the AND operation repeatedly among the number and 1, then transfer the number to the right, and we can count how many 1 bits are present.

Code

public class CountSetBits {
public static void main(String[] args) {
int num = 29; // 11101 in binary has 4 set bits
int count = 0;
// Count the number of 1 bits
while (num > 0) {
count += (num & 1); // Add 1 if the least significant bit is 1
num >>= 1; // Right shift by 1 to check the next bit
}
System.out.println("Number of 1 bits: " + count); // Output will be 4
}
}

Output

Number of 1 bits: 4

Problem 3: Swap Odd and Even Bits

Problem Statement: Write a program to swap all odd and even bits of an integer.

Solution Explanation

In this problem, the odd-placed bits want to be swapped with even-placed bits. Here, you can take the help of a bitwise mask to swap bits. First, you need to separate the odd and even bits with the help of the mask 0xAAAAAAAA (which has 1 bit in every even position). Secondly, you need to use the mask 0x55555555 (which holds 1 bit in every odd position). Finally, you will shift the odd bits right and the even bits to the left. In the end, you can integrate them with the help of bitwise OR.

Code

public class SwapOddEvenBits {
public static void main(String[] args) {
int num = 23; // Binary: 10111
// Mask odd bits and even bits
int evenBits = num & 0xAAAAAAAA; // Mask for even bits
int oddBits = num & 0x55555555; // Mask for odd bits
// Right shift even bits and left shift odd bits
evenBits >>= 1;
oddBits <<= 1;
// Combine the result
int result = evenBits | oddBits;
System.out.println("Swapped bits result: " + result); // Output will be 43
}
}

Bitwise operators in Java offer powerful ways to manipulate data at the binary level. Although they may seem complex at first, understanding them can greatly improve the efficiency of certain tasks, especially when working with low-level programming or optimising performance. From performing bit masking to handling shifts and toggling specific bits, bitwise operators provide a more direct approach to interacting with data.

In this guide, we’ve explored the special forms of bitwise operators, their applications, and practical examples. Whether you are running on embedded systems, or cryptography, or absolutely want to improve the overall performance of your algorithms, studying bitwise operators will come up with efficient and effective coding. Want to explore Java in detail? Consider pursuing Hero Vired’s Certificate Program in Full Stack Development.

FAQs

What are bitwise operators in Java?

You can use Bitwise operators to perform operations on individual bits of integers.

What is the difference between & and &&?

Here, & is a bitwise AND operator. On the other hand, you can use && as a logical AND operator.

How do I check if a number is odd using bitwise operators?

You can use (num & 1) == 1 to check if a number is odd.

What is a bit shift operator in Java?

Bit shift operators move bits of a number left or right, such as <<, >>, and >>>.

Why are bitwise operators faster than arithmetic operations?

Bitwise operations directly manipulate bits, making them faster than traditional arithmetic.

Can I use bitwise operators on non-integer types?

No, bitwise operators in Java work only with integer types like int and long.

Hero Vired is a leading LearnTech company dedicated to offering cutting-edge programs in collaboration with top-tier global institutions. As part of the esteemed Hero Group, we are committed to revolutionizing the skill development landscape in India. Our programs, delivered by industry experts, are designed to empower professionals and students with the skills they need to thrive in today’s competitive job market.