Operand1 ShiftOperator Operand2
转换规则
如果操作数中的任何一个为负,则不要忘记计算其2的补码,因为负整数使用2的补码存储在存储器中
使用0x1F掩饰Operand2
Right shift 81814621>>-12 = 78 81814621>>>-12 = 78 OK!! Right shift (Operand1 is NEGATIVE) -81814621>>-12 = -79 -81814621>>>-12 = 4017 Why different?
Left shift
21<<-12 = 22020096
-21<<-12 = -22020096
Unlike Right shift no matter Operand1 is Positive/Negative
only sign get changed instead value
感谢您的支持!现在我对它有了更好的想法...... :)
答案 0 :(得分:3)
无论你从哪里得到它,都是错的。操作数2在用0x1F屏蔽后,最左边的五位中不可能是负数或任何东西。 Java Language Specification中没有任何关于采用移位距离的二进制补码,或使用其最左边的五位。阅读它的真实内容。不要依赖任意来源,或者只是弥补。
编辑 -81814621为0xFFFFFFFFFB1F9BA3,-12为0xFFFFFFFFFFFFFFF4,其后五位为0x14或20,右移第一个操作数为20给出0xFFFFFFFFFFFFFFB1,即-79。
答案 1 :(得分:2)
&#34;规则&#34;关于如何处理移位的右侧操作符是因为正确操作数的值列表确实非常短:对于int
s,范围从0到31,包括端点;对于long
s,它是0到63。
右侧的int
的所有其他值都需要转换为指定范围内的值。 &#34;规则&#34;说出这个过程 - 即将数字重新解释为正数(这是两个补码的含义),然后屏蔽高位,保留最后五位。
相反,左操作数可以保持其全范围。您遇到的唯一区别与>>
和>>>
之间的差异有关,也就是说,在将左侧操作数解释为已签名换算的运算符与解释的换算符之间它是未签名的。
>>>
运算符背后的目的在this answer中解释。在您的示例中,当您使用两个运算符右移一个负数时,>>
通过对其进行叹气延长(即在左侧移位数字)而使数字为负数,而>>>
使其为正数换零。