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
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:
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
I was scanning a third party source code using Findbugs (just to be cautious before integrating into it mine), and found the following warning:
long a = b << 32 | c
Bug: Integer shift by 32 Pattern id:
ICAST_BAD_SHIFT_AMOUNT, type: BSHIFT,
category: CORRECTNESS
The code performs an integer shift by
a constant amount outside the range
0..31. The effect of this is to use the lower 5 bits of the integer value
to decide how much to shift by. This
probably isn't want was expected, and
it at least confusing.
Could anyone please explain what exactly does the above mean?
Thanks!
(I am quite a newbie in Java programming)
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.
So if b is an int, the expression is identical to
long a = b | c;
which I highly doubt is what is intended. It should probably have been
long a = ((long) b << 32) | c;
(If b is already a long, the code is correct and FindBugs is mistaken about the bug).
Edited: The problem almost certainly stems from the fact that 'b' is an 'int' and not a 'long'.
In C, if 'b' is an integer instead of a long and you shift left by 32 bits, all the bits from the original value have been removed, so the result of the overall expression would be the same as 'c' you would invoke undefined behaviour, so any result is permissible. Java defines things differently — as noted in the comment by Rasmus Faber and the chosen answer — and does overlong shifts modulo the maximum number of bits that can be shifted. [It seems an odd way to do business; I'd probably have arranged for an exception in a language that has them. However, it is clearly defined, which is more important than exactly what the definition is.] The coercion to 64-bits doesn't occur while the expression is evaluated; it occurs when the expression is complete and the assignment happens.
The reference to 5 bits is ... intriguing. It means that if you shift left by, say, 48, or binary 110000, it is the same as shifting left by 16. Or, alternatively, 'x << n' is the same as 'x << (n % 32)'.