/**
* Converts a BigInt to a binary string representation.
*/
function toBinary(x: bigint): string {
return x.toString(2);
}
/**
* Replaces bits in N from index i to j (inclusive) with the bits from M.
* * Logic:
* 1. Create a mask of 1s for the length (j - i + 1).
* 2. Clear the target bits in N using the inverse of that mask shifted to i.
* 3. Mask M to ensure it doesn't overflow the range, then shift it to i.
* 4. Combine them using OR.
*/
function copyBits(N: bigint, M: bigint, i: number, j: number): bigint {
// Basic validation
if (i < 0 || j < 0 || i > j) {
throw new Error("Invalid bit range: i must be <= j and both non-negative.");
}
// Calculate length as a bigint to avoid repeated casting
const length: any = BigInt(j - i + 1);
// 1. Create a mask of 1s for the width of the range: (1 << length) - 1
const rangeMask: bigint = (1n << length) - 1n;
// 2. Shift that mask to the starting position i
const positionedMask: bigint = rangeMask << BigInt(i);
// 3. Clear bits i..j in N
const Ncleared: bigint = N & ~positionedMask;
// 4. Take the bits from M (ensuring M isn't wider than the range)
// and shift them to position i
const MmaskedAndShifted: bigint = (M & rangeMask) << BigInt(i);
// 5. Merge
return Ncleared | MmaskedAndShifted;
}
function main(): void {
// N: 100 011111 00 (binary)
const N = 0b10001111100n; // 1148n
// M: 110011
const M = 0b110011n; // 51n
// We want to replace the middle 6 bits (index 2 to 7)
const result = copyBits(N, M, 2, 7);
console.log("=== Bit Manipulation Result ===");
console.log(`N: ${toBinary(N).padStart(11, '0')}`);
console.log(`M: ${toBinary(M).padStart(11, '0')}`);
console.log(`Result: ${toBinary(result).padStart(11, '0')}`);
}
main();
/*
OUTPUT:
=== Bit Manipulation Result ===
N: 10001111100
M: 00000110011
Result: 10011001100
*/