Как настроить BitArray для установки определенных битов на основе значения?

Как мне использовать BitArray, чтобы сделать несколько вещей, таких как самые простые, установка значения в биты, а не просто биты! Я начинаю сожалеть, что когда-либо использовал эту хрень под названием BitArray.

Скажем, у меня есть такие биты.

public enum RULE
{
    NOTHING = 0x0,
    FIRST_STEP = 0x1,
    FOO_YOU = 0x2,
    BAR_FOO = 0x10,
    FOO = 0x20,
    BAR = 0x40,
    FOO_BAR = 0x80,
    READY = 0x100,
    ...//LOTS MORE BITS
    FINAL_FLAG_BIT= 0x10000000 //Final bit.. uses the 29th bit.
};

Теперь скажи, что я делаю это ..

//only use 29 bits to save memory, probably still uses 4 bytes lol.
BitArray rules= new BitArray(29);

//As you can see what I tried to do.
public bool ruleEnabled(RULE i)
{
    return rules[(int)i]; //<- this is impossible as it sets BITS not bitmasks.
}

public void setRule(RULE rule, bool b) {
    rules.Set((int)rule, b);
}

Поэтому я потратил около 30 минут на реализацию этого, не зная об одном из его многочисленных ограничений.. Вы знаете, что нет даже никакого способа привести его к его значению.. без использования CopyTo

В итоге я использовал только 1 переменную (кажется, это решение и чище, и быстрее), и мне пришлось изменить только 2 метода setRule и ruleEnabled, чтобы оно работало правильно.

private int rules; //uses only 29 of the 32 bits.
public bool ruleEnabled(RULE i)
{
    int bits = (int)i;
    return (rules & bits) == bits;
}

public void setRule(RULE rule, bool set) {
    if (set)
        rules |= (int)rule;
    else
        rules &= ~(int)rule;
}

У меня вопрос правильно ли я поступил? и почему BitArray когда-либо полезен? если у него так много ограничений.. вы можете выполнять все его операции, такие как AND OR NOT XOR, уже с & | ~ ^

Я предполагаю, что BitArray лучше всего использовать, когда вы имеете дело с большим количеством битов, чем может представить любой тип данных... для сжатия/шифрования и т.д..


person SSpoke    schedule 06.07.2011    source источник
comment
Похоже, теперь вы довольно хорошо понимаете.   -  person Ben Voigt    schedule 06.07.2011
comment
Мех, да, я полностью удалил BitArray после того, как опубликовал этот вопрос ... но я надеюсь, что это может помочь другим, которые ищут этот вопрос в Google и борются с BitArray, надеюсь, переключиться.   -  person SSpoke    schedule 06.07.2011


Ответы (1)


Доступ к BitArray осуществляется по индексу, а не по флагам. Например, для битового массива длиной 29 единственные возможные индексы находятся в диапазоне от 0 до 28. Таким образом, следующее неверно:

rules[RULE.READY] = true; // where READY is equal to 0x100, but the
                    // bit array's length is only 29.

Чтобы заставить его работать как задумано, вы должны сначала преобразовать флаг в индекс. Может помочь следующая функция:

public static int FlagToIndex(int flag){
   int i=0;
   if(flag==0)return i;
   while((flag&1)==0){
     flag>>=1;
     i++;
   }
   return i;
}

С помощью этой функции теперь вы можете правильно индексировать битовый массив:

rules[FlagToIndex((int)RULE.READY)] = true;

Надеюсь, это поможет.

person Peter O.    schedule 06.07.2011
comment
Это помогает, конечно, но там происходит много всего, даже петля, ха-ха. - person SSpoke; 06.07.2011