位运算符 #

一、位运算符概述 #

位运算符直接对整数的二进制位进行操作。

二、基本位运算符 #

2.1 运算符列表 #

运算符 说明 示例
& 按位与 a & b
| 按位或 a | b
^ 按位异或 a ^ b
! 按位非 !a
<< 左移 a << n
>> 右移 a >> n

三、按位与 (&) #

3.1 规则 #

两位都为1时结果为1,否则为0:

text
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0

3.2 示例 #

rust
fn main() {
    let a = 0b1010;  // 10
    let b = 0b1100;  // 12
    
    let result = a & b;
    
    println!("  {:04b} ({})", a, a);
    println!("& {:04b} ({})", b, b);
    println!("----------");
    println!("= {:04b} ({})", result, result);  // 1000 (8)
}

3.3 应用:掩码操作 #

rust
fn main() {
    let flags = 0b1010;
    let mask = 0b0010;
    
    // 检查特定位是否设置
    if flags & mask != 0 {
        println!("第2位已设置");
    }
    
    // 清除特定位
    let cleared = flags & !mask;
    println!("清除后: {:04b}", cleared);  // 1000
}

四、按位或 (|) #

4.1 规则 #

至少一位为1时结果为1:

text
1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0

4.2 示例 #

rust
fn main() {
    let a = 0b1010;  // 10
    let b = 0b1100;  // 12
    
    let result = a | b;
    
    println!("  {:04b} ({})", a, a);
    println!("| {:04b} ({})", b, b);
    println!("----------");
    println!("= {:04b} ({})", result, result);  // 1110 (14)
}

4.3 应用:设置标志位 #

rust
fn main() {
    let mut flags = 0b0000;
    
    // 设置标志位
    flags = flags | 0b0001;  // 设置第0位
    flags = flags | 0b0100;  // 设置第2位
    
    println!("标志位: {:04b}", flags);  // 0101
}

五、按位异或 (^) #

5.1 规则 #

两位不同时结果为1:

text
1 ^ 1 = 0
1 ^ 0 = 1
0 ^ 1 = 1
0 ^ 0 = 0

5.2 示例 #

rust
fn main() {
    let a = 0b1010;  // 10
    let b = 0b1100;  // 12
    
    let result = a ^ b;
    
    println!("  {:04b} ({})", a, a);
    println!("^ {:04b} ({})", b, b);
    println!("----------");
    println!("= {:04b} ({})", result, result);  // 0110 (6)
}

5.3 应用:切换标志位 #

rust
fn main() {
    let mut flags = 0b1010;
    
    // 切换特定位
    flags = flags ^ 0b0010;  // 切换第1位
    
    println!("切换后: {:04b}", flags);  // 1000
    
    // 再次切换恢复
    flags = flags ^ 0b0010;
    println!("恢复后: {:04b}", flags);  // 1010
}

5.4 应用:交换值 #

rust
fn main() {
    let mut a = 5;
    let mut b = 10;
    
    println!("交换前: a = {}, b = {}", a, b);
    
    // 使用异或交换(无需临时变量)
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    
    println!("交换后: a = {}, b = {}", a, b);
}

六、按位非 (!) #

6.1 规则 #

反转所有位:

text
!1 = 0
!0 = 1

6.2 示例 #

rust
fn main() {
    let a: u8 = 0b1010;
    
    let result = !a;
    
    println!("! {:08b} = {:08b}", a, result);
}

6.3 注意事项 #

rust
fn main() {
    let a: i8 = 5;  // 00000101
    
    // 对有符号数取反
    let result = !a;
    println!("!{} = {}", a, result);  // -6
}

七、移位运算 #

7.1 左移 (<<) #

左移n位,低位补0:

rust
fn main() {
    let a = 0b0101;  // 5
    
    let result = a << 1;  // 左移1位
    println!("{:04b} << 1 = {:08b} ({})", a, result, result);  // 1010 (10)
    
    let result = a << 2;  // 左移2位
    println!("{:04b} << 2 = {:08b} ({})", a, result, result);  // 10100 (20)
}

7.2 左移相当于乘以2 #

