Вычисление и обнаружение битов флага - PullRequest
5 голосов
/ 25 апреля 2010

В некотором коде, над которым я работаю, я должен позаботиться о десяти независимых параметрах, которые могут принимать одно из двух значений (0 или 1). Это создает 2 ^ 10 различных условий. Некоторые из условий никогда не возникают и могут быть опущены, но те, которые возникают, по-прежнему ОЧЕНЬ МНОГО, и создание switch для обработки всех случаев является безумным.

Я хочу использовать 10 if операторов вместо огромных switch. Для этого я знаю, что я должен использовать биты флага, или, точнее, байты флага, поскольку язык является javascript, и с ним проще работать с 10-байтовой строкой для представления 10-битного двоичного файла.

Теперь моя проблема в том, что я не знаю, как это реализовать. Я видел, как это использовалось в API s, где варианты с множественным выбором выставляются с номерами 1, 2, 4, 8, ..., n ^ (n-1), которые являются десятичными эквивалентами 1, 10, 100, 1000 и т. д. в двоичном формате. Поэтому, если мы сделаем вызов наподобие bar = foo(7), bar будет объектом с любыми опциями, которые активируют три крайних правых флага.

Я могу преобразовать десятичное число в двоичное, и в каждом операторе if проверять, установлена ​​ли соответствующая цифра или нет. Но мне интересно, есть ли способ определить, что n-th цифра десятичного числа равна нулю или единице в двоичной форме, без , фактически выполняющего преобразование?

Ответы [ 3 ]

6 голосов
/ 25 апреля 2010

Просто используйте поразрядно-и. В C / C ++ это будет:

if (flags & 1) {
    // Bit zero is set.
}
if (flags & 2) {
    // Bit one is set.
}
if (flags & 4) {
    // Bit two is set.
}
...

Для совершенства производства используйте символические имена для масок флагов вместо магических чисел 1, 2, 4, 8 и т. Д.

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

for (int f = 0; f < 10; ++f) {
    if (flags & (1 << f)) {
        // Bit f is set.
    }
}
2 голосов
/ 25 апреля 2010

Вы можете использовать поразрядно и:

10 & 2^1 is true because 10 = 1010b 
                                ^ 1
 8 & 2^1 is false because 8 = 1000b 
                                ^ 0
10 & 2^3 is true because 10 = 1010b 
                              ^ 1
1 голос
/ 25 апреля 2010

Вы можете получить число, для которого установлен n-й бит, и AND с вашим номером. Если результат равен нулю, ваш номер не имеет установленного бита. В противном случае это сделал. Смотрите здесь , также.

...