I think you better just mask the bit of the negative 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 complement }
Strictly speaking, this does not tell you the same thing as your code, since there is no guarantee that int and signed char use the same sign bit value. But (a) seriously? and (b) it works for int types and more, for smaller types it is more complicated. unsigned char guaranteed to have no fill bits, but signed char not. Therefore, I consider it legal to have (for example) CHAR_BIT == 9 , UCHAR_MAX = 511 , CHAR_MAX = 127 , and signed char - 1 bit of filling. Then your code may fail: the sign bit in the stored value with the sign is not necessarily where you expect it to be, and the fill bit value can be either 0 or 1.
In many cases, you can simply use int8_t in the program instead of a signed char . It is guaranteed to be 2 extras if it exists, so it can save you from worrying about the signed char representation. If it does not exist, the program will not compile, but it is the same as assert . You will get a false negative result from platforms that are 2 add-ons but do not have an 8-bit char and therefore do not provide int8_t . It may or may not bother you ...
source share