Следуя моему предыдущему вопросу , мне нужно создать значение, состоящее из сплошного диапазона битов, установленного в 1. Я использовал следующую функцию:
void MaskAddRange(UINT& mask, UINT first, UINT count)
{
mask |= ((1 << count) - 1) << first;
}
Однако, как выяснилось, он не работал правильно для count = 32
. Результатом 1 << count
в таком случае теоретически является неопределенное поведение (или результат), а практически на x86 - 1, поскольку операнд сдвига обрабатывается по модулю 32.
Я хочу исправить это выражение для корректной работы и в этом крайнем случае. Какой самый простой / красивый / эффективный способ сделать это?
Работа с этим конкретным случаем с помощью ветвления (if
, ?
) довольно проста, хотя и уродлива, и, держу пари, она также неэффективна.
Другой способ - повысить операнд сдвига до большего типа (64 бита). Я имею в виду следующее:
void MaskAddRange(UINT& mask, UINT first, UINT count)
{
mask |= (UINT(unsigned __int64(1) << count) - 1) << first;
}
Есть ли лучший способ?