unsigned int - shift和oring产生负值

时间:2013-04-21 13:02:02

标签: c++ c bit-manipulation bit-shift

当我从文件中读取原始字节时,我正在阅读wav文件的标题并使用<<(左移)和|(或)填充我的班级成员。现在,恰巧我有以下情况
其中uBytesPerSecond的类型为unsigned,而data属于char*,因此我可以使用std::fstream::read

现在我在调试器中创建了uBytesPerSecond

this->uBytesPerSecond |= data[0x1F]; //0x00 ->uBytesPerSecond = 0x00000000
this->uBytesPerSecond <<= 8;         //     ->uBytesPerSecond = 0x00000000
this->uBytesPerSecond |= data[0x1E]; //0x02 ->uBytesPerSecond = 0x00000002
this->uBytesPerSecond <<= 8;         //     ->uBytesPerSecond = 0x00000200
this->uBytesPerSecond |= data[0x1D]; //0xb1 ->uBytesPerSecond = 0xffffffb1 !!!
this->uBytesPerSecond <<= 8;         //     ->uBytesPerSecond = 0xffffb100
this->uBytesPerSecond |= data[0x1C]; //0x10 ->uBytesPerSecond = 0xffffb110

此情况下的预期输出为uBytesPerSecond = 0x00002b110。请告诉我们这里有什么,以及如何解决这个问题。

我正在使用MSVC2012和Windows 8,这是一个VC++-Console - 应用程序。

2 个答案:

答案 0 :(得分:6)

问题是您的平台char是签名类型。因此,对于or-operation,包含的值将被符号扩展为32位,为0xffffffb1提供data[0x1D]

要解决该问题,只需将data的类型更改为unsigned char*即可。

编辑如评论中所述,该问题的另一个解决方案是使用0xFF this->uBytesPerSecond |= data[0x1F] & 0xFF明确屏蔽操作数​​,依此类推。

答案 1 :(得分:1)

为什么不使用联合而不是使用按位或移位?像

这样的东西
union ByteWord
{
    unsigned int word;
    char bytes[sizeof(unsigned int)];
}

然后你可以做

ByteWord data;
myStream.read(data.bytes, sizeof(unsigned int));
this->uBytesPerSecond = myStream.word;

如果需要进行字节交换,请使用ntohl(myStream.word)