【问题标题】:reading binary from a file gives negative number从文件中读取二进制文件给出负数
【发布时间】:2014-03-06 16:43:46
【问题描述】:

大家好,这可能是一个简单的愚蠢问题,但现在已经让我头疼了一段时间。我正在从命名二进制标记文件中读取数据,并且代码正常工作,除非我尝试读取大端数字。获取整数的代码如下所示:

long NBTTypes::getInteger(istream &in, int num_bytes, bool isBigEndian)
{
    long result = 0;
    char buff[8];

    //get bytes
    readData(in, buff, num_bytes, isBigEndian);

    //convert to integer
    cout <<"Converting bytes to integer..." << endl;
    result = buff[0];
    cout <<"Result starts at " << result << endl;
    for(int i = 1; i < num_bytes; ++i)
    {
        result = (result << 8) | buff[i];
        cout <<"Result is now " << result << endl;
    }
    cout <<"Done." << endl;

    return result;
}

还有readData函数:

void NBTTypes::readData(istream &in, char *buffer, unsigned long num_bytes, bool BE)
{
    char hold;

    //get data
    in.read(buffer, num_bytes);

    if(BE)
    {
        //convert to little-endian
        cout <<"Converting to a little-endian number..." << endl;
        for(unsigned long i = 0; i < num_bytes / 2; ++i)
        {
            hold = buffer[i];
            buffer[i] = buffer[num_bytes - i - 1];
            buffer[num_bytes - i - 1] = hold;
        }
        cout <<"Done." << endl;
    }
}

此代码最初有效(给出了正确的正值),但现在无论出于何种原因,我得到的值要么上溢,要么下溢。我错过了什么?

【问题讨论】:

  • 您期望的数字是多少?有没有可能这个数字太大而无法表示?试试 unsigned long 代替。
  • 向我们展示readData的输入和输出示例,包括isBigEndian的设置。
  • 感谢 cmets。我期望的数字是 128,但我得到的是 -128。二进制输入是 big endian short (128)。返回的字节表明我应该得到正确的答案

标签: c++ bit-manipulation long-integer binaryfiles endianness


【解决方案1】:

您的字节顺序交换很好,但是从字节序列构建整数不是。

首先,你弄错了字节序:你读入的第一个字节成为最重要的字节,而它应该是相反的。

然后,当OR-ing 来自数组的字符时,请注意它们被提升为int,对于带符号的char,它会设置很多额外的位,除非您将它们屏蔽掉.

最后,当longnum_bytes 宽时,你需要sign-extend 位。

此代码有效:

union {
    long s;           // Signed result
    unsigned long u;  // Use unsigned for safe bit-shifting
} result;

int i = num_bytes-1;
if (buff[i] & 0x80)
    result.s = -1; // sign-extend
else
    result.s = 0;
for (; i >= 0; --i)
    result.u = (result.u << 8) | (0xff & buff[i]);
return result.s;

【讨论】:

  • 我很欣赏这个答案。我从没想过符号扩展或屏蔽!我现在离 Minecraft 编程的努力又近了一步 :)
猜你喜欢
  • 2018-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 2018-08-24
  • 2015-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多