Bit shifting is not circular; for bit-shifting int
s, Java only uses the 5 least-significant bits, so that (b << 0)
is equivalent to (b << 32)
(is equivalent to (b << 64)
, etc.). You can simply take the bit-shifting amount and take the remainder when dividing by 32.
Something similar occurs for bit-shifting long
s, where Java only uses the 6 least-significant bits, so that (aLong << 0)
is equivalent to (aLong << 64)
.
Section 15.19 of the JLS talks about this:
If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.
If the promoted type of the left-hand operand is long, then only the six lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x3f (0b111111). The shift distance actually used is therefore always in the range 0 to 63, inclusive.
(emphasis mine)
(You can't bit-shift float
s or double
s, and attempting to bit-shift a short
or a byte
would be subject the value to unary numeric promotion to an int
anyway.)
You get 0
from 16 << 30
, because the 1-bit from 16
00000000 00000000 00000000 00010000
gets shifted off the end of the int
and gets discarded.
// Discarded - Result-----------------------------
(00000100) 00000000 00000000 00000000 00000000