我有十六进制值,并希望创建按位补码。例如:
0x00 -> 0xFF
0xC4 -> 0x3B
以下测试失败,但为什么?
@Test
public void testBitwiseComplement() {
char[] buffer = new char[] {0x00, 0xff};
assertEquals(buffer[0], ~buffer[1]); //expected 0, but was -256
assertEquals(buffer[1], ~buffer[0]); //expected 255, but was -1
}
按位否定算子〜[参考:https://docstore.mik.ua/orelly/java/langref/ch04_04.htm]
按位求反运算符(〜)可以作为一元表达式的一部分出现。 〜运算符的操作数类型必须是整数数据类型,否则会发生编译时错误。 〜运算符可以在执行其计算之前执行类型转换。如果操作数的类型是byte,short或char,则运算符在生成值之前将其操作数转换为int。否则,〜运算符产生与其操作数相同类型的值。
public class BitwiseNegation {
public static void main(String args[]) throws Exception {
char a = 0xff;
char b = 0x00 ;
System.out.printf(">>>>>a HexaDecimal: %x Decimal: %d\n", (int)a, (int)a);
System.out.printf(">>>>>b HexaDecimal: %x Decimal: %d\n", (int)b, (int)b);
System.out.printf(">>>>>~a HexaDecimal: %x Decimal: %d\n", ~a, ~a);
System.out.printf(">>>>>~b HexaDecimal: %x Decimal: %d\n", ~b, ~b);
}
}
输出:
>>>>>a HexaDecimal: ff Decimal: 255
>>>>>b HexaDecimal: 0 Decimal: 0
>>>>>~a HexaDecimal: ffffff00 Decimal: -256
>>>>>~b HexaDecimal: ffffffff Decimal: -1
由于对于一元运算符,char被提升为int,因此值0xff变为0x000000ff,其在按位补码后变为0xffffff00。现在这个数字是负数(符号位是1),通过反转二进制补码表示,数字变为-256。但0x00的按位补码为-1。因此断言失败了。
因此,仅对于值0xffffffff和0x00000000,它们的按位补码也相等。
java中的按位完成确实应用了一元促销,其中“char”操作数被提升为int。 https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2
Java int是一个4字节的SIGNED类型,因此您可以看到差异。
~buffer[0]=11111111111111111111111111111111 is correct
~buffer[0]=11111111 is incorrect