Операторы побитового сдвига. Подписанный и неподписанный
Я тренируюсь на экзамене 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; он не остается положительным. Причина, по которой они не мешают сделать "подписанный" сдвиг влево, состоит в том, что, если число сдвигается с положительного на отрицательное (или наоборот), вы все равно выходите за пределы переменной типа.