Почему побитовый оператор XOR C / C++ заботится о знаке? [дубликат]
На этот вопрос уже есть ответ здесь:
- неявные правила преобразования типов в операторах C++ 9 ответов
- Как работают правила продвижения, когда сигнатуры по обе стороны бинарного оператора различаются? [дубликат] 3 ответа
Я довольно долго боролся с некоторыми низкоуровневыми сообщениями, и это оказалось проблемой с вычислением контрольной суммы. Я думал, что побитовый оператор 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;    
}
Даже если оба целых числа содержат одни и те же биты, операция дает разные результаты в каждом случае.
1 ответ:
Прежде всего, вы должны помнить, что он определяется реализацией, если
charявляется подписанным или неподписанным.Тогда вы должны помнить, что значения меньших типов, таких как
Таким образом, еслиcharилиuint8_t, являются повышен в должности toint(или, возможно,unsigned int) при использовании в выражениях. Это продвижение приносит с собой расширение знака подписанных типов.charподписано, значение0b10010101будет повышено до0b11111111111111111111111110010101(используя дополнение two для отрицательных чисел). Который очень отличается от беззнакового значения0b00000000000000000000000010010101.