2015-04-04 2 views
0
private static long permute(byte[] table, int srcWidth, long src) { 
    long dst = 0; 
    for (int i=0; i<table.length; i++) { 
     int srcPos = srcWidth - table[i]; 
     dst = (dst<<1) | (src>>srcPos & 0x01); 
    } 
    return dst; 
} 

здесь ДСТ = (ДСТ < < 1) | (src >> srcPos & 0x01); как это работает?? я принимаю | является оператором OR?Как вы определяете переменную с оператором ИЛИ в Java

+1

Это не определение переменной. И '|' - это [побитовое включение или оператор] (https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html). Что вы хотите знать, когда спрашиваете «как это работает»? –

+2

Перемещает 'dst' влево 1 бит, а затем выполняет поразрядное или с' src'. Рассмотрим каждую операцию слева направо. –

+0

@ AndyTurner вы можете дать краткое объяснение строки, которую я специально указал на то, как это работает? – user2475511

ответ

1

| является побитовое ИЛИ не логическое ИЛИ

Поразрядное ИЛИ действует на каждый бит в том, что длинные индивидуально. Это изменяет его значение, которое не совпадает с его определением.

Ломая эту линию:

dst = (dst<<1) | (src>>srcPos & 0x01); 

dst<<1 // means left shift 1 place. The same as multiply by 2. Zeros lowest bit. 

src>>srcPos // means right shift srcPos places. The same as divide by 2 to the srcPos 
      // this puts the selected bit in the lowest place 

& 0x01 // means set every bit to zero except the rightmost one which will stay the same 

(src>>srcPos & 0x01) // means give me the value of the src bit at srcPos 

(dst<<1) | (src>>srcPos & 0x01); // means shift dst left and put a src bit at the end 

Здесь побитовое ИЛИ работает как это добавление немного. Это работает только потому, что биты, которые не будут использоваться, были тщательно обнулены с каждой стороны.

По мере того как петля обходит table контролирует, какой бит к образцу от src, и все, что он выбирает, добавляется в правый конец dst. Таким образом, table управляет тем, как src перестановочен.

3

Один из способов думать о побитовых операциях «и» и «или» - это как способы установки (включения) и сброса (выключения) бит в вашем результате.

Вы считаете одним операндом как свою «маску» - те и нули, которые представляют собой то, что нужно установить или сбросить. Другой операнд будет «замаскирован» этой «маской». В следующем порядке:

Если оператор &, то каждый бит в «маске», который равен нулю, будет равен нулю в результате. Каждый бит, равный 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].

1

«|» - это двоичный оператор OR, который копирует бит, если он существует в любом из операндов. в качестве примера:

A|B 

даст 61, который является 0011 1101.

"||" называется логическим ИЛИ оператором. Если какой-либо из двух операндов отличен от нуля, то условие становится истинным. в качестве примера:

(A || B) является истинным.

Смежные вопросы