首先来看一个程序,分别打印4
和-4
的取反运算结果,代码:java
public static void main(String[] args) {
System.out.println(~4);
System.out.println(~(-4));
}
不妨思考一下结果,若是结果是-4和4的话,那请继续看下去吧.显然结果不是你想的那样,一块儿看下:
web
没错,结果就是-5和3(可不是相反数那么简单的哟),这里先告诉一个万能计算公式,要计算一个整数的取反运算,好比x,那么:app
~x = -(x+1);
虽然有计算公式,相信你仍是跟我同样,想弄清楚为何是这样的结果.
首先来看,~
这个计算符号的定义是什么?
按照我平时的理解,当我使用~
按位取反运算的时候,计算机会将操做数所对应的二进制表达式的每个位进行取反计算,取反后所获得的值就是~按位取反的运算结果(这点没问题),可是怎么去理解呢,咱们来具体分析下.学习
在这以前,先说一下计算机中的数据表示:
咱们平时学习的二进制表示有三种形式:原码,反码和补码;
然而计算机只认识补码,原码和反码只是人们方便计算人为定义的,因此计算机中的全部计算二进制的输入输出都是补码的形式,理解到这点,就能够继续往下看了.spa
仍是上面的程序,咱们对4
进行取反运算,过程以下:code
0 100
1 011
-5
可能你仍是纳闷,为何1011
就获得-5
了呢,不该该是-3
吗?
回到刚刚说的,计算机中全部二进制输出都是补码的形式,所以1011
是某一个数的补码表示形式,咱们须要把他转成咱们能理解的二进制:orm
1 011
,最高位为1,表示是一个负数,所以符号位不变,而后减1,获得反码(补码 = 反码 + 1,反之): 1 010
;1 010
符号位除开,按位取反获得原码: 1 101
,这不就是-5
了嘛.同理,咱们再看-4
取反:blog
1 100
0 011
3
那为何又是3呢?
很简单,补码0 011
最高位为0,说明是正数,而正数的原码和补码是同样的,因此直接等于3
.ci
public static void main(String[] args) {
System.out.println(~4);
//补码: 0 100
//取反: 1 011
//反码: 1 010
//原码: 1 101 = -5
System.out.println(~(-4));
//1 100
//1 011
//补码: 1 100
//取反: 0 011
//原码: 0 011 = 3}