8
const unsigned char* p;
int64_t u = ...; // ??

pが指す8バイトから64ビットの2進数のリトルエンディアン整数を読み取るための推奨される方法は何ですか?x64では、単一のマシン命令で実行できますが、ビッグエンディアンのハードウェアスワップが必要です。これを最適かつ移植可能に行うにはどうすればよいですか?

カールのソリューションは優れており、十分にポータブルですが、最適ではありません。これは疑問を投げかけます:なぜC / C ++はこれを行うためのより良い標準化された方法を提供しないのですか?それは珍しい構成ではありません。

4

3 に答える 3

7

一般的に見られる:

u = (int64_t)(((uint64_t)p[0] <<  0)
  + ((uint64_t)p[1] <<  8)
  + ((uint64_t)p[2] << 16)
  + ((uint64_t)p[3] << 24)
  + ((uint64_t)p[4] << 32)
  + ((uint64_t)p[5] << 40)
  + ((uint64_t)p[6] << 48)
  + ((uint64_t)p[7] << 56));

持ち運びに便利な町で唯一のゲームです。それ以外の場合、潜在的な配置の問題を回避するのは困難です。

この回答は8ビットを想定していますchar。異なるサイズcharのをサポートする必要がある場合は、CHAR_BITをチェックし、それぞれに対して正しいことを行うプリプロセッサ定義が必要になります。

于 2013-02-21T17:54:07.083 に答える
4

Carl Norumは正しいです-読みやすくしたい場合は、ループを書くことができます(コンパイラはとにかくそれを展開します)。これは、8ビット以外のビットもうまく処理しcharます。

u = 0;
const int n = 64 / CHAR_BIT + !!(64 % CHAR_BIT);
for (int i = 0; i < n; i++) {
    u += (uint64_t)p[i] << (i * CHAR_BIT);
}
于 2013-02-21T17:56:55.727 に答える
0

次のコードを使用して、変数のバイト順序を逆にしました。異なる「エンディアン」を変換するために使用しました。

// Reverses the order of bytes in the specified data
void ReverseBytes(LPBYTE pData, int nSize)
{
    int i, j;

    for (i = 0, j = nSize - 1; i < j; i++, j--)
    {
        BYTE nTemp = pData[i];
        pData[i] = pData[j];
        pData[j] = nTemp;
    }
}
于 2013-02-21T18:01:47.450 に答える