为什么按位AND给出不同的字节?

时间:2018-06-21 16:32:01

标签: java bit-manipulation bitwise-operators

java中的一个字节长8位。 &运算符执行按位and操作。

十六进制表示形式包含两个十六进制字符0-F

0xFF是一个字节。

如果我想到&操作,我认为处理器会这样做:

   Bit no: 1 2 3 4 5 6 7 8 
   Binary: 0 0 0 0 0 0 1 0 = decimal 2
Operation: & & & & & & & &
    Value: 1 1 1 1 1 1 1 1 = 0xFF
----------------------------------------
   Result: 0 0 0 0 0 0 1 0 = decimal 2

由于所有二进制文件均保持不变,这使我认为我们不需要& 0xFF

代码

public static void main(String[] args) {
    byte b = -1;
    System.out.println(String.valueOf(b).concat(" and ").concat(String.valueOf(b & 0xFF)));
}

结果

-1 and 255

如果我的假设(我们不需要& 0xFF)是正确的,为什么会有所不同?

2 个答案:

答案 0 :(得分:4)

0xFF等于一个值为25500000000 00000000 00000000 11111111的整数。字节-1为11111111,并且由于已签名,因此被解释为-1。如果未签名,则它也将是255

当您&两个值时,Java将以两个值中较大的一个类型返回结果,即int,因此最终结果是一个带有{{1 }},其值为00000000 00000000 00000000 11111111

答案 1 :(得分:2)

0xFFint,而不是byte,因此b & 0xFF也是int。要获得所需的结果,您需要执行byte算术(Java不允许-小于int的所有数据类型在执行操作前都会隐式转换为int),否则您的掩码0xFF必须在1中的所有 位中使用int(共32个)。例如,请参见以下内容:

System.out.println(0xFF);            // 255. (only 8 of 32 bits are 1)
System.out.println((int)0xFF);       // 255. (only 8 of 32 bits are 1)
System.out.println((byte)0xFF);      // -1. (all 8 of 8 bits are 1)
System.out.println((int)(byte)0xFF); // -1. (all 32 of 32 bits are 1)

请注意,通过强制转换为byte并返回到int,我们使所有32位均为1。因此,以下代码可以满足您的要求(请注意,在将显式强制转换为int之后,将隐式强制转换为byte):

public static void main(String[] args) {
    byte b = -1;
    System.out.println(String.valueOf(b) + " and " + String.valueOf(b & (byte)0xFF)));
}

输出:

  

-1和-1

相关问题