This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Why is (-1 >>> 32) = -1?
The unsigned right shift operator inserts a 0 in the leftmost. So when I do
System.out.println(Integer.toBinaryString(-1>>>30))
output
11
Hence, it is inserting 0 in the left most bit.
System.out.println(Integer.toBinaryString(-1>>>32))
output
11111111111111111111111111111111
Shouldn't it be 0?
See http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19
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.
that is -1 >>> 32 is equivalent to -1 >>> 0 and -1 >>> 33 is equivalent to -1 >>> 1
and, especially confusing, -1 >>> -1 is equivalent to -1 >>> 31
Related
This question already has answers here:
Java right shift integer by 32 [duplicate]
(2 answers)
Is right shift undefined behavior if the count is larger than the width of the type?
(2 answers)
Closed 3 years ago.
why 3 right shift 32 is equal to 3 and not 0.
I got these results in nodeJs and Java
3 >> 31 = 0
3 >> 32 = 3
3 >> 33 = 1
3 >> 34 = 0
3 >> 35 = 0
This is part of the Java language specification. The right hand operand is wrapped so that it is always in the range 0 - bits, where bits is the number of bits of the left hand operand. Since you are shifting a 32 bit integer, the right hand operand is wrapped within 0 to 31. 32 becomes 0, 33 becomes 1 etc.
See the Java language specification for shift operators:
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.
This question already has answers here:
Is java bit shifting circular?
(2 answers)
Closed 4 years ago.
As asked in the title.
I know 1L << 3 = 8, and long type is 64 bit. 67 - 64 = 3. But still why 1L << 67 has the same effect with 1L << 3? Why not something like "bit overflow" happens?
Is there any docs define this behavior? Thanks.
From https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.19
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.
so, 67 & 0x3f = 3
The spec says that the right hand side argument in the expression 'a << b' only uses the lower X bits of b, X being the appropriate number depending on whether you're going with longs, or ints.
SOURCE: The Java Language Specification, section 15.19: https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.19
I am beginner to java... I have tried very much but could not find the way the following line
System.out.println (-1>>>1);
gives 2147483647 ?
Can anyone help me ?
This is because the binary representation of -1 is 11111111111111111111111111111111. When you perform an unsigned right bit-shift operation (>>>) on it it moves all of the bits right by the argument (1 in this case) and fills in empty spaces on the left with zeros so you get 01111111111111111111111111111111 which is the binary representation of Integer.MAX_VALUE = 2147483647 (not sure where you got 2147483648 from).
>>> is the bitwise right-shift operator, with 0 sign extension - in other words, all bits "incoming" from the left are filled with 0s.
-1 is represented by 32 bits which are all 1. When you shift that right by 1 bit with 0 sign extension, you end up with a value which has the 31 bottom bits still 1, but 0 for the top bit (the sign bit), so you end up with Integer.MAX_VALUE - which is 2147483647, not 2147483648 as your post states.
Or in JLS terms, from section 15.19:
The value of n >>> s is n right-shifted s bit positions with zero-extension, where:
If n is positive, then the result is the same as that of n >> s.
If n is negative and the type of the left-hand operand is int, then the result is equal to that of the expression (n >> s) + (2 << ~s).
If n is negative and the type of the left-hand operand is long, then the result is equal to that of the expression (n >> s) + (2L << ~s).
This definition ends up being a bit of a pain to work with - it's easier to just work with the "0 sign extension right-shift" explanation, IMO.
This question already has answers here:
why is 1>>32 == 1?
(2 answers)
unsigned right Shift '>>>' Operator in Java [duplicate]
(1 answer)
Why is (-1 >>> 32) = -1? [duplicate]
(1 answer)
Closed 9 years ago.
Why the expression (-1 >>> 32) in Java is evaluated to -1 instead of 0 as expected? The >>>-shift-operator should fill in preceeding 0s, so the result should have all bits set to 0.
This is weird, because it breaks the semantics of >>>: e.g. (-1 >>> x) has the first x bits set to 0 for all 0 <= x <= 31. The only (unexpected) exception is 32.
Is this intentional behaviour, a bug or an (overmotivated) compiler optimization?
I used the expression ~(-1 >>> x) for expanding a cidr-netmask to its 32-bit equivalent, but as it seems, /32-masks have to be handled separately.
Check this post.
Quote from answer author Rasmus Faber
From the Java Language Specification:
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.
The shift distance actually used is therefore always in the range 0 to
31, inclusive.
Long in short: due to operand range limit, -1 >>> 32 is equivalent to -1 >>> 0 which is -1.
I came across an interesting scenario, When working with bitwise shift operator. If the second operand is negative, how does the bitwise shift operation works? .
i.e a << b , "<<" shifts a bit pattern to the left by b bits in a. But if b is neagtive, shouldn't it be an error at runtime ?
I am able to run the below code successfully but I don't understand how it works?
public static void bitwiseleftShift(char testChar)
{
int val=testChar-'a';
int result= 1<<val;
System.out.println("bit wise shift of 1 with val="+val+" is "+result);
}
Input
bitwiseleftShift('A');// ASCII 65
bitwiseleftShift('0'); // ASCII 48
Results
bit wise shift of 1 with val=-32 is 1
bit wise shift of 1 with val=-49 is 32768
ASCII for 'a' is 97. Can someone help me understand how this works?
But if b is neagtive, shouldn't it be an error at runtime?
Not according to the Java Language Specification, section 15.19:
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 a shift of -32 actually ends up as a shift of 0, and a shift of -49 actually ends up as a shift of 15 - hence the results you saw.