Administrator
发布于 2025-11-13 / 2 阅读
0
0

MySQL位运算符的用法

SELECT 5 & 3; 为什么结果是1

1. 详细计算过程

步骤1:将数字转换为二进制

5 的二进制: 00000101
3 的二进制: 00000011

步骤2:按位与运算(&)规则

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

步骤3:逐位计算

位位置:  7 6 5 4 3 2 1 0
5:       0 0 0 0 0 1 0 1
3:       0 0 0 0 0 0 1 1
         ----------------
结果:     0 0 0 0 0 0 0 1

步骤4:转换回十进制

二进制 00000001 = 十进制 1

2. 可视化理解

5:  0 0 0 0 0 1 0 1
    │ │ │ │ │ │ │ │
3:  0 0 0 0 0 0 1 1
    │ │ │ │ │ │ │ │
    ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
    0 0 0 0 0 0 0 1

关键点:只有在两个数的相同位置都是1时,结果才是1。

3. 在MySQL中验证

-- 验证计算过程
SELECT 
    5 as decimal_5,
    BIN(5) as binary_5,          -- 101
    3 as decimal_3, 
    BIN(3) as binary_3,          -- 11
    5 & 3 as result,             -- 1
    BIN(5 & 3) as binary_result; -- 1

4. 更多示例帮助理解

-- 其他按位与示例
SELECT 
    10 & 6,    -- 2 (1010 & 0110 = 0010)
    15 & 7,    -- 7 (1111 & 0111 = 0111)
    12 & 5,    -- 4 (1100 & 0101 = 0100)
    9 & 3;     -- 1 (1001 & 0011 = 0001)

5. 实际应用场景

权限检查示例

-- 假设权限:1=读, 2=写, 4=执行
-- 用户权限 = 5 (二进制101 = 读+执行)
​
SELECT 
    5 & 1 as 检查读权限,    -- 1 (有权限)
    5 & 2 as 检查写权限,    -- 0 (无权限)  
    5 & 4 as 检查执行权限;  -- 4 (有权限)

奇偶数判断

-- 任何数与1进行&运算,结果为1就是奇数,为0就是偶数
SELECT 
    5 & 1 as 5的奇偶,  -- 1 (奇数)
    4 & 1 as 4的奇偶,  -- 0 (偶数)
    7 & 1 as 7的奇偶;  -- 1 (奇数)

6. 记忆技巧

按位与的特点

  • 像"严格的门卫":只有两个输入都是1才放行1

  • 可以用来"屏蔽"某些位

  • 常用于权限检查、状态判断

总结:

SELECT 5 & 3; 返回 1 是因为:

  • 5的二进制:00000101

  • 3的二进制:00000011

  • 按位与结果:00000001(只有最低位两个数都是1)

  • 十进制:1

按位与运算就像数学中的"取交集",只有在两个数相同位置都为1时,结果才为1。

SELECT 5 | 3; 为什么结果是7

1. 详细计算过程

步骤1:将数字转换为二进制

5 的二进制: 00000101
3 的二进制: 00000011

步骤2:按位或运算(|)规则

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

步骤3:逐位计算

位位置:  7 6 5 4 3 2 1 0
5:       0 0 0 0 0 1 0 1
3:       0 0 0 0 0 0 1 1
         ----------------
结果:     0 0 0 0 0 1 1 1

步骤4:转换回十进制

二进制 00000111 = 十进制 7
(4 + 2 + 1 = 7)

2. 可视化理解

5:  0 0 0 0 0 1 0 1
    │ │ │ │ │ │ │ │
3:  0 0 0 0 0 0 1 1
    │ │ │ │ │ │ │ │
    ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
    0 0 0 0 0 1 1 1

关键点:只要两个数的相同位置至少有一个是1,结果就是1。

3. 在MySQL中验证

-- 验证计算过程
SELECT 
    5 as decimal_5,
    BIN(5) as binary_5,          -- 101
    3 as decimal_3, 
    BIN(3) as binary_3,          -- 11
    5 | 3 as result,             -- 7
    BIN(5 | 3) as binary_result; -- 111

4. 更多示例帮助理解

-- 其他按位或示例
SELECT 
    10 | 6,    -- 14 (1010 | 0110 = 1110)
    15 | 7,    -- 15 (1111 | 0111 = 1111)
    12 | 5,    -- 13 (1100 | 0101 = 1101)
    9 | 3;     -- 11 (1001 | 0011 = 1011)

