В чем разница между операторами >>>
и >>
в Java?
Разница между >>> и >>
Ответ 1
>>
арифметический сдвиг вправо, >>>
логический сдвиг вправо.
При арифметическом сдвиге знаковый бит расширяется, чтобы сохранить подпись числа.
Например: -2, представленный в 8 битах, будет 11111110
(потому что старший бит имеет отрицательный вес). Если сдвинуть его вправо на один бит с помощью арифметического сдвига, вы получите 11111111
или -1. Логическое смещение вправо, однако, не заботится о том, чтобы значение могло представлять число со знаком; он просто перемещает все вправо и заполняет слева нулями. Сдвиг нашего -2 вправо на один бит с использованием логического сдвига даст 01111111
.
Ответ 2
>>>
- беззнаковый сдвиг; он вставляет 0. >>
подписывается и расширяет бит знака.
JLS 15.19 Операторы сдвига
Операторы сдвига включают сдвиг влево
<<
, сдвиг вправо>>
и беззнаковый сдвиг вправо>>>
.Значение
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 к самому большому биту.
Связанные вопросы
- Правый переход для выполнения разделить на 2 на -1
- Является ли смещение бит быстрее, чем умножение и деление на Java?.NET?
- что такое эквивалентный способ c/С++ делать → > как в java (беззнаковый сдвиг вправо)
- Отрицательный логический сдвиг
- Javas → против → > Оператор?
- В чем разница между операторами Java → и → > ?
- Разница между операторами → > и " >
- Какова причина того, что языки высокого уровня, такие как С#/Java, маскируют операнд счетчика сдвига бит?
-
1 >>> 32 == 1
-
Ответ 3
Они оба сдвинуты вправо, но >>>
есть unsigned
В документации :
Беззнаковый оператор сдвига вправо " → > " сдвигает нуль в крайнее левое положение, а крайняя левая позиция после " → " зависит от расширения знака.
Ответ 4
>>>
всегда будет помещать 0 в самый левый бит, а >>
будет помещать 1 или 0 в зависимости от того, что это за знак.
Ответ 5
Логический сдвиг вправо (v >>> n
) возвращает значение, в котором биты в v
были сдвинуты вправо на позиции бит n
, а 0 сдвинуты с левой стороны. Рассмотрим сдвиг 8-битных значений, записанных в двоичном формате:
01111111 >>> 2 = 00011111
10000000 >>> 2 = 00100000
Если мы интерпретируем биты как неподписанное неотрицательное целое число, то логический сдвиг вправо влияет на деление числа на соответствующую мощность 2. Однако, если число находится в представлении с двумя дополнениями, логический сдвиг вправо неверен делить отрицательные числа. Например, второй правый сдвиг выше сдвигает 128 до 32, когда биты интерпретируются как беззнаковые числа. Но он сдвигает -128 до 32, когда, как это типично в Java, биты интерпретируются в двух дополнениях.
Поэтому, если вы смещаетесь, чтобы разделить на две силы, вам нужен арифметический сдвиг вправо (v >> n
). Он возвращает значение, в котором биты в v
были сдвинуты вправо на позиции бит n
, а копии самого левого бита v сдвинуты с левой стороны:
01111111 >> 2 = 00011111
10000000 >> 2 = 11100000
Когда биты представляют собой число в представлении с двумя дополнениями, арифметический сдвиг вправо имеет эффект деления на две. Это работает, потому что самый левый бит является битом знака. Разделение на две силы должно поддерживать знак.
Ответ 6
Подробнее о Побитовые и операторы сдвига бит
>> Signed right shift
>>> Unsigned right shift
Бит-шаблон задается левым операндом, а количество позиций сдвигается правым операндом. Беззнаковый оператор сдвига вправо >>>
сдвигает ноль в крайнее левое положение,
а крайнее левое положение после >>
зависит от расширения знака.
В простых словах >>>
всегда сдвигает ноль в крайнее левое положение, тогда как >>
сдвигается на основе знака числа i.e. 1 для отрицательного числа и 0 для положительного числа.
Например, попробуйте использовать как отрицательные, так и положительные числа.
int c = -153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.println(Integer.toBinaryString(c <<= 2));
System.out.println();
c = 153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
выход:
11111111111111111111111111011001
11111111111111111111111101100100
111111111111111111111111011001
11111111111111111111111101100100
100110
10011000
100110
10011000
Ответ 7
Логический оператор правой сдвига (>>> N
) сдвигает биты вправо на N позиций, отбрасывая знаковый бит и заполняя N самых левых бит с помощью 0. Например:
-1 (in 32-bit): 11111111111111111111111111111111
после выполнения операции >>> 1
:
2147483647: 01111111111111111111111111111111
Арифметический оператор правого сдвига (>> N
) также сдвигает биты вправо по N позициям, но сохраняет знаковый бит и накладывает N самых левых бит на 1. Например:
-2 (in 32-bit): 11111111111111111111111111111110
после операции >> 1
:
-1: 11111111111111111111111111111111