public class CopyBits {
// 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 long to binary string without leading zeros
static String toBinary(long x) {
if (x == 0) return "0";
StringBuilder sb = new StringBuilder();
while (x != 0) {
sb.append((x & 1L) == 1L ? '1' : '0');
x >>>= 1; // unsigned shift
}
return sb.reverse().toString();
}
// Copy bits from M into N between bit positions [i, j]
static long copyBits(long N, long M, int i, int j) {
if (i < 0 || j < 0 || i > j || j >= 63) {
throw new IllegalArgumentException("Invalid bit range");
}
int length = j - i + 1;
// Mask for bits i..j
long mask = ((1L << length) - 1L) << i;
// Clear bits i..j in N
long N_cleared = N & ~mask;
// Take only the needed bits from M and shift into place
long M_shifted = (M & ((1L << length) - 1L)) << i;
return N_cleared | M_shifted;
}
public static void main(String[] args) {
/*
N: 100 011111 00
M: 110011
Result: 100 110011 00
*/
long N = 0b10001111100L;
long M = 0b110011L;
long result = copyBits(N, M, 2, 7);
System.out.println("N: " + toBinary(N));
System.out.println("M: " + toBinary(M));
System.out.println("Result: " + toBinary(result));
}
}
/*
OUTPUT:
N: 10001111100
M: 110011
Result: 10011001100
*/