How to copy bits from M into N (numbers) between bit positions i and j (edge‑case‑safe) in Rust

1 Answer

0 votes
/*
    Handles edge cases:
    - Validates i and j
    - Prevents undefined behavior from shifting by ≥ 64 bits
    - Masks M so only the required bits are copied
*/

// Convert unsigned 64‑bit integer to binary string without leading zeros
fn to_binary(x: u64) -> String {
    if x == 0 {
        return "0".to_string();
    }

    let mut s = String::new();
    let mut n = x;

    while n > 0 {
        s.insert(0, if n & 1 == 1 { '1' } else { '0' });
        n >>= 1;
    }

    s
}

// Copy bits from M into N between bit positions [i, j]
fn copy_bits(n: u64, m: u64, i: u32, j: u32) -> u64 {
    if i > j || j >= 63 {
        panic!("Invalid bit range");
    }

    let length = j - i + 1;

    // Mask for bits i..j
    let mask: u64 = ((1u64 << length) - 1) << i;

    // Clear bits i..j in N
    let n_cleared = n & !mask;

    // Take only the needed bits from M and shift into place
    let m_shifted = (m & ((1u64 << length) - 1)) << i;

    n_cleared | m_shifted
}

fn main() {
    /*
        N:      100 011111 00
        M:          110011
        Result: 100 110011 00
    */

    let n: u64 = 0b10001111100;
    let m: u64 = 0b110011;

    let result = copy_bits(n, m, 2, 7);

    println!("N:      {}", to_binary(n));
    println!("M:      {}", to_binary(m));
    println!("Result: {}", to_binary(result));
}


/*
OUTPUT:

N:      10001111100
M:      110011
Result: 10011001100

*/

 



answered Mar 30 by avibootz

Related questions

...