C ++ операция левого сдвига - PullRequest
       42

C ++ операция левого сдвига

0 голосов
/ 01 апреля 2019

Вот мой код

int a=2147483647; 
int b= a<<1;
cout<<"a="<<a<<",  b="<<b;

Вывод, который я получаю: a = 214783647, b = -2

Двоичное представление a равно

0111 1111 1111 1111 1111 1111 1111 1111

Сдвигая его на 1 бит, он изменит бит знака и заменит LSB на 0. Итак, я думаю, что ответ будет -ve и величина будут вычтены на 1, т.е. -2147483646, но это даст результат как -2.Пожалуйста, объясните.

Ответы [ 3 ]

2 голосов
/ 01 апреля 2019

[expr.shift] / 1 Значение E1 << E2 равно E1 со смещением влево E2 битовые позиции;освобожденные биты заполнены нулями.... если E1 имеет тип со знаком и неотрицательное значение, а E1 × 2^E2 представимо в соответствующем типе без знака типа результата, то это значение, преобразованное в тип результата, является результирующим значением;в противном случае, поведение не определено .

Подчеркните мое.Ваша программа демонстрирует неопределенное поведение.


Редактировать: При ближайшем рассмотрении я больше не думаю, что это неопределенное поведение.2147483647*2 вписывается в unsigned int, «соответствующий тип без знака» int.Его преобразование в int не является неопределенным, а просто определяется реализацией.Для реализации, использующей дополнение к двум, вполне разумно определить это преобразование так, чтобы 2147483647*2 == -2, просто переосмыслив битовую комбинацию, как объяснили другие ответы.

2 голосов
/ 01 апреля 2019

Это потому, что ваш компьютер использует 2 дополнения для подписанного значения.Смещенное значение без знака равно 0xFFFFFFFE, то есть -2 в 2 дополнении, а не -2147483647.

Сдвиг - это реализация, определенная в C.

Кстати, -2147483647 - 0x80000001 вкл.такой процессор.

1 голос
/ 01 апреля 2019

Ну, за этим очень длинная история.

Поскольку тип int является типом со знаком, это означает, что первый бит является знаком, а вся система состоит из двух компонентов.

, поэтому x = 0b 1111 1111 1111 1111 1111 1111 1111 0111 равен x = -9 и, например, x = 0b 1111 1111 1111 1111 1111 1111 1111 1111 равен x = -1, а x = 0b 0000 0000 0000 0000 0000 0000 0000 0010 равен 2

Подробнее о Два дополнения .

...