位运算,在平时的使用频率不是很高,大部分人都很少用到,以至于对位运算的理解也是比较模糊。

下面就来详细说说,这些平时不常用的位运算符究竟应该怎么用,以及有什么需要注意的事项。使用位运算来判断,在某种程度上也可以减轻数据库存储数据的压力(嗯,这个作用目前还感觉不明显),废话不多说,客观继续往下看(老鸟请留情,谢谢)

 

位运算符

描述信息我已经尽量用比较好理解的方式修改,官方的实在是有点儿绕,寄希望下次看到的时候能立马想起来而不是再去理解一次

运算符 含义 描述(位运算,基于二进制表示) 示例
& 按位与 只有参与运算的两位均为1时,结果才为1,否则为0 a与b:$a & $b
| 按位或 只有参与运算的两位均为0时,结果才为0,否则为1 a或b:$a | $b
^ 按位异或 只有参与运算的两位不同时,结果才为1,否则为0 a异或b:$a ^ $b
~ 按位非(取反) 将用二进制表示的操作数中为1的位转为0,为0的为转为1 a非:~$a
<< 左移 将左边的操作数在内存中的二进制数据向左移动指定位数,右侧移空的位用0补齐 a左移4位:$a<<4
>> 右移 将左边的操作数在内存中的二进制数据向右移动指定位数,左侧移空的位用0补齐 a右移4位:$a>>4

图示说明:

定义:

A=81(d)=01010001(b)

B=9(d)=00001001(b)

按位与(&)

规则:0&0=0,0&1=0,1&0=0,1&1=1

A&B运算结果:1(d)=00000001(b)

按位或(|)

规则:0|0=0,0|1=1,1|0=1,1|  1=1

A|B运算结果:89(d)=01011001(b)

按位异或(^)

规则:0^0=0,0^1=1,1^0=1,1^1=0

A^B运算结果:88(d)=01011000(b)

取反(~)

规则:0->1,1->0

~A运算结果:-82(d)=10100110(b)

左移(<<)

A<<2运算结果:324(d)=101000100(b)

注:橙色为补位码

右移(>>)

A>>2运算结果:20(d)=00010100(b)

注:橙色为补位码,浅灰色为丢弃码

在实际使用中的应用示例

假设先在有一个数据表格如下

表结构

字段 类型 描述
id int(6) 自增ID,学生编号
username varchar(40) 学生姓名
userage tinyint(3) 学生年龄
egstatus tinyint(3) 学生英语考级状态(1-四级,2-六级,3-八级)

表数据

id username userage egstatus
1 zhangsan 18 3
2 lisi 19 7
3 wangwu 18 1

先来说说 “egstatus” 这个字段的设计,它存储的是记录二进制数据第几位为真,且要求低位也必须为真,所以取值转换成十进制之后就变成了表数据中的情况,来看看为什么是1,3,7而不是1,2,3吧。

首先转换为二进制,可以看到1表示第一位为真,3表示第一二位均为真,7表示第一二三位均为真

1(d)=00000001

3(d)=00000011

7(d)=00000111

再看看我们的需求:判断用户英语考级状态

$eg = 3;
if($eg & 1){
    # code...
    //1(d)=00000001(b)第一位为真
}
if($eg & 2){
    # code...
    //2(d)=00000010(b)第二位为真
}
if($eg & 4){
    # code...
    //4(d)=00000100(b)第三位为真
}

 

到这里,也许聪明的您应该已经想到了一些更巧妙的应用场景,如果本文对您有所帮助,还忘客观多多支持!

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注