2013-07-12 3 views
0

Я студент, работающий над проектом для отдела химии моего колледжа. В прошлом году я написал программу на C++ для управления пикомоторной сценой и общался с датчиком давления, перемещая ступень вверх и вниз, пока она не коснулась датчика. Я использовал DLL, предоставленную компанией для написания этой программы. Мне потребовалось некоторое время, но я получил все, чтобы работать.Побитовая операция в C#

В этом году я включил второй этап в программу и обновил всю программу в графическом интерфейсе с использованием C#. Второй этап и датчик силы предоставляют только DLL, которые работают с C#, тогда как старая сцена предназначена для C++. Я смог заставить всех троих работать в новой программе C# GUI, это почти все, что сэкономить эту проблему:

В старой программе мне удалось определить, двигались ли двигатели на сцене с помощью этой функции:

#define MOTOR_MOVING 0x01 
byte isMoving = LdcnGetStat(pico_addr) & MOTOR_MOVING; 

байты LdcnGetStat (адрес байта) возвращают последние байты состояния модуля по данному адресу. В соответствии с инструкцией, которую я имею, бит 0 должен быть установлен, когда двигатель движется. Итак, если я тестирую его в своей программе на C++, используя переменную bool, isMoving равен 0, когда двигатели не двигаются, и 1, когда они есть, и он быстро возвращается в 0 после остановки двигателя. Работает отлично.

Но в C# у меня возникают проблемы с этим.

byte isMoving = LdcnGetStat(pico_addr) & MOTOR_MOVING; 

не работает, я должен сделать некоторое явное литье. Так что я изменил его на это:

bool isMoving = Convert.ToBoolean(LdcnGetStat(pico_addr) & 
Convert.ToBoolean(MOTOR_MOVING); 

Это не дает мне ошибку, но LdcnGetStat (pico_addr) всегда возвращает «истина», потому что он никогда не 0. Если я просто проверить значения, которые LdcnGetStat() вертела когда двигатель не двигается, он возвращается 28, когда он движется, он возвращается с 98. Если я снова тестирую пост-движение, он возвращается 23.

Есть ли способ справиться с этим на C#? Я собираюсь проверить, возвращает ли LdcnGetStat правильное числовое значение, но это не похоже на правильный способ его обработки, тем более, что значения, похоже, меняют пост-перемещение.

Благодаря

ответ

2

условий в C/C++ эффективно компилироваться для сравнения с нулем. Таким образом, выражение LdcnGetStat(pico_addr) & MOTOR_MOVING эквивалентно (LdcnGetStat(pico_addr) & MOTOR_MOVING) != 0. В C#, однако, условия выполняются с фактическим bool s, поэтому вы можете использовать только второе выражение.

Я могу объяснить больше, если вам нужно.

1

Я думаю, что вы ищете это:

bool isMoving = (LdcnGetStat(pico_addr) & MOTOR_MOVING) != 0; 

Выражение:

byte isMoving = LdcnGetStat(pico_addr) & MOTOR_MOVING; 

Вероятно, дает ошибку о неявном преобразовании int в byte. Вы должны бросить его:

byte isMoving = (byte)(LdcnGetStat(pico_addr) & MOTOR_MOVING); 

В этом случае isMoving будет равен 0x01, когда двигатель двигается.

+0

Мне действительно кажется, что оператор '&', по-видимому, предполагает, что тип результата больше, чем его операнды. Если * либо * операндов будет соответствовать неподписанному типу, то нет способа, чтобы результат мог не соответствовать этому типу. Оператор '|' обычно должен предполагать, что тип результата будет длиннее его операндов, но, возможно, с исключением, если одна из них является отрицательной константой (в этом случае результат гарантированно будет соответствовать любому типу, который мог бы удерживать эту константу). – supercat

+0

Кстати, я также очень хочу, чтобы у C# был удобный оператор или метод, определенный для типов 'int' и' enum', которые бы проверяли, было ли «побитовое» и «два целочисленных значения» отличным от нуля. В C я бы сказал, 'if (myFlags & THIS_FLAG) do_something();'. Я не думаю, что нужно написать это, как будто ((myFlags & THIS_FLAG)! = 0) do_something(); 'особенно улучшает удобочитаемость. – supercat

+0

@supercat: На самом деле побитовые и даже арифметические операторы на 'byte' возвращают' Int32'. Например, 'byte b3 = b1 & b2;' даст ошибку, даже если 'b1' и' b2' объявлены как 'byte'. 'byte b3 = b1 + b2' даст ту же ошибку. По другому вопросу, я амбивалентен. Наверное, потому, что я много работал в Паскале до C#. –

Смежные вопросы