Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, 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);
Но такой код уже сложнее воспринимается. Поэтому лучше оставить такое преобразование компилятору.