与0xff进行逐位AND运算本质上意味着返回相同的值,就此而言,在此代码中?
byte[] packet = reader.readPacket();
short sh;
sh = packet[1];
sh &= 0xFF;
System.out.print(sh+" ");
奇怪的是,如果不包括ANDing,那么我得到-1,但是当包含255时可以解释原因吗?
正如我所看到的,0xff只是1111 1111.不是吗?
答案 0 :(得分:21)
是的,0xff
只是1111 1111
。但这是尝试显示无符号字节值,即使在Java byte
中已签名。签名0xff
的值-1
为byte
,255
为short
。
当读取byte
0xff
的值时,打印该值将产生-1
。因此,它被分配给具有更大范围的short
,并且可以将通常溢出的byte
值存储为负数,作为byte
作为正整数,例如144 byte
为0x90
或-112,但它可以144
正确存储为short
。
因此byte
的{{1}}值已分配给-1
。但这又是什么呢?进行原始扩展转换,并对负值进行符号扩展。因此,short
变为1111 1111
,仍为11111111 11111111
,但这次为-1
。
然后使用位掩码short
(0xff
)再次获取最后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)
(假设两个地方都是补码)两件事:
0xff
等于-1。byte
转换为short
)时,会保留值。因此,sh = packet[1]
会将sh
设置为-1
,即0xffff
。点#2的事情是,“额外”位用1s填充,以便在原始值为负时保持该值。与0xff
进行AND运算背后的想法是sh
现在包含0x00ff
,现在删除了那些“额外”1。