Как отключить некоторые биты, игнорируя при этом другие, используя только побитовые операторы - PullRequest
17 голосов
/ 23 января 2012

Я искал это, но мои результаты были неудовлетворительными, вероятно, из-за того, как трудно это сказать.У меня есть один объект, state, который представляет собой byte, который представляет, какие части моего объекта должны отображаться при наблюдении, и метод, disableParts(byte partsToDisable), который отключит все биты в state, которые включеныв partsToDisable. Как мне добиться этой функциональности в побитовых операциях? (то есть, используя только AND, OR, XOR, NOT, LSHIFT, ARSHIFT, LRSHIFT,PLUS, MINUS, MULTIPLY и / или DIVIDE и базовые программные функции, такие как циклы и операторы ветвления)

Для ясности, вот визуальное представление моей желаемой функциональности:

  0010 0101 (current state, 37 in this example)
? 1010 0010 (bits to disable, -94 in this example)
============
  0000 0101 (new state, 5 in this example)

и фиктивный класс (на Java, потому что я так думаю, но решением может быть любой язык или псевдокод):

class BitThoughts
{
  byte state;

  public void doIt()
  {
    state = 0b00100101;
    System.out.println("Initial state: " + state);

    disableParts(0b10100010);

    if (state == 0b00000101)
      System.out.println("Success! New state is " + state);
    else
      System.out.println("Failure! New state is " + state);
  }

  public void disableParts(byte partsToDisable)
  {
    //Do magic to state
  }
}

Ответ


Точно так же, как никто не дергается так сильно, как я ... вот ответ:

   0010 0101 (current state, 37 in this example)
& ~1010 0010 (bits to disable, -94 in this example)
=============

becomes:

   0010 0101 (current state: 37)
&  0101 1101 (inverted bits to disable: 93)
=============
   0000 0101 (new state, 5 in this example)

и решение на Java:

public void disableParts(byte partsToDisable)
{
  state &= ~partsToDisable;
}

Ответы [ 2 ]

30 голосов
/ 23 января 2012

Что вам нужно сделать, это инвертировать биты (по битам НЕ) в partsToDisable, так что вы получите маску, в которой 1 - это биты, которые нужно оставить в покое, а 0 - это биты, которые нужно отключить.Тогда И эта маска со значением состояния.

public void disableParts( byte partsToDisable)
{
    state = state & (~partsToDisable);
}
1 голос
/ 23 января 2012

Если вы просто инвертируете биты частей, вы можете просто И это с состоянием

 void disableParts(byte parts) {
     byte invertOfParts = 0b11111111 - parts;
     state &= invertOfParts
 }
...