使用二进制文字的按位xor的行为

时间:2015-10-22 13:38:59

标签: java bit-manipulation bitwise-operators bitwise-xor

我很想知道使用二进制文字进行逐位比较时实际发生了什么。我刚刚遇到了以下事情:

byte b1 = (new Byte("1")).byteValue();

// check the bit representation
System.out.println(String.format("%8s", Integer.toBinaryString(b1 & 0xFF)).replace(' ', '0'));
// output: 00000001

System.out.println(b1 ^ 0b00000001);
// output: 0

所以一切都按预期运行,xor比较等于0。然而,当尝试使用负数时,它不会起作用:

byte b2 = (new Byte("-1")).byteValue();

// check the bit representation
System.out.println(String.format("%8s", Integer.toBinaryString(b2 & 0xFF)).replace(' ', '0'));
// output: 11111111

System.out.println(b2 ^ 0b11111111);
// output: -256

我原本预计最后一次xor比较也等于0。但是,如果我将二进制文字显式转换为byte

,则只会出现这种情况
byte b2 = (new Byte("-1")).byteValue();

// check the bit representation
System.out.println(String.format("%8s", Integer.toBinaryString(b2 & 0xFF)).replace(' ', '0'));
// output: 11111111

System.out.println(b2 ^ (byte)0b11111111);
// output: 0

对于我来说,在xor比较之前看起来b10b11111111具有相同的位表示,所以即使它们被转换为int(或其他内容) )xor应该仍然等于0。你是如何得到-256二进制表示11111111 11111111 11111111 00000000的结果的?为什么我必须对byte进行显式转换才能获得0

2 个答案:

答案 0 :(得分:1)

没有特定强制转换的二进制文字表示32位整数值,无论有多少位数。例如,0b000000010b00000000 00000000 00000000 00000001的缩写。

Java中的按位比较使用二进制数字提升(请参阅Javadocs)。在这种特定情况下,这意味着在执行比较之前,两个操作数都将转换为int

0b11111111已经代表int(没有前导0),只代表0b00000000 00000000 00000000 11111111,而b2是一个代表值{{}的字节1}}。在转换为-1期间,值将被保留,因此int将转换为表示相同数字(b2)的32位整数:-1

0b11111111 11111111 11111111 11111111然后评估为xor,这是0b11111111 11111111 11111111 00000000的32位二进制表示。

如果使用-256执行xor比较,则二进制文字也将被视为一个字节,因此等效地转换为表示(byte)0b11111111的32位整数。

请务必注意,使用-1double, float, long执行二进制比较(如Javadocs中所述)。如果只有其他类型参与比较(例如int),则会将其转换为byte。这就是为什么下面的代码会给出编译错误:

int

...因为两个byte b1 = (byte)0b00000001; byte b2 = (byte)0b00000001; byte b3 = b1 & b2; >>> error: incompatible types: possible lossy conversion from int to byte 的按位比较结果是byte

关于为什么的进一步阅读可以在这里完成:

答案 1 :(得分:0)

使用b1 ^ 0b11111111时,实际上在byte到int之间执行xor byte是8位变量,而int是32位数。 那么,你做的是: b1 ^ 0b(00000000 00000000 00000000 11111111) 所以当你在xor之间使用byte时(在它之前使用额外的1s与int.1s一起使用它,因为它是一个negetive数字。如果它是正数,那么它将是0)和{{1}结果将是一个整数,在您的情况下,-256。

当您将整数转换为int时,您在两个字节之间使用byte,结果将是一个字节。