5. 实际应用场景

权限组合示例

-- 假设权限:1=读, 2=写, 4=执行
-- 组合权限:读 + 写 = 1 | 2
​
SELECT 
    1 | 2 as 读写权限,        -- 3
    1 | 4 as 读执行权限,      -- 5  
    2 | 4 as 写执行权限,      -- 6
    1 | 2 | 4 as 所有权限;    -- 7

标志位合并

-- 多个状态标志合并
SET @状态1 = 1;   -- 00000001
SET @状态2 = 2;   -- 00000010
SET @状态4 = 4;   -- 00000100

SELECT @状态1 | @状态4 as 状态1和4;  -- 5 (00000101)

6. 与按位与(&)的对比

-- 对比 | 和 & 的区别
SELECT 
    5 | 3 as 按位或,   -- 7 (101 | 011 = 111)
    5 & 3 as 按位与;   -- 1 (101 & 011 = 001)

记忆技巧

  • 按位或 |:像"宽松的门卫" - 只要有一个是1就放行1

  • 按位与 &:像"严格的门卫" - 必须两个都是1才放行1

7. 数学关系验证

-- 验证二进制转十进制
SELECT 
    (1*POWER(2,2) + 1*POWER(2,1) + 1*POWER(2,0)) as 二进制111转十进制;
-- 结果:4 + 2 + 1 = 7

总结:

SELECT 5 | 3; 返回 7 是因为:

  • 5的二进制:00000101

  • 3的二进制:00000011

  • 按位或结果:00000111(第0、1、2位至少有一个是1)

  • 十进制:4 + 2 + 1 = 7

按位或运算就像数学中的"取并集",只要两个数在相同位置至少有一个为1,结果就为1。这在组合权限、合并标志位等场景中非常有用。

MySQL中SELECT ~5;为什么结果是一个很大的数

1. 根本原因:按位取反和整数表示方式

在MySQL中,整数使用补码形式表示,~运算符会对所有位进行取反。

2. 详细计算过程

步骤1:5的二进制表示(假设32位系统)

5的二进制: 00000000 00000000 00000000 00000101

步骤2:按位取反运算

~5的二进制: 11111111 11111111 11111111 11111010

步骤3:转换为十进制

这个二进制数在无符号整数解释下是一个很大的正数:

11111111 11111111 11111111 11111010 = 4294967290

3. 在MySQL中的实际验证

-- 查看系统位数和结果
SELECT 
    ~5 as 取反结果,
    BIN(5) as 5的二进制,
    CAST(~5 AS UNSIGNED) as 无符号解释,
    CAST(~5 AS SIGNED) as 有符号解释;

典型结果

  • 32位系统:4294967290

  • 64位系统:18446744073709551610

4. 不同系统位数的结果对比

-- 验证不同位数的结果
SELECT 
    ~5 as 默认显示,
    ~5 & 0xFFFFFFFF as 32位掩码结果,  -- 4294967290
    ~5 & 0xFFFF as 16位掩码结果;      -- 65530

5. 为什么不是-6?

在有符号整数中,~5确实等于-6,但MySQL默认以无符号方式显示:

-- 验证有符号解释
SELECT 
    ~5 as 默认无符号显示,
    CAST(~5 AS SIGNED) as 有符号显示;  -- 可能是-6

6. 补码原理说明

正数5的补码 = 原码

5: 00000000 00000000 00000000 00000101

按位取反

~5: 11111111 11111111 11111111 11111010

补码转原码(负数)

  1. 取反:00000000 00000000 00000000 00000101

  2. 加1:00000000 00000000 00000000 00000110 = 6

  3. 加负号:-6

7. 实际应用中的解决方案

-- 方法1:使用有符号转换
SELECT CAST(~5 AS SIGNED);  -- -6

-- 方法2:使用位掩码限制位数
SELECT ~5 & 0xFF;  -- 250 (8位取反)

-- 方法3:手动计算期望的取反
SELECT (0xFF - 5) as 8位取反;  -- 250

8. 更多示例

