I have this behavior using Java:
int b=16;
System.out.println(b<<30);
System.out.println(b<<31);
System.out.println(b<<32);
System.out.println(b<<33);
output: 0 0 16 32
Is java bit shift circular? IF not, why I get 0 when b<<30 and 16 when b<<32?
No, it's not circular shift. It's normal left-shift. It's just that, for
int
type left side operand, Java uses just 5 lower order bits of the right operand for shifting. This is as per JLS §15.9:So, for
16 << 32
, considering only 5 lower order bits of32
, the expression is equivalent to:which is equal to 16.
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:
(emphasis mine)
(You can't bit-shift
float
s ordouble
s, and attempting to bit-shift ashort
or abyte
would be subject the value to unary numeric promotion to anint
anyway.)You get
0
from16 << 30
, because the 1-bit from16
gets shifted off the end of the
int
and gets discarded.