Shift operators in java , a tutorial

A shift operator will shift the bits by a number of positions . In java we have three shift operators , they are

  • The right shift signed operator >> , which shift the bits to the right , while keeping the sign bit. So if the sign bit is 1 , it is kept as 1 and if the sign bit is 0 it is kept as 0 .
  • the right shift unsigned operator >>> , which shift the bits to the right keeping a sign bit of 0 , as such it is called unsigned .
  • the left shift operator << , which shift the bits to the left and it doesn't care what the sign bit becomes . So it can become 0 or 1 .

we can shift by either a positive number of by a negative number.

2 << 1
3 >> -1

the number we shift by is converted to bits , and we take

  • the 5 lowest bit in case the type before the shift operator is an int or is promoted to an int .
  • the lowest 6 bit in case the type before the shift operator is a long .

So the maximum number that we can shift by for an int or for a type that can be promoted to an int is 31 bits , and the maximum number of bits that we can shift by for a long is 61 bits .

The right signed shift operator >>

the right signed shift operator keeps the sign bit .

  • If the number is positive , its bits are shifted to the right by the provided number of bits . The shifted bits are replaced by zero .
  • if the number is negative ,its bits are shifted to the right by the provided number of bits. The shifted bits are replaced by 1 .

To understand this better let us see some examples . we will do shifting by using 4 bits .

                      Bits                 Bits    
example  Number     3 2 1 0       shift   3 2 1 0        Number
 1        7         0 1 1 1        >>1    0 0 1 1          3
 2        7         0 1 1 1        >>2    0 0 0 1          1
 3        7         0 1 1 1        >>3    0 0 0 0          0
 4        5         0 1 0 1        >>1    0 0 1 0          2 
 5       -1         1 1 1 1        >>1    1 1 1 1         -1
 6       -1         1 1 1 1        >>2    1 1 1 1         -1
 7       -8         1 0 0 0        >>1    1 1 0 0         -4
 8       -8         1 0 0 0        >>2    1 1 1 0         -2
 9       -3         1 1 0 1        >>1    1 1 1 0         -2

  • in the first example , we are shifting a positive number 7 . Its bits are shifted by 1 position . So bits at position 3 , 2 , 1 , 0 are shifted by 1 . Bit 3 become bit 2 , bit 2 become bit 1 , bit 1 become bit 0 , and bit 0 is dropped . The shifted bits are replaced by zero , as such bit 3 or the sign bit becomes 0 and The result is 3 . Shifting a positive number is equivalent to dividing by 2 and keeping only the integral part of the division .
  • in the second example , we are shifting the bits of 7 by two position . So position 3 becomes position 1 , and positions 2 becomes position 0 and position 1 and 0 are dropped . In the place of the shifted position we place zeros . Hence the result is 1.
  • in the fifth example , we have a negative number which is -1 . We shift its bits by 1 . As such bits at position 3, 2 , 1 , 0 are shifted to the right . Position 0 is dropped , and the shifted positions are replaced by 1 , so we end up with -1 .
  • in the six example , the negative number -1 is shifted by 2 positions . So position 0 and 1 are dropped and position 3 and 2 will take the position 1 and 0 respectively . The shifted bits are replaced by 1 , as such the result of the shifting is -1
import static java.lang.System.out;

class RightSignedShiftOperator {