-- 不同数字的取反
SELECT 
    ~0,                    -- 很大正数
    ~1,                    -- 很大正数  
    ~255,                  -- 很大正数
    CAST(~0 AS SIGNED),    -- -1
    CAST(~1 AS SIGNED),    -- -2
    CAST(~255 AS SIGNED);  -- -256

9. 实用技巧:限制位数的取反

-- 模拟8位取反
CREATE FUNCTION bit8_not(x TINYINT UNSIGNED) 
RETURNS TINYINT UNSIGNED
DETERMINISTIC
RETURN 255 - x;

SELECT bit8_not(5);  -- 250

10. 总结

SELECT ~5;返回很大数的原因:

  1. MySQL使用补码表示整数

  2. ~运算符对所有位取反

  3. MySQL默认以无符号方式显示结果

  4. 实际数学值应该是-6,但显示为很大的正数

解决方案

  • 使用CAST(~5 AS SIGNED)得到-6

  • 使用位掩码限制显示位数

  • 理解这是显示问题,不是计算错误

这就是为什么在MySQL中按位取反会产生很大数字的原因!

MySQL中SELECT 5 ^ 3;为什么结果是6

1. 按位异或运算原理

异或运算规则

  • 相同为0,不同为1

  • 记忆口诀:"相同得0,不同得1"

规则表:
0 ^ 0 = 0
0 ^ 1 = 1  
1 ^ 0 = 1
1 ^ 1 = 0

2. 详细计算过程

步骤1:转换为二进制

5的二进制: 00000101
3的二进制: 00000011

步骤2:逐位异或计算

位位置:  7 6 5 4 3 2 1 0
5:       0 0 0 0 0 1 0 1
3:       0 0 0 0 0 0 1 1
         ----------------
结果:     0 0 0 0 0 1 1 0

步骤3:分析每一位

  • 位0: 1 ^ 1 = 0 (两个都是1,相同得0)

  • 位1: 0 ^ 1 = 1 (一个0一个1,不同得1)

  • 位2: 1 ^ 0 = 1 (一个1一个0,不同得1)

  • 其他位: 都是0 ^ 0 = 0

步骤4:转换回十进制

二进制 00000110 = 十进制 6
(4 + 2 = 6)

3. 在MySQL中验证

-- 完整验证过程
SELECT 
    5 as decimal_5,
    BIN(5) as binary_5,          -- 101
    3 as decimal_3,
    BIN(3) as binary_3,          -- 11
    5 ^ 3 as xor_result,         -- 6
    BIN(5 ^ 3) as binary_result; -- 110

4. 可视化理解

5:  0 0 0 0 0 1 0 1
    │ │ │ │ │ │ │ │
3:  0 0 0 0 0 0 1 1
    │ │ │ │ │ │ │ │
    ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
    0 0 0 0 0 1 1 0
    ↑       ↑ ↑
    相同     不同 不同
    得0      得1 得1

5. 与其他位运算对比

-- 对比三种基本位运算
SELECT 
    5 & 3 as 按位与,   -- 1 (101 & 011 = 001)
    5 | 3 as 按位或,   -- 7 (101 | 011 = 111)  
    5 ^ 3 as 按位异或; -- 6 (101 ^ 011 = 110)

6. 更多异或运算示例

-- 其他异或示例
SELECT 
    10 ^ 6,    -- 12 (1010 ^ 0110 = 1100)
    15 ^ 7,    -- 8  (1111 ^ 0111 = 1000)
    12 ^ 5,    -- 9  (1100 ^ 0101 = 1001)
    9 ^ 3;     -- 10 (1001 ^ 0011 = 1010)

7. 异或运算的特性

-- 特性1:任何数与0异或等于自身
SELECT 5 ^ 0;  -- 5

-- 特性2:任何数与自身异或等于0  
SELECT 5 ^ 5;  -- 0

-- 特性3:交换律
SELECT (5 ^ 3) = (3 ^ 5);  -- 1 (true)

8. 实际应用场景

8.1 简单的加密/解密

-- 使用同一个密钥加密和解密
SET @key = 123;
SET @data = 88;

-- 加密
SET @encrypted = @data ^ @key;  -- 加密后的数据

-- 解密  
SET @decrypted = @encrypted ^ @key;  -- 恢复原数据
SELECT @decrypted;  -- 88

8.2 交换两个变量的值(不使用临时变量)

