хранение отрицательных чисел - PullRequest
9 голосов
/ 29 марта 2011

В этом коде ниже

int main()
{
int  a = -1;
printf("%d",a>>1);
return 0;
}

Почему он выдает -1.

Ответы [ 6 ]

12 голосов
/ 29 марта 2011

сдвиг битов определяется только для типов без знака, для типов со знаком это определяется реализацией. И это полезное уточнение R ..

Строго говоря, он определен для подписанные типы всякий раз, когда значение положительный результат переполнение, и сдвиг вправо реализация определяется для отрицательного ценности. Сдвиг влево, с другой стороны, не определено для отрицательных значений

┌───┬──────────────┬──────────────────────────────────┬────────────────────────┐
│   │ Unsigned     │ Signed, positive                 │ Signed, negative       │
├───┼──────────────┼──────────────────────────────────┼────────────────────────┤
│<< │ well-defined │ well-defined, except on overflow │ undefined behaviour    │
│>> │ well-defined │ well-defined                     │ implementation-defined │
└───┴──────────────┴──────────────────────────────────┴────────────────────────┘
5 голосов
/ 29 марта 2011

Потому что -1 это 1111111 ... 111 в двоичном виде.a>>1 операция "расширит знак" бит знака, поэтому вы снова получите 1111111 ... 111.

1 голос
/ 29 марта 2011

Большинство компиляторов предпочитают интерпретировать >> для чисел со знаком как арифметическое смещение. Таким образом, поскольку число изначально отрицательное (т. Е. Бит MSB равен 1), после сдвига вправо этот бит заменяется другим 1, чтобы сохранить знак, поэтому в результате вы получите -1 при запуске.

0 голосов
/ 26 декабря 2013

В памяти целое число со знаком, хранящееся как дополнение 2, если знак int и когда данные читаются из памяти {% d}, они преобразуются в исходную форму, так что здесь дополнение 2 к -1 будет сохранено в памяти, скажем, целое число занимает 2 байта, так что 2's complement of -1 is 1111 1111 1111 1111

После выполнения a>>1 Это изменится 0111 1111 1111 1111 сейчас. Как мы знаем, когда данные считываются из памяти, они снова преобразуются в 0 дополнений, поэтому возьмите 2 дополнения 0111 1111 1111 1111 Это будет похоже на 1000 0000 0000 0001 что равно -1

Примечание: дополнение 2 к числу +ve такое же, как и к исходному двоичному представлению 2, дополнение только к -ve числу.В C число всегда сохраняется как форма дополнения до 2

0 голосов
/ 29 марта 2011

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

0 голосов
/ 29 марта 2011

Оператор >> для значения со знаком может выполнять арифметическое или логическое смещение в зависимости от компилятора.Арифметические сдвиги сохраняют знаковый бит, поэтому -1 (который на 2-секундной машине дополнения, который в наши дни является практически единственным вариантом, с которым вы столкнетесь) останется -1 при смещении вправо.(Обратите внимание, что стандарт C явно не указывает, является ли >> для числа со знаком арифметическим или логическим сдвигом. Однако это всегда логический сдвиг для чисел без знака.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...