无符号移位和环将产生负值

unsigned int - shifting and oring creates negative value

本文关键字:无符号      更新时间:2023-10-16

当我从文件中读取原始字节时,我正在读取wav文件的头并使用<<(左移)和|(或)填充我的类成员。现在,巧合的是,我有以下情况
其中uBytesPerSecondunsigned类型,datachar*类型,所以我可以使用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应用程序

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

要解决这个问题,只需将data的类型更改为unsigned char*

Edit:如评论中所述,问题的另一种解决方案是显式地用0xFF: this->uBytesPerSecond |= data[0x1F] & 0xFF等掩码操作数。

为什么不使用联合而不是使用位或和移位呢?就像

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)