/*
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
*/