Сбор битов в битовую маску по набору bool-переменных
От: theven Россия  
Дата: 15.11.12 06:38
Оценка:
Имеется набор bool переменных и значения битов (1,2,4,8...), требуется собрать их в маску, поэлегантнее, пооптимальнее..
Ничего лучше чем через умножение я не придумал:

    typedef unsigned short MaskType;

    // содержат различные значения степени 2
    const MaskType bit1value = ...;
    const MaskType bit2value = ...;

    // содержат какие биты включать
    bool bit1Enable;
    bool bit2Enable;

    // умножение?
    MaskType flags = bit1value * bit1Enable + bit2value * bit2Enable;
Re: Сбор битов в битовую маску по набору bool-переменных
От: _typhoon  
Дата: 15.11.12 10:36
Оценка:
Здравствуйте, theven, Вы писали:
T>
T>    typedef unsigned short MaskType;

T>    // содержат различные значения степени 2
T>    const MaskType bit1value = ...;
T>    const MaskType bit2value = ...;

T>    // содержат какие биты включать
T>    bool bit1Enable;
T>    bool bit2Enable;

T>    // умножение?
T>    MaskType flags = bit1value * bit1Enable + bit2value * bit2Enable;
T>

Мне кажется умножения в выражениях все же более ресурсоемко чем сравнение да и сложение лучше заменить битовым или, кроме того данная запись не будет выглядеть читабильной скажем если запаковать нужно в 64-х битную переменную
Re[2]: Сбор битов в битовую маску по набору bool-переменных
От: watch-maker  
Дата: 15.11.12 11:17
Оценка:
Здравствуйте, _typhoon, Вы писали:

_>Мне кажется умножения в выражениях все же более ресурсоемко чем сравнение

Ну, компиляторы ещё в прошлом веке научились использовать побитовый сдвиг вместо умножения на степень двойки.

Хотя, конечно, запись с побитовыми операциями может оказаться более читаемой, ибо своим видом сразу покажет, что идёт работа с битами:
flags = (bit1value << bit1position) | (bit2value << bit2position).
Re: Сбор битов в битовую маску по набору bool-переменных
От: Буравчик Россия  
Дата: 15.11.12 19:28
Оценка: +1
Здравствуйте, theven, Вы писали:

T>Имеется набор bool переменных и значения битов (1,2,4,8...), требуется собрать их в маску, поэлегантнее, пооптимальнее..

T>Ничего лучше чем через умножение я не придумал:


Может, пусть компилятор сам разбирается, как ему лучше?

union mask
{
  struct
  {
    bool bit0: 1;
    bool bit1: 1;
    bool bit2: 1;
    ...
  } bits;
  MaskType mask;
};


mask m;
m.bits.bit1 = bit1Enable;
m.bits.bit2 = bit2Enable;
// using m.mask here
... << RSDN@Home (RF) 1.2.0 alpha 5 rev. 17>>
Best regards, Буравчик
Re: Сбор битов в битовую маску по набору bool-переменных
От: VladFein США  
Дата: 15.11.12 19:50
Оценка:
Здравствуйте, theven, Вы писали:

T>Имеется набор bool переменных и значения битов (1,2,4,8...), требуется собрать их в маску, поэлегантнее, пооптимальнее..

T>Ничего лучше чем через умножение я не придумал...

А нужны ли эти bool переменные?
Re[2]: Сбор битов в битовую маску по набору bool-переменных
От: Аноним  
Дата: 15.11.12 23:04
Оценка:
Здравствуйте, VladFein, Вы писали:
VF>А нужны ли эти bool переменные?

Это результаты других проверок.
Re[3]: Сбор битов в битовую маску по набору bool-переменных
От: Аноним  
Дата: 15.11.12 23:09
Оценка:
Здравствуйте, watch-maker, Вы писали:

WM>Здравствуйте, _typhoon, Вы писали:


_>>Мне кажется умножения в выражениях все же более ресурсоемко чем сравнение

WM>Ну, компиляторы ещё в прошлом веке научились использовать побитовый сдвиг вместо умножения на степень двойки.

