2009-04-27 4 views
8

Je travaille sur un petit projet d'interface hardware basé sur la carte Velleman k8055.Pourquoi ET deux nombres pour obtenir un booléen?

L'exemple de code vient dans VB.Net et je réécris cela en C#, principalement pour avoir une chance de parcourir le code et de donner un sens à tout cela.

Une chose m'a dérouté si:

A un moment ils ont lu toutes les entrées numériques puis définissez une case à cocher en fonction de la réponse aux entrées numériques lues (qui reviennent dans un entier), puis ils et cela avec un numéro:

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 

Je ne l'ai pas fait des systèmes numériques dans un certain temps et je comprends ce qu'ils essaient de faire, mais quel effet aurait-il à et deux chiffres? Tout ce qui est au-dessus de 0 n'est-il pas vrai?

Comment traduiriez-vous cela en C#?

+0

Merci pour toutes les réponses ... Je n'ai clairement jamais eu l'occasion de faire des trucs Bitwise dans le passé ... Eh bien, je suppose Je ne peux plus le dire. ;-) – Gineer

Répondre

15

Je pense que vous aurez à le traduire à ceci:

i & 1 == 1 

i & 2 == 2 

i & 4 == 4 

etc ... Ce utilise le niveau du bit opérateur. Lorsque vous utilisez l'opérateur AND au niveau du bit, cet opérateur compare la représentation binaire des deux valeurs données et renvoie une valeur binaire où seuls ces bits sont définis, qui sont également définis dans les deux opérandes.

Par exemple, lorsque vous faites ceci:

Il fera ceci:

0010 & 0010 

Et cela se traduira par:

0010 
0010 
&---- 
0010 

Ensuite, si vous comparez ce résultat avec 2 (0010), il retournera bien sûr vrai.

19

Ceci fait un bitwise AND, pas un AND logique.

Chacun de ceux détermine essentiellement si un seul bit dans i est défini, par exemple:

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

(Parce que 5 = binaire 101, et 4, 2 et 1 sont les valeurs décimales de binaire 100, 010 et 001 respectivement.)

+0

5 ET 4 = 4, bien sûr, c'est pourquoi la question dit (5 ET 4) \ 4 – MSalters

+0

Doh, fixe merci :) –

1

Pensez-y en binaire, par exemple

10101010 

AND 

00000010 

cède 00000010

à-dire non nul. Maintenant, si la première valeur était

10101000 

vous obtiendrez

00000000 

à savoir zéro.

Notez la division de réduire encore tout à 1 ou 0.

1

(i et 16)/16 extrait la valeur (1 ou 0) du 5ème bit.

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

opérateur And réalise "... Conjonction deux bitwise expressions numériques", qui mappe '|' en C#. Le '' est un integer division, et l'équivalent en C# est /, à condition que les deux opérandes soient des types entiers.

1

Les nombres constants sont masks (pensez-y en binaire). Donc, ce que le code fait est d'appliquer l'opérateur bitwise AND sur l'octet et le masque et de diviser par le nombre, afin d'obtenir le bit.

Par exemple:

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

Comme dit cela est Bitwise ET, pas un ET logique. Je vois que cela a été dit à plusieurs reprises avant moi, mais les explications de l'OMI ne sont pas si faciles à comprendre.

J'aime penser comme ceci:

Rédiger les nombres binaires sous l'autre (ici, je fais 5 et 1):

101 
001 

Maintenant, nous devons transformer cela en un nombre binaire, où tous les 1 de du 1er numéro, qui est aussi dans le second obtient transféré, qui est - dans ce cas:

001 

dans ce cas, nous voyons donne le même numéro que le 2 nombre, je n que cette opération (en VB) renvoie true.Regardons les autres exemples (en utilisant 5 comme i):

(5 et 2)

101 
010 
---- 
000 

(faux)

(5 et 4)

101 
100 
--- 
100 

(vrai)

(5 et 8)

0101 
1000 
---- 
0000 

(false)

(5 et 16)

00101 
10000 
----- 
00000 

(false)

EDIT: et, évidemment, je manque le point entier de la question - voici la traduction 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

Juste pour ajouter: Il est appelé bitmasking http://en.wikipedia.org/wiki/Mask_(computing)

Un booléen ne nécessite qu'un bit. Dans le langage de programmation le plus implémenté, un booléen prend plus d'un bit. En PC, ce ne sera pas un gros gâchis, mais le système embarqué a généralement un espace mémoire très limité, donc le gaspillage est vraiment important. Pour économiser de l'espace, les booléens sont compressés ensemble, de cette façon une variable booléenne ne prend qu'un bit.

Vous pouvez penser que faire quelque chose comme un devenir comme un tableau de 8 variables booléennes opération, avec un octet (= 8 bits) indexation tableau , alors peut-être que votre réponse: utiliser un tableau de booléens.

1

En C#, utilisez le BitArray class pour indexer directement des bits individuels.

Pour définir un bit individuel i est simple:

b |= 1 << i; 

Pour réinitialiser un bit individuel i est un peu plus gênant:

b &= ~(1 << i); 

Soyez conscient que les deux opérateurs au niveau du bit et les opérateurs de décalage tendent à tout promouvoir à int qui peut exiger de façon inattendue le casting.

1

Je préfère utiliser la notation hexadécimale lors d'un twittage de bits (par exemple, 0x10 au lieu de 16). Il est plus logique que vous augmentiez vos profondeurs de bits comme 0x20000 est mieux que 131072.

Questions connexes