0

我有一个 16 位整数,我正在尝试交换一些单独的位组件的值。

例如:

  • 交换第 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;
4

4 回答 4

1

好吧,您可以检查这些位是否相同,如果它们相同则什么也不做。如果它们不同,您可以通过适当的位掩码异或来同时翻转它们(例如,0001100 表示第 3 位和第 4 位)。我不确定这最终会变得多么“有效”。

于 2012-11-11T05:10:06.177 回答
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 ;
}
于 2012-11-11T08:04:59.860 回答
1

此函数可以轻松交换数字 n 的位位置 pos1 和 pos2。首先它检查这两个位是否不同,如果不同,则从 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;  }
于 2012-11-11T19:05:30.190 回答
0

虽然其他答案很有用,但如果您需要按顺序执行多个位交换操作,则提供的方法都不起作用。

一旦你已经移动了位,就几乎不可能知道哪些位从哪里开始,除非你想为每个可能的位交换排列编写逻辑。

相反,您需要一种适用于相对位置(最初是第 2 位的位位置)而不是绝对位置(第 2 位)的方法。

这是我的做法:

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请注意,一旦完成交换位,您将不得不重建。

于 2012-11-17T06:34:58.393 回答