Вопрос

Why if

int x = -1 // binary: 11111111111111111111111111111111
x = x >>> 31; 

we have 00000000000000000000000000000001

but if

int x = -1
x = x >>> 32;

we have 11111111111111111111111111111111 (again -1)

but not 00000000000000000000000000000000 ?

Это было полезно?

Решение

From Section 15.19 of JLS:

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.

Emphasis mine. So:

x >>> n

is equivalent to:

x >>> n & 0x1f  // or x >>> n % 32

So, x >>> 32 is equivalent to x >>> 32 & 0x1f <==> x >>> 0 == x.

So the Rule of Thumb is, whenever you shift a number by a multiple of 32(int is 32 bits), you get back the same value.

Другие советы

When applying the bit-shift operation only the lowest 5 bits of the right-hand operand are considered. Since 32 === 0 // mod 32, the result is no shifting.

Spent an entire day breaking my head over why a long l = i << 32 behaved strangely, then wrote some basic tests, had the WTF moment, and then chnged to long l = (long) i << 32 for it to work.

My only add to Rohit's answer is the reason why this is so. From IA-32 Intel Architecture Software Developer’s Manual 3:

The 8086 does not mask the shift count. However, all other IA-32 processors (starting with the Intel 286 processor) do mask the shift count to 5 bits, resulting in a maximum count of 31. This masking is done in all operating modes (including the virtual-8086 mode) to reduce the maximum execution time of the instructions

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top