MySQL位运算符
位运算一般用于操作整数,对整数进行位运算才有实际的意义。整数在内存中是以补码形式存储的,正数的补码形式和原码形式相同,而负数的补码形式和它的原码形式是不一样的,这一点大家要特别注意;这意味着,对负数进行位运算时,操作的是它的补码,而不是它的原码。
对整数存储不了解的读者请猛击《整数在内存中是如何存储的,为什么它堪称天才般的设计》。
MySQL 中的整数字面量(常量整数,也就是直接书写出来的整数)默认以 8 个字节(Byte)来表示,也就是 64 位(Bit)。例如,5 的二进制形式为:
0000 0000 ... 0000 0101
省略号部分都是 0,101 前面总共有 61 个 0。注意:为了方便大家阅读,本节在介绍正数的补码时,省略了前面的 0。
MySQL 支持 6 种位运算符,如下表所示。
运算符 | 说明 | 使用形式 | 举例 |
|---|---|---|---|
| | 位或 | a | b | 5 | 8 |
& | 位与 | a & b | 5 & 8 |
^ | 位异或 | a ^ b | 5 ^ 8 |
~ | 位取反 | ~a | ~5 |
<< | 位左移 | a << b | 5 << 2,表示整数 5 按位左移 2 位 |
>> | 位右移 | a >> b | 5 >> 2,表示整数 5 按位右移 2 位 |
位运算中的
&、|、~和逻辑运算中的&&、||、!非常相似。位或运算符 |
参与|运算的两个二进制位有一个为 1 时,结果就为 1,两个都为 0 时结果才为 0。例如1|1结果为 1,0|0结果为0,1|0结果为1,这和逻辑运算中的||非常类似。例 1
使用位或运算符进行正数运算,SQL 语句如下:10 的补码为 1010,15 的补码为 1111,按位或运算之后,结果为 1111,即整数 15;9 的补码为 1001,4 的补码为 0100,2 的补码为 0010,按位或运算之后,结果为 111,即整数 15。mysql> SELECT 10|15,9|4|2;
+-------+-------+
| 10|15 | 9|4|2 |
+-------+-------+
| 15 | 15 |
+-------+-------+
1 row in set (0.00 sec)
例 2
使用位或运算符进行负数运算,SQL 语句如下:-7 的补码为 60 个‘1’加 1001,-1 的补码为 64 个‘1’,按位或运算之后,结果为 64 个‘1’,即整数 18446744073709551615。mysql> SELECT -7|-1;
+----------------------+
| -7|-1 |
+----------------------+
| 18446744073709551615 |
+----------------------+
1 row in set (0.00 sec)
可以发现,任何数和 -1 进行位或运算时,最终结果都是 -1 的十进制数。
位与运算符 &
参与&运算的两个二进制位都为 1 时,结果就为 1,否则为 0。例如1|1结果为 1,0|0结果为 0,1|0结果为 0,这和逻辑运算中的&&非常类似。例 3
使用位与运算符进行正数运算,SQL 语句如下:10 的补码为 1010,15 的补码为 1111,按位与运算之后,结果为 1010,即整数 10;9 的补码为 1001,4 的补码为 0100,2 的补码为 0010,按位与运算之后,结果为 0000,即整数 0。mysql> SELECT 10 & 15,9 & 4 & 2;
+---------+-----------+
| 10 & 15 | 9 & 4 & 2 |
+---------+-----------+
| 10 | 0 |
+---------+-----------+
1 row in set (0.00 sec)
例 4
使用位与运算符进行负数运算,SQL 语句如下:-7 的补码为 60 个‘1’加 1001,-1 的补码为 64 个‘1’,按位与运算之后,结果为 60 个‘1’加 1001,即整数 18446744073709551609。mysql> SELECT -7&-1;
+----------------------+
| -7&-1 |
+----------------------+
| 18446744073709551609 |
+----------------------+
1 row in set (0.01 sec)
可以发现,任何数和 -1 进行位与运算时,最终结果都为任何数本身的十进制数。
位异或运算符 ^
参与^运算的两个二进制位不同时,结果为 1,相同时,结果为 0。例如1|1结果为 0,0|0结果为 0,1|0结果为1。例 5
使用位异或运算符进行正数运算,SQL 语句如下:mysql> SELECT 10^15,1^0,1^1;
+-------+-----+-----+
| 10^15 | 1^0 | 1^1 |
+-------+-----+-----+
| 5 | 1 | 0 |
+-------+-----+-----+
1 row in set (0.00 sec)
10 的补码为 1010,15 的补码为 111,按位异或运算之后,结果为 0101,即整数 5;1 的补码为 0001,0 的补码为 0000,按位异或运算之后,结果为 0001;1 和 1 本身二进制位完全相同,因此结果为 0。
例 6
使用位异或运算符进行负数运算,SQL 语句如下:-7 的补码为 60 个‘1’加 1001,-1 的补码为 64 个‘1’,按位异或运算之后,结果为 110,即整数 6。mysql> SELECT -7^-1;
+-------+
| -7^-1 |
+-------+
| 6 |
+-------+
1 row in set (0.00 sec)
位左移运算符 <<
位左移是按指定值的补码形式进行左移,左移指定位数之后,左边高位的数值被移出并丢弃,右边低位空出的位置用 0 补齐。位左移的语法格式为:
expr << n
其中,n 指定值 expr 要移位的位数,n 必须为非负数。例 7
使用位左移运算符进行正数计算,SQL 语句如下:1 的补码为 0000 0001,左移两位之后变成 0000 0100,即整数 4;4 的补码为 0000 0100,左移两位之后变成 0001 0000,即整数 16。mysql> SELECT 1<<2,4<<2;
+------+------+
| 1<<2 | 4<<2 |
+------+------+
| 4 | 16 |
+------+------+
1 row in set (0.00 sec)
例 8
使用位左移运算符进行负数计算,SQL 语句如下:-7 的补码为 60 个‘1’加 1001,左移两位之后变成 56 个‘1’加 1110 0100,即整数 18446744073709551588。mysql> SELECT -7<<2;
+----------------------+
| -7<<2 |
+----------------------+
| 18446744073709551588 |
+----------------------+
1 row in set (0.00 sec)
位右移运算符 >>
位右移是按指定值的补码形式进行右移,右移指定位数之后,右边低位的数值被移出并丢弃,左边高位空出的位置用 0 补齐。位右移语法格式为:
expr >> n
其中,n 指定值 expr 要移位的位数,n 必须为非负数。
例 9
使用位右移运算符进行正数运算,SQL 语句如下:1 的补码为 0000 0001,右移 1 位之后变成 0000 0000,即整数 0;16 的补码为 0001 0000,右移两位之后变成 0000 0100,即整数 4。mysql> SELECT 1>>1,16>>2;
+------+-------+
| 1>>1 | 16>>2 |
+------+-------+
| 0 | 4 |
+------+-------+
1 row in set (0.00 sec)
例 10
使用位右移运算符进行负数运算,SQL 语句如下:-7 的补码为 60 个‘1’加 1001,右移两位之后变成 0011 加 56 个‘1’加 1110,即整数 4611686018427387902。mysql> SELECT -7>>2;
+---------------------+
| -7>>2 |
+---------------------+
| 4611686018427387902 |
+---------------------+
1 row in set (0.00 sec)
位取反运算符 ~
位取反是将参与运算的数据按对应的补码进行反转,也就是做 NOT 操作,即 1 取反后变 0,0 取反后变为 1。例 11
下面看一个经典的取反例子,对 1 进行位取反运算,具体如下所示:常量 1 的补码为 63 个‘0‘加 1 个’1‘,位取反后就是 63 个’1‘加一个’0‘,转换为二进制后就是 18446744073709551614。mysql> SELECT ~1,~18446744073709551614;
+----------------------+-----------------------+
| ~1 | ~18446744073709551614 |
+----------------------+-----------------------+
| 18446744073709551614 | 1 |
+----------------------+-----------------------+
1 row in set (0.00 sec)
可以使用 BIN() 函数查看 1 取反之后的结果,BIN() 函数的作用是将一个十进制数转换为二进制数,SQL 语句如下:
1 的补码表示为最右边位为 1,其他位均为 0,取反操作之后,除了位,其他位均变为 1。mysql> SELECT BIN(~1);
+------------------------------------------------------------------+
| BIN(~1) |
+------------------------------------------------------------------+
| 1111111111111111111111111111111111111111111111111111111111111110 |
+------------------------------------------------------------------+
1 row in set (0.01 sec)
例 12
使用位取反运算符进行运算,SQL 语句如下:逻辑运算mysql> SELECT 5 & ~1;
+--------+
| 5 & ~1 |
+--------+
| 4 |
+--------+
1 row in set (0.00 sec)
5&~1 中,由于位取反运算符‘~’的级别高于位与运算符‘&’,因此先对 1 进行取反操作,结果为 63 个‘1’加一个‘0’,然后再与整数 5 进行与运算,结果为 0100,即整数 4。- 随机文章
- 核心危机(核心危机魔石合成攻略)
- 饿了么红包怎么用(饿了么红包怎么用微信支付)
- 光遇花手先祖位置(安卓光遇手花先祖)
- 广州4a广告公司(广州4a广告公司创意总监年薪)
- 抖音卡(抖音卡顿怎么解决)
- 兵马俑(兵马俑介绍和历史背景)
- 陈武简历
- 帆船比赛(帆船比赛视频)
- 海猫鸣泣之时游戏(海猫鸣泣之时游戏在哪玩)
- 韩国媳妇和小雪(韩国媳妇和小雪的父亲工资是多少)
- 鬼泣5攻略(鬼泣5攻略第三关怎么跳)
- 地球日主题(2020年世界地球日主题)
- 和柳亚子(和柳亚子先生于田)
- 国外成人游戏(国外成人游戏注册需要visa信用卡)
- 拆奶罩
- 杭同(杭同培训中心怎么样)
- 蝙蝠给人类的一封信(蝙蝠给人类的一封信)
- 服饰加盟(服饰加盟店招商)
- 疯狂填字(疯狂填字5)
- 点对点短信息(点对点短信息费是什么意思)
- 观音普门品(观音普门品念诵全文)
- 哈利波特官网(哈利波特官网在哪里)
- 骇客神条(骇客神条怎么辨别真假)
- 查传倜(查传倜个人生活)
- 广州晓港公园(广州晓港公园正门图片)
- 钢筋等级符号(钢筋等级符号电脑怎么输入)
- 常州天宁寺(常州天宁寺求什么灵验)
- 河源巴伐利亚(河源巴伐利亚庄园)
- 广州中山大学(广州中山大学录取分数线2023)
- 风云三国(风云三国2.8作弊指令Ctrl)
