如何使用 BitSlices 进行算术运算?

How to do arithmetic operations with BitSlices?

使用 bitvec crate,假设我有两个 BitSlice

let num1: &BitSlice = 10.view_bits::<Lsb0>();
let num2: &BitSlice = 9.view_bits::<Lsb0>();

有没有办法用这些 运行 位算术运算,例如 num1 - num2

我在 no-std 环境中工作受到限制,而且位片可能很大,所以我无法将它们转换为数字,进行运算并转换回位表示。

bitvec 曾经包含 addition and subtraction, but they were removed in version 0.18. Also, there was never subtraction on BitSlice, only addition. Although it was mentioned they should be moved into a separate crate,我找不到这样的 crate。所以,你需要自己去实现。

最简单(虽然绝对不是最有效)的方法是步行 bit-by-bit 并执行操作。

例如加法(改编自0.17.4版本的代码):

/// May overflow.
pub fn add_assign(lhs: &mut BitSlice, rhs: &BitSlice) {
    fn add_with_carry(a: bool, b: bool, carry: bool) -> (bool, bool) {
        let result = u8::from(a) + u8::from(b) + u8::from(carry);
        ((result & 0b01) != 0, (result & 0b10) != 0)
    }

    let mut carry = false;
    let extended_rhs = rhs.iter().by_vals().rev().chain(core::iter::repeat(false));
    for (mut lhs_bit, rhs_bit) in lhs.iter_mut().rev().zip(extended_rhs) {
        (*lhs_bit, carry) = add_with_carry(*lhs_bit, rhs_bit, carry);
    }
}

请注意,除非可以扩展切片,否则无法防止溢出,这需要 BitVec 和分配支持。

为了完整起见,我还将添加自己的减法函数:

pub fn subtract(lhs: &mut BitSlice, rhs: &BitSlice) {
    let mut borrow = false;
    for (mut l, r) in lhs
        .iter_mut()
        .rev()
        .zip(rhs.iter().by_vals().rev().chain(core::iter::repeat(false)))
    {
        if borrow {
            *l = !(*l);
            borrow = *l;
        }
        *l = match (*l, r) {
            (true, false) => true,
            (false, true) => {
                borrow = true;
                true
            }
            (_, _) => false,
        };
    }
}

我可以为我的用例做出某些假设,例如位顺序和 lhs >= rhs,因此如果您要复制粘贴此代码,请也考虑这些情况。