、私は32ビットリトルエンディアンのプロセッサを使用していて、次の4バイトのバッファを宣言していると仮定します。32/64ビットでバイトを効率的にビットシフトしますか?簡単にするために
unsigned char buffer[] = { 0xab, 0xcd, 0xef, 0x46 };
のが私の目標は、バッファ内のビット単位の左シフトに各バイトであるとしましょう4ビット分。つまり、バッファ値を { 0xbc, 0xde, 0xf4, 0x60 }
に変換したいとします。これは動作しますが、私はむしろ私のプロセッサのネイティブ32ビットレジスタを使用して、同時にすべての4つのバイトをシフトしたい
for (int i = 0; i < 3; ++i)
{
buffer[i] <<= 4;
buffer[i] |= (buffer[i + 1] >> 4);
}
buffer[3] <<= 4;
::のように、このような変換を実行するためには、コードを書くかもしれません
unsigned char buffer[] = { 0xab, 0xcd, 0xef, 0x46 };
unsigned int *p = (unsigned int*)buffer; // unsigned int is 32 bit on my platform
*p <<= 4;
ザ・上のスニペットは正常にシフトを実行しますが、私が探している方法ではありません。 unsigned intにバッファをキャストしているので、レジスタは0x46efcdab
(0xabcdef46
ではなく)の値(リトルエンディアン)でロードされているようです。したがって、左ビットシフトを4ビット実行すると、0xbcdef460
の代わりに0xb0dafc6e
になります。
シフト(たとえばhtonl
など)の前にバイトをスワップする以外に、効率的にバイトをシフトさせる方法がありますか?
あなたの洞察を前もってありがとうございます。
@ user3386109、はいそれはx86です – digitale
私はnneonneoの答えに同意します。コンパイラは 'htonl'を単一の命令として(適切な最適化レベルで)実装します。最小値は何か分かりませんが、 '-O3'は間違いなく動作します。 – user3386109
C言語が提供するfixed型を使用した場合、プラットフォーム上に 'unsigned'がどのくらい広まっているか、さまざまな仮定をすることができます。' stdint.h'を参照してください。そして、データをシリアライズしたい場合は、キャストではなく適切なビットシフト/マスキングを使用してください。 – Olaf