Почему побитовый оператор 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
.