Индексация переменной без выхода за границы перечисления
int8_t state;
enum light_state {OFF, White, Red, Blue, Green, Pink, Color, Random};
// Событие может происходить до 100 000 раз.
//
// Flag выставлен, как сделать переменную, чтоб глубина
// (длина) была Enum?
//
// Или light_state использовать для контроля состояния:
//
// 0, __, __, __|> __, __, 7 — и дальше по кругу
//
// Как я понял из литературы, перечисление — это список указателей
// искомой длины на CONST INDEX[CONST МАСИВОВ[]].
//
// lite <= light_st можно ли light_st++ ??????????????????? 7>>++>>0
if (event)
state++;
Создавать переменную в 3-бит можно, но не всегда, если число 191. Битовую маску накладывать на каждой итерации и проверять переполнение.
Может, я что-то не знаю? Подскажите.
Type_def_типа enum{...} переменная State той же глубины.
Ответы (1 шт):
Есть несколько вариантов.
Один из них — как вы догадались сами — накладывать битовую маску с помощью побитового умножения при каждом инкременте, чтобы значение не выходило за заданный диапазон:
state = (state + 1) & 0x111;Такой вариант подойдет только если в перечислении 2N − 1 элементов†, зато это самый быстрый вариант — все выражение компилируется всего в 4 инструкции:
movzx eax, BYTE PTR state[rip] add eax, 1 and eax, 17 mov BYTE PTR state[rip], alИспользовать оператор взятия остатка от деления
%:state = (state + 1) % StatesCount;Если в перечислении 2N − 1 элементов, то компилятор оптимизирует так, что все это считается без деления обычным побитовым сдвигом:
movzx eax, BYTE PTR state[rip] movzx eax, al add eax, 1 cdq shr edx, 29 add eax, edx and eax, 7 sub eax, edx mov BYTE PTR state[rip], alИспользовать условие:
state = (state == StatesCount - 1) ? 0 : state + 1;Обычно, ветвление плохо сказывается на производительности, но как вариант можно сделать и так.
† Думаю, не стоит говорить что нумерация элементов перечисления должна начинаться с 0, а номер каждого следующего элемента должен быть на 1 больше предыдущего.