Оператор сдвига отрицательного числа вправо в C ++ - PullRequest
0 голосов
/ 26 января 2019

Я новичок в C ++ и нахожу что-то, чего не могу понять.Может ли кто-нибудь помочь?

Для следующих кодов:

int i = -3;
printf("i=%d\n",i);
i = i >> 1:
printf("i >> 1 evaluates to: %d\n", i);

тогда я получил результат:

i = -3 i >> 1 оценивается как: -2

Я не совсем понимаю.Поскольку 3 закодировано как (пусть будет просто):

3 : 0000 0011
-3 : 1111 1100

, то после операции сдвига вправо мы должны иметь:

-1 : 1111 1110

правильно?Почему я получил -2?(Мой компьютер в 64-разрядной версии)

Спасибо за любую помощь!

Ответы [ 2 ]

0 голосов
/ 26 января 2019

Ваша ошибка в предположении, что, поскольку 3 равно 00000011, -3 представляется просто инвертированием битов (так называемое представление отрицательного числа «одно дополнение») для получения 11111100. И это также 00000001 становится 11111110 при отрицании. На самом деле это не так - вместо этого ваш компьютер, похоже, использует почти универсальную систему «два дополнения» , в которой -3 представляется как 11111101, -2 - 11111110, а -1 - 11111111.

Один хороший интуитивный насос для системы с двумя дополнениями состоит в том, чтобы рассмотреть последовательность приращений и отметить, что поведение несколько непротиворечиво и интуитивно понятно, независимо от того, представляете ли вы их в самом битовом шаблоне, в подписанном представлении, или в неподписанном. Для простоты давайте придерживаться 8 бит (представьте, что «9-й бит» просто отбрасывается):

bit pattern           interpreted as...
               signed byte    unsigned byte
11111101            -3             253
11111110            -2             254
11111111            -1             255
00000000             0               0  (wrap-around)
00000001             1               1 

Когда он изменяется от -1 до 0, я почти "слышу", как все эти биты переворачиваются один за другим.

0 голосов
/ 26 января 2019

Фактически -1 = 0xFFFF = 1111 1111 1111 1111b, -3 = 0xFFFD = 1111 1111 1111 1101b (для 4 байтов int).

Таким образом, когда вы используете правое смещение, вы получаете 1111 1111 1111 1110b, что составляет -2

...