开发者

Clarification is needed on bitwise not (~) operator

Suppose you have the following C code.

 unsigned char a = 1;

 printf("%d\n", ~a); // prints -2
 printf("%d\n", a); // prints 1

I am surprised to see -2 printed as a result of ~1 conversion:

The opp开发者_StackOverflowosite of 0000 0001 is 1111 1110. That is anything but -2.

What am I missing here?


It is two's complement.

In two's complement representation, if a number x's most significant bit is 1, then the actual value would be −(~x + 1).

For instance,

0b11110000 = -(~0b1111 + 1) = -(15 + 1) = -16.

This is a natural representation of negative numbers, because

0000001 =  1
0000000 =  0
1111111 = -1  (wrap around)
1111110 = -2
1111101 = -3 etc.

See http://en.wikipedia.org/wiki/Two%27s_complement for detail.


BTW, to print an unsigned value, use the %hhu or %hhx format. See http://www.ideone.com/YafE3.


%d stands for signed decimal number, not unsigned. So your bit pattern, even though it is stored in an unsigned variable, is interpreted as a signed number.

See this Wikipedia entry on signed number representations for an understanding of the bit values. In particular see Two's complement.


One (mildly humorous) way to think of signed maths is to recognize that the most significant bit really represents an infinite number of bits above it. So in a 16-bit signed number, the most significant bit is 32768+65536+131072+262144+...etc. which is 32768*(1+2+4+8+...) Using the standard formula for a power series, (1+ X + X^2 + X^3 +...) = 1/(1-X), one discovers that (1+2+4+8+...) is -1, so the sum of all those bits is -32768.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