Java 使用0xff进行位与运算很重要吗?
在这段代码中,0xff的按位ANDing本质上不是意味着返回相同的值吗Java 使用0xff进行位与运算很重要吗?,java,byte,bitwise-operators,short,bitwise-and,Java,Byte,Bitwise Operators,Short,Bitwise And,在这段代码中,0xff的按位ANDing本质上不是意味着返回相同的值吗 byte[] packet = reader.readPacket(); short sh; sh = packet[1]; sh &= 0xFF; System.out.print(sh+" "); 奇怪的是,如果不包括ANDing,我会得到-1,但如果包括255,有人能解释原因吗 在我看来,0xff只是1111111。是吗?(假设到处都是2的补码)两件事: 字节是有符号的,因此字节中的0xff等于-1 当从较小
byte[] packet = reader.readPacket();
short sh;
sh = packet[1];
sh &= 0xFF;
System.out.print(sh+" ");
奇怪的是,如果不包括ANDing,我会得到-1,但如果包括255,有人能解释原因吗
在我看来,0xff只是1111111。是吗?(假设到处都是2的补码)两件事:
0xff
等于-1字节
转换为短
),保留该值。因此,sh=packet[1]
将sh
设置为-1
,即0xffff
点#2的问题是,当原始值为负值时,“额外”位会被1填充,以保持该值。与
0xff
进行ANDing的背后思想是sh
现在包含0x00ff
,而那些“额外”1现在被删除。是的,0xff
只是1111111
。但这是试图显示无符号字节值,即使在Java中,字节是有符号的。有符号的字节的值0xff
为-1
,但在短的中为255
当读取0xff
的byte
值时,打印该值将产生-1
。因此,它被分配给一个short
,它的范围更大,可以存储byte
值,这些值通常会溢出为负数,作为byte
作为正整数,例如作为byte
的144是0x90
或-112,但它可以作为144
作为short
正确存储
因此,-1
的字节
值被分配给短
。但那有什么用呢?将进行基本体加宽转换,并对负值进行符号扩展。所以1111111
变成11111111111
,仍然-1
,但这次是短的
然后使用位掩码0xff
(00000000 11111111
)再次取出最后8位:
-1: 11111111 1111111
0xFF: 00000000 1111111
======================
255: 00000000 1111111
这只是一种获取无符号字节
值的方法,将其转换为短
,然后屏蔽字节
中的原始位,将其显示为无符号值。a字节
的范围为-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);
}
在问题中,他确实说“奇怪的是,如果不包括ANDing,我会得到-1”。在我看来,他似乎知道发生了什么,但想知道为什么。@SimonAndréForsberg说得对。这就是我所期望的,一点也不奇怪。@SimonAndréForsberg谢谢你支持我。。。你对我说。。我想知道为什么……我会给你一张赞成票,但你得等24分钟才能得到我的赞成票。我目前没有投票权。“所以-1的字节值被分配给一个short。但是这有什么作用呢?一个原始的加宽转换发生了,负值被符号扩展。”——非常好的信息。“然后使用位掩码0xff(00000000 11111111)再次取出最后8位”-huhh。。就是这样。。太感谢了,老兄…“这个价值被保留了”。。这就解释了。。非常感谢你!
-128 & 0xFF = 128
-127 & 0xFF = 129
....
-2 & 0xFF = 254
-1 & 0xFF = 255
0 & 0xFF = 0
1 & 0xFF = 1
...
125 & 0xFF = 125
126 & 0xFF = 126