8

2 つの条件 (A と B)のNANDtrue論理ゲートは、いずれかの条件が真であるか、またはいずれの条件も真でない限り有効です。両方のfalse条件が真の場合です。

F NAND F = T
F NAND T = T
T NAND F = T
T NAND T = F

C# では、これを少なくとも 2 つの方法で記述できます。

!(A && B)

また

(!A || !B)

どちらがより効率的ですか?

if(A)B は常にテストされif(!A)、B は決してテストされないように思えます。

しかし、最初の条件は結果を反転する必要があります....

4

3 に答える 3

9

それほど単純ではありません。C# 言語は、&& 演算子を使用して NAND ゲートをまったくモデル化しません。その演算子には短絡動作があり、C# プログラムでは非常に便利です。中括弧言語の一般的な動作として、次のような式はコードをクラッシュさせません。

arr[] = somefunction();
int ix = foo;
if (ix < arr.Length && arr[ix] == 42) {
    EmailBookRecommendation();
}

しかし、これは式の非常に非効率的なバージョンであり、これははるかにパフォーマンスが高いです:

if (ix < arr.Length & arr [ix] == 42) 

これは完全に正当な式であり、& 演算子はブール オペランドで問題なく機能します。しかし残念ながら、これはコードをクラッシュさせます。配列のインデックス式を評価し、それが Kaboom! になります。IndexOutOfRangeException で。

これは、NAND ゲートの問題ではありません。最初の入力が F の場合はクラッシュしません :) それが問題にならない C# 式は多数あります。あなたは本当に & 演算子を好むべきです。それは大きな違いを生みます。したがって、常に次のように記述します。

if (ix >= 1 & ix <= 42) 

もちろん、これは決して失敗することはありません。&& 演算子が & 演算子よりもはるかに非効率的である理由を理解するには、分岐予測を理解する必要があります。それはこの回答で非常によくカバーされています。

于 2013-08-04T00:49:12.993 に答える
3

ない。どちらもまったく同じ短絡動作を持ち、コンパイラは両方を MSIL に変換して のテストを要求しA、その後に条件分岐を行います。Atrue だったブランチには、 のテストがありBます。

あなたが心配すべきことは次のとおりです。

!(A && B)

!(B && A)

場合によって異なるかAB副作用や複雑な計算を引き起こします。

両方が同じであるという例外として考えられるのは、 のカスタム定義がoperator!ある場合です。この場合、実際にはまったく同等ではありません。

于 2013-08-03T21:15:00.160 に答える
-1

2 つの間の 10000 回の比較の短いテストでは、firsone の方が高速であることがわかります。

最初の合計で 1353 ティック、2 番目の合計で 1373 ティックが必要でした。

編集:もう一度、これを数回試してみましたが、結果はさまざまであるため、両方とも同じです。

于 2013-08-03T21:16:03.183 に答える