porgarmingduod
porgarmingduod

Reputation: 7888

Overwriting a range of bits in an integer in a generic way

Given two integers X and Y, I want to overwrite bits at position P to P+N.

Example:

int x      = 0xAAAA; // 0b1010101010101010
int y      = 0x0C30; // 0b0000110000110000
int result = 0xAC3A; // 0b1010110000111010

Does this procedure have a name?

If I have masks, the operation is easy enough:

int mask_x =  0xF00F; // 0b1111000000001111
int mask_y =  0x0FF0; // 0b0000111111110000
int result = (x & mask_x) | (y & mask_y);

What I can't quite figure out is how to write it in a generic way, such as in the following generic C++ function:

template<typename IntType>
IntType OverwriteBits(IntType dst, IntType src, int pos, int len) {
// If:
// dst    = 0xAAAA; // 0b1010101010101010
// src    = 0x0C30; // 0b0000110000110000
// pos    = 4                       ^
// len    = 8                ^-------
// Then:
// result = 0xAC3A; // 0b1010110000111010
}

The problem is that I cannot figure out how to make the masks properly when all the variables, including the width of the integer, is variable.

Does anyone know how to write the above function properly?

Upvotes: 10

Views: 3905

Answers (4)

drawnonward
drawnonward

Reputation: 53679

This site is dedicated to bit twiddling hacks:

http://graphics.stanford.edu/~seander/bithacks.html

Upvotes: 1

Charles Bretana
Charles Bretana

Reputation: 146551

Make the mask for positions P to P+N by taking ((2^N+1) - 1) << P ??

2^ (N+1) gives you a 1 in position N+1, Suntracting 1 sets all the first N bits, and then left shifting P times moves the whole arrangement P positions...

Since 2^ N is equivilent to 1 left shift N times, the whole thing is done by:

 ((1 << (N+1)) -1 ) << P

the N and the P may be off by one, but generally, this should work

Upvotes: 1

Dietrich Epp
Dietrich Epp

Reputation: 213558

A little bit shifting will give you the masks you need.

template<typename IntType>
IntType OverwriteBits(IntType dst, IntType src, int pos, int len) {
    IntType mask = (((IntType)1 << len) - 1) << pos;
    return (dst & ~mask) | (src & mask);
}

Upvotes: 13

Michael Mrozek
Michael Mrozek

Reputation: 175595

You can create the masks using:

int mask_y = ((1 << len) - 1) << pos;
int mask_x = ~mask_y;

Upvotes: 0

Related Questions