位运算

逢2进一,因为使用二进制只有0.1两个数,简单,易于电子方式实现。

二进制-----原码、反码、补码

基本概念:对于有符号的而言:

①二进制的最高位是符号位:0表示正数,1表示负数。

②正数的原码、反码、补码都一样。

③负数的反码=它的原码符号位不变,其他位取反(0->1,1->0)

④负数的补码=它的反码+1

⑤0的反码、补码都是0

⑥php没有无符号数,换言之,php中的数都是有符号的

⑦在计算机运算的时候,都是以补码的方式来运算的。

1、原码

   用二进制表示一个数,这个码就是原码。

2、负数的反码=它的原码符号位不变,其它位取反(0->1,1->0)

   举例

-1

-1的原码 10000000 00000000 00000000 00000001

-1的反码 11111111 11111111 11111111 11111110

-1的补码是它的反码全部加1

结果是:11111111 11111111 11111111 11111111

3、在计算机运算的时候,都是以补码的方式来运算的。

   这句话的意思是,不管一个数是正数还是负数,都要被转成补码,然后进行运算。

4、其运算规则是:

按位与&:两位全为1,结果为1

按位或|:两位有一个为1,结果为1

按位异或^:两位一个为0,一个为1,结果为1

按位取反:0->1,1->0

举例:

~2=?

步骤:首先要求出2的补码

2是正数,所以它的原码=反码=补码

二的原码:000000000 00000000 00000000 00000010

~2取反(0->1,1->0)

11111111 11111111 11111111 11111101(补码)

补码要推出反码要推出原码

补码-1推出其反码

11111111 11111111 11111111 11111100

推出原码

符号位不变,0->1,1->0

10000000 00000000 00000000 00000011原码是-3

例题

~-5=?

把-5的补码找出来

-5的原码10000000 00000000 00000000 00000101

-5的反码

符号位不变其余的0->1,1->0

11111111 11111111 11111111 11111010

-5的补码 11111111 11111111 11111111 11111011

-5取反00000000 00000000 00000000 00000100

2&3=?

首先要找到2和3的补码

按位与,两位全为1则为1

2的补码00000000 00000000 00000000 00000010

3的补码00000000 00000000 00000000 00000011

2&3    00000000 00000000 00000000 00000010(这还是补码)

2|3=?

2的补码00000000 00000000 00000000 00000010

3的补码00000000 00000000 00000000 00000011

2|3=    00000000 00000000 00000000 00000011

2|3==3

2^3

2的补码00000000 00000000 00000000 00000010

3的补码00000000 00000000 00000000 00000011

2^3     00000000 00000000 00000000 00000001

2^3==1 

Php中有移位运算符

>>、<<算术右移和算术左移,运算规则

算术右移:低位溢出,符号位不变,并用符号位补溢出的高位

算术左移:符号位不变,低位补0 

请看下面的代码,回答a,b,c,d结果是什么

<?php

$a=1>>2;

先找到1的补码:原码=补码=反码

00000000 00000000 00000000 00000001

右移后00000000 00000000 00000000 00000000

$b=-1>>2;

先算出-1的补码,先找到-1的原码100000000 00000000 00000000 00000001

-1的反码,符号位不变,然后1变0,0变1

111111111 11111111 11111111 11111110

-1的补码111111111 11111111 11111111 11111111

-1>>2

11111111 11111111 11111111 111111111补码

结果

补码->原码

反码11111111 11111111 11111111 11111110

原码10000000 00000000 00000000 00000001  

$c=1<<2;

1的补码

000000000 00000000 00000000 00000001

000000000 00000000 00000000 00000100 

$d=-1<<2;

左移的方式就是乘2,所以3*8等价于3<<3