2009-04-27 21 views
8

Estoy trabajando en un pequeño proyecto de interfaz de hardware basado en la placa Velleman k8055.¿Por qué Y dos números para obtener un booleano?

El código de ejemplo viene en VB.Net y estoy reescribiendo esto en C#, sobre todo para tener la oportunidad de recorrer el código y darle sentido a todo.

Una cosa me ha desconcertado sin embargo:

En una etapa que leen todas las entradas digitales y luego establecer una casilla de verificación en base a la respuesta a las entradas digitales de lectura (que vienen de vuelta en un entero) y entonces ellos y este con un número:

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 

no he hecho los sistemas digitales desde hace tiempo y entiendo lo que están tratando de hacer, pero ¿qué efecto tendría que tener que soportar y dos números? ¿No todo lo que está por encima de 0 equivale a verdadero?

¿Cómo traducirías esto a C#?

+0

Gracias por todas las respuestas ... Claramente nunca tuve la oportunidad de hacer cosas de Bitwise en el pasado ... Bueno, supongo No puedo decir eso nunca más. ;-) – Gineer

Respuesta

15

Creo que te tiene que traducirlo a esto:

i & 1 == 1 

i & 2 == 2 

i & 4 == 4 

etc ... Se trata de utilizar el AND bit a bit operador.

Cuando utiliza el operador AND bit a bit, este operador comparará la representación binaria de los dos valores dados, y devolverá un valor binario donde solo se establecen esos bits, que también se establecen en los dos operandos.

Por ejemplo, cuando se hace esto:

Lo hará:

0010 & 0010 

Y esto se traducirá en:

0010 
0010 
&---- 
0010 

Entonces, si usted compara este resultado con 2 (0010), por supuesto, devolverá verdadero.

19

Esto está haciendo un bitwise AND, no un AND lógico.

Cada uno de los básicamente determina si un único bit en i se establece, por ejemplo:

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

(Debido a 5 = binario 101, y 4, 2 y 1 son los valores decimales de binario 100, 010 y 001, respectivamente.)

+0

5 Y 4 = 4, por supuesto, es por eso que la pregunta dijo (5 Y 4) \ 4 – MSalters

+0

Doh, corregido gracias :) –

1

Piense en esto en formato binario, por ejemplo

10101010 

AND 

00000010 

produce 00000010

es decir, no cero. Ahora bien, si el primer valor era

10101000 

se obtendría

00000000 

es decir, cero.

Nota de la división adicional de reducir todo a 1 ó 0.

1

(iy 16)/16 extrae el valor (1 o 0) del 5º bit.

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

And operador lleva a cabo "... conjunción bit a bit en dos expresiones numéricas", que asigna a '|' Cª#. El `` es un integer division, y el equivalente en C# es /, siempre que ambos operandos sean tipos enteros.

1

Los números constantes son masks (piénsalos en formato binario). Entonces, lo que hace el código es aplicar el operador bitwise AND en el byte y la máscara y dividir por el número, para obtener el bit.

Por ejemplo:

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

Como se ha dicho se trata de un AND bit a bit, no un AND lógico. Veo que esto ha sido dicho bastantes veces antes que yo, pero las explicaciones de la OMI no son tan fáciles de entender.

me gusta pensar en ello como esto:

redactar los números binarios debajo de los otros (en este caso estoy haciendo 5 y 1):

101 
001 

Ahora tenemos que convertir esto en un número binario, donde todos los 1 de de la primera serie, que también se encuentra en el segundo obtiene transferida, que es - en este caso:

001 

en este caso vemos que da el mismo número que el segundo número, yo n que esta operación (en VB) devuelve verdadero.Veamos los otros ejemplos (usando 5 como i):

(5 y 2)

101 
010 
---- 
000 

(falsa)

(5 y 4)

101 
100 
--- 
100 

(verdadera)

(5 y 8)

0101 
1000 
---- 
0000 

(falso)

(5 y 16)

00101 
10000 
----- 
00000 

(falso)

EDIT: y obviamente se pierda el punto de la cuestión entera - aquí está la traducción a 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

sólo para añadir: Se llama bitmasking http://en.wikipedia.org/wiki/Mask_(computing)

Un booleano solo requiere 1 bit. En la mayoría de los lenguajes de programación de implementación, un booleano toma más de un bit. En PC esto no será un gran desperdicio, pero el sistema integrado generalmente tiene un espacio de memoria muy limitado, por lo que el desperdicio es realmente significativo. Para ahorrar espacio, los booleanos se empaquetan juntos, de esta forma una variable booleana solo ocupa 1 bit.

Usted puede pensar que es hacer algo como una operación de indexación gama, con un byte (= 8 bits) llegar a ser como una matriz de 8 variables booleanas, y quizás por su respuesta: utilizar una matriz de booleanos.

1

En C#, utilice BitArray class para indexar los bits individuales.

Para establecer un bit individual i es sencillo:

b |= 1 << i; 

Para restablecer un bit individual i es un poco más incómoda:

b &= ~(1 << i); 

Tenga en cuenta que tanto los operadores de bits y los operadores de turno tienden a promocionar todo al int que inesperadamente puede requerir un casting.

1

Prefiero usar la notación hexadecimal cuando se hace un twiddling (por ejemplo, 0x10 en lugar de 16). Tiene más sentido a medida que aumenta las profundidades de bits, ya que 0x20000 es mejor que 131072.

Cuestiones relacionadas