我有一个包含服务器响应的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];
答案 0 :(得分:3)
char
可能(或可能不会)签名,看起来就像是在您的平台上。这意味着在您或高位字节之前,0xa5符号扩展为0xffa5。
在进行位操作之前,尝试将每个字节转换为unsigned char
。
答案 1 :(得分:1)
raw[0]
是char
类型的对象,在您的平台上恰好是8位有符号整数类型。当您将0xA5
值填充到此类已签名的char
对象中时,它实际上会获取-91
的值。当raw[0]
用作|
运算符的操作数时,它将经历通常的算术转换。后者将其转换为int
类型的值,其值为-91
(0xFFA5
)。如果导致观察结果的原因,那么FF
位于较高字节中。