2009-04-27 5 views
8

Я работаю над небольшим проектом аппаратного интерфейса, основанным на плате Velleman k8055.Почему и два числа, чтобы получить логическое значение?

Пример кода представлен в VB.Net, и я переписываю его на C#, в основном, чтобы иметь возможность пройти через код и понять все это.

Одно есть я сбит с толку, хотя:

На одном этапе они читают все цифровые входы, а затем установите флажок на основе ответа на считанных цифровых входов (которые возвращаются в Integer), а затем они и это с номером:

i = ReadAllDigital 
cbi(1).Checked = (i And 1) 
cbi(2).Checked = (i And 2) \ 2 
cbi(3).Checked = (i And 4) \ 4 
cbi(4).Checked = (i And 8) \ 8 
cbi(5).Checked = (i And 16) \ 16 

Я не сделал цифровые системы, в то время, и я понимаю, что они пытаются сделать, но то, что эффект был бы это должно было и два номера? Разве все выше 0 не соответствует истине?

Как бы вы перевели это на C#?

+0

Спасибо за все ответы ... У меня явно никогда не было возможности делать какие-либо побитовые вещи в прошлом ... Ну, я думаю Я не могу этого больше сказать. ;-) – Gineer

ответ

15

Я думаю, что вы будете иметь, чтобы перевести его на это:

i & 1 == 1 

i & 2 == 2 

i & 4 == 4 

и т.д ... Это с помощью побитового И оператор.

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

Например, когда вы это делаете:

Он будет делать это:

0010 & 0010 

И это приведет:

0010 
0010 
&---- 
0010 

Тогда если вы сравниваете этот результат с 2 (0010), он, конечно же, вернет true.

19

Это делает bitwise AND, а не логический И.

Каждые из тех, в основном определяет, является ли один бит в i установлен, например:

5 AND 4 = 4 
5 AND 2 = 0 
5 AND 1 = 1 

(Из 5 = двоичных 101 и 4, 2 и 1 являются десятичными значениями двоичных 100, 010 и 001 соответственно.)

+0

5 И 4 = 4, конечно, поэтому вопрос сказал (5 И 4) \ 4 – MSalters

+0

Дох, исправлено спасибо :) –

1

Подумайте об этом в двоичном выражении, например

10101010 

AND 

00000010 

дает 00000010

т.е. не равен нулю. Теперь, если первое значение было

10101000 

вы получите

00000000 

т.е. ноль.

Обратите внимание на дальнейшее разделение, чтобы свести все к 1 или 0.

1

(i и 16)/16 извлекает значение (1 или 0) 5-го разряда.

1xxxx and 16 = 16/16 = 1 
0xxxx and 16 = 0/16 = 0 
1

And оператор выполняет «... побитовую конъюнкцию на два числовых выражениях», который отображает до „|“ в C#. «` - это integer division, а эквивалент в C# - /, при условии, что оба операнда являются целыми типами.

1

Постоянными числами являются masks (думайте о них в двоичном виде). Итак, что делает код, применяется оператор bitwise AND по байту и маске и делятся на число, чтобы получить бит.

Например:

xxxxxxxx & 00000100 = 00000x000 
if x == 1 
    00000x00/00000100 = 000000001 
else if x == 0 
    00000x00/00000100 = 000000000 
1

Как было сказано, что это побитовое И, а не логическое И. Я вижу, что это было сказано несколько раз передо мной, но ИМО объяснения не так-то просто понять.

Мне нравится думать об этом так:

Выпишите двоичные числа друг под другом (здесь я делаю 5 и 1):

101 
001 

Теперь нам нужно, чтобы превратить это в двоичное число, где все 1 от 1-го числа, то есть также во втором получает передано, то есть - в этом случае:

001 

в данном случае мы видим, что дает тот же номер, как 2-й число, i n, который эта операция (в VB) возвращает true.Давайте посмотрим на другие примеры (с использованием 5, как я):

(5 и 2)

101 
010 
---- 
000 

(ложь)

(5 и 4)

101 
100 
--- 
100 

(правда,)

(5 и 8)

0101 
1000 
---- 
0000 

(ложь)

(5 и 16)

00101 
10000 
----- 
00000 

(ложь)

EDIT: и, очевидно, я пропускаю всю точку вопроса - вот перевод на C#:

cbi[1].Checked = i & 1 == 1; 
cbi[2].Checked = i & 2 == 2; 
cbi[3].Checked = i & 4 == 4; 
cbi[4].Checked = i & 8 == 8; 
cbi[5].Checked = i & 16 == 16; 
3

Просто добавить: Это называется bitmasking http://en.wikipedia.org/wiki/Mask_(computing)

Логическое значение требует только 1 бит. В реализации большинства языков программирования логическое значение принимает более одного бита. В ПК это не будет большой тратой, но встроенная система обычно имеет очень ограниченное пространство памяти, поэтому отходы действительно значительны. Чтобы сэкономить место, булевы упакованы вместе, таким образом, логическая переменная принимает только 1 бит.

Вы можете думать об этом, как делать что-то вроде операции индексации массива, с байта (= 8 бит) становится как массив из 8 логических переменных, так что, возможно, что ваш ответ: использовать массив логических значений.

1

В C# используйте BitArray class, чтобы напрямую индексировать отдельные биты.

Чтобы установить отдельный бит я проста:

b |= 1 << i; 

Для сброса отдельного бита я немного более неловко:

b &= ~(1 << i); 

Имейте в виду, что и битовые операторы и операторы смены стремятся продвигать все до int, что может неожиданно потребовать кастинга.

1

Я предпочитаю использовать шестнадцатеричные обозначения при свертке бит (например, 0x10 вместо 16). Это имеет большее значение, поскольку вы увеличиваете свои битовые глубины, так как 0x20000 лучше, чем 131072.