programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
• Campbell Ritchie
• Jeanne Boyarsky
• Ron McLeod
• Paul Clapham
• Liutauras Vilda
Sheriffs:
• paul wheaton
• Rob Spoor
• Devaka Cooray
Saloon Keepers:
• Stephan van Hulst
• Tim Holloway
• Carey Brown
• Frits Walraven
• Tim Moores
Bartenders:
• Mikalai Zaikin

# Doubt on shift operator

Greenhorn
Posts: 3
• Number of slices to send:
Optional 'thank-you' note:
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: 491
23
• 2
• Number of slices to send:
Optional 'thank-you' note:
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: 79233
377
• Number of slices to send:
Optional 'thank-you' note:
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
• Number of slices to send:
Optional 'thank-you' note:
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: 79233
377
• Number of slices to send:
Optional 'thank-you' note:
It was a good explanation, wasn't it

Bala Eesan
Greenhorn
Posts: 3
• Number of slices to send:
Optional 'thank-you' note:
@Ritchie - Ya..definitely!!

 Consider Paul's rocket mass heater.