zoukankan      html  css  js  c++  java
  • 你不会还不知道按位取反运算的原理吧

    引入

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

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

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

    187MFUkJ
    187MFUkJ

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

    ~x = -(x+1);

    理解

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

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

    还是上面的程序,我们对4进行取反运算,过程如下:

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

    可能你还是纳闷,为什么1011就得到-5了呢,不应该是-3吗?
    回到刚刚说的,计算机中所有二进制输出都是补码的形式,因此1011是某一个数的补码表示形式,我们需要把他转成我们能理解的二进制:

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

    同理,我们再看-4取反:

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

    那为什么又是3呢?
    很简单,补码0 011最高位为0,说明是正数,而正数的原码和补码是一样的,所以直接等于3.

    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)
  • 相关阅读:
    Cookie数据的编码及解码
    删除单链表节点,时间复杂度为O(1)
    匹配URL
    C#文本框允许使用ctrl+A
    实现统计一个字符串所含的不同字符的总数
    调用win32 api 函数SendMessage() 实现消息直接调用
    关于C++的const对象
    从一个文本文件中找出使用频率最高的五个字符
    C++基础中的基础(深拷贝与浅拷贝)
    python+Django CRM客户关系管理系统开发(十)--左右移动选择框功能开发
  • 原文地址:https://www.cnblogs.com/gongsir/p/13335359.html
Copyright © 2011-2022 走看看