私は最近that SO questionを見つけました。ビットマップを90度回転させる方法の説明
Rhubbarbの回答と回答はうまくいきますが、どのように動作するのか分かりません。私は自分のプロジェクトで理解できないコードを使用したくありません。基本的なビット操作(シフト、AND、ORなど)は何かを知っていますが、これらの操作の組み立てがどのように処理しているのか分かりません。
この質問をご覧いただき、ありがたいことに私を助けてくれてありがとうございます。
私は最近that SO questionを見つけました。ビットマップを90度回転させる方法の説明
Rhubbarbの回答と回答はうまくいきますが、どのように動作するのか分かりません。私は自分のプロジェクトで理解できないコードを使用したくありません。基本的なビット操作(シフト、AND、ORなど)は何かを知っていますが、これらの操作の組み立てがどのように処理しているのか分かりません。
この質問をご覧いただき、ありがたいことに私を助けてくれてありがとうございます。
64ビット整数value
を8×8ブロックとして表されている - のは、次のように、我々は、各セルの「コンテンツ」を理解するだろうふりをしましょう:value
が実際として順次格納されているが
1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64
我々はまた、それをシフトする
に4(value << 4
)の結果によって残されたと言う
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...
4(value >> 4
)で右にシフト0
または
5 6 7 8 9 10 11 12
13 14 15 16 17 18 19 20 ...
とは0xFFFFFFFF00000000ull
様の作品が少しあり、今
0 0 0 0 1 2 3 4
5 6 7 8 9 10 11 12 ...
のは、ここで
uint64 reflect_vert (uint64 value)
{
value = ((value & 0xFFFFFFFF00000000ull) >> 32) | ((value & 0x00000000FFFFFFFFull) << 32);
value = ((value & 0xFFFF0000FFFF0000ull) >> 16) | ((value & 0x0000FFFF0000FFFFull) << 16);
value = ((value & 0xFF00FF00FF00FF00ull) >> 8) | ((value & 0x00FF00FF00FF00FFull) << 8);
return value;
}
てみましょう提供しますAND演算と組み合わせて、value
からビットを選択するマスク。 また、0xFF
は8ビットが設定された1バイトに対応するため、0xFFFFFFFF
は4*8=32
の選択ビットを効果的に説明しています。各行は8
ビット長であるため、これは4
行に対応します。
具体的には、value & 0xFFFFFFFF00000000ull
選択(保持!)value
の上位32ビット、すなわち、最初の4行、及びvalue & 0x00000000FFFFFFFFull
は下位32ビットを選択して最初に破棄しながら、残りを廃棄します。
((value & 0xFFFFFFFF00000000ull) >> 32)
((value & 0x00000000FFFFFFFFull) << 32)
で
シフト操作は、下位32ビットまたは上方(<< 32
)の位置にこれらのビットをいずれか下向き(>> 32
)移動します。それらをOR結合すると、効果的にスワップしたことになります。
value = ((value & 0xFFFFFFFF00000000ull) >> 32) | ((value & 0x00000000FFFFFFFFull) << 32);
幅16
スワップ二列それぞれとのずれを用いて、0xFFFF0000FFFF0000ull
と0x0000FFFF0000FFFFull
と同じ実行
33 34 35 36 37 38 39 40 \
41 42 43 44 45 46 47 48 |__
49 50 51 52 53 54 55 56 | |
57 58 59 60 61 62 63 64/|
1 2 3 4 5 6 7 8 \ |
9 10 11 12 13 14 15 16 |__|
17 18 19 20 21 22 23 24 |
25 26 27 28 29 30 31 32/
:今下位32ビットはブロックの「下半分」に対応するので、私たちはそうのような行を入れ替え隣人:8
スワップ他のすべての行のシフトを有する
49 50 51 52 53 54 55 56 \__
57 58 59 60 61 62 63 64/|
33 34 35 36 37 38 39 40 \__|
41 42 43 44 45 46 47 48/
17 18 19 20 21 22 23 24 \__
25 26 27 28 29 30 31 32/|
1 2 3 4 5 6 7 8 \__|
9 10 11 12 13 14 15 16/
最後に、0xFF00FF00FF00FF00ull
と0x00FF00FF00FF00FFull
、
この時点でブロックは正常に垂直に反転されています。
reflect_diag
メソッドは、ビットを選択的にスワップする同じ方法を使用します。
0000 0001 0000 0000
0000 0000 0000 0000
0000 0000 0000 0000
0000 0000 0000 0000
0x0000000000000080
ながら(右中央の、下段)八最小を選択
0x0100000000000000
が8最高(中央の左一番上の行)ビットを選択することです
0000 0000 0000 0000
0000 0000 0000 0000
0000 0000 0000 0000
0000 0000 1000 0000
ビット。それらはちょうど49
ビット離れているので、49
によってそれらをシフトすると、その位置が入れ替わります。その対応0x0080402010080402
が
0000 0000 1000 0000
0100 0000 0010 0000
0001 0000 0000 1000
0000 0100 0000 0010
を選択し、一方、別の例として
、パターン0x4020100804020100
あなたはビット間の距離が全体を可能にするパターンを形成することがわかりますビット
0100 0000 0010 0000
0001 0000 0000 1000
0000 0100 0000 0010
0000 0001 0000 0000
を選択しますブロックが互いの元の位置と整列するようにシフトされる。
このコードでは、水平および垂直反転されたバージョンと比較して、元の値は上書きされずに新しい出力が作成されます。ミシェルのコードはインプレースでシフトし、シフトを8進数でエンコードするので、>> 010
は実際には>> 8
を意味し、020
は16
などを意味します。
すばらしい説明!大いに感謝する ! –