关于按位取反~和负数的二进制输出问题
程序员文章站
2022-07-14 23:51:02
...
public class test {
public static void main(String[] args) {
short a = (short) 0;
System.out.println(~a);
}
}
结果输出 -1
分析:a=0x0000, ~a=0xffff,二进制为1111 1111 1111 1111,当你要输出的时候,编译器发现最高位符号位是1,这个数是个负数,而负数在计算机里面是用补码存储的,所以此时计算机认为这个0xffff是补码,它要转换成原码输出,于是先减去1,再除了符号位不变,其他位全部取反。
就得到了原码0x8001即二进制1000 0000 0000 0001,我们知道原码这个数就代表-1
再来一个例子:
public class test {
public static void main(String[] args) {
short a = (short) -2;
System.out.println(~a);
}
}
结果输出 1
分析:a=-2,原码是0x8002,二进制为1000 0000 0000 0010,在计算机中补码表示为1111 1111 1111 1110
要输出的时候按位取反~,~a就是0000 0000 0000 0001,此时计算机发现它最高位是0,这个数是正数,原码补码是一样的,所以直接输出为1
public class test {
public static void main(String[] args) {
short a = (short) 3;
System.out.println(~a);
}
}
结果输出 -4
分析:a=3的二进制位为0000 0000 0000 0011,~a=1111 1111 1111 1100
输出时计算机发现最高位符号位是1,这个数是负数,也就是存储的是补码,要转换成原码输出,就在原数基础上-1再除开符号位其他位都取反
变成了1000 0000 0000 0100,这个数就是-4的原码,所以输出-4
总结提示:按位取反这个符号~是数据的所有位取反,不管什么符号位,而求补码是原码取反再加1,这个步骤中的取反是除开了符号位的其他位取反。
========================================Talk is cheap, show me the code=======================================
推荐阅读