С# Bitmasking не возвращает ожидаемый результат

У меня есть приложение, которое требует от меня некоторой битовой маскировки. Маскирование проверяет строку, и в зависимости от того, какие биты в этой строке являются высокими (1) или низкими (0), вводятся различные методы.

Биты бессильны, если они низкие (0), и мы предполагаем, что если они высокие (1), то все в порядке.

254 = 11111110 в двоичном формате. Это маска, которую я хочу использовать, чтобы проверить последний бит,

void Main()
{
    ushort[] data = new ushort[]{254};

    int alertPosition = 251;
    int tempCriticalPosition = 247;
    int fan1FailurePosition = 253;
    ** int fan2FailurePosition = 254;

    int alarmCritialBit = (tempCriticalPosition & data[0]) == 0 ? 0 : 1;
    int fan1LedFlag = (fan1FailurePosition & data[0]) == 0 ? 0 : 1;
    **int fan2CameraFlag = (fan2FailurePosition & data[0]) == 0 ? 0 : 1;
    int alertFlag = (alertPosition & data[0]) == 0 ? 0 : 1;

    System.Console.WriteLine(alarmCritialBit);
    System.Console.WriteLine(fan1LedFlag);
    System.Console.WriteLine(fan2CameraFlag);
    System.Console.WriteLine(alertFlag);
} 

В данном примере это fan2Failure. Итак, данные в моем массиве и моей битовой маске одинаковы, но результат, который я получаю, равен 1. Результат, который я получаю для выполнения других проверок, также равен 1, поэтому я теперь не понимаю, как это работает.

Все, что я искал в Интернете, рекомендует аналогичный подход, я думал, что для проверки моих данных на наличие ошибки fan2failure я указал в своей маске строку для ошибки fan2failure, и если данные и моя маска совпадают, она вернет 0?

Я знаю, что это что-то простое, но я посмотрел в Интернете и не могу понять, что я делаю неправильно.

Спасибо


person Colm Clarke    schedule 28.07.2014    source источник
comment
Почему fan2CameraFlag не должно быть 1? 254 & 254 == 254, и таким образом вы получите 1 из его выражения. Это неправильно?   -  person Lasse V. Karlsen    schedule 28.07.2014
comment
возможный дубликат Использование битовой маски в C#   -  person Eugene Podskal    schedule 28.07.2014
comment
Ради любви ко всему дырявому. ПОЖАЛУЙСТА, используйте перечисление! Для здравомыслия. Для безопасности типов! Для удобства чтения. ПОЖАЛУЙСТА ПОЖАЛУЙСТА ПОЖАЛУЙСТА.   -  person Aron    schedule 28.07.2014


Ответы (3)


Зачем использовать inverted битовые маски?

Что я обычно делаю при проверке битов, так это сначала определяю такие константы:

const uint fMyFlag = 1u<<0;
const uint fSecond = 1u<<1;

const uint mMyMask = 3u<<2;
const uint mOpt1   = 0u<<2;
const uint mOpt2   = 1u<<2;
const uint mOpt3   = 2u<<2;
const uint mRsvd   = 3u<<2;

и проделайте эти операции:

if((value&fMyFlag) != 0) flag_is_set();
if((value&fMyFlag) == 0) flag_is_not_set();
if((value&mMyMask) == mOpt1) option_one();

value |= fMyFlag; // set the flag
value &=~fMyFlag; // clear the flag
value = (value&~mMyMask) | mOpt2; // set option 2

ПРИМЕЧАНИЕ: описанные выше операции должны работать и для перечислений;)

person firda    schedule 28.07.2014

Чтобы проверить маску, вы должны сделать:

(value & mask) == mask

So :

**int fan2CameraFlag = (fan2FailurePosition & data[0]) == fan2FailurePosition ? 0 : 1;
person Troopers    schedule 28.07.2014

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

Например:

ushort[] data = new ushort[] { 254 };  // 11111110
int fan1FailurePosition = 253; //11111101

Вы ожидаете, что это вернет false, но на самом деле вы выполняете AND, поэтому:

11111110
11111101  (AND)
--------
11111100  (WHICH IS TRUE)

Чтобы получить правильное значение, вы можете просто установить:

int fan1FailurePosition = 1; //0000001

В результате чего:

11111110
00000001  (AND)
--------
00000000  (WHICH IS FALSE)
person thalesfc    schedule 28.07.2014