Оператор >>
под номером Подписана правая смена, сдвиньте все биты вправо определенное количество раз. Важным является >>
заполняет крайний левый бит (наиболее значимый бит MSB) до самого левого разряда после смены. Это называется расширением знака и служит для сохранить знак отрицательных чисел, когда вы смещаете их вправо.
Ниже мое схематическое изображение с примера, чтобы показать, как это работает (для одного байта):
Пример:
i = -5 >> 3; shift bits right three time
Пять в форме дополнения до двух является представление 1111 1011
памяти:
MSB
+----+----+----+---+---+---+---+---+
| 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
+----+----+----+---+---+---+---+---+
7 6 5 4 3 2 1 0
^This seventh, the left most bit is SIGN bit
И ниже, как работает >>
? Когда вы -5 >> 3
this 3 bits are shifted
out and loss
MSB (___________)
+----+----+----+---+---+---+---+---+
| 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
+----+----+----+---+---+---+---+---+
| \ \
| ------------| ----------|
| | |
▼ ▼ ▼
+----+----+----+---+---+---+---+---+
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
+----+----+----+---+---+---+---+---+
(______________)
The sign is
propagated
Примечание: левые большинство три бита один, так как на сохраняется каждый сдвиг знаковый бит, и каждый бит прав тоже. Я написал Знак распространяется, потому что все эти три бита из-за знака (но не данных).
Также из-за трех правых сдвигов справа большинство трех бит являются потерями.
Биты между двумя правыми стрелками отображаются из предыдущих бит в -5
.
Я думаю, было бы хорошо, если бы я написал пример для положительного числа. Следующий пример 5 >> 3
и пять является один байт 0000 0101
this 3 bits are shifted
out and loss
MSB (___________)
+----+----+----+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
+----+----+----+---+---+---+---+---+
| \ \
| ------------| ----------|
| | |
▼ ▼ ▼
+----+----+----+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+----+----+----+---+---+---+---+---+
(______________)
The sign is
propagated
См я снова пишет знак распространяется, поэтому три левых нулей должны подписать немного.
Таким образом, это оператор >>
Подписана правая смена do, сохраняет знак левого операнда.
[ваш ответ]
В коде, вы сдвигаете -15
вправо для 31
раз, используя >>
оператора, чтобы ваш самой правого 31
бит засыпки и результатов всех биты 1
, что на самом деле -1
по величине.
Вы заметили, что таким образом -1 >> n
эквивалентно утверждению.
Я верю, что если один сделать i = -1 >> n
он должен быть оптимизирован для i = -1
с помощью Java-компиляторов, но это другое дело
Далее, было бы интересно узнать, в Java еще один оператор правого сдвига доступен >>>
называется Unsigned Правый сдвиг. И он работает логически и заполняет ноль слева для каждой операции переключения. Поэтому при каждой правой смене вы всегда получаете бит нуля в левой позиции слева, если используете беззнаковый сдвиг вправо >>>
для обоих отрицательных и положительных чисел.
Пример:
i = -5 >>> 3; Unsigned shift bits right three time
И ниже моя диаграмма, которая показывает, как выражение -5 >>> 3
работает?
this 3 bits are shifted
out and loss
MSB (___________)
+----+----+----+---+---+---+---+---+
| 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
+----+----+----+---+---+---+---+---+
| \ \
| ------------| ----------|
| | |
▼ ▼ ▼
+----+----+----+---+---+---+---+---+
| 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
+----+----+----+---+---+---+---+---+
(______________)
These zeros
are inserted
И вы можете заметить: на этот раз я не пишу, что знаковые биты распространяющихся, но на самом деле >>>
оператор вставки нулей. Следовательно, >>>
не сохраняет знак вместо логического сдвига вправо.
Насколько мне известно, сдвиг вправо без знака полезен в VDU (графическое программирование), хотя я его не использовал, но читал его где-то в прошлом.
Я предлагаю вам прочитать следующее: Difference between >>> and >>: >>
- это арифметический сдвиг вправо, >>>
- это логический сдвиг вправо.
Edit:
Некоторые интересные про сдвиг вправо без знака оператора >>>
оператора.
без знака оператор правого сдвига >>>
производит чистое значение, которое является его левый операнд справа сдвигается с нулевым расширением 0
по количеству битов, указанных правого операнда.
и <<
, оператор >>>
также оператор не исключает.
Тип каждого операнда без знакового оператора сдвига вправо должен быть целым типом данных или возникает ошибка времени компиляции.
Оператор >>>
может выполнять преобразования типов на своих операндах; в отличие от арифметических двоичных операторов, каждый операнд преобразуется независимо. Если тип операнда является байтом, коротким или символом, этот операнд преобразуется в int до вычисления значения оператора.
Тип значения, созданного беззнаковым оператором сдвига вправо, является типом его левого операнда.LEFT_OPERAND >>> RHIGT_OPERAND
Если преобразованный тип левого операнда INT, только пять младшие биты от значения правого операнда используются в качестве расстояния сдвига. (, что составляет 2 = 32 бит = количество бит в Int)
Таким образом, расстояние сдвига находится в диапазоне от 0 до 31.
Здесь значение получают r >>> s
такое же, как:
s==0 ? r : (r >> s) & ~(-1<<(32-s))
Если тип левого операнда имеет длину, то только шесть младших битов значения правого операнда используются в качестве расстояния сдвига. (, что составляет 2 = 64 бита = число бит в длинном)
Здесь значение получают r >>> s
такое же, как следующее:
s==0 ? r : (r >> s) & ~(-1<<(64-s))
интересный Ссылка: [Chapter 4] 4.7 Shift Operators
Кстати, вы можете использовать '>>> -1', и он будет работать для типов' int' и 'long'. –