Why does Java mask shift operands with 0x1F?

后端 未结 2 1492
忘了有多久
忘了有多久 2021-01-11 15:54

In Java:

(0xFFFFFFFF <<  1) = 0xFFFFFFFE = 0b1111111111111110
                :         :               :
(0xFFFFFFFF << 30) = 0xE0000000 = 0b111         


        
相关标签:
2条回答
  • 2021-01-11 16:22

    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

    to put it simply 0xFFFFFFFF << 32 is equivalnt to 0xFFFFFFFF << (32 & 0x1f) is equivalent to 0xFFFFFFFF << 0

    0 讨论(0)
  • 2021-01-11 16:31

    Sure, there is: it's how most processors (specifically including x86) implement bit shifting, and to do what you want -- to check if the shift is greater than 32, and if so, return zero -- requires a branch, which can be expensive on modern CPUs. It's not just "annoying," it can slow things down by orders of magnitude.

    In short, doing what you want would add significant overhead to an operation that is expected to be blazing fast by high-performance code.

    For reference, the logic isn't exactly the same as %, it's a mask. See JLS 15.19 for details:

    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.

    0 讨论(0)
提交回复
热议问题