2

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

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两者b1并且0b11111111具有相同的位表示,所以即使它们被强制转换为int(或其他东西),xor应该仍然相等0。您如何得出二进制表示-256的结果?11111111 11111111 11111111 00000000为什么我必须进行显式强制转换byte才能获得0

4

2 回答 2

1

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

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

0b11111111已经代表一个int(没有前导0s)并且只代表一个0b00000000 00000000 00000000 11111111b2而是一个代表值的字节-1。在转换为该值的过程中,int该值被保留,因此b2被转换为表示相同数字的 32 位整数 ( -1): 0b11111111 11111111 11111111 11111111

然后xor评估0b11111111 11111111 11111111 00000000哪个是 的 32 位二进制表示-256

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

重要的是要注意二进制比较是使用double, float, longor执行的int(如Javadocs中所指定)。如果只有其他类型参与比较(例如byte),它们将被转换为int. 这就是为什么以下代码会给出编译错误的原因:

byte b1 = (byte)0b00000001;
byte b2 = (byte)0b00000001;
byte b3 = b1 & b2;

>>> error: incompatible types: possible lossy conversion from int to byte

...因为两个按位比较的结果byteint.

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

于 2015-11-12T09:51:04.070 回答
0

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

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

于 2015-10-22T13:54:43.970 回答