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.
Related
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
This question already has answers here:
Why does Java mask shift operands with 0x1F?
(2 answers)
Closed 9 years ago.
How does the shift operator << work when the value of the shift bits is greater than the total number of bits for the datatype?
For example,
int i = 2;
int j = i<<34;
System.out.println(j);
The size of an integer is 32 bits, however we are shifting 34 bits. How does this work?
I'm not sure the source on this, but according to WikiPedia (emphasis mine):
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 & with the mask value 0x1f (0b11111).[4]
The shift distance actually used is therefore always in the range 0 to
31, inclusive.
Edit: It looks like the WikiPedia entry basically lifted the information straight out of the Java Specification.
When you shift an integer with the << or >> operator and the shift distance is greater than or equal to 32, you take the shift distance mod 32 (in other words, you mask off all but the low order 5 bits of the shift distance).
This can be very counterintuitive. For example (i >> 32) == i, for every integer i. You might expect it to shift the entire number off to the right, returning 0 for positive inputs and -1 for negative inputs, but it doesn't; it simply returns i, because
(i << (32 & 0x1f)) == (i << 0) == i.
Getting back to your original problem, (i << 33) == (i << (33 & 0x1f))
== (i << 1). You can do the whole thing in binary if you like. 270 in binary is : 0000 0000 0000 0000 0000 0001 0000 1110 Shifting right by 1,
you get: 0000 0000 0000 0000 0000 0000 1000 0111 which is 135.
But a better way to do this problem in your head is to dispense with the binary entirely.
The value of i >> s is floor(i / 2<sup>s</sup>) (where s has already been masked off so it's less than 32). So, 270 << 1 = floor(270/2) = 135.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19
If you try 1 << 34, you end up with 4. The runtime basically has an implicit mod NUMBER_OF_BITS on the right-hand operand of the shift. In the previous example, it's 1 << (34 % 32), which becomes 1 << 2, which is 4.
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.
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