Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is java bit shifting circular?

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?

like image 588
dykw Avatar asked Feb 10 '14 18:02

dykw


People also ask

Does Java have bit shifting?

The Java programming language also provides operators that perform bitwise and bit shift operations on integral types.

How does shift work in Java?

A shift operator performs bit manipulation on data by shifting the bits of its first operand right or left. The next table summarizes the shift operators available in the Java programming language. Each operator shifts the bits of the first operand over by the number of positions indicated by the second operand.

What is bit shifting operations?

Bit shifting is an operation done on all the bits of a binary value in which they are moved by a determined number of places to either the left or right. Bit shifting is used when the operand is being used as a series of bits rather than as a whole.


2 Answers

Bit shifting is not circular; for bit-shifting ints, 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 longs, 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 floats or doubles, 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 
like image 84
rgettman Avatar answered Sep 18 '22 15:09

rgettman


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:

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

So, for 16 << 32, considering only 5 lower order bits of 32, the expression is equivalent to:

16 << 32 & 0x1f

which is equal to 16.

like image 27
Rohit Jain Avatar answered Sep 18 '22 15:09

Rohit Jain