1. ホーム
  2. c

[解決済み] 2バイトの整数を入れ替える

2022-02-01 19:59:15

質問

int x, int n, int mの3つのパラメータを受け取るメソッドがあり、xのn番目とm番目のバイトを入れ替えたintを返します。

x は通常の整数で、任意の値を設定します。n と m は 0 から 3 までの整数です。

例えば、xの16進数表現を0x12345678とし、nを0、mを2とします。 最後と最後から3番目のバイトは入れ替わることになっている(n=78、m=34)。

xからn番目とm番目のバイトを取り出す方法はわかりましたが、4バイトすべてをメソッドが返すはずの整数に再結合する方法がわかりません。

以下は現在の私のコードです。 `

int byteSwap(int x, int n, int m)
{
    // Initialize variables which will hold nth and mth byte
    int xn = x;
    int xm = x;
    // If n is in bytes, n << 3 will be the number of bits in that byte
    // For example, if n is 2 (as in 2 bytes), n << 3 will be 16 (as in 16 bits)
    xn = x >> (n << 3);
    // Mask off everything except the part we want
    xn = xn & 0xFF;
    // Do the same for m
    xm = x >> (m << 3);
    xm = xm & 0xFF;
}

`

さらにいくつかの制約があります - 以下のものだけが許可されます。

~ & ^ | ! + << >>

(つまり - * / , ループ。 if sなど。ただし、追加の変数を初期化し、追加することは問題ありません)。

私のコードでは、n番目とm番目のバイトを抽出することはできますが、ifを使用せずにすべてを再結合する方法がわかりません。

どのように解決するのですか?

いくつかのこと

xをmバイトとnバイトを除くすべてのFFでマスクすることで再結合できます。 0xFFをm回、n回左シフトしてマスクを計算し、その結果を組み合わせて0xFFFFFFとXORすればよい。

int mask = 0;
int mask_m = 0xFF << (m << 3);
int mask_n = 0xFF << (n << 3);

mask = (mask_m | mask_n) ^ 0xFFFFFFFF;

int x_swapped = (x & mask) | (xm << (n <<3)) | (xn << (m <<3));
return x_swapped;

参考までに、符号付き値を右シフトした場合、高次ビットに0ではなく1が伝搬されることがありますが、これは実装定義です。 いずれにせよ、0xFFはこの問題を回避することができます。