我有一个16位的int,我试图交换一些单独的位组件的值。
例如:
- 交换第3位和第4位的值。
- 交换第5位和第6位的值。
我还必须处理更复杂的价值转移链。
- 将第2位的值移至第3位
- 将第3位的值移动到第1位
- 将第1位的值移动到第4位
- 将第4位的值移动到第2位。
有没有合理的方法呢?这些位并不总是相邻的,因此旋转似乎不太可行。现在,我所能想到的只是逐位重建int(通过连续& s +>> s),但这似乎并不特别有效。
我现在有这个:
// 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;
答案 0 :(得分:1)
你可以检查一下这些位是否相同,如果它们是相同的则什么都不做。如果它们不同,您可以通过相应的位掩码(例如,第3和第4位的0001100)进行异或,同时翻转它们。我不确定这最终会有多么“有效”。
答案 1 :(得分:1)
假设:
[Flags]
public enum MyBits
{
Bit1 = 0x01,
Bit2 = 0x02,
Bit3 = 0x04,
Bit4 = 0x08,
Bit5 = 0x10,
Bit6 = 0x20
}
然后:
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 ;
}
答案 2 :(得分:1)
此功能可以轻松交换数字n的位位置pos1和pos2。 1,它检查两个位是否不同,如果不同,那么它从1切换到0或从0切换到1,如果相同则它什么也不做,只是返回那个数字
int swap_bit(int n, int pos1, pos2)
{
((n >> pos1) & 1 ) != ( (n >> pos2) & 1 ) ? n = n ^ (( 1 << pos1) |( 1 << pos2)):n;
return n; }
答案 3 :(得分:0)
虽然其他答案很有用,但如果您需要按顺序执行多个这些位交换操作,则所提供的方法都不会起作用。
一旦你已经移动了这些位,就几乎不可能知道哪些位从哪里开始,除非你想为每次可能的位交换排列编写逻辑。
相反,你需要一个适用于相对位置的方法(原来是第二位的位位置),而不是绝对位置(第二位)。
我将如何做到这一点:
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;
此代码的优点是一目了然更容易理解,而且您不必对您不想更改的位进行进一步操作。最后,如前所述,此代码适用于任意连续的位交换链,改变相对面(在您的情况下),同时保持绝对面。
请注意,一旦完成交换位,您将不得不重建l_shape
。