WM>Хотя, конечно, запись с побитовыми операциями может оказаться более читаемой, ибо своим видом сразу покажет, что идёт работа с битами:

WM>
WM>flags = (bit1value << bit1position) | (bit2value << bit2position).
WM>


В этом и суть вопроса, я не могу использовать тут побитовый сдвиг, потому что нет положения бита, есть только само значение. Конечно можно огород сделать с вычислением положения, а потом снова значение из него получать, но в этом и суть вопроса
Re[2]: Сбор битов в битовую маску по набору bool-переменных
От: theven Россия  
Дата: 15.11.12 23:13
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Здравствуйте, theven, Вы писали:


T>>Имеется набор bool переменных и значения битов (1,2,4,8...), требуется собрать их в маску, поэлегантнее, пооптимальнее..

T>>Ничего лучше чем через умножение я не придумал:


Б>Может, пусть компилятор сам разбирается, как ему лучше?


Б>
Б>union mask
Б>{
Б>  struct
Б>  {
Б>    bool bit0: 1;
Б>    bool bit1: 1;
Б>    bool bit2: 1;
Б>    ...
Б>  } bits;
Б>  MaskType mask;
Б>};


Б>mask m;
Б>m.bits.bit1 = bit1Enable;
Б>m.bits.bit2 = bit2Enable;
Б>// using m.mask here

Б>


Я не знаю положения каждого бита, у меня есть только их значения в маске.
Re[2]: Сбор битов в битовую маску по набору bool-переменных
От: theven Россия  
Дата: 15.11.12 23:15
Оценка:
Здравствуйте, _typhoon, Вы писали:

_>Здравствуйте, theven, Вы писали:

T>>
T>>    typedef unsigned short MaskType;

T>>    // содержат различные значения степени 2
T>>    const MaskType bit1value = ...;
T>>    const MaskType bit2value = ...;

T>>    // содержат какие биты включать
T>>    bool bit1Enable;
T>>    bool bit2Enable;

T>>    // умножение?
T>>    MaskType flags = bit1value * bit1Enable + bit2value * bit2Enable;
T>>

_>Мне кажется умножения в выражениях все же более ресурсоемко чем сравнение да и сложение лучше заменить битовым или, кроме того данная запись не будет выглядеть читабильной скажем если запаковать нужно в 64-х битную переменную

Даже если и более ресурсоемкое, в отличие от сравнения, умножение не срывает конвейер процессора.
Re[4]: Сбор битов в битовую маску по набору bool-переменных
От: watch-maker  
Дата: 16.11.12 10:23
Оценка: 3 (1)
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, watch-maker, Вы писали:


WM>>Здравствуйте, _typhoon, Вы писали:


_>>>Мне кажется умножения в выражениях все же более ресурсоемко чем сравнение

WM>>Ну, компиляторы ещё в прошлом веке научились использовать побитовый сдвиг вместо умножения на степень двойки.

WM>>Хотя, конечно, запись с побитовыми операциями может оказаться более читаемой, ибо своим видом сразу покажет, что идёт работа с битами:

WM>>
WM>>flags = (bit1value << bit1position) | (bit2value << bit2position).
WM>>


А>В этом и суть вопроса, я не могу использовать тут побитовый сдвиг, потому что нет положения бита, есть только само значение. Конечно можно огород сделать с вычислением положения, а потом снова значение из него получать, но в этом и суть вопроса


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

Если сомневаешься в возможностях компилятора оптимизировать умножения, то можешь явно расписать условия:
flags = (bit1Enable ? bit1value : 0) | (bit2Enable ? bit2value : 0);
Такой тернарный оператор обычно не порождает ветвлений, а реализуется либо через одну инструкцию conditional-move, либо через размножение младшего бита флага, соответственно, в таком случае нет ни сравнений, ни ветвлений, ни умножений, есть только тривиальная битовая логика.
Можно, конечно, и вручную биты размножать:
flags = (-bit1Enable & bit1value) | (-bit2Enable & bit2value);
Но такой код уже сложнее воспринимается. Поэтому лучше оставить такое преобразование компилятору.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.