17

与 0xff 进行按位与运算本质上是否意味着在此代码中返回相同的值?

byte[] packet = reader.readPacket();
short sh;
sh = packet[1];
sh &= 0xFF;
System.out.print(sh+" ");

奇怪的是,如果不包含 ANDing,我会得到 -1,但包含时会得到 255 有人可以解释原因吗?

如我所见,0xff 只是 1111 1111。不是吗?

4

3 回答 3

32

是的,0xff只是1111 1111。但这是试图显示无符号字节值,即使在 Javabyte中是有符号的。该值0xff适用-1于一个有符号byte的,但它255在一个short.

当读取 的byte值时0xff,打印该值将产生-1。因此它被分配给short具有更大范围的 a 并且可以byte将通常溢出为负数的值存储为正byte整数,例如 144 作为 a或 -112,但它可以正确存储为 a 。byte0x90144short

所以 的byte-1被分配给 a short。但这有什么作用?发生原始扩展转换,并且负值被符号扩展。1111 1111就这样11111111 11111111,仍然-1,但这次是short

然后位掩码0xff( 00000000 11111111) 用于再次取出最后 8 位:

  -1: 11111111 1111111
0xFF: 00000000 1111111
======================
 255: 00000000 1111111

这只是一种获取无符号byte值的方法,通过将其转换为short然后从 中屏蔽掉原始位,byte将其显示为无符号值。

于 2013-09-27T23:30:18.647 回答
3

Abyte的范围是 -128 到 127。这意味着某些值是负数。这是设置了最高位的所有值。(byte) 0xFF-1也是如此。当您使用符号扩展使其成为有符号短时,它变为(short) 0xFFFF-1 作为短。当您屏蔽它时,它会切断扩展位,并且您将字节视为无符号的。


除非您的代码与您在问题中的代码不同,否则您不会得到 -1。

for (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) {
    short s = b;
    s &= 0xff;
    System.out.println(b + " & 0xFF = " + s);
}

印刷

-128 & 0xFF = 128
-127 & 0xFF = 129
....
-2 & 0xFF = 254
-1 & 0xFF = 255
0 & 0xFF = 0
1 & 0xFF = 1
...
125 & 0xFF = 125
126 & 0xFF = 126
于 2013-09-27T23:31:17.450 回答
1

(假设到处都是补码)两件事:

  1. 字节是有符号的,所以0xff一个字节等于-1。
  2. 当从较小的数据类型变为较大的数据类型时(在这种情况下,从 abyte到 a short),该被保留。因此,sh = packet[1]将设置sh-1,即0xffff

第 2 点的问题是,只要原始值为负,“额外”位就会用 1 填充以保持该值。ANDing 背后的想法0xffsh现在包含0x00ff, 那些“额外”的 1 现在被删除了。

于 2013-09-27T23:30:11.847 回答