Один из способов думать о побитовых операциях «и» и «или» - это как способы установки (включения) и сброса (выключения) бит в вашем результате.
Вы считаете одним операндом как свою «маску» - те и нули, которые представляют собой то, что нужно установить или сбросить. Другой операнд будет «замаскирован» этой «маской». В следующем порядке:
Если оператор &
, то каждый бит в «маске», который равен нулю, будет равен нулю в результате. Каждый бит, равный 1, будет иметь значение из другого операнда.
Так например, result = x & 0b11111111_11111111_11111111_11110111
(это большое количество - наша маска, и я показываю его в двоичном виде) будет иметь все биты такие же, как x
, за исключением четвертого бита справа, который будет 0 , независимо от того, является ли оно 0 или 1 в x
.
Таким образом, &
с «маской» считается операцией «бит-сброс» или «обнулением».
Для оператора |
(или) вы можете рассматривать его как операцию «бит-набора». Каждый бит в маске, который равен 1, будет 1 в результате. Каждый бит, равный 0, будет иметь все, что находится в другом операнде. Таким образом, в результате все биты, которые были 1 в маске, будут установлены.
Например, result = x | 0b1000
будет иметь все биты, которые были в x, за исключением четвертого бита справа, который будет равен 1, независимо от того, что он был в x.
Написание масок в двоичном формате является длинным и является довольно недавней вещью в Java, поэтому вы, скорее всего, увидите маски, написанные в шестнадцатеричном формате. В этом случае 0xfffffff7
для примера &
и 0x8
для примера |
.
Теперь давайте посмотрим на ваш выражение с «маской» точки зрения:
dst<<1
означает переход dst
на 1. Все его биты сдвигаются на одну позицию влево, а крайний правый бит установлен нуль. По сути, это «создание комнаты» для чего-то в самом правом бите.
- В правой скобке оператор сдвига имеет приоритет, поэтому сначала оценивается.
src
перемещается srcPos
позиции справа. Итак, бит, который был srcPos+1
мест справа, теперь самый правый бит.
- Теперь мы «маскируем», что с
0x01
. То есть, 0b00000000_00000000_00000000_00000001
. Это маска &
, поэтому все, что не является самым правым битом, будет равным нулю. Сохраняется только самый правый бит. Конечным результатом является то, что это бит, который был в srcPos+1
месте в src
, и только, что бит - все остатки сбрасываются.
- И теперь мы «маскируем» это с помощью
dst<<1
вещей, которые мы подготовили. Поскольку это операция |
, это «настройка» маски. Наша маска имеет только один значительный бит - тот, который мы не стирали в операции &
. И он находится на самом правом месте. Если это 1, в результате будет 1, а если оно равно 0, то результат будет равен 0 (потому что левый операнд имеет нулевое значение в этой позиции).
Поэтому в основном то, что он делает:
- Сместите биты в
dst
слева.
- Поместите бит из
srcPos
+ 1 место справа в крайнем правом углу.
Если значения в table
все уникальные позиции между 0 и srcWidth
, то это даст вам скремблирования из битов src
- в каждом раунде один бит будет выталкиваться в dst
на основе стоимости table[i]
.
Это не определение переменной. И '|' - это [побитовое включение или оператор] (https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html). Что вы хотите знать, когда спрашиваете «как это работает»? –
Перемещает 'dst' влево 1 бит, а затем выполняет поразрядное или с' src'. Рассмотрим каждую операцию слева направо. –
@ AndyTurner вы можете дать краткое объяснение строки, которую я специально указал на то, как это работает? – user2475511