Похоже, что ваша реализация, вероятно, выполняет арифметический сдвиг битов с двумя числами дополнения. В этой системе он сдвигает все биты вправо, а затем заполняет верхние биты копией того, что было последним битом. Итак, для вашего примера, трактуя int как 32-битный здесь:
nPosVal = 00000000000000001111111111111111
nNegVal = 11111111111111110000000000000001
После смены у вас есть:
nPosVal = 00000000000000000111111111111111
nNegVal = 11111111111111111000000000000000
Если вы преобразуете это обратно в десятичное число, вы получите 32767 и -32768 соответственно.
По сути, сдвиг вправо округляет в сторону отрицательной бесконечности.
Редактировать: В соответствии с разделом 6.5.7 последнего проекта стандарта , это поведение для отрицательных чисел зависит от реализации:
Результат E1 >> E2 равен E1 сдвинутые вправо битовые позиции E2. Если E1 имеет тип без знака или если E1 имеет тип со знаком и неотрицательное значение, значение результата является неотъемлемой частью отношения E1 / 2 E2 . Если E1 имеет тип со знаком и отрицательное значение, результирующее значение определяется реализацией.
Они заявили рационально для этого:
Комитет C89 подтвердил свободу в реализации, предоставленную K & R, в том, что она не требует подписанной операции сдвига вправо для подписи расширения, поскольку такое требование может замедлить быстрый код и поскольку полезность знака расширенных сдвигов является предельной. (Перенос отрицательного дополнения до двух
целое арифметически правильное одно место - , а не - это то же самое, что деление на два!)
Так что это зависит от реализации в теории. На практике я никогда не видел, чтобы реализация , а не выполняла арифметическое смещение вправо, когда левый операнд подписан.