Сравнение битовых полей разных размеров

#c #bit-manipulation #low-level #bit-fields

#c #манипулирование битами #низкоуровневый #битовые поля

Вопрос:

Что произойдет, если вы используете побитовый оператор ( amp; , | и т.д.) Для сравнения двух битовых полей разных размеров?

Например, сравнивая 0 1 1 0 с 0 0 1 0 0 0 0 1 :

 0 1 1 0 0 0 0 0 The smaller one is extended with zeros and pushed to the
0 0 1 0 0 0 0 1 most-significant side.
  

Или…

 0 0 0 0 0 1 1 0 The smaller one is extended with zeros and pushed to the
0 0 1 0 0 0 0 1 least-significant side.
  

Или…

 0 1 1 0 The longer one is truncated from its least-significant side,
0 0 1 0 keeping its most significant side.
  

Или…

 0 1 1 0 The longer one is truncated from its most-significant side,
0 0 0 1 keeping its least-significant side.
  

Комментарии:

1. Я использовал C тег, потому что не был уверен, варьируется ли это от языка к языку.

Ответ №1:

Побитовые операторы всегда работают с расширенными операндами. Итак, что именно может произойти, может зависеть от того, подписано ли одно (или оба) битовых поля (поскольку это может привести к расширению знака).

Итак, для значений вашего примера битовое поле с двоичным значением 0 1 1 0 будет повышено до int 6 , а битовое поле с двоичным значением 0 0 1 0 0 0 0 1 будет повышено до int 33 , и это операнды, которые будут использоваться с любой операцией.

Комментарии:

1. Итак, оба операнда повышаются до типа, который может содержать наибольший из пары (возможно, со знаком), и тогда сравнение будет выполнено нормально? По сути, это означало бы, что меньшее поле расширяется нулями и перемещается в сторону наименьшего значения большего, правильно?

2. @Maxpm: Я думаю, вот к чему это сводится. Для меня проще всего просто думать о операторах, работающих с int (предполагая, что битовые поля достаточно малы), а не продумывать сдвиги, а что нет. Но разные люди понимают вещи по-разному…

Ответ №2:

0 0 0 0 0 0 1 1 0 Меньшее поле дополняется нулями и переносится на 0 0 1 0 0 0 0 0 1 сторону с наименьшим значением.

Ответ №3:

Если вы на самом деле используете значения в качестве битовых полей, в чем смысл сравнения битовых полей разных размеров? Даст ли это значимый результат для вас?

При этом оба операнда будут увеличены до минимального размера int / unsigned со знаком в зависимости от знака исходных операндов. Затем эти повышенные значения будут сравниваться с помощью побитового оператора.

Это похоже на ваш второй пример: меньшее поле дополнено нулями на стороне MSB (если вы предпочитаете, перенесено на сторону LSB).

Если один операнд является знаковым и отрицательным, в то время как другой беззнаковый, отрицательный будет преобразован в соответствующее число без знака перед выполнением битовой операции.

Если вместо целых чисел вы имеете в виду std::bitset , вы не можете выполнять побитовые операции с битовыми наборами разных размеров.