Home > Software engineering >  How can I swap two bits starting from MSB?
How can I swap two bits starting from MSB?

Time:12-30

I'm looking for a way to swap 2 bits at a given position but counting starts from MSB(most significant bit) to LSB (least significant bit). Lets say i have position p1 = 0 and p2 = 2 and my number is 1000 = 8 . The result should be 0010 .

I tried this piece of code but it swaps the bits starting from LSB to MSB . How do I "reverse" the process?

    unsigned int bit1 =  (num >> p1) & 1;
    unsigned int bit2 =  (num >> p2) & 1;
    unsigned int x = (bit1 ^ bit2);
      x = (x << p1) | (x << p2);
     result = num ^ x;

CodePudding user response:

By your example, I will assume you mean to start numbering bits from the MSB of the number value. That is, given:

00010100
   ↑
   msb == most significant bit in the number

In that case, you need a way to count the bit index of the MSB. There are actually processor instructions you can use to do that, and both MSVC and GCC (and Clang) provide special functions to access that functionality...

...but you don’t need that. Instead, just write yourself a function:

int index_of_msb( unsigned long value )
{
  ...
}

Remember that you can shift a number down by one bit at a time. As long as the number is not zero, you have at least one set bit left.

  1 0 1 0 0 0
→   1 0 1 0 0  (1 shift)
→     1 0 1 0  (2 shifts)
→       1 0 1  (3 shifts)
→         1 0  (4 shifts)
→           1  (5 shifts)
→           0

Five shifts → bit 5 is MSB.

Now you can convert your bit positions to the standard shift offsets.

p1 = p_msb - p1;
p2 = p_msb - p2;

What remains to do is use your standard bit operators to swap the two bit values.

CodePudding user response:

Four bits is small enough that you can use a 256-byte table:

unsigned char SwapBits(unsigned char number, int p0, int p1)
{
    static const unsigned char Table[16][4][4] = {
{ { 0,  0,  0,  0}, { 0,  0,  0,  0}, { 0,  0,  0,  0}, { 0,  0,  0,  0} },
{ { 1,  0,  0,  0}, { 0,  0,  0,  0}, { 0,  0,  0,  0}, { 0,  0,  0,  0} },
{ { 2,  1,  0,  0}, { 1,  2,  2,  2}, { 0,  2,  2,  2}, { 0,  2,  2,  2} },
{ { 3,  3,  1,  1}, { 3,  3,  2,  2}, { 1,  2,  3,  3}, { 1,  2,  3,  3} },
{ { 4,  2,  1,  0}, { 2,  4,  4,  4}, { 1,  4,  4,  4}, { 0,  4,  4,  4} },
{ { 5,  3,  5,  1}, { 3,  5,  6,  5}, { 5,  6,  5,  4}, { 1,  5,  4,  5} },
{ { 6,  6,  3,  2}, { 6,  6,  5,  4}, { 3,  5,  6,  6}, { 2,  4,  6,  6} },
{ { 7,  7,  7,  3}, { 7,  7,  7,  5}, { 7,  7,  7,  6}, { 3,  5,  6,  7} },
{ { 8,  4,  2,  1}, { 4,  8,  8,  8}, { 2,  8,  8,  8}, { 1,  8,  8,  8} },
{ { 9,  5,  3,  9}, { 5,  9,  9, 12}, { 3,  9,  9, 10}, { 9, 12, 10,  9} },
{ {10,  6, 10,  3}, { 6, 10, 12, 10}, {10, 12, 10,  9}, { 3, 10,  9, 10} },
{ {11,  7, 11, 11}, { 7, 11, 13, 14}, {11, 13, 11, 11}, {11, 14, 11, 11} },
{ {12, 12,  6,  5}, {12, 12, 10,  9}, { 6, 10, 12, 12}, { 5,  9, 12, 12} },
{ {13, 13,  7, 13}, {13, 13, 11, 13}, { 7, 11, 13, 14}, {13, 13, 14, 13} },
{ {14, 14, 14,  7}, {14, 14, 14, 11}, {14, 14, 14, 13}, { 7, 11, 13, 14} },
{ {15, 15, 15, 15}, {15, 15, 15, 15}, {15, 15, 15, 15}, {15, 15, 15, 15} },
    };
    return Table[number][p0][p1];
}
  • Related