rust - 在8位整数中插入一位

标签 rust

我有一个5位的u8,我们说0b10101。我想在位置1、2和4中插入全部为3的位,以便获得:ii1i0101,即11110101。我想通过三个函数调用来完成此操作,这意味着该函数应将索引作为参数之一,并在该位置插入一个位。
我遇到过this question,但是该页面上的答案对我不起作用。例如,实现时具有最小支持的 panic 的答案,而其他答案则无法给出正确的结果。

fn insert_at(x: u8, index: u8, bit: u8) -> u8 {
    let mask = (1 << (8 - index + 1)) - 1;
    (x & !mask) | (bit << (8 - index)) | ((x & mask) >> 1)
}

#[cfg(test)]
mod tests {
    use super::*;
    use rstest::*;

    #[rstest(
        input, index, expected,
        case(0b10101, 1, 0b110101),
    )]
    fn test_bla(input: u8, index: u8, expected: u8) {
        let result = insert_at(input, index, 1);
        assert_eq!(result, expected);
    }
}
thread 'tests::test_bla::case_1' panicked at 'attempt to shift left with overflow' 

最佳答案

我做了一些假设(和修改),以使您的问题的语义更加具体:

  • 操作的结果必须符合8位;如果不是,则不返回任何值。
  • index 0(而不是index 1)是指最高有效设置位左侧的位置。
  • 在任何index > 0中插入的一位将所有更高有效位的位向左移动1。

  • 一个有效的实现(playground link):
    fn insert_at(x: u8, index: u8, bit: u8) -> Option<u8> {
        if bit != 0 && bit != 1 {
            return None;
        }
        
        // most significant set bit, from right
        // 0b00010101
        //   87654321
        let msb = 8 - x.leading_zeros() as u8;
        
        if index >= msb {
            // the new bit is past the LSB
            return None;
        }
        
        // an index of 0 means insert as the new MSB (if it fits).
        // insert is the absolute index of the inserted bit.
        let insert = msb - index;
    
        if insert == 8 {
            // the new bit is out of u8 range.
            // 0b_11111111
            //   ^ trying to insert here
            return None;
        }
        
        let mask = (1 << insert) - 1;
        Some((x & !mask) << 1 | (bit << insert) | (x & mask))
    }
    
    您的实现 panic 的原因是检查了Rust的左移操作:如果将任何一位从整数的左侧移出,则检查将失败。这样做的主要原因是,在这种情况下,不同的平台具有不同的行为。
    在这些情况下,Rust还提供具有指定行为的算术运算,例如overflowing_shl()wrapping_shl()

    关于rust - 在8位整数中插入一位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65755600/

    相关文章:

    rust - 为什么 Rust 程序不从 if 语句返回值?

    recursion - 递归宏使无限递归

    rust - 得到 Rust 的商和余数 (DIVMOD) 的函数是什么?

    javascript - 在 Rust web 程序集中访问 UInt8ClampedArray

    tcp - 如何在 Rust 中建立与 kafka 服务器的连接

    html - 是否有 html5ever 的替代库接受一个字符串并返回一个可查询的对象?

    rust - Cargo 无法解析 url 版本 0.5.7 的 Cargo.toml

    python - 为什么相同的过程在Rust中比在Python中花费更长的时间?

    rust - mutex.lock是否需要提前结束其生命周期?

    rust - 如何返回指向拥有值 "does not live long enough"的指针?