我很想知道使用二进制文字进行逐位比较时实际发生了什么。我刚刚遇到了以下事情:
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
?
答案 0 :(得分:1)
没有特定强制转换的二进制文字表示32位整数值,无论有多少位数。例如,0b00000001
是0b00000000 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位整数。
请务必注意,使用-1
或double, 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
,结果将是一个字节。