/*
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 to_binary(int $x): string {
if ($x === 0) {
return "0";
}
return decbin($x);
}
/* Copy bits from M into N between bit positions [i, j] */
function copy_bits(int $N, int $M, int $i, int $j): int {
if ($i < 0 || $j < 0 || $i > $j || $j >= 63) {
throw new InvalidArgumentException("Invalid bit range");
}
$length = $j - $i + 1;
// Mask for bits i..j
$mask = ((1 << $length) - 1) << $i;
// Clear bits i..j in N
$N_cleared = $N & (~$mask);
// Take only the needed bits from M and shift into place
$M_shifted = ($M & ((1 << $length) - 1)) << $i;
return $N_cleared | $M_shifted;
}
/*
N: 100 011111 00
M: 110011
Result: 100 110011 00
*/
$N = 0b10001111100;
$M = 0b110011;
$result = copy_bits($N, $M, 2, 7);
echo "N: " . to_binary($N) . PHP_EOL;
echo "M: " . to_binary($M) . PHP_EOL;
echo "Result: " . to_binary($result) . PHP_EOL;
/*
OUTPUT:
N: 10001111100
M: 110011
Result: 10011001100
*/