读二进制整数

时间:2013-02-21 17:47:44

标签: c++ c++11

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

从p指向的8个字节读取64位二进制小端整数的推荐方法是什么? 在x64上,单个机器指令应该这样做,但是在大端硬件上需要交换。 如何以最佳和便携的方式做到这一点?

Carl的解决方案很好,足够便携但不是最佳的。这引出了一个问题:为什么C / C ++没有提供更好和标准化的方法来做到这一点?这不是一个不常见的结构。

3 个答案:

答案 0 :(得分: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并为每个定义做正确的事。

答案 1 :(得分:4)

Carl Norum是对的 - 如果你想要也是可读的,你可以写一个循环(编译器无论如何都要展开它)。这也很好地处理非8位char s。

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);
}

答案 2 :(得分:0)

我使用以下代码来反转任何变量的字节顺序。我用它来转换不同的“Endianess”。

// 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;
    }
}