EgoRusMarch
@EgoRusMarch
C++ Developer

Почему в битовых сдвигах остаётся минус?

Вот такой код:
int a=-7;
a<<=1;
a>>=1; 
printf("%d\n",a);

Двоичное представление -7 (если я правильно понял знак хранится в первом бите):
10000111

Если сделать сдвиг влево, то должно получится:
00001110

Затем сдвиг вправо:
00000111

Что в двоичном представлении равно 7. Но у меня как было -7, так и осталось.
  • Вопрос задан
  • 557 просмотров
Решения вопроса 4
@Alexander1705
если я правильно понял знак хранится в первом бите

Неправильно, отрицательные числа представлены с помощью дополнительного кода.

P. S. Это не для того, чтоб расширить диапазон возможных значений.
Дополнительный код позволяет заменить операцию вычитания на операцию сложения и сделать операции сложения и вычитания одинаковыми для знаковых и беззнаковых чисел, чем упрощает архитектуру ЭВМ.
Ответ написан
@Free_ze
Пишу комментарии в комментарии, а не в ответы
В интернете пишут, что сохранение знака при сдвиге влево зависит от компилятора.
источник:
В данном случае при первом сдвиге всё работает, как и задумано, потому что число без знака. Во втором случае компилятор VSE2013 оставляет знак.


При этом на MSDN пишут про VS2015 и C++:
Сдвиг влево является логическим сдвигом (биты, сдвигаемые с конца отбрасываются, включая бит знака)
Ответ написан
Комментировать
@Mercury13
Программист на «си с крестами» и не только
1. Двоичное представление −7 будет немного другое: 256−7 = 249 = 1111.1001
2. В знаковом типе используется т.н. арифметический сдвиг вправо: на освободившееся место приходит не 0, а копия верхнего бита (простой и арифметический сдвиг влево идентичны). Возьми вместо −7 что-нибудь начинающееся на 10 в двоичной системе — например, 0x8000.FFFF — и объясни, что выходит.
Ответ написан
Комментировать
@abcd0x00
По стандарту C89 (и до C11), при сдвиге вправо знакового отрицательного числа результат зависит от реализации.


3.3.7 Bitwise shift operators

...

The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1
has an unsigned type or if E1 has a signed type and a nonnegative
value, the value of the result is the integral part of the quotient of
E1 divided by the quantity, 2 raised to the power E2 . If E1 has a
signed type and a negative value, the resulting value is
implementation-defined.


То есть отрицательные числа вообще нельзя свдигать вправо, так как результат непредсказуем.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@wrench10x12
Двоичное представление -7 вообще-то 11111001 * **
*если не принимать во внимание экзотические архитектуры
**если полагать, что int, внезапно, стал однобайтовым
Ответ написан
Foolleren
@Foolleren
Компас есть, копать не люблю...
существует 4 вида сдвигов, загляните в отладчик, и посмотрите что на самом деле запихал туда компилятор.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы