Java Bitwise and Shift Operators


In Java, bitwise and shift operators allow you to perform operations directly on the bits of numbers. These operators can be incredibly useful in scenarios where performance is critical, such as systems programming, cryptography, and network communication. Understanding how these operators work is essential for any Java programmer who needs to work with low-level data manipulation.


Bitwise Operators in Java

Bitwise operators in Java work on individual bits of integer values (e.g., int, long) and perform operations directly on them. These operators are often used in low-level operations where manipulation of individual bits is necessary.

List of Bitwise Operators

Operator Description Example
& Bitwise AND: Sets each bit to 1 if both bits are 1 5 & 3 = 1
` ` Bitwise OR: Sets each bit to 1 if one of the bits is 1
^ Bitwise XOR: Sets each bit to 1 if only one of the bits is 1 5 ^ 3 = 6
~ Bitwise NOT: Inverts all the bits ~5 = -6
<< Left shift: Shifts the bits to the left, filling 0 on the right 5 << 1 = 10
>> Right shift: Shifts the bits to the right, filling with the leftmost bit (sign extension) 5 >> 1 = 2
>>> Unsigned right shift: Shifts the bits to the right, filling with 0 on the left (no sign extension) 5 >>> 1 = 2

Understanding Bitwise Operators

1. Bitwise AND (&)

The bitwise AND operator compares corresponding bits of two operands. It sets the resulting bit to 1 if both bits are 1, otherwise it sets it to 0.

Example:

public class BitwiseExample {
    public static void main(String[] args) {
        int a = 5;  // Binary: 0101
        int b = 3;  // Binary: 0011
        int result = a & b;  // Binary result: 0001
        System.out.println("5 & 3 = " + result);  // Output: 1
    }
}

Explanation:

  • 0101 (5 in binary)
  • 0011 (3 in binary)
  • AND result: 0001 (1 in binary)

2. Bitwise OR (|)

The bitwise OR operator compares corresponding bits of two operands. It sets the resulting bit to 1 if at least one of the bits is 1.

Example:

public class BitwiseExample {
    public static void main(String[] args) {
        int a = 5;  // Binary: 0101
        int b = 3;  // Binary: 0011
        int result = a | b;  // Binary result: 0111
        System.out.println("5 | 3 = " + result);  // Output: 7
    }
}

Explanation:

  • 0101 (5 in binary)
  • 0011 (3 in binary)
  • OR result: 0111 (7 in binary)

3. Bitwise XOR (^)

The bitwise XOR (exclusive OR) operator compares corresponding bits of two operands. It sets the resulting bit to 1 if only one of the bits is 1, but not both.

Example:

public class BitwiseExample {
    public static void main(String[] args) {
        int a = 5;  // Binary: 0101
        int b = 3;  // Binary: 0011
        int result = a ^ b;  // Binary result: 0110
        System.out.println("5 ^ 3 = " + result);  // Output: 6
    }
}

Explanation:

  • 0101 (5 in binary)
  • 0011 (3 in binary)
  • XOR result: 0110 (6 in binary)

4. Bitwise NOT (~)

The bitwise NOT operator inverts all the bits of its operand, flipping 1s to 0s and 0s to 1s.

Example:

public class BitwiseExample {
    public static void main(String[] args) {
        int a = 5;  // Binary: 0101
        int result = ~a;  // Binary result: 1010 (which equals -6 in decimal)
        System.out.println("~5 = " + result);  // Output: -6
    }
}

Explanation:

  • 0101 (5 in binary)
  • NOT result: 1010 (which represents -6 in decimal using two's complement representation)

Shift Operators in Java

Shift operators in Java allow you to move bits left or right within an integer value. These operators are useful when you need to perform operations such as multiplying or dividing by powers of 2.

1. Left Shift (<<)

The left shift operator shifts all the bits of its operand to the left by a specified number of positions. The vacant bits on the right are filled with 0s.

Example:

public class ShiftExample {
    public static void main(String[] args) {
        int a = 5;  // Binary: 0101
        int result = a << 1;  // Left shift by 1: 1010 (which equals 10 in decimal)
        System.out.println("5 << 1 = " + result);  // Output: 10
    }
}

Explanation:

  • 0101 (5 in binary)
  • Left-shifted by 1: 1010 (10 in binary)

2. Right Shift (>>)

The right shift operator shifts all the bits of its operand to the right by a specified number of positions. If the number is positive, the leftmost bit (sign bit) is preserved in case of signed integers (sign extension). For negative numbers, the sign bit (1 for negative numbers) will be filled.

Example:

public class ShiftExample {
    public static void main(String[] args) {
        int a = 5;  // Binary: 0101
        int result = a >> 1;  // Right shift by 1: 0010 (which equals 2 in decimal)
        System.out.println("5 >> 1 = " + result);  // Output: 2
    }
}

Explanation:

  • 0101 (5 in binary)
  • Right-shifted by 1: 0010 (2 in binary)

3. Unsigned Right Shift (>>>)

The unsigned right shift operator is similar to the regular right shift operator, but it always fills the leftmost bits with 0s, regardless of the sign bit.

Example:

public class ShiftExample {
    public static void main(String[] args) {
        int a = -5;  // Binary: 11111111111111111111111111111011
        int result = a >>> 1;  // Unsigned right shift by 1
        System.out.println("-5 >>> 1 = " + result);  // Output: 2147483642
    }
}

Explanation:

  • 11111111111111111111111111111011 (binary representation of -5)
  • Unsigned right-shifted by 1: 01111111111111111111111111111101 (2147483642 in decimal)

When to Use Bitwise and Shift Operators

  1. Performance: Bitwise operations are faster than regular arithmetic operations and can be used for optimization in performance-critical code (e.g., gaming, cryptography, embedded systems).

  2. Low-Level Data Manipulation: Bitwise operators allow you to manipulate individual bits of data. This is useful when working with protocols, file formats, or encryption algorithms that require precise control over bits.

  3. Flags and Masking: Bitwise operators are commonly used for setting, clearing, and testing flags in bit fields. They allow multiple boolean values to be packed into a single integer.

  4. Efficient Multiplication/Division: The shift operators (<<, >>) are particularly useful for multiplying or dividing numbers by powers of 2, which is more efficient than using arithmetic multiplication and division.