I encountered misunderstanding of primitive promotion in the next code snippet.
byte a = 2;
int b = a >> 4L;
What would I expect?
long b = (int)a >> 4L;
long b = a >> 4L;
int b = a >> 4L;
int >> long
will promote to the larger data type (long
) and it won't compile with resulted int
type.
What have I received?
It compiles fine. Why?
The JLS won't "promote to the larger datatype" here, because it does not perform binary numeric promotion for shifting operators. This is covered by the JLS, Section 15.19.
Unary numeric promotion (§5.6.1) is performed on each operand separately. (Binary numeric promotion (§5.6.2) is not performed on the operands.)
Unary numeric promotion promotes the byte a
to an int
. The literal 4L
is not changed, but it only needs to be a integral type anyway.
It is a compile-time error if the type of each of the operands of a shift operator, after unary numeric promotion, is not a primitive integral type.
Then for the shifting, only the least 5 significant bits are used to shift an int
.
If the promoted type of the left-hand operand is int, then 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.
The result of the operator is an int
, not a long
, so it can be assigned to an int
without a compiler error.
The type of the shift expression is the promoted type of the left-hand operand.
By the JLS:
The type of the shift expression is the promoted type of the left-hand operand.
The right-hand operand of a shift operator doesn't have any effect on the expression's type. Unlike with an operator like +
, a bigger type on the right doesn't mean the result could be any bigger or any smaller.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With