为什么对于负数,无符号右移(逻辑右移)和有符号右移(算术右移)为什么都产生相同的结果?
Log.v("-59 >>> 5 expected 6, actual", String.valueOf((byte)(-59 >>> 5)));
Log.v("11000101 >>> 5 expected 00000110, actual",Integer.toBinaryString( -59 >>> 5));
Log.v("11000101 >> 5 expected 00000110, actual",Integer.toBinaryString( -59 >> 5));
Android Studio Logcat输出
-59 >>> 5 expected 6, actual: -2
11000101 >>> 5 expected 00000110, actual: 111111111111111111111111110
11000101 >> 5 expected 00000110, actual: 11111111111111111111111111111110
答案 0 :(得分:1)
这是正常现象。任何具有负值的整数都具有以1s开头的二进制表示形式。
因此,如果您首先说:-3二进制表示形式如下:
...11 1101
因此,如果我们将其右移2,我们将得到
...11 1111
现在开始未标记/右移。这取决于我们的整数中没有无限位数的事实。所以说我们有一个分配为-3的8位整数,它看起来像这样:
1111 1101
如果我们进行有符号移位,它将查看MSB(最高有效位,最左位),并在移位时保留该值。因此,按3号右移的符号移位如下所示:
1111 1111
相反,无符号右移将不会检查MSB,而只会右移并用零填充,结果是:
0011 1111
这正是您所看到的,但是输出会截断前面的零。
如果您不知道为什么以这种方式存储负整数,请check this answer。
(b & 0xff) >>> 5
为何表现不同java中的整数是32位,这意味着二进制表示形式将具有32位数字。您的-59将类似于以下二进制表示形式:
1111 1111 1111 1111 1111 1111 1100 0101 == -59
0000 0111 1111 1111 1111 1111 1111 1110 == -59 >>> 5
如果现在与0xff
一起和,您将获得以下信息:
1111 1111 1111 1111 1111 1111 1100 0101 == -59
0000 0000 0000 0000 0000 0000 1111 1111 == 0xff
0000 0000 0000 0000 0000 0000 1100 0101 == -59 & 0xff
0000 0000 0000 0000 0000 0000 0000 0110 == (-59 & 0xff) >>> 5
答案 1 :(得分:0)
右移运算符:-如果数字为负数,则用1填充。如果数字为正数,则用0填充。 无符号移位运算符:-填充0,与数字的符号无关。