• Post Reply Bookmark Topic Watch Topic
  • New Topic

Doubt on shift operator  RSS feed

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi.. Please could someone check the below code and explain why the bit pattern output for the second for-loop is different from the third for-loop.
NOTE: The total number of unsigned right shift on -1 is the same (i.e 32 shifts) in both cases.



OUTPUT:

11111111
00000000
11111111
 
Ranch Hand
Posts: 461
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Bala,
Welcome to the CodeRanch!

let's see what is going in your code:
at line 4 you have-int I = 1 which is eqquivalent in bits as
00000000 00000000 00000000 00000001
applying the left shift as I <<= 7 is similar to I = I << 7,that is we are required to shift the bits to the left side by 7 positions by doing so we have:
00000000 00000000 00000000 10000000after shifting the bits the empty posn were filled with bit(0).
now you have the for loop with conditional expression as I <= 1 and the Afterthought as I >>= 1.now come inside the body of loop we have another variable as
byte i = -1note here you have given a int value to the byte.you are lucky here because 1 is in the range of byte values(-128,127).it would overflow if you will use out of range values(though in that case probably you will get a compile time error)
so our byte is
111111112's complement.
now we have an if statement in a loop having condition.(i&I)==0.let's see what is the type of expression-"i&I"
From the Java® Language specification(JLS) the type of a binary numeric exression is expression is:
JLS wrote:Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:

If either operand is of type double, the other is converted to double.

Otherwise, if either operand is of type float, the other is converted to float.

Otherwise, if either operand is of type long, the other is converted to long.

Otherwise, both operands are converted to type int.

for a reference you can see the spec→(§15.19) , (§5.6.1) and (§5.6.2)
so in the expression the byte will be converted to int(by widening conversion) and type of the expression is int so we have to evaluate:
11111111 11111111 11111111 11111111widening with sign extension.
&
00000000 00000000 00000000 10000000
it would evaluate to
00000000 00000000 00000000 10000000
which discards the if condition so prints 1.similarly if you will right shift bits of I by 1 in each iteration you will get the similar result(bit 1 is present in I in each iteration) so you will get the output for this loop as11111111

now the next part is i >>>= 31 go through the links for the type of these expression(int here).
according to the JLS,in the shift expression:
JLS wrote: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

here we have the right hand operand=32 which is in bit form:
00000000 00000000 00000000 00011111
clearly its 5 lower bits are 11111 which is 31 in decimal and
i is 11111111 11111111 11111111 11111111
doing the unsigned right shift with 31 as the distance will produce:
00000000 00000000 00000000 00000001
now doing the unsigned shift again on it with distance 1,here we have the right hand operand as 1 which is
00000000 00000000 00000000 00000001
its last 5 bits are 00001 which is 1 so shifting the i by 1 would produce
00000000 00000000 00000000 00000000
now if you will see the performing the & of the above bits with any int will produce the answer 0 that's why this time you have all 0's printed(as per your print statement).output00000000
the next time you have again set the i to -1 which would make it again 11111111
next we have i >>>= 32,here the promoted type of the i is int and the type of the expression is also int(for promoted type go through above links).
here the right hand operand is 32 whose bit representation is:
00000000 00000000 00000000 00100000.
you can see its lowest 5 bits are 00000 which is equivalent to 0 in decimal so no any shift will be done here and i would remain -1 here.so this loop is equivalent to your first one.

Hope it helps!

Kind Regards,
Praveen.
 
Marshal
Posts: 56610
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

My, that is confusing code, with incorrect indentation and two variables with confusing names, i and I.
You do realise that the composite assignment operators can produce unexpected results with variables narrower than 32 bits because of the implicit cast?
 
Bala Eesan
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Praveen,

Thanks for your thorough explanation. Now i'm clear with this concept.
I sincerely appreciate your effort on this.

Best regards,
Bala
 
Campbell Ritchie
Marshal
Posts: 56610
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It was a good explanation, wasn't it
 
Bala Eesan
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Ritchie - Ya..definitely!!
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!