理解位运算
原码,反码,补码
我们以整数来说,php中整型数据占内存8byte,也就是64bit位,每个位要么是0,要么是1;
我们用左边第一位作为符号位,0为正,1为负;
- 原码:十进制转换成的二进制
10000000 ... 00000101 -5原码
- 反码则是在原码基础上,符号位不变,其它位取反
11111111 ... 11111010 -5反码
- 补码则是在反码的基础上+1
11111111 ... 11111011 -5补码
可以看到负数是以补码形式存储
总结
正数的原码,反码,补码,都是原码;
负数以补码的形式存储,得到原码也很简单,将补码-1,得到反码,然后取反(符号位不变),得到原码;
计算机能表示的最大正整数
01111111 ... 11111111,即2^63 - 1
我们看+0,-0
+0
原码:00000000 ... 00000000
反码:00000000 ... 00000000
补码: 00000000 ... 00000000
-0
原码: 10000000 ... 00000000
反码: 11111111 ... 11111111
补码:100000000 ... 00000000 溢出最高位为0 , 00000000 ... 00000000
最终+0与-0的补码一致,因此存储的一致
位运算
数据存到计算机,最终都是二进制的,1bit存一位二进制数字
&
按位与,两位都为1,则结果为1,否则为0|
按位或,两位有一个为1,则结果为1,否则为0^
按位异或,两位不同则为1,相同则为0~
按位取反,本身为1则为0,本身为0则为1<<
按位左移,全部位向左移,右边补0>>
按位右移,全部位向右移动,左边补符号位
$a = 5;
$b = 3;
//按位与
echo $a & $b;
//00000000 ... 00000101
//00000000 ... 00000011
//00000000 ... 00000001 //最终结果:1
//按位或
echo $a | $b;
//00000000 ... 00000101
//00000000 ... 00000011
//00000000 ... 00000111 //最终结果:7
//按位异或
echo $a ^ $b;
//00000000 ... 00000101
//00000000 ... 00000011
//00000000 ... 00000110 //最终结果:6
//按位取反
echo ~$a;
//00000000 ... 00000101
//11111111 ... 11111010 //注意:这是异或后的结果:符号位为1,表示你负数(系统为补码),所以要输出的话要转化成原码
//11111111 ... 11111001 //反码:补码-1
//10000000 000 00000110 //原码:符号位不变,其他位取反,最终结果-6
//按位左移
echo $a << 1;
//00000000 ... 00000101
//00000000 ... 00001010 //最终结果:10
//按位右移
echo $a >> 1;
//00000000 ... 00000101
//00000000 ... 00000010 //最终结果:2
echo -5 >> 1;
位运算的应用
在不使用第三方变量的情况下,交换两个变量的值
$a = $a ^ $b;
$b = $a ^ $b;
$a = $a ^ $b;
echo $a,$b; //35,实现交换
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: