第十七 位运算

目录

  • [Rust 位运算详解](#Rust 位运算详解)
    • 一、与(AND)运算
      • [1.1 Brian Kernighan 算法(布赖恩·克尼根算法)](#1.1 Brian Kernighan 算法(布赖恩·克尼根算法))
    • 二、或(OR)运算
    • 三、非(NOT)运算
    • 四、异或(XOR)运算
      • [4.1 运算规则](#4.1 运算规则)
      • [4.2 运算法则](#4.2 运算法则)
    • [五、左移(SHL,Shift Left)运算](#五、左移(SHL,Shift Left)运算)
    • [六、右移(SHR,Shift Right)运算](#六、右移(SHR,Shift Right)运算)
    • [七、Rust 中的位运算 Trait](#七、Rust 中的位运算 Trait)
    • [八、LeetCode 实战练习](#八、LeetCode 实战练习)
    • 总结

Rust 位运算详解

与十进制的算数运算一样,二进制的位运算也有其独特的运算规律。

参考资料:位运算 - 百度百科

一、与(AND)运算

运算符: &

1.1 Brian Kernighan 算法(布赖恩·克尼根算法)

利用与运算的一个经典技巧:n & (n - 1) 可以将 n 的二进制最右边的 1 置为 0

应用:统计二进制数中 1 的个数

rust 复制代码
fn count_ones(n: u64) -> u64 {
    // n 为正整数,其二进制表示中 1 的个数
    let mut n = n;
    let mut count = 0;
    while n != 0 {
        n = n & (n - 1);
        count += 1;
    }
    count
}

fn main() {
    println!("{}", count_ones(15)); // 输出:4
}

算法解析: 每次执行 n = n & (n - 1) 都会消去最低位的 1,循环次数即为 1 的个数,时间复杂度为 O(k)(k 为 1 的个数)。

二、或(OR)运算

运算符: |

或运算规则:只要有一个操作数为 1,结果就为 1;两者都为 0 时,结果才为 0

A B 结果
0 0 0
0 1 1
1 0 1
1 1 1

三、非(NOT)运算

运算符: ~!

非运算对每一位取反:0110

四、异或(XOR)运算

运算符: ^

参考资料:

4.1 运算规则

A B 结果
0 0 0
0 1 1
1 0 1
1 1 0

4.2 运算法则

法则 表达式 说明
归零律 a ⊕ a = 0 任何数异或其本身都等于 0
恒等律 a ⊕ 0 = a 任何数异或 0 都等于其本身
交换律 a ⊕ b = b ⊕ a 交换操作数不影响结果
结合律 a ⊕ b ⊕ c = a ⊕ (b ⊕ c) 运算顺序不影响结果
自反性 a ⊕ b ⊕ a = b 与同一个数异或两次等于原数
可推导性 d = a ⊕ b ⊕ c ⇒ a = d ⊕ b ⊕ c ---

示例:

  • x = 0101(二进制),y = 1011(二进制),则 x ⊕ y = 1110
  • 对任意整数 i,有 4i ⊕ (4i+1) ⊕ (4i+2) ⊕ (4i+3) = 0

五、左移(SHL,Shift Left)运算

运算符: <<

用途: 快速乘 2,比算术乘法(*)速度更快。

rust 复制代码
fn main() {
    let x = 5;
    let y = x << 1; // 相当于 x * 2
    println!("{}", y); // 输出:10
}

原理: 二进制数左移一位,末位补 0,相当于乘以 2。

六、右移(SHR,Shift Right)运算

运算符: >>

用途: 快速除 2,比算术除法(/)速度更快。

rust 复制代码
fn main() {
    // 偶数右移
    let mut x = 1024;
    let mut y = x >> 1;
    println!("{}", y); // 输出:512

    // 奇数右移(小数部分截断)
    x = 11;
    y = x >> 1;
    println!("{}", y); // 输出:5
}

注意: 奇数右移会丢弃最低位(小数部分截断),例如 11 >> 1 = 5(而非 5.5)。

七、Rust 中的位运算 Trait

Rust 标准库为位运算提供了对应的 trait,可用于自定义类型的运算符重载:

Trait 运算符 说明
std::ops::BitAnd & 按位与运算符
std::ops::BitAndAssign &= 按位与赋值运算符
std::ops::BitOr ` `
std::ops::BitOrAssign ` =`
std::ops::BitXor ^ 按位异或运算符
std::ops::Not ! 按位非运算符

参考文档:BitAnd · BitAndAssign · BitOr · BitOrAssign · BitXor · Not

八、LeetCode 实战练习

位运算在算法题中有广泛应用,以下是推荐的练习题:

题目 主要考点
136. 只出现一次的数字 异或消除重复数
137. 只出现一次的数字 II 位统计
191. 位 1 的个数 Brian Kernighan 算法
201. 数字范围按位与 公共前缀
231. 2 的幂 n & (n-1) == 0
260. 只出现一次的数字 III 分组异或(同剑指 Offer 56-I)
338. 比特位计数 动态规划 + 位运算
461. 汉明距离 异或 + 1 的个数

总结

运算 符号 典型用途
与 AND & 清除位、掩码、判断奇偶
或 OR ` `
非 NOT ! / ~ 取反
异或 XOR ^ 消除重复、交换两数、校验
左移 SHL << 快速乘 2 的幂次
右移 SHR >> 快速除 2 的幂次

提示: 位运算直接操作底层二进制,执行效率极高,在性能敏感场景和算法竞赛中被广泛使用。

本文为《Rust 编程》系列教程第十七章,持续更新中。

相关推荐
花褪残红青杏小2 小时前
Rust图像处理第15节-鱼眼广角畸变:非线性几何变换
rust·webassembly·图形学
doiito16 小时前
Gliding Horse 时间感知系统:让 AI Agent 真正“感知“时间流逝
ai·rust·架构设计·系统设计·ai agent
Rockbean17 小时前
10分钟Solana-性能web3-4.3 跨合约调用
rust·web3·智能合约
程序员爱钓鱼19 小时前
第一个 Rust 程序 Hello World
后端·rust
花褪残红青杏小1 天前
Rust图像处理第14节-图片缩放与斜切畸变:齐次坐标 + 共享仿射变换
rust·webassembly·图形学
梦帮科技1 天前
GRAVIS v4.0:基于Web的极速套利架构设计与实时数据流实现
前端·人工智能·rust·自动化·区块链·智能合约·数字货币
花褪残红青杏小2 天前
Rust图像处理第13节-任意角度旋转:旋转矩阵 + 双线性插值 + 自动补白边
rust·webassembly·图形学
小杍随笔2 天前
【Rust + Argon2id 生产级密码管理模块设计与实现】
网络·后端·算法·rust
梦帮科技2 天前
GRAVIS v5.5:向硬核桌面端进化与云端多节点容灾部署实践
windows·架构·rust·自动化·区块链·智能合约·数字货币
梦醒沉醉2 天前
2、Rust程序设计语言——常见编程概念
rust