IUnknown
IUnknown

Reputation: 9819

Bit manipulation in a range

While I know the process to set/unset a bit at a specific location - what is the most efficient way to do this operation over a range (say from position x to y)?

101011011011

n=12
x=3,y=7(from right)

Bit set: 101011111111
Bit unset: 101010000011

The mask has to be pushed dynamically as x and y will obviously be random.
Thanks for the help.

Upvotes: 0

Views: 742

Answers (3)

Gene
Gene

Reputation: 46990

Are we talking about C-like operations? If you want x and y to be variables, you can build two masks:

unsigned set(unsigned val, int x, int y) {
  unsigned hi = ~0 << x;    // 1's at position x and higher
  unsigned lo = ~(~0 << y); // 1's at positions lower than y
  return val | (lo & hi);
}

and

unsigned clear(unsigned val, int x, int y) {
  unsigned hi = ~(~0 << x);   
  unsigned lo = ~0 << y; 
  return val & (lo | hi);
}

Note the end of the range is non-inclusive at the high end. So set(foo, 5, 9) sets bits 5 through 8, where each bit i is the one with value 2^i.

Upvotes: 1

Falk H&#252;ffner
Falk H&#252;ffner

Reputation: 5040

If you count bits from 0 as usual, you can use:

unsigned set(unsigned x, unsigned l, unsigned h) {
    return x | (((1u << h) << 1) - (1u << l));
}

unsigned reset(unsigned x, unsigned l, unsigned h) {
    return x & ~(((1u << h) << 1) - (1u << l));
}

Upvotes: 0

Michael Dorgan
Michael Dorgan

Reputation: 12515

To follow up to set from 3 to 7:

value = 1010110...
mask = 0x7C; // 0111 1100 binary
value |= mask;

to clear

value = 1010110...
mask = 0x7C; // 0111 1100 binary
value &= ~mask;

using C style above where | is or, & is and, and ~ is compliment.

Upvotes: 0

Related Questions