как сохранить эксклюзивное ИЛИ логическое значение в виде битовой маски

Я работаю с интерфейсом, в котором большинство флагов неявно ложны, когда они не установлены, но некоторые параметры имеют явный флаг «x-not-set», так что любой флаг может быть передан, но никогда оба, а в некоторых случаях ни один из них не должен быть Я думаю, что основная логика заключается в том, что «x-not-set» не эквивалентен исключению «x-set» в сценариях, где x не должен быть включен по умолчанию.

Пример перестановки флагов параметров для параметров X, Z с флагами X, Z, no-Z:

<empty>
/X
/Z
/no-Z
/X /Z
/X /no-Z

Поэтому, если я буду рассматривать Z и no-Z как один бит на маске, это сделает пустую битовую маску и установит только no-Z и 00, но если я обработаю их как отдельные биты, то оба могут быть установлены следующим образом:

/Z /no-Z
/X /Z /no-Z

который не только может иметь непредсказуемый или фатальный ответ, но и в моем реальном сценарии, где может быть 5 простых (например, /X) параметров и 3 XOR (например, /Z, /no-Z или пустой), тестирование всех перестановок по сравнению с все действительные перестановки ( 2^11 против (2^8)+8 ) имеют значительно более высокую стоимость.

Есть ли способ, о котором я не думаю, чтобы установить биты так, чтобы некоторые из них были либо включены, либо выключены, а другие (из-за отсутствия лучших терминов) включены, выключены или NULL?

Быстрое запоздалое размышление:

Записав все это, самое простое решение, которое приходит на ум, — это определить константы, в которых установлены эти недопустимые комбинации, а затем XOR маскировать параметры против них, так что, если оба установлены, оба сбрасываются. Но я все еще не уверен, как сделать это элегантным способом, то есть каким-то способом «пометить», какие из битов являются битами XOR (если это имеет какой-либо смысл. Я только что ударил свою стену на этом уровне логики) .


person Anthony    schedule 21.11.2014    source источник


Ответы (1)


Вы можете закодировать три возможные конфигурации для Z следующим образом, используя два бита:

Z1  Z0
-------
 0   0      Z undefined (value for Z0 irrelevant)
 1   0      Z = No
 1   1      Z = Yes

Чтобы определить значение для Z, бит Z1 должен быть установлен через OR. Бит Z0 также можно установить с помощью OR или сбросить с помощью AND и инвертировать маску.

Пример с синтаксисом C:

 #define DEF_Z 2
 #define SET_Z 1

 flags = (flags | DEF_Z) | SET_Z;     //   /Z

 flags = (flags | DEF_Z) & ~ SET_Z    //   /no-Z
person Axel Kemper    schedule 29.12.2014