30

次のコードはどのように機能し、変数は何を意味しますか:

y = (x << shift) | (x >> (sizeof(x)*CHAR_BIT - shift));

循環シフトの記事で見つけましたが、これがどのように機能するかについての説明はありません。

4

4 に答える 4

31

これは循環シフトを行う方法です。それxが8ビットだとします。

+----+----+----+----+----+----+----+----+
| | x1 x2 x3 x4 x5 x6 x7 x8 | x1 x2 x3 x4 x5 x6 x7 x8 |
+----+----+----+----+----+----+----+----+

次に、それを 3 だけ左にシフトすると、次のようになります。

+----+----+----+----+----+----+----+----+
| | x4 x5 x6 x7 x8 0 0 0 |
+----+----+----+----+----+----+----+----+

現在、CHAR_BIT*sizeof(x)は のビット幅と同じ8 です。したがって、右にxシフトすると次のようになります。x8 - 3

+----+----+----+----+----+----+----+----+
| | 0 0 0 0 0 x1 x2 x3 |
+----+----+----+----+----+----+----+----+

ORを取ると、次のようになります。

+----+----+----+----+----+----+----+----+
| | x4 x5 x6 x7 x8 x1 x2 x3 | x4 x5 x6 x7 x8 x1 x2 x3 |
+----+----+----+----+----+----+----+----+

これは、型の幅に等しい量だけシフトすることは移植性がないため、技術的に移植性がありません。したがって、シフトが 8 の場合、左シフトは間違っており、シフトが 0 の場合、右シフトは間違っています。間違っている。ただし、これは実際には、タイプの幅だけシフトする場合の 3 つの一般的な動作すべてで機能します。(実際には、シフト量は、型のビット幅またはより大きな数のいずれかのモジュロで減少します。)

これは循環シフトまたは「ローテーション」と呼ばれます。これは、左にシフトアウトされたビットが右にシフトインされるためです。

洗練されたコンパイラは、実際にコードをハードウェア回転命令にまでコンパイルします。

于 2012-11-08T12:56:48.637 に答える
25

CHAR_BITはバイトあたりのビット数で、常に 8 である必要があります。

shift循環的に左にシフトするビット数です。したがって、左にシフトアウトされたビットは右に戻ります。

     1110 0000 << 2 results in:
     1000 0011

例のコード:

   y = (x << 2) | (x >> (8 - 2));
于 2012-11-08T12:52:48.123 に答える
7
(x << shift) 

'シフト'ビット数を左にシフトし、シフトアウトされたビットを返します

(x >> (sizeof(x)*CHAR_BIT - shift));

それらのビットを収容するためのスペースを作ります

CHAR_BITはcharのビット数であるため、ほとんどの場合8です。Cでは、一度に1ビットを処理するのではなく、少なくともcharビット数を処理します。これが、得られる粒度です。

一般に、

charの場合、ビットローテーションを実行するときは、8ビットフィールド(1バイト)で実行します。

intの場合、回転を実行するときは、32ビットフィールド(4バイト)で実行します。


8ビットの例:

x = 11010101
shift = 2

x << (shift) = 01010100 //shifted left by 2 bits

= x >> ((1 * CHAR_BIT) - shift)
= x >> (6) 
= 00000011 //shifted right by 6bits

ORこれらをビット単位で与える

01010100 //x << 2
00000011 //x >> 6
________
01010111

これは、2ビットの循環シフト値です。

于 2012-11-08T12:54:59.967 に答える
2

これは、符号なしタイプでのみ機能します。符号付きの負の数の場合、左端のビットは、右シフト演算子(> >>")によって最上位ビット(1-s)の値に置き換えられます。

私はそれを次のように書きます:

y = (x << shift) | ( (x >> (sizeof(x)*CHAR_BIT - shift)) & (0x7F >> (sizeof(x)*CHAR_BIT - shift) );

ここで「|」の前に 演算子では、最初のnビット(n = sizeof(x)* CHAR_BIT-シフト)がゼロになっていることを確認します。また、xは短い(2バイト長)と仮定します。したがって、タイプにも依存します。

于 2012-11-08T14:27:09.440 に答える