>>>
- сдвиг без знака; он вставит 0. >>
подписан и расширит знаковый бит.
Операторы сдвига включают сдвиг влево
<<
, сдвиг вправо со знаком>>
и сдвиг вправо без знака>>>
.Значение
n >> s
равноn
сдвинутых вправоs
позиций битов с расширением знака .Значение
n >>> s
равноn
сдвинутых вправоs
позиций битов с нулевым расширением .
System.out.println(Integer.toBinaryString(-1));
// prints "11111111111111111111111111111111"
System.out.println(Integer.toBinaryString(-1 >> 16));
// prints "11111111111111111111111111111111"
System.out.println(Integer.toBinaryString(-1 >>> 16));
// prints "1111111111111111"
Чтобы прояснить ситуацию, добавление положительного аналога
System.out.println(Integer.toBinaryString(121));
// prints "1111001"
System.out.println(Integer.toBinaryString(121 >> 1));
// prints "111100"
System.out.println(Integer.toBinaryString(121 >>> 1));
// prints "111100"
Поскольку он положителен, сдвиги со знаком и без знака добавят 0 к самому левому биту.
1 >>> 32 == 1
>>
- это арифметический сдвиг вправо, >>>
- логический сдвиг вправо.
При арифметическом сдвиге знаковый бит расширяется, чтобы сохранить знаковость числа.
Например: -2, представленное в 8 битах, будет 11111110
(поскольку старший бит имеет отрицательный вес). Если сдвинуть его на один бит вправо с помощью арифметического сдвига, то получится 11111111
, или -1. Логический сдвиг вправо, однако, не заботится о том, что значение может представлять собой знаковое число; он просто сдвигает все вправо и заполняет слева 0. Сдвиг нашего -2 на один бит вправо с помощью логического сдвига даст 01111111
.
>>>
всегда помещает 0 в крайний левый бит, а >>
помещает 1 или 0 в зависимости от его знака.
Они оба сдвига вправо, но >>>
равно unsigned
Оператор сдвига вправо без знака ">>> "сдвигает ноль в крайнее левое положение, а крайнее левое положение после" >> "зависит от расширения знака.