Java无符号位移(>>>)会给出奇怪的结果

3

我有这段代码:

int i = 255;
byte b = (byte) i;
int c;
System.out.println(Integer.toBinaryString( i));
System.out.println("b = " + b); // b = -1
c=b>>>1;
System.out.println(Integer.toBinaryString( c));
System.out.println(c);

但是我不明白它是如何工作的。我认为将无符号位移设置为 255(11111111) 应该会得到 127(0111111),但实际上并没有。我的假设是错误的吗?


一个 byte 可以取的最大值是多少? - Rohit Jain
我知道在Java中,我们有带符号的字节,范围为-127到127,但在二进制表示中,255为真正的11111111。 - mechanikos
Java 中的位移操作是针对 int 类型而非 byte 类型的。 - John Dvorak
抱歉如果找不到重复的内容。哦...我必须更好地学习英语。 - mechanikos
3个回答

2
移位运算符包括>>>,作用于int类型。因为byte类型是有符号的,变量b的值是-1,在移位之前会被提升为int类型。这就是你看到的结果。
255重新解释为-1的原因是它的八个二进制位都设置为1。当你将它赋给一个8位有符号类型byte时,根据二进制补码规则,它被解释为-1

但如果我执行System.out.println(b>>>1);,我也会得到这个结果。那么对于字节移位,我该怎么做? - mechanikos
没错,由于 Java 的升级规则 b>>>1 意味着 ((int)b) >>> 1。这是将 b 提升为 int 导致添加了所有这些 1 的结果 - 这是必要的,以保持值等于原始的 -1 - Sergey Kalinichenko
这个问题是重复的,请投票关闭而不是回答。 - John Dvorak

1
试一下,你就会明白:
System.out.println(Integer.toBinaryString(i)); // 11111111
System.out.println(Integer.toBinaryString(b)); // 11111111111111111111111111111111
System.out.println(Integer.toBinaryString(c)); // 1111111111111111111111111111111

变量int i等于255,因此第一次打印看起来有意义。

变量byte b等于-1,因为您将255存储在单个字节中。

  • 但是当您调用Integer.toBinaryString(b)时,编译器将bbyte转换为int(int)-1 == FFFFFFFFh == 11111111111111111111111111111111b,因此第二个打印结果。

变量int c等于b>>>1,因此第三个打印结果有意义。


1
这是如何获得预期结果的。
c = (0xFF & b) >>> 1;

请参见dasblinkenlight的答案以获取详细信息。

此问题已有重复。请投票关闭而不是回答。 - John Dvorak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接