rust
fn main() {
    let a = 5;
    
    println!("{} << 1 = {} ({} * 2)", a, a << 1, a);
    println!("{} << 2 = {} ({} * 4)", a, a << 2, a);
    println!("{} << 3 = {} ({} * 8)", a, a << 3, a);
}

7.3 右移 (>>) #

右移n位,高位补符号位(算术右移):

rust
fn main() {
    let a = 0b1010;  // 10
    
    let result = a >> 1;
    println!("{:04b} >> 1 = {:04b} ({})", a, result, result);  // 0101 (5)
    
    let result = a >> 2;
    println!("{:04b} >> 2 = {:04b} ({})", a, result, result);  // 0010 (2)
}

7.4 右移相当于除以2 #

rust
fn main() {
    let a = 20;
    
    println!("{} >> 1 = {} ({} / 2)", a, a >> 1, a);
    println!("{} >> 2 = {} ({} / 4)", a, a >> 2, a);
    println!("{} >> 3 = {} ({} / 8)", a, a >> 3, a);
}

7.5 有符号数右移 #

rust
fn main() {
    let a: i8 = -8;  // 11111000
    
    println!("{} >> 1 = {}", a, a >> 1);  // -4
    println!("{} >> 2 = {}", a, a >> 2);  // -2
}

八、复合赋值运算符 #

8.1 运算符列表 #

运算符 等价形式
&= a = a & b
|= a = a | b
^= a = a ^ b
<<= a = a << n
>>= a = a >> n

8.2 示例 #

rust
fn main() {
    let mut a = 0b1010;
    
    a |= 0b0101;
    println!("|= 0101: {:04b}", a);  // 1111
    
    a &= 0b1100;
    println!("&= 1100: {:04b}", a);  // 1100
    
    a ^= 0b0011;
    println!("^= 0011: {:04b}", a);  // 1111
    
    a <<= 1;
    println!("<<= 1: {:08b}", a);
    
    a >>= 2;
    println!(">>= 2: {:08b}", a);
}

九、实践示例 #

9.1 权限系统 #

rust
const READ: u8 = 0b0001;
const WRITE: u8 = 0b0010;
const EXECUTE: u8 = 0b0100;
const ADMIN: u8 = 0b1000;

fn main() {
    let mut permissions = 0;
    
    // 添加权限
    permissions |= READ | WRITE;
    println!("权限: {:04b}", permissions);
    
    // 检查权限
    if permissions & READ != 0 {
        println!("有读权限");
    }
    
    if permissions & EXECUTE != 0 {
        println!("有执行权限");
    } else {
        println!("无执行权限");
    }
    
    // 移除权限
    permissions &= !WRITE;
    println!("移除写权限后: {:04b}", permissions);
    
    // 切换权限
    permissions ^= EXECUTE;
    println!("切换执行权限后: {:04b}", permissions);
}

9.2 颜色处理 #

rust
fn main() {
    // RGB颜色 (24位)
    let red: u32 = 0xFF0000;
    let green: u32 = 0x00FF00;
    let blue: u32 = 0x0000FF;
    
    // 组合颜色
    let yellow = red | green;
    println!("黄色: #{:06X}", yellow);
    
    // 提取颜色分量
    let color: u32 = 0xFF8040;
    let r = (color >> 16) & 0xFF;
    let g = (color >> 8) & 0xFF;
    let b = color & 0xFF;
    
    println!("颜色 #{:06X}: R={}, G={}, B={}", color, r, g, b);
}

9.3 位计数 #

rust
fn count_ones(n: u32) -> u32 {
    let mut count = 0;
    let mut num = n;
    
    while num > 0 {
        count += num & 1;
        num >>= 1;
    }
    
    count
}

fn main() {
    let n = 0b10110101;
    
    println!("{} 中有 {} 个1", n, count_ones(n));
    println!("使用内置方法: {} 个1", n.count_ones());
    println!("前导零: {}", n.leading_zeros());
    println!("尾随零: {}", n.trailing_zeros());
}

十、总结 #

本章学习了:

  • 按位与 &、按位或 |、按位异或 ^
  • 按位非 !
  • 左移 <<、右移 >>
  • 复合赋值运算符
  • 位运算的实际应用

下一章,我们将学习控制流。

最后更新:2026-03-27