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