Reputation: 7160
I have a 16-bit int, and I am trying to exchange the values of some of the individual bit components.
For instance:
- swap the values of the 3rd and 4th bit.
- swap the values of the 5th and 6th bit.
I also have to deal with more complicated chains of value transference.
- move the value of the 2nd bit to the 3rd bit
- move the value of the 3rd bit to the 1st bit
- move the value of the 1st bit to the 4th bit
- move the value of the 4th bit to the 2nd bit.
Is there a sensible way to do this? The bits aren't always adjacent, so a rotate doesn't seem particularly viable. Right now, all I can think to do is rebuild the int bit-by-bit (via successive &s + >>s), but that doesn't seem particularly effective.
I've got this right now:
// bit 2 to bit 3
temp_shape = 0;
temp_shape = l_shape & NegXFace;
temp_shape >>= 1;
resultShape |= temp_shape;
// bit 3 to bit 1
temp_shape = 0;
temp_shape = l_shape & PosYFace;
temp_shape <<= 2;
resultShape |= temp_shape;
// bit 1 to bit 4
temp_shape = 0;
temp_shape = l_shape & PosXFace;
temp_shape >>= 2;
resultShape |= temp_shape;
// bit 4 to bit 2
temp_shape = 0;
temp_shape = l_shape & PosYFace;
temp_shape <<= 2;
resultShape |= temp_shape;
// bits 5 and 6
temp_shape = 0;
temp_shape = l_shape & (PosZFace | NegZFace);
resultShape |= temp_shape;
Upvotes: 0
Views: 1084
Reputation: 101
This function can easily swap bit positions pos1 and pos2 of a number n. 1st it checks that the two bits are different or not, if diffrent then it toggled from 1 to 0 or from 0 to 1 and if same then it do nothing and simply return that number
int swap_bit(int n, int pos1, pos2)
{
((n >> pos1) & 1 ) != ( (n >> pos2) & 1 ) ? n = n ^ (( 1 << pos1) |( 1 << pos2)):n;
return n; }
Upvotes: 1
Reputation: 7160
While the other answers were useful, none of the provided methods will work if you ever need to perform more than one of these bit swapping operations in sequence.
Once you've already moved the bits around, it becomes damn near impossible to know which bits started where, unless you want to write logic for every possible permutation of bit swappings.
Instead, you need a method that works for relative position (the bit position of what was originally the 2nd bit), rather than absolute position (the 2nd bit).
Here's how I would do it:
bool[] relFaces = new bool[6];
bool swapBool;
//start relFaces with the absolute faces.
//default value of bool is "FALSE"
if((l_shape & PosXFace) == PosXFace)
{
relFaces[0] = true;
}
if((l_shape & NegXFace) == NegXFace)
{
relFaces[1] = true;
}
if((l_shape & PosYFace) == PosYFace)
{
relFaces[2] = true;
}
if((l_shape & NegYFace) == NegYFace)
{
relFaces[3] = true;
}
if((l_shape & PosZFace) == PosZFace)
{
relFaces[4] = true;
}
if((l_shape & NegZFace) == NegZFace)
{
relFaces[5] = true;
}
// -z >> -x
swapBool = relFaces[1];
relFaces[1] = relFaces[5];
// +x >> -z
relFaces[5] = relFaces[0];
// +z >> +X
relFaces[0] = relFaces[4];
// -X >> +z
relFaces[4] = swapBool;
break;
This code has the advantage of being much easier to understand at a glance, and you don't have to do further operations on bits you're not interested in changing. Finally, as mentioned earlier, this code will work for an arbitrary chain of successive bit-swaps, changing the relative facing (in your case) while maintaining the absolute facing as well.
Do note that you will have to rebuild l_shape
once you're done swapping bits.
Upvotes: 0
Reputation: 21024
Assuming:
[Flags]
public enum MyBits
{
Bit1 = 0x01,
Bit2 = 0x02,
Bit3 = 0x04,
Bit4 = 0x08,
Bit5 = 0x10,
Bit6 = 0x20
}
Then:
public MyBits SwitchBits(MyBits oldBits)
{
// Extracting every bits
bool Bit1 = oldBits.HasFlag(MyBits.Bit1);
bool Bit2 = oldBits.HasFlag(MyBits.Bit2);
bool Bit3 = oldBits.HasFlag(MyBits.Bit3);
bool Bit4 = oldBits.HasFlag(MyBits.Bit4);
bool Bit5 = oldBits.HasFlag(MyBits.Bit5);
bool Bit6 = oldBits.HasFlag(MyBits.Bit6);
MyBits newBits = new MyBits();
// Scrambling the bits
if (Bit4) newBits = newBits | MyBits.Bit1;
if (Bit2) newBits = newBits | MyBits.Bit2;
if (Bit3) newBits = newBits | MyBits.Bit3;
if (Bit1) newBits = newBits | MyBits.Bit4;
if (Bit6) newBits = newBits | MyBits.Bit5;
if (Bit5) newBits = newBits | MyBits.Bit6;
return newBits ;
}
Upvotes: 1
Reputation: 993
well you can check to see if the bits are the same, and if they are the same do nothing. And if they are different, you can flip both of them at the same time by XORing by the appropriate bit mask (eg 0001100 for 3rd and 4th bit). I'm not really sure how "efficient" this will end up being though.
Upvotes: 1