    public static void rightSignedShiftOperator() {
        /*
            right signed shift operator
        */

        out.println(String.format("%d >> 1 = %d ", Integer.MAX_VALUE, Integer.MAX_VALUE >> 1));
        /* right signed Shift Integer max value which is  2147483647 by 1 bit
         output : 2147483647 >> 1 = 1073741823 
        */

        out.println(String.format("%d >> 30 = %d ", Integer.MAX_VALUE, Integer.MAX_VALUE >> 30));
        /* right signed Shift Integer max value which is  2147483647 by 30 bits
        output : 2147483647 >> 30 = 1 
        */

        out.println(String.format("%d >> 31 = %d ", Integer.MAX_VALUE, Integer.MAX_VALUE >> 31));
        /* right signed Shift Integer max value which is  2147483647 by 31 bits
        output : 2147483647 >> 31 = 0 
        */

        out.println(String.format("%d >> 1 = %d ", Integer.MAX_VALUE - 2, (Integer.MAX_VALUE - 2) >> 1));
        /* right signed Shift (Integer max value - 2 ) which is  2147483645 by 1 bit
         output : 2147483645 >> 1 = 1073741822 
        */

        out.println(String.format("%d >> 1 = %d ", -1, -1 >> 1));
        /* right signed Shift -1 by 1 bit
        output : -1 >> 1 = -1 */

        out.println(String.format("%d >> 2 = %d ", -1, -1 >> 2));
        /* right signed Shift -1 by 2 bits
        output : -1 >> 2 = -1 
        */

        out.println(String.format("%d >> 1 = %d ", Integer.MIN_VALUE, Integer.MIN_VALUE >> 1));
        /* right signed Shift integer min value which is -2147483648 by 1 bit 
        output : -2147483648 >> 1 = -1073741824 
        */

        out.println(String.format("%d >> 2 = %d ", Integer.MIN_VALUE, Integer.MIN_VALUE >> 2));
        /* right signed Shift integer min value which is -2147483648 by 2 bits 
        output : -2147483648 >> 2 = -536870912 
        */

        out.println(String.format("%d >> 1 = %d ", Integer.MIN_VALUE + 5, (Integer.MIN_VALUE + 5) >> 1));
        /* right signed Shift  (integer min value + 5 ) which is -2147483643 by 1 bits 
        output : -2147483643 >> 1 = -1073741822 
        */

    }

    public static void main(String[] args) {
        rightSignedShiftOperator();

    }
}

The right unsigned shift operator >>>

The right unsigned shift operator will shift the bits of a number by the specified value , and it will replace the shifted bits by a zero . So it is just as if we are keeping a sign bit of zero, as such it is called unsigned .

                      Bits                 Bits     
example  Number     3 2 1 0       shift   3 2 1 0        Number
 1        7         0 1 1 1       >>>1    0 0 1 1          3
 2        7         0 1 1 1       >>>2    0 0 0 1          1
 3        7         0 1 1 1       >>>3    0 0 0 0          0
 4        5         0 1 0 1       >>>1    0 0 1 0          2 
 5       -1         1 1 1 1       >>>1    0 1 1 1          7
 6       -1         1 1 1 1       >>>2    0 0 1 1          4
 7       -8         1 0 0 0       >>>1    0 1 0 0          7
 8       -8         1 0 0 0       >>>2    0 0 1 0          2
 9       -3         1 1 0 1       >>>1    0 1 0 1          5
  • in the first example we are shifting the number 7 by one position . As such bits 3,2,1,0 are shifted by 1 position . The bit at position 0 is dropped , and the shifted bits are replaced by 0 . hence 7 will become 3 . When shifting a positive number the unsigned shift operator act the same as the signed shift operator .
  • in the second example , the result is 1 .
  • in the third example , the result is 0 .
  • in the fifth example we are shifting the negative number -1 by one position . so bits at position 3 , 2 ,1 ,0 are shifted by one position . Bit at position zero is dropped and the shifted bits are replaced by 0 . As such the result of the shifting is 7 .
import static java.lang.System.out;

class RightUnsignedShiftOperator {

