Поддерживает ли ANSI C битовые поля со знаком или без знака? - PullRequest
13 голосов
/ 29 сентября 2008

Имеет ли смысл квалифицировать битовые поля как подписанные / беззнаковые?

Ответы [ 10 ]

14 голосов
/ 29 сентября 2008

Соответствующей частью стандарта (ISO / IEC 9899: 1999) является 6.7.2.1 # 4:

Битовое поле должно иметь тип, который является квалифицированным или неквалифицированным версия _Bool, подписанный int, unsigned int или какой-либо другой, определенный реализацией типа.

8 голосов
/ 29 сентября 2008

Да. Пример из здесь :

struct {
  /* field 4 bits wide */
  unsigned field1 :4;
  /*
   * unnamed 3 bit field
   * unnamed fields allow for padding
   */
  unsigned        :3;
  /*
   * one-bit field
   * can only be 0 or -1 in two's complement!
   */
  signed field2   :1;
  /* align next field on a storage unit */
  unsigned        :0;
  unsigned field3 :6;
}full_of_fields;

Только вы знаете, имеет ли это смысл в ваших проектах; как правило, это делается для полей с более чем одним битом, если поле может быть значительным отрицательным.

7 голосов
/ 28 октября 2008

Очень важно квалифицировать ваши переменные как подписанные или неподписанные. Компилятор должен знать, как обрабатывать переменные во время сравнений и приведения. Проверьте вывод этого кода:

#include <stdio.h>

typedef struct
{
    signed s : 1;
    unsigned u : 1;
} BitStruct;

int main(void)
{
    BitStruct x;

    x.s = 1;
    x.u = 1;

    printf("s: %d \t u: %d\r\n", x.s, x.u);
    printf("s>0: %d \t u>0: %d\r\n", x.s > 0, x.u > 0);

    return 0;
}

Выход:

s: -1    u: 1
s>0: 0   u>0: 1

Компилятор сохраняет переменную, используя один бит, 1 или 0. Для знаковых переменных старший значащий бит определяет знак (старший считается отрицательным). Таким образом, переменная со знаком, хотя она хранится как 1 в двоичном виде, интерпретируется как отрицательная.

В этом разделе двухбитное число без знака имеет диапазон от 0 до 3, а двухбитное число со знаком имеет диапазон от -2 до 1.

2 голосов
/ 04 января 2011

Скорее всего, ANSI-C предусматривает битовые поля со знаком и без знака. Требуется. Это также является частью написания наложений отладчика для типов с плавающей запятой IEEE-754 [[1] [5] [10]], [[1] [8] [23]] и [[1] [10] [53] ]. Это полезно при машинном или сетевом преобразовании таких данных или проверке преобразований с двойным (64 бита для математики) на половинную точность (16 бит для сжатия) перед отправкой по ссылке, как текстуры видеокарты.

// Fields need to be reordered based on machine/compiler endian orientation

typedef union _DebugFloat {
   float f;
   unsigned long u;
   struct _Fields {
        signed   s :  1;
        unsigned e :  8;
        unsigned m : 23;
      } fields; 
   } DebugFloat;

Eric

2 голосов
/ 29 сентября 2008

Я не думаю, что Эндрю говорит об однобитовых битовых полях. Например, 4-битные поля: 3 бита числовой информации, один бит для знака. Это вполне может иметь смысл, хотя я признаю, что не мог придумать такой сценарий в голове.

Обновление: я не говорю, что не могу придумать, как использовать многобитовые битовые поля (используя их все время в модемном режиме 2400 бит / с, чтобы максимально сжать данные для передачи), но я могу Не думаю, что использование подписанных битовых полей, особенно не странное, очевидное, было бы "ага" момент для читателей.

1 голос
/ 18 января 2012

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

В настоящее время я смотрю на эмуляцию 48-битной машины и пытаюсь разобраться, разумно ли использовать 48 бит из 64-битной "long long" через битовые поля ... сгенерированный код будет таким же как будто я делал всю маскировку, расширение знака и т. д. явно, но это читалось бы намного лучше ...

1 голос
/ 29 сентября 2008

Да, это возможно. Битовые поля C по сути являются просто целыми числами с ограниченным диапазоном. Часто аппаратные интерфейсы объединяют биты так, что некоторый элемент управления может переходить, скажем, от -8 до 7, в этом случае вам нужно битовое поле со знаком, или от 0 до 15, в этом случае вам нужен бит без знака. поле.

0 голосов
/ 30 июля 2009

Типы подписанных битовых масок варьируются от аппаратного обеспечения платформы к аппаратному обеспечению платформы из-за того, как оно может справиться с переполнением после смены и т. Д.

Любой наполовину хороший инструмент QA будет предупреждать о таком использовании.

0 голосов
/ 29 сентября 2008
0 голосов
/ 29 сентября 2008

если «бит» подписан, то у вас есть диапазон -1, 0, 1, который затем становится троичной цифрой. Я не думаю, что стандартная аббревиатура для этого подойдет здесь, но делает для интересных разговоров:)

...