zoukankan      html  css  js  c++  java
  • 位运算

    这一起也要说一下这最后一个运算符:位运算符

    注意:本篇大部分都是讲二进制的,如果不会转换,还需去前面补补课

    既然讲到了位运算,有一个知识点是肯定不能落下的:

    那就是原码,反码,补码这三个的概念

    看图:

     

    嗯!感觉差不多。

    对了

    本篇的主要内容是位运算,差点忘了

    那就先看一下一共有那些位运算符吧

    << ,>>,>>>,&,|,^

    看到这你一定会想:

    这什么鬼东西,几个小于号大于号就说是位运算符?

    还有后面三个家伙不是逻辑运算符吗?怎么也是位运算符?

    那么就由我来一一解开这几个疑问

     语法:要位移的数   位运算符  位移值(移多少位)

    <<:表示将要位移的数的二进制向左移,后面产生的空位补0

     代码图:

    运行图:

    没错,结果就是这样。

    那么我们应该要知道2是如何变成8的。对吧

     首先应该要得到2的二进制数:

    0000 0010(这里只有一个字节,实际是int有四个字节)

    然后将它左移两位,变成:

    0000 1000

    最后转换成十进制数

    就是我们最后的结果8

    看看负数

     运行结果:

    我们上面说了计算机都是用补码来计算的

    所以先求出-3的二进制补码:

    原码:1000 0011

    反码:1111 1100

    补码:1111 1101

    然后左移两位

    1111 0100

    得到的是补码,我们可以把补码逆运算变成原码

    补码:1111 0100

    反码:1111 0011

    原码:1000 1100

    转换成十进制就是-12(开头是一,表示负数)

    >>:将要位移的数的二进制向右移,

    假如是正数前面补0 ,负数前面补1

    代码测试:

     运行结果是:

    1

    -2

    回到上面的操作,我们来还原一下计算机底层是如何实现的

    1.得到要位移数的二进制数的补码(为了方便两个一起运算)

    原码:0000 1001   1000 0111

    反码:0000 1001   1111 1000

    补码:0000 1001   1111 1001

    然后向右移动,正数前面补0,负数补1

    0000 1001  >>   3  

    0000 0001  

    结果就是1

    1111 1001  >> 2

    1111 1110

    我们把得到的补码逆运算成原码

    补码:1111 1110

    反码:1111 1101

    原码:1000 0010

    得到结果就是-2

    可以,完全没毛病。

    接下来就这个东西了

    >>>:也表示向右位移,不过它是不管正负数的,右移后前面直接补0

    嗯哼,代码试试:

     结果为:

    1

    536870911

    同上继续手工还原(看到第二个数,有点慌)

    分开一个个来吧:

    先来正数的二进制

    0001 0001

    右移4位

    0000 0001

    结果是1

    第二个负数:

    首先我们应该要知道这个数怎么会这么大?

    看我推演就知道了

    前面我们写的二进制都是八位的对吧  八位就是一个字节,

    然而int是有四个字节的,前面的计算没有写出前面的三个字节

    是因为前面三个字节其实没什么很大的关系

    这里就要全写出来了

    -7实际在计算机是这样存储的

    原码:1000 0000  0000 0000  0000 0000  0000 0111

    反码:1111 1111  1111 1111  1111 1111  1111 1000

    补码:1111 1111  1111 1111  1111 1111  1111 1001

     右移3位,前面补0:

    0001 1111  1111 1111  1111 1111  1111 1111

    直接算出结果(这里是正数,无需转换成原码,因为三码合一)

    就是:

    1+2+4+8+16+32+64+128+256+512+1024+2048....

    反正最后的结果就是刚才好长的那个

    这三个位移运算符讲完了

    再看看我们其它的三个逻辑运算符(就这样叫吧)

    前面链接的是表达式,这里连接的是整数

    &:表示将两个数的二进制进行比较,同一位中都是1结果为1否则为0

    |:表示将两个数的二进制进行比较,同一位中都是0结果为0,否则就为1

    ^:表示将两个数的二进制进行比较,同一位相同结果为0,不相同结果为1

    实际测试:

     

    结果为:

    8

    11

    3

    老样子:我们要知道他底层是如何运算的,所以需要还原一下他的操作

    先来&:

    先得到两个数的二进制

    0000 0000  0000 0000  0000 0000  0000 1001 (9)

    0000 0000  0000 0000  0000 0000  0000 1010 (10)

     然后进行比较,得到结果是:

    0000 0000  0000 0000  0000 0000  0000 1000

    转换成十进制就是8

    第二个|:

    这里直接使用上面算出来的二进制得出结果为:

    0000 0000  0000 0000  0000 0000  0000 1011

    转换成十进制就是11

    最后一个^:

    同上,直接算出结果

    0000 0000  0000 0000  0000 0000  0000 0011

    结果就是十进制的3

    到最后:

    终于说完了这篇,唉。

    例如:如何高效率的将2变成8

    就可以使用我们的左移完成

    int a = 2 << 2;

  • 相关阅读:
    学习:类和对象——继承
    学习:类和对象——运算符重载
    域权限维持:Skeleton Key
    域权限维持:SSP密码记录
    学习:类和对象——友元
    学习:类和对象——对象模型和this指针
    学习:类和对象——静态成员变量和函数
    学习:类和对象——初始化列表和内部类
    学习:类和对象——深拷贝和浅拷贝
    二维数组中的查找
  • 原文地址:https://www.cnblogs.com/menghujava/p/9662276.html
Copyright © 2011-2022 走看看