我很难理解负无符号按位运算符。 例如,我有下面的代码。它打印出值 7,我不明白为什么。
int num1 = -37, num2 = -3;
System.out.println( num1 >>> num2);
// Essentially the same as System.out.println( -37 >>> -3);
// I just wanted to emphasize that i am working with Integers
据我所知,二进制格式的数字-37如下所示。
11111111 11111111 11111111 11011010 = -37(十进制格式)
如果我们对 3 进行无符号右移(-37 >>> 3,而不是 -37 >>> -3),据我所知(如果我的理论有缺陷或缺乏关键概念,请纠正我),它会改变向右移动 3 个字节,最右边位置掉出的 3 位以向下翻转的状态(从 0 到 1)出现在最左边的位置,这意味着我们得到以下结果。
00011111 11111111 11111111 11111011 = 536870907(十进制格式)。
但是,如果我们应用无符号右移 -3 (-37 >>> -3),我们会得到结果 7。我不明白为什么它返回 7。有人可以向我解释一下吗?
最佳答案
这似乎违反直觉,但根据 JLS, Section 15.19,当移位 int
时,仅使用移位量的最后 5 位。 .
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.
这意味着-3
仅使用了最后5位,即29
。这里的 -3
位显示发生了什么:
11111111 11111111 11111111 11111101
最后 5 位是十进制的 11101
或 29
。
右移距离为29
,这意味着前3位被保留并一直向右移动。取-37
:
11111111 11111111 11111111 11011010
无符号移位 29 位后,剩下 7
:
00000000 00000000 00000000 00000111
正如您所看到的,负移位量充其量只是令人困惑。尽量避免这种情况,并始终尝试使用 0 到 31 之间的实际数字作为移位 int
的移位量。
关于java - Java中无符号右移负数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31306213/