0

Consider I have a number 100101 of length 6. I wish to flip bits starting from position 2 to 5 so my answer will be 111011. I know that I can flip individual bits in a loop. But is there an efficient way of doing this without a for loop?

Leena
  • 703
  • 1
  • 12
  • 21
  • 4
    Presumably you aren't always trying to flip all unset bits? Please clarify your input/output a little bit. It also seems like you're assuming indices to start at `1`? And is it big-endian or little endian? – AndyG Jan 03 '21 at 20:17
  • @AsteroidsWithWings I am trying to solve a competitive coding problem. Using a loop increases gets me a Time limit Exceeded output. – Leena Jan 03 '21 at 20:28
  • _What_ competitive coding problem? – Asteroids With Wings Jan 03 '21 at 20:32
  • @AsteroidsWithWings Leetcode 995. There may be a different solution to the problem, but when i looked for flipping part of bitset, i couldnt find anything – Leena Jan 03 '21 at 20:36

2 Answers2

2

If I understand you correctly, try

namespace {
unsigned flip(unsigned a)
{
   return a ^ 0b011110u;
}
}  // namespace

Just adjust the constant to the actual bits you want to flip by having them as 1's in the constant.

On the otherhand, if you need just to update an individual variable you also use

unsigned value = 0b100101u;
value ^= 0b011110u;
assert(value == 0b111011u);

EDIT And here is the same using std::bitset<6u> and C++98:

#include <bitset>
#include <cassert>

int main()
{
   std::bitset<6u> const kFlipBit2to6WithXor(0x1Eu);  // aka 0b011110u
   std::bitset<6u> number(0x25u);                     // aka 0b100101u
   number ^= kFlipBit2to6WithXor;
   assert(number.to_ulong() == 0x3Bu);                // aka 0b111011u
   return 0;
}
Bo R
  • 2,334
  • 1
  • 9
  • 17
1

0b1111 is 0b10000-1.

constexpr unsigned low_mask(unsigned x){
  return (1u<<x)-1;
}

0b1100 is 0b1111-0b11.

constexpr unsigned mask(unsigned width, unsigned offset){
  return low_mask(width+offset)-low_mask(offset);
}

then use xor to flip bits.

unsigned result = 0b100001 ^ mask(4,2);
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524