    public static void rightUnsignedShiftOperator() {
        /*
            right unsigned shift operator
        */

        out.println(String.format("%d >>> 1 = %d ", Integer.MAX_VALUE, Integer.MAX_VALUE >>> 1));
        /* right unsigned Shift Integer max value which is  2147483647 by 1 bit
         output : 2147483647 >>> 1 = 1073741823 
        */

        out.println(String.format("%d >>> 30 = %d ", Integer.MAX_VALUE, Integer.MAX_VALUE >>> 30));
        /* right unsigned Shift Integer max value which is  2147483647 by 30 bits
        output : 2147483647 >>> 30 = 1 
        */

        out.println(String.format("%d >>> 31 = %d ", Integer.MAX_VALUE, Integer.MAX_VALUE >>> 31));
        /* right unsigned Shift Integer max value which is  2147483647 by 31 bits
        output : 2147483647 >>> 31 = 0 
        */

        out.println(String.format("%d >>> 1 = %d ", Integer.MAX_VALUE - 2, (Integer.MAX_VALUE - 2) >> 1));
        /* right unsigned Shift (Integer max value - 2 ) which is  2147483645 by 1 bit
         output : 2147483645 >>> 1 = 1073741822 
        */

        out.println(String.format("%d >>> 1 = %d ", -1, -1 >>> 1));
        /* right unsigned Shift -1 by 1 bit
        output : -1 >>> 1 = 2147483647 
        */

        out.println(String.format("%d >>> 2 = %d ", -1, -1 >>> 2));
        /* right unsigned Shift -1 by 2 bits
        output : -1 >>> 2 = 1073741823 
        */

        out.println(String.format("%d >>> 1 = %d ", Integer.MIN_VALUE, Integer.MIN_VALUE >>> 1));
        /* right unsigned Shift integer min value which is -2147483648 by 1 bit 
        output : -2147483648 >>> 1 = 1073741824 
        */

        out.println(String.format("%d >>> 2 = %d ", Integer.MIN_VALUE, Integer.MIN_VALUE >>> 2));
        /* right unsigned Shift integer min value which is -2147483648 by 2 bits 
        output : -2147483648 >>> 2 = 536870912
        */

        out.println(String.format("%d >>> 1 = %d ", Integer.MIN_VALUE + 5, (Integer.MIN_VALUE + 5) >>> 1));
        /* right unsigned Shift  (integer min value + 5 ) which is -2147483643 by 1 bits 
        output : -2147483643 >>> 1 = 1073741826
        */
    }

    public static void main(String[] args) {
        rightUnsignedShiftOperator();

    }
}

The left shift operator <<

The left shift operator will just shift the bits of a number to the left by the specified value . The shifted bits are replaced by a zero .

                      Bits                 Bits  
example  Number     3 2 1 0       shift   3 2 1 0        Number
 1        7         0 1 1 1       <<1     1 1 1 0          -2
 2        7         0 1 1 1       <<2     1 1 0 0          -4
 3        7         0 1 1 1       <<3     1 0 0 0          -8
 4        5         0 1 0 1       <<1     1 0 1 0          -6 
 5       -1         1 1 1 1       <<1     1 1 1 0          -1
 6       -1         1 1 1 1       <<2     1 1 0 0          -4
 7       -8         1 0 0 0       <<1     0 0 0 0           0
 8       -8         1 0 0 0       <<2     0 0 0 0           0
 9       -3         1 1 0 1       <<1     1 0 1 0          -6
  • In the first example , we have a positive number 7 which is shifted by 1 place , as such bits in position 3 , 2 , 1 , 0 are shifted to the left by 1 position . Hence bit 3 is dropped , and replaced by bit 2 , bit 2 by bit 1 , bit 1 by bit 0 and bit 0 is replaced by a zero . hence the result is -2 .
  • in the six example , we are shifting the bits of the number -1 by 2 position . Hence bits 3 and 2 are dropped and replaced by bits 1 and 0 . Bits 1 and 0 are replaced by a zero , and the result is -4 .
import static java.lang.System.out;

class LeftShiftOperator {

