Побитовая настройка в C

#c #c

#c #c

Вопрос:

 #define OUTGOING_MASK         0x0c
#define OUTGOING_DISABLED     0x04
#define OUTGOING_ENABLED      0x08
#define OUTGOING_AUTO         0x00
#define REFER_SUPPORTED       0x80 
  

Предположим, support это некоторое значение типа int.
У меня есть функция получения

 int get()
{
if(OUTGOING_DISABLED == support amp; OUTGOING_MASK)
return 1;
else if(OUTGOING_ENABLED == support amp; OUTGOING_MASK)
return 2;
else if(OUTGOING_AUTO == support amp; OUTGOING_MASK)
return 3;
}
  

Мне нужно написать функцию set для этого, например

 void set(int val)
{
if(val ==1)
//todo
else if(value == 2)
//todo
else if(value == 3)
//todo
}
  

Как написать функции получения и установки для этого?
Мне нужно получить / установить support переменную здесь

REFER_SUPPORTED всегда будет установлен в support .

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

1. b по-прежнему содержит значение b даже после выполнения инструкции. Что вы хотите сделать со значением b? Вывести значение b?

2. Учитывая a2 и a1, которые равны b amp; a2, хотите ли вы восстановить значение b?

3. Есть ли причина, по которой вы возвращаете 1,2,3 вместо OUTGOING_DISABLED, OUTGOING_ENABLED и OUTGOING_AUTO?

Ответ №1:

У меня есть оператор типа a1 = b amp; a2; Как узнать значение b с помощью побитовых операторов?

Вы не сможете восстановить значение b, если в a не установлены ВСЕ биты. «amp;» является необратимой.

Объяснение. операция amp; имеет следующую таблицу:

 a   b   result
1 amp; 1 = 1
0 amp; 1 = 0
1 amp; 0 = 0
0 amp; 0 = 0
  

это означает, что для восстановления b вы могли бы попробовать использовать следующую таблицу:

 a   result  b
0   0       unknown - could be 1 or 0
0   1       invalid/impossible - could not happen
1   0       0
1   1       1
  

Как вы можете видеть, не во всех случаях возможно угадать b.

В выражении a amp; b = c, если вы знаете c и a, вы не сможете восстановить b, потому что для каждого обнуленного бита c, и если соответствующий бит a также равен нулю, существует два возможных состояния соответствующих битов b. Вы можете надежно восстановить b, только если каждый бит a установлен в 1.

Ответ №2:

Вы этого не делаете. В общем случае вы не можете восстановить эту информацию, заданную только a1 и a2 . Чтобы убедиться в этом, рассмотрим случай a2 == 0 . b amp; 0 всегда равно 0.

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

1. Спасибо Мэтью. В моем коде a2 никогда не может быть равен нулю. Обычно это будет 3 или 4. В таком случае, как это сделать? Но a1 может быть равен нулю

2. Вы все еще не можете. 8 amp; 3 и 4 amp; 3 оба равны 0, чтобы привести пример.

Ответ №3:

Является ли следующее тем, что вы хотите:

 void set(int val)
{
    support amp;= ~OUTGOING_MASK;
    support |= REFER_SUPPORTED;

    if(val == 1)
    {
        support |= OUTGOING_DISABLED;
    }
    else if(value == 2)
    {
        support |= OUTGOING_ENABLED;
    }
    else if(value == 3)
    {
        support |= OUTGOING_AUTO;
    }
}
  


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

 int get()
{
    if(OUTGOING_DISABLED == ((support amp; OUTGOING_MASK) >> 2))
        return 1;
    else if(OUTGOING_ENABLED == ((support amp; OUTGOING_MASK) >> 2))
        return 2;
    else if(OUTGOING_AUTO == ((support amp; OUTGOING_MASK) >> 2))
        return 3;
}
  

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

1. Да … но у меня есть другая, называемая #define REFER_SUPPORTED 0x80, которая всегда будет установлена в support

2. Спасибо. можете ли вы написать getter также в соответствии с настройщиком.

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

Ответ №4:

Для вывода двоичного эквивалента можно использовать следующий код

 void printBit(int n)
{
  unsigned int i;
  i = 1<<(sizeof(n) * 8 - 1);

  while (i > 0)
  {
     if (n amp; i)
     {  
       printf("1");
     }
     else
     { 
        printf("0");
     }
    i >>= 1;
}
}
  

Это просто вывело бы двоичный эквивалент ‘b’. Это то, что вы хотите сделать?

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

1. Нет. Мне не нужен двоичный эквивалент b. Я просто хочу значение b

2. Я думаю, вам нужно немного более четко понимать, что вы подразумеваете под «значением».