0

一度に3バイトのデータを読み取ることができるアルゴリズムを作成する必要があります。

たとえば、ユーザー入力を想像してみてください:Uof

バイナリのUofは、010101010110111101100110として表示されます。

これをそれぞれ6ビットの4つの等しい部分に分割するのに助けが必要です。

010101(21)

010110(22)

111101(61)

100110(38)

私はintのみを使用することが許可されています。最初の文字を読み、それを2つ右にシフトして、結果21を問題なく取得できます。

22を取得することは私には意味がありません。どんなポインタでも役に立ちます。正確な解決策は必要ありませんが、私に考えさせることができるものは何ですか?

4

2 に答える 2

1

自問してみてください:

  • 各部分の 6 ビットはどこから来たのですか?

  • 値内の別の位置にビットを移動するにはどうすればよいですか?

  • それぞれの興味深いビットのみが取得されるように、2 つの値を組み合わせるにはどうすればよいですか?

3 番目の質問に答えるために、次のことを自問することもできます。

  • 値をマスクして、関心のあるビットがそのまま残り、関心のないビットがすべて 0 (またはすべて 1) になるようにするにはどうすればよいですか?
于 2012-09-17T23:39:43.943 に答える
0

OK、まず、3 バイトを 1 つの整数に入れようとします。シフトとORロジックを使用します。と入力変数がaあるとします。(それぞれ、 、およびに分割されます)。bcUofabc

まず、b変数用にさらに 1 バイトのスペースを追加します。

(b << 8)

に変換01101111され0110111100000000ます。

では、ゼロは実際には次のようにOR cなります。bc

((b << 8) | c))

次に、 で同じロジックを実行しaます。の右側にさらに 16 ビットを予約するaので、OR取得した最後の式を取得できます。

((a << 16) | ((b << 8) | c))

ここまでで、すべてのビットが 1 つの 4 バイト整数にマージされました。

ここで必要なのは、それをそれぞれ 6 ビットの 4 つの部分に分割することだけです。これにはマスクロジックを使用します。

まず、「マスク」ロジックを使用する場合、マスク自体を作成する必要があります。マスクは0x3F(2 進数 111111、つまり 6 ビットから) であるため、ANDこのマスクを使用して数値を計算すると、右側の最初の 6 ビットを抽出できます。

r1 = (merged & 0x00003F);

の略r1ですresult 1

さて、同じことですが、マージされた数値が 6 ビット右にあるため、次の 6 ビット数値を取得できます。残りは以下のようになります。

r1 = ((merged >> 0)  & 0x3F);
r2 = ((merged >> 6)  & 0x3F);
r3 = ((merged >> 12) & 0x3F);
r4 = ((merged >> 18) & 0x3F);

したがって、最終的なコードは次のようになります。

char /*or int*/ a, b, c;
int merged, r1, r2, r3, r4;

scanf(" %c %c %c", &a, &b, &c);

merged = ((a << 16) | ((b << 8) | c));

r1 = ((merged >> 0)  & 0x3F);
r2 = ((merged >> 6)  & 0x3F);
r3 = ((merged >> 12) & 0x3F);
r4 = ((merged >> 18) & 0x3F);

printf("%d %d %d %d\n", r1, r2, r3, r4);

編集:マスク部分を修正しました。

于 2012-09-18T00:07:22.627 に答える