How to copy bits from M into N (numbers) between bit positions i and j (edge‑case‑safe) in C++

1 Answer

0 votes
#include <iostream>
#include <string>
#include <stdexcept>
#include <algorithm> 

// 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 long to binary string without leading zeros
std::string to_binary(unsigned long long x) {
    if (x == 0) return "0";
    std::string s;
    while (x > 0) {
        s.push_back((x & 1) ? '1' : '0');
        x >>= 1;
    }
    std::reverse(s.begin(), s.end());
    
    return s;
}

// Copy bits from M into N between bit positions [i, j]
unsigned long long copy_bits(unsigned long long N,
                             unsigned long long M,
                             int i, int j)
{
    if (i < 0 || j < 0 || i > j || j >= 63) {
        throw std::invalid_argument("Invalid bit range");
    }

    int length = j - i + 1;

    // Mask for bits i..j
    unsigned long long mask = ((1ULL << length) - 1) << i;

    // Clear bits i..j in N
    unsigned long long N_cleared = N & ~mask;

    // Take only the needed bits from M and shift into place
    unsigned long long M_shifted = (M & ((1ULL << length) - 1)) << i;

    return N_cleared | M_shifted;
}

int main() {
    // N:      100 011111 00
    // M:          110011
    // Result: 100 110011 00
    unsigned long long N = 0b10001111100ULL;
    unsigned long long M = 0b110011ULL;
    int i = 2;
    int j = 7;

    unsigned long long result = copy_bits(N, M, i, j);

    std::cout << "N:      " << to_binary(N) << "\n";
    std::cout << "M:      " << to_binary(M) << "\n";
    std::cout << "Result: " << to_binary(result) << "\n";
}


/*
OUTPUT:

N:      10001111100
M:      110011
Result: 10011001100

*/

 



answered Mar 29 by avibootz

Related questions

...