与0xff进行逐位AND运算很重要?

时间:2013-09-27 23:23:08

标签: java byte bitwise-operators short bitwise-and

与0xff进行逐位AND运算本质上意味着返回相同的值,就此而言,在此代码中?

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

奇怪的是,如果不包括ANDing,那么我得到-1,但是当包含255时可以解释原因吗?

正如我所看到的,0xff只是1111 1111.不是吗?

3 个答案:

答案 0 :(得分:21)

是的,0xff只是1111 1111。但这是尝试显示无符号字节值,即使在Java byte中已签名。签名0xff的值-1byte255short

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

因此byte的{​​{1}}值已分配给-1。但这又是什么呢?进行原始扩展转换,并对负值进行符号扩展。因此,short变为1111 1111,仍为11111111 11111111,但这次为-1

然后使用位掩码short0xff)再次获取最后8位:

00000000 11111111

这只是一种获取无符号 -1: 11111111 1111111 0xFF: 00000000 1111111 ====================== 255: 00000000 1111111 值的方法,方法是将其转换为byte,然后屏蔽short中的原始位,将其显示为无符号值。

答案 1 :(得分:2)

byte的范围是-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

答案 2 :(得分:1)

(假设两个地方都是补码)两件事:

  1. 字节已签名,因此字节中的0xff等于-1。
  2. 从较小的数据类型转到较大的数据类型(在这种情况下,从byte转换为short)时,会保留。因此,sh = packet[1]会将sh设置为-1,即0xffff
  3. 点#2的事情是,“额外”位用1s填充,以便在原始值为负时保持该值。与0xff进行AND运算背后的想法是sh现在包含0x00ff,现在删除了那些“额外”1。