9

私は、Velleman k8055 ボードに基づく小さなハードウェア インターフェイス プロジェクトに取り組んでいます。

サンプル コードは VB.Net で提供されています。これを C# に書き直しています。これは主に、コードをステップ実行してすべてを理解できるようにするためです。

ただし、1つのことが私を困惑させました:

ある段階で、すべてのデジタル入力を読み取り、読み取ったデジタル入力 (整数で返される) への回答に基づいてチェックボックスを設定し、これを数値で AND します。

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

私はしばらくの間デジタル システムを行っていません。彼らが何をしようとしているのかは理解していますが、2 つの数値の AND を行うとどのような影響が生じるでしょうか? 0 より大きいものはすべて true に相当しませんか?

これを C# に翻訳するとどうなりますか?

4

10 に答える 10

19

これは、論理 ANDではなく、ビットごとの AND を実行しています。

これらのそれぞれは、基本的に、単一のビットiが設定されているかどうかを決定します。たとえば、次のようになります。

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

(5 = 2 進数の 101 であるため、4、2、および 1 はそれぞれ 2 進数の 100、010、および 001 の 10 進値です。)

于 2009-04-27T08:57:51.040 に答える
15

これを次のように翻訳する必要があると思います。

i & 1 == 1

i & 2 == 2

i & 4 == 4 

etc...これはビットごとの AND 演算子を使用しています。

ビットごとの AND 演算子を使用すると、この演算子は指定された 2 つの値のバイナリ表現を比較し、2 つのオペランドにも設定されているビットのみが設定されているバイナリ値を返します。

たとえば、これを行うと:

2 & 2

それはこれを行います:

0010 & 0010

そして、これは次のようになります:

 0010
 0010
&----
 0010

この結果を 2 (0010) と比較すると、もちろん true が返されます。

于 2009-04-27T08:58:27.217 に答える
3

追加するだけです:これはビットマスキングと呼ばれます http://en.wikipedia.org/wiki/Mask_(computing)

ブール値には 1 ビットしか必要ありません。ほとんどのプログラミング言語の実装では、ブール値は 1 ビット以上かかります。PC では、これは大きな無駄にはなりませんが、組み込みシステムでは通常、メモリ スペースが非常に限られているため、無駄が非常に大きくなります。スペースを節約するために、ブール値は一緒にパックされます。このようにして、ブール変数は 1 ビットしか占有しません。

バイト (= 8 ビット) が 8 つのブール変数の配列のようになる配列インデックス操作のようなことを行うと考えることができるので、おそらくそれがあなたの答えです: ブール値の配列を使用します。

于 2009-04-27T09:15:23.883 に答える
1

(iおよび16)/ 16は、5番目のビットの値(1または0)を抽出します。

1xxxx and 16 = 16 / 16 = 1
0xxxx and 16 = 0 / 16 = 0
于 2009-04-27T08:59:00.333 に答える
1

そして、演算子は「...2つの数式のビット論理積」を実行します。これは「|」にマップされます。C#で。'`は整数除算/であり、両方のオペランドが整数型である場合、C#で同等のものはです。

于 2009-04-27T08:59:49.723 に答える
1

定数はマスクです(2進数で考えてください)。したがって、コードが行うことは、ビットを取得するために、バイトとマスクにビット単位のAND演算子を適用し、数値で除算することです。

例えば:

xxxxxxxx & 00000100 = 00000x000
if x == 1
    00000x00 / 00000100 = 000000001
else if x == 0
    00000x00 / 00000100 = 000000000
于 2009-04-27T09:05:37.450 に答える
1

前述のように、これはビット単位のANDであり、論理ANDではありません。これは私の前で何度も言われているようですが、IMOの説明はそれほど簡単ではありません。

私はそれをこのように考えるのが好きです:

2進数を互いに書き留めます(ここでは5と1を実行しています)。

101
001

次に、これを2進数に変換する必要があります。ここで、1番目の数値からのすべての1が転送されます。これは、2番目の数値にもあります。つまり、この場合は次のようになります。

001

この場合、2番目の数値と同じ数値が得られ、この演算(VB)はtrueを返します。他の例を見てみましょう(iとして5を使用):

(5と2)

101
010
----
000

(false)

(5と4)

101
100
---
100

(真)

(5と8)

0101
1000
----
0000

(false)

(5と16)

00101
10000
-----
00000

(false)

編集:そして明らかに私は質問の全体のポイントを逃しています-これが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;
于 2009-04-27T09:06:23.907 に答える
1

C# では、BitArray クラスを使用して個々のビットに直接インデックスを付けます。

個々のビットiを設定するのは簡単です:

b |= 1 << i;

個々のビットをリセットするには、もう少し厄介です

b &= ~(1 << i);

ビット単位の演算子とシフト演算子の両方が、int予期せずキャストが必要になる可能性のあるすべてのものをプロモートする傾向があることに注意してください。

于 2009-04-27T09:28:55.350 に答える
1

これをバイナリで考えてください。

10101010

AND

00000010

収量00000010

つまり、ゼロではありません。最初の値が

10101000

あなたが得るだろう

00000000

つまり、ゼロです。

すべてを 1 または 0 に減らすためのさらなる除算に注意してください。

于 2009-04-27T08:58:18.090 に答える