Дополнительно
Каково назначение оператора беззнакового сдвига вправо ">>>" в Java?
Я понимаю, что делает оператор беззнакового сдвига вправо ">>>" в Java, но зачем он нам нужен и почему нам не нужен соответствующий оператор беззнакового сдвига влево?
28
6
Оператор
>>>
позволяет рассматриватьint
иlong
как 32- и 64-битные беззназнаковые интегральные типы, которые отсутствуют в языке Java.Это полезно, когда вы смещаете что-то, что не представляет собой числовое значение. Например, вы можете представить черно-белое изображение битовой карты с помощью 32-битных
int
, где каждыйint
кодирует 32 пикселя на экране. Если вам нужно прокрутить изображение вправо, вы предпочтете, чтобы биты слева отint
стали нулями, чтобы вы могли легко поместить биты из соседнихint
:`>>> и в безопасный и эффективный способ нахождения округлые имею в виду двух (больших) целых чисел:
Если чисел
высокий
инизкий
близко к крупнейшей машина число, тем выше будут правильными, номожно получить неверный результат из-за переполнения.
Здесь'ы пример использования, исправление ошибки в наивный двоичный поиск.
В основном это связано со знаковыми (числовые сдвиги) или беззнаковыми сдвигами (обычно связанные с пикселями).
Поскольку сдвиг влево не имеет дела с битом знака, это одно и то же ( Как вы только что видели, оператор >> автоматически заполняет
Дополнительное чтение:
http://henkelmann.eu/2011/02/01/java_the_unsigned_right_shift_operator
http://www.java-samples.com/showtutorial.php?tutorialid=60
Подписанный оператор сдвига вправо полезно, если есть
инт
, который представляет номер и хочет разделить его на два, округление в сторону минус бесконечности. Это может быть приятно, когда делаешь такие вещи, как масштабирование координаты отображения; это не только быстрее, чем деление, но координаты которых отличаются на коэффициент масштабирования до масштабирования будет отличаться на один пиксель позже. Если вместо того, чтобы использовать сменную использует деление, что выиграл'т работу. При масштабировании с коэффициентом два, например, -1 и +1 отличаются на две, и таким образом должны опосля отличаться по отдельности, а -1/2=0 и 1/2=0. Если вместо этого используется подпись сдвига вправо, все получается хорошо: -1>>1=1 и 1>>1=0, правильно уступая значений одного пикселя отдельно.Беззнаковый оператор полезен в случаях, когда входные ожидается ровно один бит и один результат сделать то же самое, или в тех случаях, когда одна будет через цикл, чтобы вывести все биты в слове и хочет его расторгнуть чисто. Например:
Если код был подписанный правой смену и принял отрицательное значение, это выход 1'ы на неопределенный срок. С unsigned-оператор сдвига вправо, однако, наиболее существенная часть заканчивается интерпретируется просто как и любой другой.
Беззнаковый сдвиг вправо оператор может также оказаться полезной при расчете бы, арифметически, дают положительное число от 0 до 4 294 967 295 и хочет разделить это число на степень двойки. Например, при вычислении суммы двух
инт
ценности, которые, как известно, будет положительным, можно использовать(П1+П2)>>>1
без содействия операнды "долго". Также, если кто-то хочет разделить положительные типаint
значение что-то вроде Пи без использования операций с плавающей точкой, можно вычислить((значение*5468522205L) >>> 34)
[(1л<<34)/Пи 5468522204.61, которые сгоняют дает 5468522205]. На выплату дивидендов за 1686629712, расчет стоимости*5468522205L бы дать на "негативный" и значение, но, поскольку арифметически-правильное значение считается позитивным, используя беззнаковый сдвиг вправо позволит правильное положительное число, чтобы быть использованы.При обычном сдвиге вправо
>>
отрицательного числа оно останется отрицательным. То есть бит знака будет сохранен.При беззнаковом сдвиге вправо
>>>
бит знака тоже сдвигается, заменяясь нулевым битом.Эквивалентный сдвиг влево не нужен, потому что существует только один бит знака, и он является крайним левым битом, поэтому мешает только при сдвиге вправо.
По сути, разница в том, что один сохраняет знаковый бит, а другой заменяет его нулями.
Для положительных чисел они действуют одинаково.
Пример использования и
>>
, и>>>
приведен в BigInteger shiftRight.В Java наиболее типичные применения домена, чтобы избежать переполнения заключается в использовании литья или большое число, например, int в Long и в предыдущих примерах.