3

私の質問は、エンディアンが変化したときのビット操作に関するものです。uint32_t特に、値の個々のビットを読み取り、それらに対してビット操作を実行するコードがいくつかあります。目的はUTF-8エンコーディングでした。それは私の小さなエンディアンマシンに完全に機能します。

最近コードを再検討すると、uint32_t値のビット表現に関する限り、マシンのエンディアンを考慮していないことに気づきました。それで、私はその点に関していくつか質問があります。

uint32_t別のバイトに保存されたビット7〜10を必要とするサンプルコードを想定してみましょう。

uint32_t v;
v = 18341;
char c = (v &(uint32_t) 0x3C0)>>6;

リトルエンディアンの場合、番号18341は2進数として0x47A5 または2進数で表されます。

0100 01 11 10 10 0101

上記のコードは、charに格納された1110を提供するはずです。

ここで問題となるのは、ビッグエンディアンマシンでこれをどのように達成するかということです。同じ数値は、まったく異なる0xA5470000方法で、または2進数で表されます。

10 10 0101 0100 01 11 0000 0000 0000 0000

私たちが求めているビットは、まったく異なる位置にあり、結果でさえありません。

0x3C0の反対側で使用する代わりに、バイト順序が異なるため、別のものを使用する必要があります。特に、バイトの結果ビットが必要なため、右下のような複数のブール値演算が必要になりますか?

char c = ((v&(uint32_t)0xc0)>>6) | ((v&(uint32_t)0x300)>>6)

まとめます。2進数で表される整数値のシーケンシャルビットを取得する必要がある場合、2つのエンディアンの場合に異なる操作を実行する必要があるというのは私の理解は正しいですか?

最後に、私が上に示したものと同じことを達成するためのより良い方法はありますか?多分私は完全に明白な何かを逃しています。

4

1 に答える 1

1

いいえ。値(0x300など)と言語演算子(<<、|、&)を使用している場合、値はマシンに応じて表されるため、問題ありません。したがって、あなたの場合、この問題について心配する必要はありません。たとえば、ファイルからメモリにバイトをコピーする場合は、心配する必要があります。

メモリ表現を直接処理している場合は、操作前に表現を変換できます。

#if defined (BENDIAN)
   val = makelittle(val);
#endif
   manip_lendian(val);
#if defined (BENDIAN)
   val = makebig(val);
#endif

この回答も参照してください

于 2012-07-11T07:16:21.750 に答える