位运算,在平时的使用频率不是很高,大部分人都很少用到,以至于对位运算的理解也是比较模糊。
下面就来详细说说,这些平时不常用的位运算符究竟应该怎么用,以及有什么需要注意的事项。使用位运算来判断,在某种程度上也可以减轻数据库存储数据的压力(嗯,这个作用目前还感觉不明显),废话不多说,客观继续往下看(老鸟请留情,谢谢)
描述信息我已经尽量用比较好理解的方式修改,官方的实在是有点儿绕,寄希望下次看到的时候能立马想起来而不是再去理解一次
运算符 | 含义 | 描述(位运算,基于二进制表示) | 示例 |
---|---|---|---|
& | 按位与 | 只有参与运算的两位均为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)第三位为真
}
到这里,也许聪明的您应该已经想到了一些更巧妙的应用场景,如果本文对您有所帮助,还忘客观多多支持!
本文采用 「CC BY-NC-SA 4.0」创作共享协议,转载请标注以下信息:
原文出处:Yiiven https://cloud.tencent.com/developer/article/2193171