使用二进制文字的按位异或行为
Behavior of bitwise xor using binary literals
我很想知道在使用二进制文字进行按位比较时实际发生了什么。我刚刚遇到以下事情:
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
?
当你使用 b1 ^ 0b11111111
时,你实际上在 byte 到 int 之间做了 xor
byte
是 8 位变量,而 int
是 32 位数字。
所以,你所做的是:
b1 ^ 0b(00000000 00000000 00000000 11111111)
因此,当您在 byte
之间使用 xor
(在它之前附加 1 以将其与 int.1s 一起使用,因为它是一个负数。如果它是正数,则为 0)和 int
结果将是一个整数,在你的例子中,-256.
当您将整数转换为 byte
时,您在两个字节之间使用 xor
,结果将是一个字节。
没有特定转换的二进制文字表示 32 位整数值,无论有多少位。例如 0b00000001
是 shorthand 对应 0b00000000 00000000 00000000 00000001
.
Java 中的按位比较使用 二进制数字提升 (请参阅 Javadocs)。在这种特定情况下,这意味着两个操作数在执行比较之前都转换为 int
。
0b11111111
已经表示一个 int
(没有前导 0
s)并且只表示 0b00000000 00000000 00000000 11111111
,而 b2
是一个表示值的字节-1
。在转换为 int
期间,值被保留,因此 b2
被转换为表示相同数字 (-1
) 的 32 位整数:0b11111111 11111111 11111111 11111111
.
然后 xor
的计算结果为 0b11111111 11111111 11111111 00000000
,这是 -256
.
的 32 位二进制表示
如果使用 (byte)0b11111111
执行 xor
比较,二进制文字也将被视为一个字节,因此等效地转换为表示 -1
的 32 位整数。
重要的是要注意二进制比较是使用 double, float, long
或 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
...因为两个byte
按位比较的结果是int
.
进一步阅读为什么可以在这里完成:
- Types and the Java Virtual Machine
- Bitwise operators in java only for integer and long?
我很想知道在使用二进制文字进行按位比较时实际发生了什么。我刚刚遇到以下事情:
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
?
当你使用 b1 ^ 0b11111111
时,你实际上在 byte 到 int 之间做了 xor
byte
是 8 位变量,而 int
是 32 位数字。
所以,你所做的是:
b1 ^ 0b(00000000 00000000 00000000 11111111)
因此,当您在 byte
之间使用 xor
(在它之前附加 1 以将其与 int.1s 一起使用,因为它是一个负数。如果它是正数,则为 0)和 int
结果将是一个整数,在你的例子中,-256.
当您将整数转换为 byte
时,您在两个字节之间使用 xor
,结果将是一个字节。
没有特定转换的二进制文字表示 32 位整数值,无论有多少位。例如 0b00000001
是 shorthand 对应 0b00000000 00000000 00000000 00000001
.
Java 中的按位比较使用 二进制数字提升 (请参阅 Javadocs)。在这种特定情况下,这意味着两个操作数在执行比较之前都转换为 int
。
0b11111111
已经表示一个 int
(没有前导 0
s)并且只表示 0b00000000 00000000 00000000 11111111
,而 b2
是一个表示值的字节-1
。在转换为 int
期间,值被保留,因此 b2
被转换为表示相同数字 (-1
) 的 32 位整数:0b11111111 11111111 11111111 11111111
.
然后 xor
的计算结果为 0b11111111 11111111 11111111 00000000
,这是 -256
.
如果使用 (byte)0b11111111
执行 xor
比较,二进制文字也将被视为一个字节,因此等效地转换为表示 -1
的 32 位整数。
重要的是要注意二进制比较是使用 double, float, long
或 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
...因为两个byte
按位比较的结果是int
.
进一步阅读为什么可以在这里完成:
- Types and the Java Virtual Machine
- Bitwise operators in java only for integer and long?