web-dev-qa-db-ja.com

ビットごとの演算子と「エンディアン」

endianness はビット単位の演算ではまったく重要ですか? 論理 またはシフトのどちらか?

私はビットワイズ演算子に関して宿題に取り組んでいます、そしてそれで頭と尾を作ることができません、そして私はエンディアネスにかなり夢中になっていると思います。つまり、私はリトルエンディアンマシンを使用しています(ほとんどのマシンと同様)が、これを考慮する必要がありますか、それとも無駄な事実ですか?

必要に応じて、Cを使用しています。

65
Frank V

エンディアンは、メモリ内のデータのレイアウトにのみ重要です。操作対象のプロセッサによってデータがロードされるとすぐに、エンディアンは完全に無関係になります。シフト、ビット単位の演算などは、エンディアンに関係なく、期待どおりに実行されます(データは論理的に下位ビットから上位に配置されます)。

68
Michael

ビット演算子はエンディアンを抽象化します。たとえば、>>演算子は常にビットを最下位桁にシフトします。ただし、これは、それらを使用するときにエンディアンを完全に無視しても安全であるという意味ではありません。たとえば、より大きな構造で個々のバイトを処理する場合、それらが同じ場所にあるとは限りません。

short temp = 0x1234;
temp = temp >> 8;

// on little endian, c will be 0x12, on big endian, it will be 0x0
char c=((char*)&temp)[0];

明確にするために、私はここでの他の答えと基本的に意見の相違はありません。ビットワイズ演算子は本質的にエンディアンニュートラルですが、特に他の演算子と組み合わせると、コードのエンディアンの影響を無視できないことを強調します。

61

他の人が述べたように、シフトはC言語の仕様で定義され、エンディアンとは無関係ですが、アーキテクチャが1の補数または2の補数演算を使用する場合は、右シフトの実装が異なる場合があります。

5
rpetrich

場合によります。数値を新しい型にキャストしなくても、エンディアンを透過的に処理できます。

ただし、操作に新しい型キャストが含まれる場合は、注意してください。

たとえば、一部のビットを右シフトして新しいタイプに(明示的に、または明示的に)キャストする場合、エンディアンが重要です!

エンディアンをテストするには、intcharにキャストするだけです。

int i = 1;

char *ptr;

...

ptr = (char *) &i;  //Cast it here

return  (*ptr);
3
Rongkai Xu

言語を指定していませんが、通常、Cなどのプログラミング言語はビット単位の演算でエンディアンを抽象化します。したがって、ビット単位の操作では問題になりません。

1
Mehrdad Afshari