1

問題と解決策:

/** Return the result of swapping the two lower-order bytes of X.
* For example, if X is 0x12345678, then swap(X) is 0x12347856. */
static int swapLower(int X) {
    /* Solution */
    int lower = X & 0x0000ffff;
    int upper = X & 0xffff0000;

    return upper | (0xffff & ((lower << 8) | (lower >> 8)));
}

解決策を理解する方法について混乱しています。ロジックを実行しようとしましたが、理解できませんでした。

また、そもそも解決策の出し方がわからない!

編集:

プロパティ:

x & 1 = x
x & 0 = 0
x | 1 = 1
x | 0 = x
  1. int 下位 = X & 0x0000ffff = X & 0b0000000000000000111111111111111 = 0b0000000000000000x 15 ... x 0

  2. int 上 = X & 0xffff0000 = X & 0b11111111111111110000000000000000 = 0bx 31 ... x 16 0000000000000000

  3. 下 << 8 = 0b0000000000000000x 15 ... x 0 << 8 = 0b00000000x 15 ... x 0 00000000

  4. 下 >> 8 = 0b0000000000000000x 15 ... x 0 >> 8 = 0bssssssss00000000x 15 ... x 8

    • X(が符号付きの数値であると仮定すると、sは符号ビットです。正の場合は 0、負のX場合は 1 です)X
  5. (下位 << 8) | (下 >> 8) = 0b00000000x 15 ... x 0 00000000 | 0bssssssss00000000x 15 ... x 8 = 0bssssssssx 15 ... x 0 x 15 ... x 8

  6. 0xffff & ((下位 << 8) | (下位 >> 8)) = 0b000000000000000001111111111111111 & 0bssssssssx 15 ... x 0 x 15 ... x 8 = 0b00000000000000000x 7 ... x 0 x 15 ... x 8

  7. アッパー | (0xffff & ((下位 << 8) | (下位 >> 8))) = 0bx 31 ... x 16 0000000000000000 | 0b00000000000000000x 7 ... x 0 x 15 ... x 8 = x 31 ... x 16 x 7 ... x 0 x 15 ... x 8

4

2 に答える 2

2

はい、それは必要以上にわかりにくいです。

これは理解しやすいと思います:

int lowest2     = (X & 0x000000FF) << 8; // lowest byte moved 8 bits left
int nextLowest2 = (X & 0x0000FF00) >> 8; // next lowest byte move 8 bits right
int upper4      = (X & 0xFFFF0000);
return upper4 | lowest2 | nextLowest2;

次に、X = 0x12345678 の場合:

upper4 | lowest2 | nextLowest2 = 0x12340000 | 0x00007800 | 0x00000056;

しかし、もちろん、与えられたソリューションを分析すると、同じことが得られます。

上限と下限が次のように定義されている場合:

int lower = X & 0x0000FFFF
int upper = X & 0xffff0000;

それで:

X                                                = 0x12345678
lower                                            = 0x00005678
(lower << 8)                                     = 0x00567800
(lower >> 8)                                     = 0x00000056
((lower << 8) | (lower >> 8))                    = 0x00567856
(0xFFFF & ((lower << 8) | (lower >> 8)))         = 0x00007856
upper                                            = 0x12340000
upper | (0xffff & ((lower << 8) | (lower >> 8))) = 0x12345678
于 2013-08-10T02:21:05.313 に答える
0

与えられた解決策は正しいですが、過度に複雑であるため、必要以上に理解するのが困難です。次の解決策は、理解するのがはるかに簡単です。

return X & 0xffff0000 | ((X & 0xff00) >> 8) | ((X & 0xff) << 8);

数字から 3 つの部分を取り出して並べ替えるだけです。それを理解するには、 で区切られた各|コンポーネントについて考え、それが数字のどの部分を選択し、その部分が結果のどこに到達するかを考慮します。

于 2013-08-10T01:36:33.640 に答える