这个问题在这里已有答案:
一段时间以来,我一直在努力处理一些低级别的消息,结果证明校验和计算存在问题。我认为按位XOR运算符不关心符号,所以我使用QByteArray
来存储字节,并使用at
方法返回char
来计算校验和。这些消息有时被正确承认,但并非总是如此。
看起来另一端的人正在使用uint8_t
来存储字节,并且校验和在某些情况下失败了。我通过将char
投射到uint8_t
解决了这个问题,但我对此感到非常困惑。
为什么按位XOR运算符关心符号?不管他们代表什么,我认为它在一定程度上有效。这是我用来试图理解它的一段代码。
#include <stdio.h>
#include <stdint.h>
#include <iostream>
#include <bitset>
int main ()
{
uint8_t a = 0b10010101;
char b = 0b10010101;
uint32_t checksum;
checksum = 55;
checksum ^= a;
std::cout << std::bitset<32>(checksum) << std::endl;
checksum = 55;
checksum ^= b;
std::cout << std::bitset<32>(checksum) << std::endl;
}
即使两个整数都保持相同的位,操作在每种情况下产生不同的结果。
首先,你必须记住,如果char
是有符号或无符号的,它是实现定义的。
然后你必须记住,当在表达式中使用时,char
或uint8_t
等较小类型的值是promoted到int
(或者可能是unsigned int
)。此促销带来签名类型的签名扩展。
因此,如果签署了char
,则值0b10010101
将被提升为0b11111111111111111111111110010101
(使用two's complement作为负数)。这与无符号值0b00000000000000000000000010010101
有很大不同。