Я студент, работающий над проектом для отдела химии моего колледжа. В прошлом году я написал программу на 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 правильное числовое значение, но это не похоже на правильный способ его обработки, тем более, что значения, похоже, меняют пост-перемещение.
Благодаря
Мне действительно кажется, что оператор '&', по-видимому, предполагает, что тип результата больше, чем его операнды. Если * либо * операндов будет соответствовать неподписанному типу, то нет способа, чтобы результат мог не соответствовать этому типу. Оператор '|' обычно должен предполагать, что тип результата будет длиннее его операндов, но, возможно, с исключением, если одна из них является отрицательной константой (в этом случае результат гарантированно будет соответствовать любому типу, который мог бы удерживать эту константу). – supercat
Кстати, я также очень хочу, чтобы у C# был удобный оператор или метод, определенный для типов 'int' и' enum', которые бы проверяли, было ли «побитовое» и «два целочисленных значения» отличным от нуля. В C я бы сказал, 'if (myFlags & THIS_FLAG) do_something();'. Я не думаю, что нужно написать это, как будто ((myFlags & THIS_FLAG)! = 0) do_something(); 'особенно улучшает удобочитаемость. – supercat
@supercat: На самом деле побитовые и даже арифметические операторы на 'byte' возвращают' Int32'. Например, 'byte b3 = b1 & b2;' даст ошибку, даже если 'b1' и' b2' объявлены как 'byte'. 'byte b3 = b1 + b2' даст ту же ошибку. По другому вопросу, я амбивалентен. Наверное, потому, что я много работал в Паскале до C#. –