Ответ 1
>>>
логический сдвиг, >>
арифметический сдвиг.
У меня нет моего справочника по Java, и мне сложно найти ответ с Google.
В чем разница между операторами " → " и " → > " в Java?
int value = 0x0100;
int result = (value >> 8);
System.out.println("(value >> 8) = " + result); // Prints: "(value >> 8) = 1"
result = (value >>> 8);
System.out.println("(value >>> 8) = " + result); // Prints: "(value >>> 8) = 1"
>>>
логический сдвиг, >>
арифметический сдвиг.
Подписанные целые числа используют старший бит для обозначения знака.
So >>
сохраняет знак, а >>>
- нет. Вот почему >>
называется арифметическим сдвигом, а >>>
является логическим сдвигом.
Таким образом, вы можете сделать (предполагая 32-битные целые числа) следующее:
-10 >> 1
дает -5 (0xFFFFFFF6 >> 1
дает 0xFFFFFFFB - обратите внимание, что бит старшего разряда остается тем же.)-10 >>> 1
дает 2147483643 (0xFFFFFFF6 >>> 1
дает 0x7FFFFFFB - уведомление о том, что все биты были сдвинуты, поэтому бит старшего порядка теперь равен нулю. Число больше не отрицательно в соответствии с арифметикой twos-комплемента.)Для положительных целых чисел >>
и >>>
действуют одинаково, так как бит высокого порядка уже равен нулю.
Это также объясняет, почему нет необходимости в операторе <<<
. Поскольку знак будет разбит, сдвинув биты влево, он не будет отображаться без разумной арифметической операции.
От Заметки Java: Побитовые операторы:
n → p (правый сдвиг) Сдвигает бит n правильных позиций p. Если n является номером с номером в 2 дополнения, знаковый бит сдвигается в позиции высокого порядка.
Пример: 5 → 2 = 1
n → > p (правый сдвиг) Сдвигает бит n правильных позиций p. Нули сдвинуты в позиции высокого порядка.
Пример: -4 → > 28 = 15
Правильный ответ был отправлен несколько раз, но не из авторитетного источника.
Это из JLS §15.19 Операторы сдвига:
Операторы сдвига включают в себя сдвиг влево
<<
, сдвиг вправо>>
и сдвиг вправо без знака>>>
; они синтаксически лево-ассоциативные (они группируются слева направо). Левым операндом оператора сдвига является сдвинутое значение; правый операнд указывает расстояние сдвига....
Значение
n>>s
- этоn
смещенные вправоs
битовые позиции с расширением знака. Результирующее значение равно: n/2 s & rfloor;. Для неотрицательных значенийn
это эквивалентно усечению целочисленного деления, которое вычисляется оператором целочисленного деления/
, на два с мощностьюs
.Значение
n>>>s
- этоn
смещенные вправо позицииs
с нулевым расширением. Еслиn
положительно, то результат будет таким же, как результатn>>s
; еслиn
отрицательно, результат равен выражению(n>>s)+(2<<~s)
, если тип левого операндаint
и результат выражения(n>>s)+(2L<<~s)
, если тип левого символа - ручной операндlong
. Добавленный термин(2<<~s)
или(2L<<~s)
отменяет распространенный знаковый бит. (Заметим, что из-за неявного маскирования правого операнда оператора сдвига~s
как расстояние сдвига эквивалентно31-s
при смещении значенияint
и63-s
при смещении along
значение.)
Для положительных чисел разницы нет. Отрицательные (два дополнения) числа будут заполнены нулями для → > и единиц для → .
1010 0110 → > 2 = 0010 1001
1010 0110 → 2 = 1110 1001
→ - это арифметический сдвиг, который сохраняет знаковый бит в любых "свободных" битах. Другой - логический сдвиг, который заполняет свободные пятна нулями.
some информация
оператор → сохраняет самые левые биты. Самые левые биты заполняются предыдущим контентом. Это связано с расширением знака. В этом случае есть 1 слева, и он сохраняется. Если вы не хотите оставить 1 слева, используйте оператор → > , который сдвигает 0 в самые левые бит
Он имеет отношение к значению математического значения. Таблетки >>>
в нулях для битов верхнего порядка, >>
сохраняет знаковый бит и втягивает его.
Арифметический сдвиг → является делением на два для целых чисел со знаком, тогда как логический сдвиг → > является делением на два для неподписанных чисел (если вы интерпретируете шаблон бита в подписанном Java int как целое без знака).