/*
Handles edge cases:
- Validates i and j
- Prevents undefined behavior from shifting by ≥ 64 bits
- Masks M so only the required bits are copied
*/
object CopyBitsApp {
// Convert unsigned 64‑bit integer to binary string without leading zeros
def toBinary(x: Long): String = {
if (x == 0L) "0"
else {
val sb = new StringBuilder
var n = x
while (n != 0L) {
sb.insert(0, if ((n & 1L) == 1L) '1' else '0')
n = n >>> 1 // unsigned shift
}
sb.toString
}
}
// Copy bits from M into N between bit positions [i, j]
def copyBits(N: Long, M: Long, i: Int, j: Int): Long = {
if (i < 0 || j < 0 || i > j || j >= 63)
throw new IllegalArgumentException("Invalid bit range")
val length = j - i + 1
// Mask for bits i..j
val mask = ((1L << length) - 1L) << i
// Clear bits i..j in N
val Ncleared = N & ~mask
// Take only the needed bits from M and shift into place
val Mshifted = (M & ((1L << length) - 1L)) << i
Ncleared | Mshifted
}
def main(args: Array[String]): Unit = {
/*
N: 100 011111 00
M: 110011
Result: 100 110011 00
*/
val N = 0b10001111100L
val M = 0b110011L
val result = copyBits(N, M, 2, 7)
println("N: " + toBinary(N))
println("M: " + toBinary(M))
println("Result: " + toBinary(result))
}
}
/*
OUTPUT:
N: 10001111100
M: 110011
Result: 10011001100
*/