10
byte x = -1;
for(int i = 0; i < 8; i++)
{
    x = (byte) (x >>> 1);
    System.out.println("X: " + x);
}

据我了解,java将数据存储在二进制补码中,意思是-1 = 11111111(根据维基百科)。

此外,来自 java 文档:“位模式由左侧操作数给出,而要移位的位置数由右侧操作数给出。无符号右移位运算符 >>>”将零移到最左边位置,而“>>”后最左边的位置取决于符号扩展。”

这意味着 >>> 每次都会将 0 移到最左边。所以我希望这段代码是

迭代:x的位表示

0:11111111

1:01111111

2:00111111

3:00011111

...很快

但是,我的输出始终是 X: -1,这意味着(我猜)>>> 将符号位放在最左边的位置。所以我然后尝试>>,结果相同。

这是怎么回事?我希望我的输出是:X:-1,x:127,x:63,等等。

4

5 回答 5

28

那些认为在发明 Java 时应该对字节进行签名的人应该取出并用一根湿芹菜棒殴打直到他们哭泣:-)

您可以通过强制转换为 int 并确保您永远不会将 1 移到最高位来做您想做的事情,如下所示:

byte x = -1;
int x2 = ((int)x) & 0xff;
for(int i = 0; i < 8; i++)
{
    x2 = (x2 >>> 1);
    System.out.println("X: " + x2);
}

您的特殊问题是因为 >>> 正在转换为 int 来进行转换,然后您将其转换回字节,如下所示:

byte x = -1;
int x2 = ((int)x) & 0xff;
int x3;
int x4 = x2;
for(int i = 0; i < 8; i++)
{
    x2 = (x2 >>> 1);
    System.out.println("X2: " + x2);
    x3 = (x >>> 1);
    x = (byte)x3;
    x4 = (x4 >>> 1);
    System.out.println("X: " + x3 + " " + x + " " + x4);
}

哪个输出:

X2: 127
X: 2147483647 -1 127
X2: 63
X: 2147483647 -1 63
X2: 31
X: 2147483647 -1 31
X2: 15
X: 2147483647 -1 15
X2: 7
X: 2147483647 -1 7
X2: 3
X: 2147483647 -1 3
X2: 1
X: 2147483647 -1 1
X2: 0
X: 2147483647 -1 0

您可以清楚地看到 x 和 x3 不起作用(即使 x3 正确移动,将其转换回 x 中的字节也会再次将其设置为 -1)。x4 完美运行。

于 2009-02-19T01:16:34.137 回答
5

请记住:

  • 按位运算的操作数总是被提升为至少一个 int
  • 强制转换总是涉及符号扩展

因此,当您执行 (x >>> n) 时,即使您将 x 定义为字节,出于移位的目的,它也会首先转换为 int。如果要转换的字节为负数,则添加到 int 的所有“额外位”(因此,结果 int 的最左边 24 位)将设置为 1。或者换一种方式,如果原始byte 是 -1,你实际移动的东西是 -1 作为int,即所有 32 位设置为 1 的 32 位数字。将这个右移 1-8 位仍然会导致底部 8 位全部设置为 1,因此当您转换回一个字节时,您最终会得到一个所有 8 位都设置为 1 的字节,或者换句话说,一个字节值为 -1。

于 2009-02-19T03:25:10.850 回答
3

我不确定。但是,我的猜测是

x >>> 1 

从字节提升为 int,因为文字“1”是一个 int。那么你所观察的东西是有道理的。

于 2009-02-19T01:16:17.680 回答
0

我不知道为什么它不起作用,但是清除最高位的一种简单方法是与(二进制)0111111 一起使用:

x = (byte) (x >>> 1) & 0x7F;
于 2009-02-19T01:27:03.613 回答
0

问题是,如前所述(很久以前),x 在进行移位之前被向上转换为 int(符号扩展)。
进行“位到位”转换应该会有所帮助:

byte x = -1;
for(int i = 0; i < 8; i++)
{
    x = (byte) ((x & 0xFF) >>> 1);
    System.out.println("X: " + x);
}
于 2009-11-24T20:02:24.273 回答