如何在Rust中设置、清除和切换单个位?

41

我该如何在Rust中设置、清除和切换比特位?


3
你想了解如何操作二进制位吗? - Matthieu M.
Rust有位运算符吗? - phuclv
6
你尝试过使用 &|^ 吗?它们在 Rust 中都可用。 - E net4
@LưuVĩnhPhúc:已经有了。 - Matthieu M.
那为什么不直接使用另一个问题中的内容呢? - phuclv
3个回答

64

与其他许多语言一样,位运算符 &(按位与)、|(按位或)、^(按位异或)也存在:

fn main() {
    let mut byte: u8 = 0b0000_0000;

    byte |= 0b0000_1000; // Set a bit
    println!("0b{:08b}", byte);

    byte &= 0b1111_0111; // Unset a bit
    println!("0b{:08b}", byte);

    byte ^= 0b0000_1000; // Toggle a bit
    println!("0b{:08b}", byte);
}

与其他编程语言的主要区别在于按位非运算使用!而不是~

fn main() {
    let mut byte: u8 = 0b0000_0000;

    byte = !byte; // Flip all bits
    println!("0b{:08b}", byte);
}

你也可以将位向左或向右移动:

fn main() {
    let mut byte: u8 = 0b0000_1000;

    byte <<= 1; // shift left one bit
    println!("0b{:08b}", byte);

    byte >>= 1; // shift right one bit
    println!("0b{:08b}", byte);
}

还有许多其他概念性的东西,最终进行位级操作时并没有使用运算符来表达。查看整数文档以获取示例。一个有趣的例子是leading_zeros。以下是如何旋转一定数量的位:

fn main() {
    let mut byte: u8 = 0b1000_0000;

    byte = byte.rotate_left(1); // rotate left one bit
    println!("0b{:08b}", byte);

    byte = byte.rotate_right(1); // rotate right one bit
    println!("0b{:08b}", byte);
}

这本书提供了更多信息


1
有趣的一点关于 !~ 的区别。我可能会先尝试后者。 - Xavier T.
2
@XavierT。是的,它肯定不同,但在我看来,最终它确实更有意义。毕竟,它只是一个否定。 - Shepmaster
1
请注意,符号"{:#08b}"的设计是在二进制数字前打印'0b'(或'0x'等)。 - Djzin
1
@Djzin TIL!然而,零填充并不感觉“正确”;你实际上必须使用{:#010b},因为它是一个总体宽度 :-( - Shepmaster

13

Rust有位运算符和二进制格式打印(对于调试非常有帮助):

fn bit_twiddling(original: u8, bit: u8) {
    let mask = 1 << bit;

    println!(
        "Original: {:b}, Set: {:b}, Cleared: {:b}, Toggled: {:b}",
        original,
        original |  mask,
        original & !mask,
        original ^  mask
    );
}

fn main() {
    bit_twiddling(0, 3);
    bit_twiddling(8, 3);
}

它还有复合赋值运算符的变体(|=&=^=)。

这本书提供了更多信息


2
此外,我想添加以下用例:如果你有一个位域(bitfield),例如0b10001000,并且你想要无论如何将第3位更新为true或false,你可以按照以下方式执行:
    const SHIFT: u8 = 3;
    let set_bit_3 = false;
    let bits = 0b10001000;
    let bits = bits & !(1 << SHIFT) | (u16::from(set_bit_3) << SHIFT);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接