又颓废了几天,半条咸鱼,下面来学习以下位运算
学习位运算,就先要搞懂二进制Binary
二进制。就是逢二进一
计算机的世界,都是二进制,因为0和1是最稳定的
二进制的概念:
1.二进制的最高位是符号位:0代表正数,1代表负数
2.正数的原码,反码,补码都一样
3.负数的反码=它的原码符号位不变,其它位取反(0->1,1->0)
4.负数的补码=它的反码+1
5.0的反码和补码都是0
6.php没有无符号数!!!
7.在计算机运算的时候都是以补码的方式来运算的!!!
原码:用二进制表示一个数,这个码就是原码
例如:1---->原码、反码、补码:00000000 00000000 00000000 00000001
-1--->原码:10000000 00000000 000000000 00000001
-1的反码就是:11111111 11111111 11111111 11111110
-1的补码就是:11111111 11111111 11111111 11111111
位运算符允许对整型数中指定的位进行求值和操作。
例子 | 名称 | 结果 |
---|---|---|
$a & $b | And(按位与) | 将把 $a 和 $b 中都为 1 的位设为 1。 |
$a | $b | Or(按位或) | 将把 $a 和 $b 中任何一个为 1 的位设为 1。 |
$a ^ $b | Xor(按位异或) | 将把 $a 和 $b 中一个为 1 另一个为 0 的位设为 1。 |
~ $a | Not(按位取反) | 将 $a 中为 0 的位设为 1,反之亦然。 |
$a << $b | Shift left(左移) | 将 $a 中的位向左移动 $b 次(每一次移动都表示"乘以 2")。 |
$a >> $b | Shift right(右移) | 将 $a 中的位向右移动 $b 次(每一次移动都表示"除以 2")。 |
<?php
echo ~2;
因为机器都是以补码进行运算,所以要先求出2的补码:00000000 00000000 00000000 00000010
所以~2在机器中:11111111 11111111 11111111 11111101(补码形式)
最后结果显示是根据原码来显示,所以需要求出~2的原码,所以先要求出反码再退出原码
~2的反码:11111111 11111111 11111111 11111100
~2的原码:10000000 00000000 00000000 00000011---->-3
echo ~-5;
-5的原码:10000000 00000000 00000000 00000101
-5的反码:11111111 11111111 11111111 11111010
-5的补码:11111111 11111111 11111111 11111011
所以~-5:00000000 00000000 00000000 00000100(补码)正数
所以~-5的原码、反码、补码都一样,所以~-5=4
echo 2&3;
首先需要找到2和3的补码
2:00000000 00000000 00000000 00000010
3:00000000 00000000 00000000 00000011
所以2&3:00000000 00000000 00000000 00000010
所以2&3-->2
echo 2|3;
2,3补码同上
所以2|3:00000000 00000000 00000000 00000011
echo 2^3;
2^3:00000000 00000000 00000000 00000001
13&7;
13:00000000 00000000 00000000 00001101
7:00000000 00000000 00000000 00000111
所以13&7:00000000 00000000 00000000 00000101--->5
5|4;
5:00000000 00000000 00000000 00000101
4:00000000 00000000 00000000 00000100
5|4:00000000 00000000 00000000 00000101--->5
-3^3;
-3原码:10000000 00000000 00000000 00000011
-3反码:11111111 11111111 11111111 11111100
-3补码:11111111 11111111 11111111 11111101
3补码:00000000 00000000 00000000 00000011
所以-3^3补码:11111111 11111111 11111111 11111110
-3^3反码:11111111 11111111 11111111 11111101
-3^3的原码:10000000 00000000 000000000 00000010--->-2
下面是位运算:php中有两种位运算
>>(右移) :低位溢出,符号位不变,并用符号位补溢出的高位
<<(左移):符号位不变,低位补0
$a=1>>2;
1的补码:00000000 00000000 00000000 00000001
1>>2:00000000 00000000 00000000 00000000--->0
$b=-1>>2;
-1原码:10000000 00000000 00000000 00000001
反码:11111111 11111111 11111111 11111110
补码:11111111 11111111 11111111 11111111
-1>>2:11111111 11111111 11111111 11111111
所以-1>>2:-1
$c=1<<2;
1补码:00000000 00000000 00000000 00000001
1<<2:00000000 000000000 00000000 00000100-->4
$d=-1<<2;
-1补码:11111111 11111111 11111111 11111111
-1<<2:11111111 11111111 11111111 11111100
反码:11111111 11111111 11111111 11111011
原码:10000000 00000000 00000000 00000100--->-4
?>