Поскольку я чувствую, что это действительно необходимо, я просто хочу изложить некоторые правила C и C ++ (они одинаковы в этом отношении). Во-первых, все биты из unsigned char
участвуют в определении значения любого неподписанного объекта типа char. Во-вторых, unsigned char
явно указано без знака.
Теперь я поговорил с кем-то о том, что происходит, когда вы конвертируете значение -1
типа int в unsigned char
. Он отказался от идеи, что в результате unsigned char
все биты установлены в 1, потому что он беспокоился о представлении знака. Но он не должен. Из этого правила сразу следует, что преобразование выполняет то, что предназначено:
Если новый тип без знака, значение преобразуется путем многократного добавления или
вычитание больше, чем максимальное значение, которое может быть представлено в новом типе
пока значение не окажется в диапазоне нового типа. (6.3.1.3p2
в черновике C99)
Это математическое описание. С ++ описывает это в терминах исчисления по модулю, которое подчиняется тому же правилу. В любом случае, не гарантирует, что все биты в целом числе -1
равны единице перед преобразованием. Итак, что же у нас есть, чтобы мы могли утверждать, что в результате unsigned char
все его CHAR_BIT
биты установлены в 1?
- Все биты участвуют в определении его значения, то есть в объекте не возникает битов заполнения.
- Добавление только одного раза
UCHAR_MAX+1
к -1
приведет к значению в диапазоне, а именно: UCHAR_MAX
Этого достаточно, на самом деле! Поэтому, когда вы хотите, чтобы unsigned char
имел все биты один, вы делаете
unsigned char c = (unsigned char)-1;
Из этого также следует, что преобразование является , а не только усечением битов более высокого порядка. Удачным событием для дополнения до двух является то, что это просто усечение, но это не обязательно верно для других представлений знаков.