是否有一种简单的方法来交换位值?

时间:2012-11-11 04:41:08

标签: c# bit-manipulation

我有一个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;

4 个答案:

答案 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