你不会还不知道按位取反运算的原理吧

引入

首先来看一个程序,分别打印4-4的取反运算结果,代码:java

public static void main(String[] args) {
    System.out.println(~4);
    System.out.println(~(-4));
}

不妨思考一下结果,若是结果是-4和4的话,那请继续看下去吧.显然结果不是你想的那样,一块儿看下:
web

187MFUkJ
187MFUkJ

没错,结果就是-5和3(可不是相反数那么简单的哟),这里先告诉一个万能计算公式,要计算一个整数的取反运算,好比x,那么:app

~x = -(x+1);

理解

虽然有计算公式,相信你仍是跟我同样,想弄清楚为何是这样的结果.
首先来看,~这个计算符号的定义是什么?
按照我平时的理解,当我使用~按位取反运算的时候,计算机会将操做数所对应的二进制表达式的每个位进行取反计算,取反后所获得的值就是~按位取反的运算结果(这点没问题),可是怎么去理解呢,咱们来具体分析下.学习

在这以前,先说一下计算机中的数据表示:
咱们平时学习的二进制表示有三种形式:原码,反码和补码;
然而计算机只认识补码,原码和反码只是人们方便计算人为定义的,因此计算机中的全部计算二进制的输入输出都是补码的形式,理解到这点,就能够继续往下看了.spa

仍是上面的程序,咱们对4进行取反运算,过程以下:code

  1. 4的二进制表示(补码): 0 100
  2. 计算机对它进行按位取反: 1 011
  3. 这时计算机将计算结果反馈给咱们,获得的答案是: -5

可能你仍是纳闷,为何1011就获得-5了呢,不该该是-3吗?
回到刚刚说的,计算机中全部二进制输出都是补码的形式,所以1011是某一个数的补码表示形式,咱们须要把他转成咱们能理解的二进制:orm

  1. 首先看补码1 011,最高位为1,表示是一个负数,所以符号位不变,而后减1,获得反码(补码 = 反码 + 1,反之): 1 010;
  2. 将反码1 010符号位除开,按位取反获得原码: 1 101,这不就是-5了嘛.

同理,咱们再看-4取反:blog

  1. 64的二进制表示(补码): 1 100
  2. 计算机对它进行按位取反: 0 011
  3. 这时计算机将计算结果反馈给咱们,获得的答案是: 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}
> 欢迎关注 [码之泪殇](http://www.gongsir.club)
相关文章
相关标签/搜索