    public static void leftShiftOperator() {
        /*
            left shift operator
        */

        out.println(String.format("%d << 1 = %d ", Integer.MAX_VALUE, Integer.MAX_VALUE << 1));
        /* left Shift Integer max value which is  2147483647 by 1 bit
         output : 2147483647 << 1 = -2 
        */

        out.println(String.format("%d << 30 = %d ", Integer.MAX_VALUE, Integer.MAX_VALUE << 30));
        /* left Shift Integer max value which is  2147483647 by 30 bits
        output : 2147483647 << 30 = -1073741824
        */

        out.println(String.format("%d << 31 = %d ", Integer.MAX_VALUE, Integer.MAX_VALUE << 31));
        /* left Shift Integer max value which is  2147483647 by 31 bits
        output : 2147483647 << 31 = -2147483648
        */

        out.println(String.format("%d << 1 = %d ", Integer.MAX_VALUE - 2, (Integer.MAX_VALUE - 2) << 1));
        /* left Shift (Integer max value - 2 ) which is  2147483645 by 1 bit
         output : 2147483645 << 1 = -6 
        */

        out.println(String.format("%d << 1 = %d ", -1, -1 << 1));
        /* left  Shift -1 by 1 bit
        output : -1 << 1 = -2 
        */

        out.println(String.format("%d << 2 = %d ", -1, -1 << 2));
        /*  left Shift -1 by 2 bits
        output : -1 << 2 = -4 
        */

        out.println(String.format("%d << 1 = %d ", Integer.MIN_VALUE, Integer.MIN_VALUE << 1));
        /* left Shift integer min value which is -2147483648 by 1 bit 
        output : -2147483648 << 1 = 0 
        */

        out.println(String.format("%d << 2 = %d ", Integer.MIN_VALUE, Integer.MIN_VALUE << 2));
        /* left Shift integer min value which is -2147483648 by 2 bits 
        output : -2147483648 << 2 = 0 
        */

        out.println(String.format("%d << 1 = %d ", Integer.MIN_VALUE + 5, (Integer.MIN_VALUE + 5) << 1));
        /* left Shift  (integer min value + 5 ) which is -2147483643 by 1 bits 
        output : -2147483643 << 1 = 10 
        */
    }

    public static void main(String[] args) {
        leftShiftOperator();

    }
}

shifting by a number larger or equal to the number of bits , and by a negative number

When we are shifting the bits , we specify the value that we want to shift by . The value that is actually taken is

  • the last five bits of the specified value , when the number to shift is an integer or can be promoted to an integer . As such we can shift by a value between 0 and 31 inclusive .
  • the last six bits of the specified value , when the number to shift is a long . A such we can shift by a value between 0 and 63 .
import static java.lang.System.out;

class ShiftNegativeLarge {

    public static void shiftNegativeLarge() {
        long aLongNumber = 1L;
        /*
        a long number can be shift by a value between 0 and 63
        if we specify a larger or a negative value only the last 6 bits are taken  
        */

        out.println(String.format("%d << 1 = %d ", aLongNumber, aLongNumber << -1));
        /*
            we are shifting by -1
            -1  is 1111111111111111111111111111111111111111111111111111111111111111
            we take the last 6 bits which are 111111 as such 
            we must shift 1L left by 63  , 
            1L is 0000000000000000000000000000000000000000000000000000000000000001
            will become
                  1000000000000000000000000000000000000000000000000000000000000000
            output : 1 << 1 = -9223372036854775808 
        */

        short aShortValue = 1;
        /*
        a short value will be promoted to an int when shifting , as such
        the min value and max values that we can shift by are 0 and 31
        */

        out.println(String.format("%d << 31 = %d ", aShortValue, aShortValue << 31));
        /*
        aShortValue is promoted to an int 
            00000000000000000000000000000001 
        and shifted by 31 bits 
            10000000000000000000000000000000
        output : 1 << 31 = -2147483648 
        */

        out.println(String.format("%d << 31 = %d ", aShortValue, (short) (aShortValue << 31)));
        /*
        aShortValue is promoted to an int 
            00000000000000000000000000000001 
        and shifted by 31 bits 
            10000000000000000000000000000000
        after that the result is cast to a short , so we truncate the bits larger than bit
            0000000000000000
        output : 1 << 31 = 0  
        */

        aShortValue = 1;
        out.println(String.format("%d << 121 = %d ", aShortValue, (aShortValue << 121)));
        /*
        aShortValue is promoted to an int 
        we are shifting by 121 
        121 is : 
            00000000000000000000000001111001
        we take the last 5 bits which are :
            11001
        and they are in decimal 25 , so we are shifting by 25
        and the result is 
            00000010000000000000000000000000 in binary which is 2 to the power 25
        so the result is 
            33554432
        output : 1 << 121 = 33554432    
        */

    }

    public static void main(String[] args) {
        shiftNegativeLarge();
    }
}