Подтвердить что ты не робот

Java побитовый оператор <<

Может кто-нибудь объяснить, почему следующие побитовые выражения возвращают разные результаты:

System.out.println((-1<<31)<<1);   // it prints 0
System.out.println(-1<<32);        // it prints -1
4b9b3361

Ответ 1

-1<<32 эквивалентен -1<<0, т.е. нет-op. Причина в том, что расстояние сдвига (32) равно AND с помощью 0x1f и 32 & 0x1f равно 0.

Это определено в JLS # 15.19 (выделено мной):

Если продвинутым типом левого операнда является int, тогда только пять младших бит правого операнда используются как расстояние сдвига. Это как если бы правый операнд подвергался поразрядному логическому оператору И и (§15.22.1) с значением маски 0x1f (0b11111). Поэтому фактически используемое расстояние сдвига всегда находится в диапазоне от 0 до 31 включительно.

Ответ 2

Значение счетчика сдвига используется по модулю 32. Таким образом, второй пример фактически совпадает с сдвигом на 0.