Я думаю, вам лучше просто замаскировать кусочки негатива int
:
if ((-1 & 0x1) == 0) {
// -1 ends in "0" => 1s' complement
} else if ((-1 & 0x2) == 0) {
// -1 ends in "01" => sign-magnitude
} else {
// -1 ends in "11" => two's complement
}
Строго говоря, это не говорит о том же, что и ваш код, поскольку нет гарантии, что int
и signed char
используют одно и то же значение бита знака. Но (а) серьезно? и (b) это работает для типов int
и больше, для меньших типов это сложнее. unsigned char
гарантированно не имеет битов заполнения, а signed char
- нет. Поэтому я думаю, что законно иметь (например) CHAR_BIT == 9
, UCHAR_MAX = 511
, CHAR_MAX = 127
и signed char
с 1 битом заполнения. В этом случае ваш код может потерпеть неудачу: бит знака в сохраненном значении со знаком не обязательно там, где вы ожидаете, и значение бита заполнения может быть 0 или 1.
Во многих случаях вы можете просто использовать int8_t
в программе вместо signed char
. Это гарантированно будет дополнением 2, если оно существует, поэтому может избавить вас от заботы о представлении signed char
. Если он не существует, программа не будет компилироваться, что в любом случае является чем-то вроде того, что вы assert
. Вы получите ложный минус от платформ, которые являются дополнением 2, но не имеют 8-битного символа и, следовательно, не предоставляют int8_t
. Это может или не может беспокоить вас ...