SET @a = 5, @b = 3;
SELECT @a, @b;  -- 5, 3

-- 使用异或交换
SET @a = @a ^ @b;
SET @b = @a ^ @b; 
SET @a = @a ^ @b;
SELECT @a, @b;  -- 3, 5

8.3 找出只出现一次的数字

-- 在一组数字中,只有一个数字出现一次,其他都出现两次
SELECT 2 ^ 3 ^ 4 ^ 2 ^ 3;  -- 4 (4只出现一次)

9. 记忆技巧

异运算符的特点

  • 像"找不同"的游戏

  • 两个输入不同时输出1,相同时输出0

  • 可用于加密、交换变量、找单一元素等场景

10. 数学验证

-- 验证二进制转十进制
SELECT 
    (1*POWER(2,2) + 1*POWER(2,1) + 0*POWER(2,0)) as 二进制110转十进制;
-- 结果:4 + 2 + 0 = 6

总结:

SELECT 5 ^ 3; 返回 6 是因为:

  • 5的二进制:00000101

  • 3的二进制:00000011

  • 按位异或结果:00000110(第1位和第2位不同,其他位相同)

  • 十进制:4 + 2 = 6

异或运算在编程中有很多巧妙的应用,理解它的原理对于掌握位运算非常重要!

MySQL中5 << 2为什么结果是20

1. 左移运算符原理

左移运算规则

  • 将所有二进制位向左移动指定位数

  • 右边空出的位用0填充

  • 相当于乘以2的n次方

2. 详细计算过程

步骤1:5的二进制表示

5的二进制: 00000101

步骤2:向左移动2位

原始:   00000101
左移1位: 00001010  (10)
左移2位: 00010100  (20)

步骤3:填充规则

5:      00000101
        ↑↑      (向左移动2位)
结果:   00010100
         ↑↑↑↑   (右边补4个0)

步骤4:转换回十进制

二进制 00010100 = 十进制 20
(16 + 4 = 20)

3. 在MySQL中验证

-- 完整验证过程
SELECT 
    5 as decimal_5,
    BIN(5) as binary_5,           -- 101
    5 << 2 as left_shift_result,  -- 20
    BIN(5 << 2) as binary_result; -- 10100

4. 数学关系验证

-- 左移相当于乘以2的n次方
SELECT 
    5 << 2 as 左移2位,
    5 * POWER(2, 2) as 乘以4,     -- 5 × 4 = 20
    5 * 4 as 直接乘以4;           -- 20

5. 更多左移示例

-- 不同数字的左移运算
SELECT 
    1 << 1,    -- 2 (1×2)
    1 << 2,    -- 4 (1×4)
    1 << 3,    -- 8 (1×8)
    
    3 << 1,    -- 6 (3×2)
    3 << 2,    -- 12 (3×4)
    3 << 3,    -- 24 (3×8)
    
    10 << 1,   -- 20 (10×2)
    10 << 2,   -- 40 (10×4)
    10 << 3;   -- 80 (10×8)

6. 二进制可视化过程

原始数字5:
位:  7 6 5 4 3 2 1 0
值:  0 0 0 0 0 1 0 1
     = 4 + 1 = 5
​
左移2位后:
位:  7 6 5 4 3 2 1 0  
值:  0 0 0 1 0 1 0 0
     = 16 + 4 = 20
​
移动过程:
1位: 0 0 0 0 1 0 1 0 = 10
2位: 0 0 0 1 0 1 0 0 = 20

7. 实际应用场景

7.1 快速计算2的幂次

-- 使用左移快速计算2的n次方
SELECT 
    1 << 0 as 2的0次方,  -- 1
    1 << 1 as 2的1次方,  -- 2
    1 << 2 as 2的2次方,  -- 4
    1 << 3 as 2的3次方,  -- 8
    1 << 4 as 2的4次方;  -- 16

7.2 权限系统中的位标志

-- 使用左移定义权限位
SET @READ = 1 << 0;    -- 00000001 = 1
SET @WRITE = 1 << 1;   -- 00000010 = 2  
SET @EXECUTE = 1 << 2; -- 00000100 = 4
SET @DELETE = 1 << 3;  -- 00001000 = 8

-- 组合权限
SELECT @READ | @WRITE | @DELETE as 组合权限;  -- 11 (读+写+删除)

7.3 颜色值处理

