2009-04-27 5 views
8

Sto lavorando ad un piccolo progetto di interfaccia Hardware basato sulla scheda Velleman k8055.Perché AND due numeri per ottenere un booleano?

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 di tutto questo.

Una cosa mi ha sconcertato però:

A un certo punto hanno letto tutti gli ingressi digitali e quindi impostare una casella di controllo in base alla risposta agli ingressi digitali di lettura (che tornano in un intero) e poi hanno 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? Non tutto sopra lo zero equivale a vero?

Come ti tradurre questo in C#?

+0

Grazie per tutte le risposte ... Non ho mai avuto l'opportunità di fare qualsiasi bit di bit nel passato ... Beh, credo Non posso più dirlo. ;-) – Gineer

risposta

15

io ti penso 'll deve tradurlo a questo:

i & 1 == 1 

i & 2 == 2 

i & 4 == 4 

ecc ... Questo sta usando l'AND bit a bit operatore.

Quando si utilizza l'operatore AND bit a bit, questo operatore confronta la rappresentazione binaria dei due valori dati e restituisce un valore binario in cui sono impostati solo quei bit, anch'essi impostati nei due operandi.

Per esempio, quando si esegue questa operazione:

Si farà questo:

0010 & 0010 

E questo si tradurrà in:

0010 
0010 
&---- 
0010 

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

19

Questo sta facendo un bitwise AND, non un AND logico.

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

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

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

+0

5 E 4 = 4, naturalmente, è per questo che la domanda ha detto (5 e 4) \ 4 – MSalters

+0

Doh, risolti grazie :) –

1

pensare a questo, ad esempio in binario

10101010 

AND 

00000010 

cede 00000010

cioè non zero. Ora, se il primo valore è stato

10101000 

si otterrebbe

00000000 

vale a dire pari a zero.

nota l'ulteriore divisione di ridurre tutto a 1 o 0.

1

(i e 16)/16 estrae il valore (1 o 0) del quinto bit.

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

And operatore esegue "... bit a bit insieme su due espressioni numeriche", che associa a '|' in C#. Il simbolo `` è un integer division e l'equivalente in C# è /, a condizione che entrambi gli operandi siano tipi interi.

1

I numeri costanti sono masks (pensateli in binario). Quindi, ciò che fa il codice è applicare l'operatore bitwise AND sul byte e la maschera e dividere per il numero, in modo da ottenere il bit.

Ad esempio:

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

Come detto si tratta di 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, che è - in questo caso:

001 

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

(5 e 2)

101 
010 
---- 
000 

(falsa)

(5 e 4)

101 
100 
--- 
100 

(vero)

(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; 
3

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

Un booleano richiede solo 1 bit. Nell'implementazione della maggior parte del linguaggio di programmazione, un booleano richiede più di un singolo bit. In PC questo non sarà un grande spreco, ma il sistema embedded di solito ha uno spazio di memoria molto limitato, quindi lo spreco è davvero significativo. Per risparmiare spazio, i booleani sono raggruppati insieme, in questo modo una variabile booleana richiede solo 1 bit.

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

1

In C# utilizzare BitArray class per indicizzare direttamente singoli bit.

Per impostare un singolo bit i è semplice:

b |= 1 << i; 

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

b &= ~(1 << i); 

essere consapevoli del fatto che sia gli operatori bit per bit e gli operatori di turno tendono a promuovere tutto a int che potrebbe richiedere in modo imprevisto la trasmissione.

1

Preferisco utilizzare la notazione esadecimale quando si utilizza il bit twiddling (ad esempio 0x10 anziché 16). Ha più senso quando aumenti le tue profondità di bit come 0x20000 è meglio di 131072.

Problemi correlati