Подтвердить что ты не робот

Создание целого из трех значений bool как битов в С++

У меня есть три значения bool, которые представляют биты. Я хочу иметь целое число в форме

true true true = 7
false true false = 2

У меня

int val = 4*boolVal1 + 2*boolVal2 + boolVal3;

Есть ли другой способ, может быть, еще проще?

4b9b3361

Ответ 1

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

int val = (boolVal1 << 2) | (boolVal2 << 1) | boolVal3; 

Ответ 2

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

int val = (((boolVal1 << 1) | boolVal2) << 1) | boolVal3.

Это также упрощает добавление или удаление переменных из середины инструкции без необходимости изменения всех остальных коэффициентов.

Однако это может быть немного менее очевидно для читателя.

Ответ 3

Помимо умножения и битрейта, вы также можете использовать перечисление для документирования отношений. Обычно это не стоит усилий, а просто для полноты...

enum Encoding
{ 
    Flag3 = 1,      NotFlag3 = 0,
    Flag2 = 1 << 1, NotFlag2 = 0,
    Flag1 = 1 << 2, NotFlag1 = 0
};

int val = (boolVal1 ? Flag1 : NotFlag1) |
          (boolVal2 ? Flag2 : NotFlag2) |
          (boolVal3 ? Flag3 : NotFlag3);

Почему бы вам побеспокоить это? Это немного более общее, так что вы можете потенциально изменить значения кодирования позже, не касаясь потенциально распределенного кода с использованием фактических значений (например, если вы поняли, что упустили немного по сравнению с форматом какого-либо файла или сети данных, которые вам нужно проанализировать, вы можете добавить их только в одном месте и перекомпилировать). Конечно, лучше всего обеспечить единую функцию кодирования/декодирования в любом случае, и если вы добавляете новые флаги, вам все равно понадобится.

Хотя Flag1 и NotFlag1 могут показаться бессмысленными, часто случается, что у вас есть что-то вроде взаимоисключающих значений, таких как Sticky и Floating, или Male and Female, и нет особых причин заставить клиентов проверять, скажем, Floating as! Sticky или Female as! Male и т.д.

Ответ 4

Если вы знаете конечную точку, вы также можете использовать поведение, определенное реализацией, и биты, версию little-endian:

union foo {
        unsigned int the_int;
        struct {
                unsigned int bit3:1
                unsigned int bit2:1
                unsigned int bit1:1
        };
};

а затем установите их:

foo.bit1 = true;
foo.bit2 = false;
foo.bit3 = true;

и читать:

foo.the_int;

В варианте с биг-эндиантами бит меняется на противоположное, и большая часть отступов (29 бит, если unsigned int шириной 32 бита) впереди.