按位与操作与0xff很重要吗?

22

在这段代码中,将一个值与0xff按位相与后是否基本上意味着得到相同的值?

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

奇怪的是,如果不加入那个AND运算符,结果会是-1,但如果加上,结果会变成255。有人能解释一下原因吗?

在我看来,0xff只是1111 1111,对吗?

3个回答

34
是的,0xff只是1111 1111。但这试图显示无符号字节值,尽管在Java中byte是有符号的。对于有符号的byte,值0xff-1,但对于short,它是255
当读取0xffbyte值时,打印该值将产生-1。因此,将其分配给一个具有较大范围并可以存储通常会溢出为负数的byte值作为正整数的short。例如,作为byte的144是0x90或-112,但可以正确地存储为short144
因此,-1byte值被分配给short。但这样做有什么用呢?进行了原始扩展转换,并且对负值进行了符号扩展。因此,1111 1111变成了11111111 11111111,仍然是-1,但这次作为short
然后使用位掩码0xff00000000 11111111)再次获取最后8位:
  -1: 11111111 1111111
0xFF: 00000000 1111111
======================
 255: 00000000 1111111

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


我想给你点赞,但你需要等待24分钟才能收到我的点赞。我现在没有投票的机会了。 - Simon Forsberg
"So the byte value of -1 is assigned to a short. But what does that do? A primitive widening conversion takes place, and negative values are sign-extended." -- 很好的信息。"Then the bitmask 0xff (00000000 11111111) is used to get the last 8 bits out again" -- 哦,原来如此。非常感谢! - Shashank Sabniveesu

3
一个 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

在这个问题中,他确实说:“奇怪的是,如果没有包含AND运算符,我会得到-1。”对我来说,他似乎知道发生了什么,但想知道为什么。 - Simon Forsberg
1
@SimonAndréForsberg 很好的观点。这正是我所期望的,一点也不奇怪。 - Peter Lawrey
@SimonAndréForsberg 谢谢你的支持... 你理解得很对.. 我想知道为什么.. - Shashank Sabniveesu

1
(假设在各处都使用二进制补码)有两件事情:
  1. 字节是有符号的,因此一个字节中的 0xff 等于 -1。
  2. 当从较小的数据类型转换为较大的数据类型时(在本例中,从 byte 转换为 short),会保留 。因此,sh = packet[1] 会将 sh 设置为 -1,即 0xffff

关于第二点的问题是,“额外”的位被填充为 1,以保持原始值为负数。与 0xff 进行 AND 操作的想法是,现在 sh 包含 0x00ff,其中这些“额外”的 1 已经被移除。


值被保留了。..这解释了..非常感谢! - Shashank Sabniveesu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接