/*
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 integer to binary string without leading zeros */
function toBinary(x) {
if (x === 0) return "0";
return x.toString(2);
}
/* Copy bits from M into N between bit positions [i, j] */
function copyBits(N, M, i, j) {
if (i < 0 || j < 0 || i > j || j >= 63) {
throw new Error("Invalid bit range");
}
const length = j - i + 1;
// Mask for bits i..j
const mask = ((1n << BigInt(length)) - 1n) << BigInt(i);
// Convert to BigInt for safe 64‑bit operations
const Nbig = BigInt(N);
const Mbig = BigInt(M);
// Clear bits i..j in N
const Ncleared = Nbig & ~mask;
// Take only the needed bits from M and shift into place
const Mshifted = (Mbig & ((1n << BigInt(length)) - 1n)) << BigInt(i);
return Number(Ncleared | Mshifted);
}
/*
N: 100 011111 00
M: 110011
Result: 100 110011 00
*/
const N = 0b10001111100;
const M = 0b110011;
const result = copyBits(N, M, 2, 7);
console.log("N: " + toBinary(N));
console.log("M: " + toBinary(M));
console.log("Result: " + toBinary(result));
/*
OUTPUT:
N: 10001111100
M: 110011
Result: 10011001100
*/