Pergunta

Eu estou trabalhando em um pequeno projeto de interface de hardware com base na placa Velleman K8055.

O código de exemplo vem em VB.Net e eu estou reescrevendo isso em C #, principalmente para ter uma chance de passo através do código e fazer sentido de tudo isso.

Uma coisa tem me perplexo, porém:

Em um estágio que lêem todas as entradas digitais e, em seguida, definir uma caixa de seleção com base na resposta às entradas digitais (que voltar em uma Integer) ler e então eles e isso com um 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

Eu não fiz sistemas digitais em um tempo e eu entendo o que eles estão tentando fazer, mas o que efeito teria para e dois números? Será que nem tudo acima de 0 equivale a verdade?

Como você traduzir isso para C #?

Foi útil?

Solução

Eu acho que você vai ter que traduzi-lo para o seguinte:

i & 1 == 1

i & 2 == 2

i & 4 == 4 

etc ... Esta é usando o bit a bit E operador.

Quando você usa o bit a bit E operador, este operador irá comparar a representação binária dos dois valores dados, e retornar um valor binário, onde apenas os bits são definidos, que também são definidas nos dois operandos.

Por exemplo, quando você faz isso:

2 & 2

Ele vai fazer isso:

0010 & 0010

E isso vai resultar em:

 0010
 0010
&----
 0010

Então, se você comparar este resultado com 2 (0010), ele é claro retornar true.

Outras dicas

Este está fazendo um bit a bit E , não um E lógico.

Cada um desses basicamente determina se um único bit em i está definido, por exemplo:

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

(5 Porque = binária 101, e 4, 2 e 1 são os valores decimais de binário 100, 010 e 001, respectivamente.)

Só para acrescentar: É chamado bitmasking http://en.wikipedia.org/wiki/Mask_(computing)

Um booleano requerem apenas 1 bit. Na implementação mais linguagem de programação, um booleano preciso mais do que um único bit. No PC isso não será um grande desperdício, mas sistema embarcado normalmente têm espaço de memória muito limitada, de modo que o desperdício é realmente significativo. Para economizar espaço , os booleans são embalados juntos, desta forma uma variável boolean ocupa apenas 1 bit.

Você pode pensar nisso como fazer algo como um operação de indexação array , com um byte (= 8 bits) tornar-se como um conjunto de 8 variáveis ??booleanas, talvez por isso que é a sua resposta: usar uma matriz de booleanos.

Pense nisso em binário por exemplo.

10101010

AND

00000010

rendimentos 00000010

i. Não zero. Agora, se o primeiro valor era

10101000

que você deseja obter

00000000

i. zero.

Observe a divisão adicional para reduzir tudo a 1 ou 0.

(i e 16) / 16 extrai o valor (1 ou 0) da 5ª bit.

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

e operadora executa" .. conjunto .bitwise em duas expressões numéricas", que mapeia para '|' em C #. A '' é uma divisão de número inteiro, e equivalente em C # é / , desde que ambos os operandos são inteiros tipos.

Os números constantes são máscaras (pensar neles em binário). Então, o que o código faz é aplicar o operador bit a bit E no byte ea máscara e dividir pelo número, a fim de obter o bit.

Por exemplo:

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

Em C # usar a classe BitArray para directamente índice bits individuais.

Para definir um bit individual i é simples:

b |= 1 << i;

Para repor um bit individual i é um pouco mais complicado:

b &= ~(1 << i);

Esteja ciente de que tanto os operadores bit a bit e os operadores de deslocamento tendem a promover tudo para int que podem inesperadamente requerem vazamento.

Como disse este é um bit a bit E, não uma lógica AND. Eu vejo que esta tem sido dito algumas vezes antes de mim, mas IMO as explicações não são tão fácil de entender.

Eu gosto de pensar nisso como este:

Escrever os números binários em si (aqui eu estou fazendo 5 a 1):

101
001

Agora precisamos transformar isso em um número binário, onde todos os 1s da 1ª série, que também está no segundo fica transferido, isto é - neste caso:

001

Neste caso, vemos que dá o mesmo número que o segundo número, em que esta operação (em VB) retorna true. Vamos olhar os outros exemplos (usando 5 como i):

(5 e 2)

101
010
----
000

(falso)

(5 e 4)

101
100
---
100

(true)

(5 e 8)

0101
1000
----
0000

(falso)

(5 e 16)

00101
10000
-----
00000

(falso)

EDIT: e, obviamente, eu sinto falta de todo o ponto da questão - aqui é a tradução para 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;

Eu prefiro usar a notação hexadecimal quando twiddling bit (por exemplo 0x10 em vez de 16). Faz mais sentido como você aumentar suas profundidades de bits como 0x20000 é melhor do que 131072.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top