🎉 Special Offer !    Code: GET300OFF    Flat ₹300 OFF on every Java Course
Grab Deal 🚀

Shift Operators in Java  


Introduction

  • Shift operators in Java are used to shift the bits of integer types (int, long, short, byte, char) either to the left or right, allowing efficient manipulation of binary data.
  • Usage:
    Useful for tasks such as:
    • Low-level programming: Used for manipulating binary data and hardware interaction.
    • Efficient calculations: Scale numbers by powers of two, faster than multiplication/division.
    • Optimizing performance: Faster than arithmetic/logical operations in performance-critical tasks.
    • Data encoding/decoding: Important in bit-packing and handling bits in data.
  • Operation:
    • Binary Manipulation: Shift bits left or right to perform efficient binary tasks.
  • Operand Types:
    • Works only with integer data types (int, long, short, byte and char) but not with floating-point or boolean values.
  • Efficiency:
    • Shift operations are faster than multiplication/division, ideal for performance-critical code.
  • Common Applications:
    • Scaling numbers: Left shift (<<) for multiplication by 2, right shift (>>) for division by 2.
    • Flag manipulation: Combined with bitwise operators for flag management.
    • Memory optimization: Efficiently uses memory, especially with bitmasks.
    • Efficient arithmetic operations: Fast for low-level calculations and cryptography.
  • Shift operators are explained as below :-
    • << (Left shift operator):
      • Purpose: Shifts the bits of a number to the left by the specified number of positions, filling the empty positions with zeros.
      • Effect: Multiplies the number by 2 for each position the bits are shifted.
      • Example:
        int a = 5; 
        System.out.println(a << 1); // Output: 10 (binary 101 << 1 becomes 1010)
    • >> (Right shift operator):
      • Purpose: Shifts the bits of a number to the right by the specified number of positions. The empty positions on the left are filled based on the sign of the number (for signed types).
      • Effect: Divides the number by 2 for each position the bits are shifted, maintaining the sign of the number.
      • Example:
        int a = 20;
        System.out.println(a >> 2); // Output: 5 (binary 10100 >> 2 becomes 101)
    • >>> (Unsigned right shift operator):
      • Purpose: Shifts the bits of a number to the right by the specified number of positions, filling the empty positions with zeros, regardless of the sign.
      • Effect: Divides the number by 2 for each position the bits are shifted but does not preserve the sign.
      • Example:
        int a = -20;
        System.out.println(a >>> 2); // Output: 1073741815 (binary of -20 shifted right with zero-fill)
  • Program:
    public class ShiftOperators
    {
        public static void main(String[] args)
        {
            // Initialize variables
            int a = 5;  // Binary: 0101
            int b = -10; // Binary: 11111111111111111111111111110110 (in 32-bit two's complement)
    
            // Left shift (<<)
            System.out.println("Left Shift (a << 1): " + (a << 1)); // Output: 10 (Binary: 1010)
    
            // Right shift (>>)
            System.out.println("Right Shift (a >> 1): " + (a >> 1)); // Output: 2 (Binary: 0010)
    
            // Unsigned right shift (>>>)
            System.out.println("Unsigned Right Shift (a >>> 1): " + (a >>> 1)); // Output: 2 (Binary: 0010)
    
            // Left shift with negative number
            System.out.println("Left Shift (b << 1): " + (b << 1)); // Output: -20 (Binary: 11111111111111111111111111101100)
    
            // Right shift with negative number
            System.out.println("Right Shift (b >> 1): " + (b >> 1)); // Output: -5 (Binary: 11111111111111111111111111111011)
    
            // Unsigned right shift with negative number
            System.out.println("Unsigned Right Shift (b >>> 1): " + (b >>> 1)); // Output: 2147483643 (Binary: 01111111111111111111111111111011)
        }
    }
    Output:
    Left Shift (a << 1): 10
    Right Shift (a >> 1): 2
    Unsigned Right Shift (a >>> 1): 2
    Left Shift (b << 1): -20
    Right Shift (b >> 1): -5
    Unsigned Right Shift (b >>> 1): 2147483643
Some Advance Important Points :-
  • Shift Operators with Literals:
    • Shift operators can be directly applied to literals or variables.
    • Example:
      System.out.println(4 << 2); // Output: 16 (Binary: 0100 << 2 positions results in 10000)
      System.out.println(8 >> 1); // Output: 4 (Binary: 1000 >> 1 position results in 0100)
  • Supported Data Types:
    • Shift operators work only with integer types such as byte, short, int, long and char.
    • Applying shift operators to floating-point types (float, double) will result in a compilation error.
      System.out.println(5.5 << 1); // Compilation error: incompatible types: possible lossy conversion from double to int
  • Left Shift (<<) for Multiplication:
    • The left shift operator (<<) is used for efficient multiplication by powers of two.
    • Example :
      int x = 3;
      System.out.println(x << 2); // Output: 12 (Equivalent to 3 * 2^2)
    • This is computationally faster than using multiplication (x * 4).
  • Right Shift (>>) for Division:
    • The right shift operator (>>) is used for efficient division by powers of two.
    • Example :
      int x = 16;
      System.out.println(x >> 2); // Output: 4 (Equivalent to 16 / 2^2)
    • This is faster than using division (x / 4).
  • Unsigned Right Shift (>>>) and Negative Numbers:
    • The unsigned right shift operator (>>>) behaves differently for negative numbers by filling with zeros instead of extending the sign bit.
    • Example :
      int x = -8; 
      System.out.println(x >>> 1); // Output: 2147483640 (In binary: 11111111111111111111111111111000 >> 1 results in 01111111111111111111111111111100)
  • Shift Operators with Negative Numbers:
    • The behavior of shift operators is distinct when applied to negative numbers, especially the sign extension in the right shift (>>).
    • The left shift (<<) of a negative number behaves the same as for positive numbers but can result in sign changes if the leftmost bit is shifted into the sign bit.
    • Example :
      int x = -5;
      System.out.println(x << 1); // Output: -10 (Binary: 11111111111111111111111111111011 << 1 results in 11111111111111111111111111110110)
  • Zero-Fill Right Shift (>>>) with Negative Numbers:
    • The unsigned right shift (>>>) on negative numbers replaces the sign bit with 0, making it useful for operations like bit masks or extracting specific parts of a number.
    • Example:
      int x = -4;
      System.out.println(x >>> 1); // Output: 2147483643 (Binary: 11111111111111111111111111111100 >>> 1 results in 01111111111111111111111111111110)
  • Shifting on Larger Numbers (long):
    • The shift operators can be used on larger integer types like long. However, the right operand should be masked with & 0x3F (for long shift) to avoid shifting more than 63 positions (for 64-bit long).
    • Example:
      long x = 100L;
      System.out.println(x << 3); // Output: 800 (Equivalent to 100 * 2^3)
  • Shift Operations with Negative Powers:
    • Negative values in the right shift operator (>> and >>>) will throw a compile-time error.
    • Example:
      int x = 8;
      System.out.println(x >> -2); // Compile-time error: shift count must be non-negative
  • Overflow and Underflow in Shift Operations:
    • While shifting, if the value overflows or underflows beyond the range of the data type, the result can be unpredictable. Java’s shift operators do not raise errors for overflows but wrap the result around based on the data type size.
    • Example:
      int x = Integer.MAX_VALUE;
      System.out.println(x << 1); // Output: -2 (Overflow: 2147483647 << 1 results in a negative value)