2010-09-12 2 views
4

Предположим, что у вас есть следующий код C.Требуется уточнение по побитовому оператору (~)

unsigned char a = 1; 

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

Я удивлен видеть -2 печататься в результате преобразования ~ 1:

Противоположностью 0000 0001 1111 1110. То есть ничего, кроме -2.

Что мне здесь не хватает?

+2

Запишите значение 0 и -1 в двоичном формате. –

+3

"1111 1110 -> ничего, кроме -2" Где вы это делаете? Это точно -2 в дополнении. – recursive

+0

try 'print ("% x ")' – pmg

ответ

10

Это дополнение к двум.

В представлении дополнений двух, если старший значащий бит числа x равен 1, тогда фактическое значение будет − (~ x + 1).

Например,

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

Это естественное представление отрицательных чисел, потому что

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

См http://en.wikipedia.org/wiki/Two%27s_complement для деталей.


BTV, чтобы напечатать значение без знака, использовать формат %hhu или %hhx. См. http://www.ideone.com/YafE3.

4

%d означает знак десятичного числа, не являющийся без знака. Таким образом, ваш бит-шаблон, даже если он хранится в неподписанной переменной, интерпретируется как подписанный номер.

См. Это Wikipedia entry on signed number representations для понимания значений бит. В частности, см. Two's complement.

+1

Но при вызове функции varargs 'unsigned char' чаще всего присваивается' int', чем 'unsigned int', поэтому'% d', вероятно, будет правильной спецификацией формата в этом случае. –

+1

Но 'unsigned char' продвигается до' int' до того, как происходит побитовое отрицание. После этого вам нужно будет вернуться к 'unsigned char', чтобы он работал по желанию. –

0

Один (слегка юмористический) способ думать о подписанных математиках состоит в том, чтобы признать, что самый значащий бит действительно представляет собой бесконечное количество бит над ним. Таким образом, в 16-разрядном подписанном числе наиболее значимый бит составляет 32768 + 65536 + 131072 + 262144 + ... и т. Д. которая равна 32768 * (1 + 2 + 4 + 8 + ...) Используя стандартную формулу для степенного ряда, (1 + X + X^2 + X^3 + ...) = 1/(1-X), обнаруживается, что (1 + 2 + 4 + 8 + ...) равно -1, поэтому сумма всех этих бит равна -32768.

Смежные вопросы