PHP位运算详解
PHP位运算
一、位运算符
例子 | 名称 | 结果 |
---|---|---|
$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”)。 |
二、位运算原理
-
位运算符是指对
二进制
位从低位到高位对齐后进行运算。 -
正数的原码,反码、补码都是一样的,负数不一样
-
原码:数字的8位 二进制,符号位(第一位)为0表示正数,为1表示负数
-
反码:正数反码与原码一样,负数的反码是符号位1不变,整数的每一位二进制数位求反,得到反码
-
补码:正数补码与原码一样,负数反码的符号位1不变,按位取反,末尾(最低位)加1;计算机中的运算都是以补码的形式运算的,存储也是补码
-
补码的特性:
a. 一个负整数(或原码)与其补数(或补码)相加,和为模。 b. 对一个整数的补码再求补码,等于该整数自身。 c. 补码的正零与负零表示方法相同。
-
三、运算实例
&运算符
- 代码
<?php $a = 2; $b = 1; $c = $a & $b; var_dump($c); // int(0)
- 原理 (按位比较,全1为1)
$a 转成二进制 00000010 $b 转成二进制 00000001
变量 $a(二进制表示法): 0 0 0 0 0 0 1 0 $b(二进制表示法): 0 0 0 0 0 0 0 1 $a & $b(二进制表示法): 0 0 0 0 0 0 0 0
&运算符
-
代码
<?php $a = 2; $b = 1; $c = $a | $b; var_dump($c); // int(3)
-
原理 (按位比较,有1为1)
$a 转成二进制 00000010 $b 转成二进制 00000001 // $c = $a | $b 等于二进制 00000011 则等于十进制3
变量 $a(二进制表示法): 0 0 0 0 0 0 1 0 $b(二进制表示法): 0 0 0 0 0 0 0 1 $a | $b(二进制表示法): 0 0 0 0 0 0 1 1
^运算符
-
代码
<?php $a = 2; $b = 1; $c = $a ^ $b; var_dump($c); // int(3)
-
原理 (按位比较,不同为1)
$a 转成二进制 00000010 $b 转成二进制 00000001 // $c = $a | $b 等于二进制 00000011 则等于十进制3
变量 $a(二进制表示法): 0 0 0 0 0 0 1 0 $b(二进制表示法): 0 0 0 0 0 0 0 1 $a ^ $b(二进制表示法): 0 0 0 0 0 0 1 1
~运算符
- 代码
<?php $m = 2; $n = ~$m; var_dump($n); //-3
- 原理
- 2的32位原码为 0000 0000 0000 0000 0000 0000 0000 0010
- 按位取反后为:1111 1111 1111 1111 1111 1111 1111 1101
- 由于最前面的数为1,符号位为1,即为负数,所以,以其正值的补码形式表示为:(反码的符号位不变,按位取反,末尾加1)1000 0000 0000 0000 0000 0000 0000 0011 所以为-3
<<运算符
- 代码
<?php $m = 3; $m1=$m << 1; echo $m1; // 6
- 原理
左移运算的实质是将对应的数据的二进制值逐位左移若干位,并在空出的位置上填0,最高位溢出并舍弃。 3的32位原码为,0000 0000 0000 0000 0000 0000 0000 0011 左移一位:0000 0000 0000 0000 0000 0000 0000 0110 所以为6
>>运算符
右移一位,和<<运算符,类似,只不过这个是右移。