-- RGB颜色分量组合
SET @red = 255;
SET @green = 128;  
SET @blue = 64;

-- 组合成24位颜色值
SELECT (@red << 16) | (@green << 8) | @blue as RGB颜色值;

8. 边界情况说明

-- 注意:左移可能溢出
SELECT 
    127 << 1,   -- 254
    127 << 2,   -- 508  
    127 << 3;   -- 1016

-- 对于TINYINT UNSIGNED(0-255),256会溢出
SELECT CAST(128 << 1 AS UNSIGNED) as 可能溢出;

9. 与右移运算对比

-- 左右移对比
SELECT 
    5 << 2 as 左移2位,   -- 20 (乘以4)
    20 >> 2 as 右移2位;  -- 5 (除以4)

10. 性能优势

-- 在需要频繁乘以2的幂次时,左移运算更快
-- 例如:图形处理、网络协议解析等

总结:

5 << 2 返回 20 的原因:

  1. 二进制转换5 = 00000101

  2. 左移操作:向左移动2位 → 00010100

  3. 右边补零:空出的低位补0

  4. 十进制结果16 + 4 = 20

  5. 数学等价5 × 2² = 5 × 4 = 20

左移运算的特点

  • 高效实现乘以2的n次方

  • 在底层编程、图形处理、权限系统中广泛应用

  • 比直接乘法运算更快

  • 需要注意数据类型和溢出问题

这就是为什么在MySQL中5 << 2等于20的完整解释!

MySQL中5 >> 2为什么结果是1

1. 右移运算符原理

右移运算规则

  • 将所有二进制位向右移动指定位数

  • 左边空出的位用0填充(对于无符号数)

  • 相当于除以2的n次方并向下取整

2. 详细计算过程

步骤1:5的二进制表示

5的二进制: 00000101

步骤2:向右移动2位

原始:   00000101
右移1位: 00000010  (2) - 舍去最低位的1
右移2位: 00000001  (1) - 舍去低2位

步骤3:舍去规则

5:      00000101
        →→       (向右移动2位)
结果:   00000001
              ↑↑ (舍去这2位)

步骤4:转换回十进制

二进制 00000001 = 十进制 1

3. 在MySQL中验证

-- 完整验证过程
SELECT 
    5 as decimal_5,
    BIN(5) as binary_5,           -- 101
    5 >> 2 as right_shift_result, -- 1
    BIN(5 >> 2) as binary_result; -- 1

4. 数学关系验证

-- 右移相当于除以2的n次方并向下取整
SELECT 
    5 >> 2 as 右移2位,
    FLOOR(5 / POWER(2, 2)) as 除以4取整,  -- 5 ÷ 4 = 1.25 → 1
    FLOOR(5 / 4) as 直接除以4取整;        -- 1

5. 更多右移示例

-- 不同数字的右移运算
SELECT 
    10 >> 1,   -- 5 (10÷2)
    10 >> 2,   -- 2 (10÷4)
    10 >> 3,   -- 1 (10÷8)
    
    20 >> 1,   -- 10 (20÷2)
    20 >> 2,   -- 5 (20÷4)
    20 >> 3,   -- 2 (20÷8)
    
    15 >> 1,   -- 7 (15÷2=7.5→7)
    15 >> 2,   -- 3 (15÷4=3.75→3)
    15 >> 3;   -- 1 (15÷8=1.875→1)

6. 二进制可视化过程

原始数字5:
位:  7 6 5 4 3 2 1 0
值:  0 0 0 0 0 1 0 1
     = 4 + 1 = 5
​
右移2位后:
位:  7 6 5 4 3 2 1 0  
值:  0 0 0 0 0 0 0 1
     = 1
​
移动过程:
1位: 0 0 0 0 0 0 1 0 = 2 (舍去位0的1)
2位: 0 0 0 0 0 0 0 1 = 1 (舍去位0和位1)

7. 舍去的位分析

5: 00000101
         ↑↑ (这2位将被舍去)
   位1=0, 位0=1

舍去的值: 0×2¹ + 1×2⁰ = 1
这就是为什么5 ÷ 4 = 1.25,小数部分0.25被舍去

8. 实际应用场景

8.1 快速除以2的幂次

