Разъяснение необходимо для побитового оператора not (~) - PullRequest
4 голосов
/ 12 сентября 2010

Предположим, у вас есть следующий код C.

 unsigned char a = 1;

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

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

Противоположность 0000 0001 - 1111 1110. Это не что иное, как -2.

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

Ответы [ 3 ]

10 голосов
/ 12 сентября 2010

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

В представлении дополнения до двух, если старший значащий бит числа 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.


Кстати, для печати значения без знака используйте формат %hhu или %hhx. Смотри http://www.ideone.com/YafE3.

4 голосов
/ 12 сентября 2010

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

См. Эту запись в Википедии о представлении чисел со знаком для понимания значений бит. В частности см. Два дополнения .

0 голосов
/ 17 сентября 2010

Один (слегка шутливый) способ думать о математике со знаком - это признать, что самый значимый бит действительно представляет бесконечное число битов над ним.Таким образом, в 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.

...