Операторы побитового сдвига. Подписанный и неподписанный

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

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

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

Я должен что-то не понимать, но что?

Ответы

Ответ 1

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

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

    01010010
 >> 00101001 

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

    11011011 
>>> 01101101  

    01010010
>>> 00101001

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

Ответ 2

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