位运算

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

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

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

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

看图:

 

嗯!感觉差不多。

对了

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

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

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

看到这你一定会想:

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

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

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

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

<<:表示将要位移的数的二进制向左移,后面产生的空位补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;

原文地址:https://www.cnblogs.com/menghujava/p/9662276.html