使用位移来缩短2个字符会产生一个奇怪的结果,值很大

时间:2014-07-07 20:47:30

标签: c++ char bit-shift short

我有一个包含服务器响应的std :: string。在解析了一下字符串之后,我遇到了一个简短的问题。 short是big-endian并相应地存储在字符串中:

raw[0] == 0xa5;
raw[1] == 0x69;

我知道这是

file << raw[0] << std::endl << raw[1];

作为十六进制结果显示为“0xa5 0x0a 0x69”。

我将它们写成这样的短片然后写入受https://stackoverflow.com/a/300837/1318909启发的文件:

short x = (raw[1] << 8) | raw[0];
file << std::to_string(x);

预期结果? 27045(0x69a5)。

实际结果? -91(0xffa5)&lt; - 溢出!。

这是为什么?我进行了测试,它的工作正常,值为2402.我还做了一些额外的测试,并且可以使用

short x = (raw[1] << 8) | 0xa5;

但不是

short x = (0x69 << 8) | raw[0];

2 个答案:

答案 0 :(得分:3)

char可能(或可能不会)签名,看起来就像是在您的平台上。这意味着在您或高位字节之前,0xa5符号扩展为0xffa5。

在进行位操作之前,尝试将每个字节转换为unsigned char

答案 1 :(得分:1)

raw[0]char类型的对象,在您的平台上恰好是8位有符号整数类型。当您将0xA5值填充到此类已签名的char对象中时,它实际上会获取-91的值。当raw[0]用作|运算符的操作数时,它将经历通常的算术转换。后者将其转换为int类型的值,其值为-910xFFA5)。如果导致观察结果的原因,那么FF位于较高字节中。