-- 在性能敏感的场景中使用右移代替除法
SELECT 
    256 >> 3 as 快速除以8,   -- 32
    128 >> 2 as 快速除以4,   -- 32
    64 >> 1 as 快速除以2;    -- 32

8.2 提取颜色分量

-- 从24位RGB颜色值中提取分量
SET @color = 0xFF8040;  -- RGB(255, 128, 64)

SELECT 
    (@color >> 16) & 0xFF as Red,    -- 255
    (@color >> 8) & 0xFF as Green,   -- 128
    @color & 0xFF as Blue;           -- 64

8.3 数据压缩和编码

-- 将多个小数字打包到一个整数中
SET @packed = (12 << 8) | (34 << 4) | 56;

-- 使用右移解包
SELECT 
    (@packed >> 8) & 0xF as 第一个数,   -- 12
    (@packed >> 4) & 0xF as 第二个数,   -- 34
    @packed & 0xF as 第三个数;          -- 56

9. 边界情况说明

-- 注意:右移会丢失精度(小数部分)
SELECT 
    7 >> 1,   -- 3 (7÷2=3.5→3)
    3 >> 1,   -- 1 (3÷2=1.5→1)
    1 >> 1;   -- 0 (1÷2=0.5→0)

-- 右移0位等于原数
SELECT 5 >> 0;  -- 5

10. 与左移运算对比

-- 左右移互为逆运算(除了精度损失)
SELECT 
    5 << 2 as 左移2位,   -- 20
    20 >> 2 as 右移2位,  -- 5
    
    7 << 1 as 左移1位,   -- 14  
    7 >> 1 as 右移1位;   -- 3 (注意精度损失)

11. 性能优势

-- 在需要频繁除以2的幂次时,右移运算更快
-- 例如:图像处理、数据解码、哈希计算等

总结:

5 >> 2 返回 1 的原因:

  1. 二进制转换5 = 00000101

  2. 右移操作:向右移动2位 → 00000001

  3. 左边补零:空出的高位补0

  4. 舍去低位:最低2位01被丢弃

  5. 十进制结果1

  6. 数学等价floor(5 ÷ 2²) = floor(5 ÷ 4) = 1

右移运算的特点

  • 高效实现除以2的n次方

  • 会自动向下取整,丢失小数部分

  • 在数据解包、颜色处理、性能优化中广泛应用

  • 比直接除法运算更快

这就是为什么在MySQL中5 >> 2等于1的完整解释!

1. 准备工作:创建测试表

-- 创建测试表
CREATE TABLE bitwise_demo (
    id INT AUTO_INCREMENT PRIMARY KEY,
    num1 TINYINT UNSIGNED,
    num2 TINYINT UNSIGNED,
    binary_rep VARCHAR(10)
);
​
-- 插入测试数据
INSERT INTO bitwise_demo (num1, num2, binary_rep) VALUES
(5, 3, '示例'),
(10, 6, '示例'),
(15, 7, '示例');

2. 按位与运算符 &

功能:两个位都为1时,结果才为1

-- 示例:5 & 3
SELECT 
    num1, BIN(num1) as bin1,
    num2, BIN(num2) as bin2,
    num1 & num2 as result,
    BIN(num1 & num2) as bin_result
FROM bitwise_demo WHERE num1 = 5 AND num2 = 3;

计算过程

5:  00000101  (二进制)
3:  00000011  (二进制)
    -------- &
1:  00000001  (只有最后一位都是1)

实际应用:权限检查

-- 假设权限:1=读, 2=写, 4=执行
SELECT 
    5 & 1 as 读权限,    -- 1 (有读权限)
    5 & 2 as 写权限,    -- 0 (无写权限)
    5 & 4 as 执行权限;  -- 4 (有执行权限)

3. 按位或运算符 |

功能:两个位有一个为1时,结果就为1

-- 示例:5 | 3
SELECT 
    num1, BIN(num1) as bin1,
    num2, BIN(num2) as bin2,
    num1 | num2 as result,
    BIN(num1 | num2) as bin_result
FROM bitwise_demo WHERE num1 = 5 AND num2 = 3;

计算过程

5:  00000101
3:  00000011
    -------- |
7:  00000111  (第1、2、3位至少有一个是1)

实际应用:权限组合

-- 组合权限:读(1) + 写(2) = 3
SELECT 1 | 2 as 读写权限;  -- 3

