Domanda

Sto lavorando su un piccolo progetto Interfaccia hardware basata a bordo della Velleman K8055.

Il codice di esempio viene fornito in VB.Net e sto riscrivendo questo in C #, soprattutto per avere la possibilità di eseguire il codice e dare un senso a tutto questo.

Una cosa mi ha sconcertato però:

A un certo punto leggono tutti gli ingressi digitali e quindi impostare una casella di controllo basato sulla risposta agli ingressi digitali lettura (che tornano in un intero) e poi E questo con un numero:

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

Non ho fatto i sistemi digitali in un po 'e ho capito che cosa stanno cercando di fare, ma che effetto sarebbe dovuto e due numeri? Fa non tutto superiore a 0 equivale a vero?

Come vi tradurre questo in C #?

È stato utile?

Soluzione

Penso che si 'll deve tradurre in questo modo:

i & 1 == 1

i & 2 == 2

i & 4 == 4 

ecc ... Si tratta di utilizzare il bit a bit operatore AND.

Quando si utilizza l'operatore AND bit a bit, questo operatore confronterà la rappresentazione binaria dei due valori dati, e restituire un valore binario in cui sono impostati solo i bit, che sono anche impostato nelle due operandi.

Per esempio, quando si esegue questa operazione:

2 & 2

Si farà questo:

0010 & 0010

E questo si tradurrà in:

 0010
 0010
&----
 0010

Poi, se si confronta questo risultato con 2 (0010), sarà naturalmente tornare vero.

Altri suggerimenti

Questo sta facendo un AND bit a bit , non è un AND logico.

Ciascuno di questi determina sostanzialmente se un singolo bit in i è impostato, per esempio:

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

(5 Poiché = binario 101, e 4, 2 e 1 sono i valori decimali dei binari 100, 010 e 001 rispettivamente.)

Giusto per aggiungere: Si chiama bitmasking http://en.wikipedia.org/wiki/Mask_(computing)

Un valore booleano richiedono solo 1 bit. Nell'implementazione più linguaggio di programmazione, un valore booleano prende più di un singolo bit. In PC questo non sarà una gran perdita, ma sistema embedded di solito hanno spazio di memoria molto limitata, quindi i rifiuti è davvero significativo. Per risparmiare spazio , i booleani sono imballate insieme, in questo modo una variabile booleana occupa solo 1 bit.

Si può pensare ad esso come fare qualcosa di simile a un operazione di allineamento indicizzazione , con un byte (= 8 bit) di diventare come un array di 8 variabili booleane, quindi forse è la risposta: utilizzare un array di booleani.

Pensate a questo in per esempio binario.

10101010

AND

00000010

rendimenti 00000010

vale a dire. non zero. Ora, se il primo valore è stato

10101000

si otterrebbe

00000000

vale a dire. zero.

Si noti l'ulteriore divisione ridurre tutto a 1 o 0.

(ie 16) / 16 estrae il valore (1 o 0) del 5 ° bit.

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

e l'operatore esegue " .. congiunzione .bitwise su due espressioni numeriche", che associa a '|' in C #. Il '`è un divisione intera , ed equivalente in C # è / , a condizione che entrambi gli operandi sono tipi interi.

I numeri costanti sono maschere (pensare a loro in binario). Quindi, ciò che il codice non fa altro che applicare la bit a bit operatore AND sul byte e la maschera e dividere per il numero, al fine di ottenere il bit.

Ad esempio:

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

In C # utilizzano il BitArray all'indice direttamente singoli bit.

Per impostare un singolo bit i è semplice:

b |= 1 << i;

Per ripristinare un singolo bit i è un po 'più scomodo:

b &= ~(1 << i);

Si tenga presente che sia gli operatori bit a bit e gli operatori di spostamento tendono a promuovere tutto per int che possono inaspettatamente richiedere casting.

Come ha detto che questo è un AND bit per bit, non è un AND logico. Vedo che questo è stato detto diverse volte prima di me, ma IMO le spiegazioni non sono così facili da capire.

Mi piace pensare a come questo:

Scrivi i numeri binari sotto l'altro (qui sto facendo 5 e 1):

101
001

Ora dobbiamo trasformare questo in un numero binario, dove tutti i 1 S da 1 ° numero, che è anche nel secondo viene trasferito, cioè - in questo caso:

001

In questo caso vediamo che dà lo stesso numero come il 2 ° numero, in cui l'operazione (in VB) restituisce true. Diamo un'occhiata ad altri esempi (con 5 come i):

(5 e 2)

101
010
----
000

(false)

(5 e 4)

101
100
---
100

(true)

(5 e 8)

0101
1000
----
0000

(false)

(5 e 16)

00101
10000
-----
00000

(false)

EDIT: e, ovviamente, mi manca l'intero punto della questione - qui è la traduzione di 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;

Io preferisco usare la notazione esadecimale quando il bit girarsi (ad esempio 0x10 invece di 16). Ha più senso, come si aumenta la profondità di bit come 0x20000 è meglio di 131072.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top