欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于按位取反~和负数的二进制输出问题

程序员文章站 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=======================================