11

さまざまなソースの助けを借りて、コードを必要とせずに生の C# ですべてビット演算を使用して、 、、およびでSwapBytesエンディアンを交換するバイナリ リーダー クラスにいくつかのメソッドを記述しました。ushortuintulongunsafe

public ushort SwapBytes(ushort x)
{
    return (ushort)((ushort)((x & 0xff) << 8) | ((x >> 8) & 0xff));
}

public uint SwapBytes(uint x)
{
    return ((x & 0x000000ff) << 24) +
           ((x & 0x0000ff00) << 8) +
           ((x & 0x00ff0000) >> 8) +
           ((x & 0xff000000) >> 24);
}

public ulong SwapBytes(ulong value)
{
    ulong uvalue = value;
    ulong swapped =
         ((0x00000000000000FF) & (uvalue >> 56)
         | (0x000000000000FF00) & (uvalue >> 40)
         | (0x0000000000FF0000) & (uvalue >> 24)
         | (0x00000000FF000000) & (uvalue >> 8)
         | (0x000000FF00000000) & (uvalue << 8)
         | (0x0000FF0000000000) & (uvalue << 24)
         | (0x00FF000000000000) & (uvalue << 40)
         | (0xFF00000000000000) & (uvalue << 56));
    return swapped;
}

上記と同じメソッドのみを使用して、short、int、long などの各タイプの署名付きバージョンに対して同じメソッドを作成するにはどうすればよいでしょうか。また、上記のメソッドにどのような改善を加えることができますか?

4

4 に答える 4

23

概念的に分解してバイトを分離し、逆に再構築する代わりに、次のように概念的にバイトのグループを交換できます: (未テスト)

public uint SwapBytes(uint x)
{
    // swap adjacent 16-bit blocks
    x = (x >> 16) | (x << 16);
    // swap adjacent 8-bit blocks
    return ((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8);
}

32ビットではあまり(またはまったく)役に立ちませんが、64ビットでは役に立ちます(テストされていません)

public ulong SwapBytes(ulong x)
{
    // swap adjacent 32-bit blocks
    x = (x >> 32) | (x << 32);
    // swap adjacent 16-bit blocks
    x = ((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16);
    // swap adjacent 8-bit blocks
    return ((x & 0xFF00FF00FF00FF00) >> 8) | ((x & 0x00FF00FF00FF00FF) << 8);
}

符号付きの型の場合は、符号なしにキャストし、これを行ってからキャスト バックします。

于 2013-10-24T08:19:07.870 に答える
2

最初にunsignedにキャストを追加し、最後にsignedに戻すだけです。

public long SwapBytes(long value)
{
    return (long)SwapBytes((ulong)value);
}

SwapBytes最大のパフォーマンスを得るには、呼び出しを手動でインライン化する必要がある場合があります。


別の注意として、目的のエンディアンで元のバイト配列からデータを直接読み取ることを優先して、スワッピングを避けたい場合があります。詳細については、C# でビッグ エンディアン データを効率的に読み取る方法を参照してください。

于 2013-10-24T08:18:07.893 に答える