Операции побитового сдвига. Подпись и неподпись - PullRequest
18 голосов
/ 11 февраля 2010

Я готовлюсь к экзамену SCJP, используя заметки из Интернета.

Согласно моим заметкам, оператор >> должен быть подписан вправо со смещением знака, вводимого слева. В то время как левый оператор сдвига << должен сохранять знаковый бит.

Однако, играя по-другому, я могу сместить знак с помощью оператора << (например, Integer.MAX_VALUE << 1 оценивается как -2, тогда как я никогда не смогу сместить знак с помощью оператора >>.

Должно быть, я что-то здесь неправильно понимаю, но что?

Ответы [ 2 ]

43 голосов
/ 11 февраля 2010

">>" подписано, потому что оно сохраняет знак. Он использует самую левую цифру в двоичном представлении числа в качестве заполнителя. Например:

    | this value is used as a filler 
    11011011 
 >> 11101101  

    01010010
 >> 00101001 

">>>" является неподписанной версией этого оператора. В качестве наполнителя всегда используется ноль:

    11011011 
>>> 01101101  

    01010010
>>> 00101001

В двоичном представлении самая левая цифра определяет знак числа. Итак, если это «1», то у нас отрицательное значение, а если «0», то наше число положительное Поэтому использование самой левой цифры в качестве заполнителя позволяет сохранить знак постоянным.

2 голосов
/ 28 апреля 2014

Идея, лежащая в основе сдвигов, заключается в том, что они могут действовать как умножение и деление на степени 2 (<< 1 эквивалентно * = 2, >> 2 эквивалентно / = 4), поэтому подписанная версия сдвиг существует. Смещение без знака не сохраняет негативы, но обязательно. Оператор << на самом деле не сохраняет знак, как вы предлагаете; это просто происходит в вашем примере. Попробуйте сделать сдвиг влево на 2 147 483 647; это не остается положительным. Причина, по которой они не стараются сделать «смещенный» левый сдвиг, заключается в том, что если число сдвигается с положительного на отрицательное (или наоборот), то вы все равно вышли за границы типа переменной. </p>

...