4

私は学校のプロジェクトにエラトステネスのふるいを実装しようとしていますが、ビット配列を使用して実装することにしました。資料を探していると、この3つのマクロに出くわしましたが、問題なく動作しますが、実際には読めません(理解できません)。

#define ISBITSET(x,i) ((x[i>>3] & (1<<(i&7)))!=0)
#define SETBIT(x,i) x[i>>3]|=(1<<(i&7));
#define CLEARBIT(x,i) x[i>>3]&=(1<<(i&7))^0xFF;

そのうちの少なくとも1つについて詳しく説明していただけますか。私は、Cでのビット演算について非常に基本的な知識を持っています(基本的には、それらが「存在する」ことを知っています)。

これは、異なるエンディアンを使用する別のアーキテクチャで機能しますか?前もって感謝します。

4

3 に答える 3

5

x文字の配列です。iビットのインデックスです。すべてcharが8ビットであるため、最後の3ビットはicharのビットを定義し、残りのビットは配列のcharを定義します。

i>>3iを3ビット右にシフトすると、どの文字かを示す部分が得られ、 。x[i>>3]でインデックス付けされたビットを含む文字も同様になりますi

i&7i(以降)の最後の3ビットであるため、char内のビットのインデックスです。はchar(実際にはintですが、このコンテキストでは違いを無視できます)であり、ビットはonでインデックス付けされ、残りのビットはoffです。(ビットのマスク)710==11121<<(i&7)i

char&maskビットがオンかどうかを確認する一般的な方法です。

char|=maskビットを入れる一般的な方法です。

char&=~maskビットをオフにする一般的な方法です。maskがcharの場合、~mask==mask^0xFF

これらのマクロはエンディアンに依存しているとは思いません。x(に変換int[]して得た場合*char、それは別の話です)

于 2012-02-12T12:13:45.640 に答える
4

まず、これらのマクロは悪意を持ってそれを想定しCHAR_BIT == 8i >> 3実際にはi / 8です。(したがって、実際にはこのコードは言う必要があります。)この最初の式は、目的のビットを含むバイトi / CHAR_BITを計算します。したがって、配列内の配列インデックス(!の配列である必要があります)です。xunsigned char

正しいバイトを選択したので、つまりx[i >> 3](またはx[i / CHAR_BIT]あなた自身のより良いコードで)、ビットをいじる必要があります。繰り返しになりますが、i & 7本当になりたいのですが、バイトi % CHAR_BITのオフセットを与えるビットカウントの残りの部分だけを抽出します。

例。で44番目のビットを要求し、が5であるi = 43と仮定すると、6番目のバイトにあり、3であるため、6番目のバイトの4番目のビットを調べています。CHAR_BIT = 8i / CHAR_BITi % CHAR_BIT

実際のビット操作自体が通常のことを行います。たとえば、特定のビットのテストは、適切なビットパターン(つまり1 << kkthビット)を使用してビット単位でANDを実行します。ビットの設定にはビット単位のORが使用され、ゼロにするにはもう少し複雑なものが必要です(考えてみてください)。

于 2012-02-12T12:18:09.073 に答える
-1
#define ISBITSET(x,i) (((x)[(i) / CHAR_BIT] & (1u << ((i) % CHAR_BIT))) != 0)
#define SETBIT(x,i) (x)[(i) / CHAR_BIT] |= (1u << ((i) % CHAR_BIT);
#define CLEARBIT(x,i) (x)[(i) / CHAR_BIT] &= ~(1u << ((i) % CHAR_BIT))
  • マクロ引数は常に括弧で囲んでください
  • ビット演算には常に符号なし型を優先します
  • (1u << CHAR_BIT)は、8ビットプラットフォームの場合は256です。
  • ;最後のマクロの後にexraがありました
于 2012-02-12T12:12:56.987 に答える