4. 按位异或运算符 ^

功能:两个位不同时结果为1,相同时为0

-- 示例:5 ^ 3
SELECT 
    num1, BIN(num1) as bin1,
    num2, BIN(num2) as bin2,
    num1 ^ num2 as result,
    BIN(num1 ^ num2) as bin_result
FROM bitwise_demo WHERE num1 = 5 AND num2 = 3;

计算过程

5:  00000101
3:  00000011
    -------- ^
6:  00000110  (第2、3位不同)

实际应用:简单的加密/切换状态

-- 切换开关状态
SELECT 1 ^ 1 as 关,  -- 0
       0 ^ 1 as 开;  -- 1

5. 按位取反运算符 ~

功能:所有位取反(0变1,1变0)

-- 示例:~5
SELECT 
    num1, BIN(num1) as bin1,
    ~num1 as result,
    BIN(~num1 & 0xFF) as bin_result_8bit  -- 限制8位显示
FROM bitwise_demo WHERE num1 = 5;

计算过程(8位示例):

5:  00000101
    -------- ~
250:11111010  (所有位取反)

注意:MySQL中整数有更多位,实际结果会很大

6. 左移运算符 <<

功能:所有位向左移动,右边补0

-- 示例:5 << 1
SELECT 
    num1, BIN(num1) as bin1,
    num1 << 1 as result,
    BIN(num1 << 1) as bin_result
FROM bitwise_demo WHERE num1 = 5;

计算过程

5:  00000101
    -------- << 1
10: 00001010  (相当于乘以2)

实际应用:快速乘以2的幂

SELECT 
    5 << 1 as 乘2,    -- 10
    5 << 2 as 乘4,    -- 20
    5 << 3 as 乘8;    -- 40

7. 右移运算符 >>

功能:所有位向右移动,左边补0

-- 示例:5 >> 1
SELECT 
    num1, BIN(num1) as bin1,
    num1 >> 1 as result,
    BIN(num1 >> 1) as bin_result
FROM bitwise_demo WHERE num1 = 5;

计算过程

5:  00000101
    -------- >> 1
2:  00000010  (相当于除以2取整)

实际应用:快速除以2的幂

SELECT 
    10 >> 1 as 除2,   -- 5
    10 >> 2 as 除4,   -- 2
    10 >> 3 as 除8;   -- 1

8. 综合示例:权限系统

-- 定义权限常量
SET @READ = 1;    -- 00000001
SET @WRITE = 2;   -- 00000010  
SET @EXECUTE = 4; -- 00000100
​
-- 创建用户权限
SET @user_permissions = @READ | @EXECUTE;  -- 5 (读+执行)
​
-- 检查权限
SELECT 
    @user_permissions & @READ as 有读权限,      -- 1
    @user_permissions & @WRITE as 有写权限,     -- 0
    @user_permissions & @EXECUTE as 有执行权限; -- 4
​
-- 添加写权限
SET @user_permissions = @user_permissions | @WRITE;
SELECT @user_permissions;  -- 7 (读+写+执行)
​
-- 移除执行权限  
SET @user_permissions = @user_permissions & ~@EXECUTE;
SELECT @user_permissions;  -- 3 (读+写)

9. 实用技巧总结

-- 1. 判断奇偶数
SELECT 
    num1, 
    num1 & 1 as 奇偶判断  -- 1=奇数, 0=偶数
FROM bitwise_demo;
​
-- 2. 交换两个变量的值(不使用临时变量)
SET @a = 5, @b = 3;
SELECT @a, @b;  -- 5, 3
​
SET @a = @a ^ @b;
SET @b = @a ^ @b; 
SET @a = @a ^ @b;
SELECT @a, @b;  -- 3, 5
​
-- 3. 检查第n位是否为1
SELECT 
    num1,
    (num1 >> 2) & 1 as 第3位状态  -- 从0开始计数
FROM bitwise_demo;

10. 注意事项

  • 无符号整数:建议使用UNSIGNED类型进行位运算

  • 结果类型:位运算结果通常是BIGINT UNSIGNED

  • 取反运算~运算会产生很大的数,要注意数据类型

  • 移位边界:移位不要超过数据类型的位数限制

这个教程涵盖了MySQL位运算符的所有基础用法,适合初学者理解和实践!


评论