簡體   English   中英

無符號整數-移位和運算產生負值

[英]unsigned int - shifting and oring creates negative value

我正在讀取wav文件的標題,並使用<< (左移)和|填充類成員| (或)當我從文件讀取原始字節時。 現在,碰巧我有以下情況
其中uBytesPerSecond的類型為unsigneddata的類型為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 MSVC2012 VC++-Console

問題在於,對於您的平台, char是帶符號的類型。 因此,對於“或”運算,包含的值將被符號擴展為32位,從而為data[0x1D]提供0xffffffb1

要解決該問題,只需將data類型更改為unsigned char*

編輯:如評論中所述,該問題的另一種解決方案是顯式屏蔽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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM