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...
Пока на собственное сообщение не было ответов, его можно удалить.