0

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

4 に答える 4

1

この関数は、数値 n のビット位置 pos1 と pos2 を簡単に入れ替えることができます。まず、2 つのビットが異なるかどうかを確認します。異なる場合は 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 に答える
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

ビットが同じかどうかを確認できます。同じ場合は何もしません。また、それらが異なる場合は、適切なビット マスク (たとえば、3 番目と 4 番目のビットの場合は 0001100) で XOR することにより、両方を同時に反転できます。ただし、これがどの程度「効率的」になるかはよくわかりません。

于 2012-11-11T05:10:06.177 に答える
0

他の回答は役に立ちましたが、これらのビットスワッピング操作を2つ以上順番に実行する必要がある場合は、提供されている方法はどれも機能しません。

すでにビットを移動すると、ビットスワッピングのすべての可能な順列のロジックを記述したい場合を除いて、どのビットがどこから始まったかを知ることはほぼ不可能になります。

代わりに、絶対位置(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 に答える