次のコードでは:
Expression<Func<int, bool>> isOdd = i => (i & 1) == 1;
...の意味は(i & 1) == 1
何ですか?
ビットごとのAND。この場合、の最後のビットi
が設定されているかどうかを確認します。そうである場合、最後のビットは1を表し、他のすべてのビットは偶数を表すため、奇数である必要があります。
'&'はビット単位の演算子です。&'を1にすると、他のすべての2進数が削除され、数値が偶数の場合は0、奇数の場合は1になります。
それがハッカーのやり方です。もちろん、数学者はモジュロ2算術を使用して、代わりに((i%2)== 1)と書きます。ソフトウェアエンジニアは!IsEven(i)を記述しますが、ライブラリ関数を再利用して再利用ブラウニーポイントを獲得します... :-)
さて、これらのいずれかがより効率的であるかどうかは、コンパイラとCLRに依存します。この場合、誰がLINQ式ツリーを処理できるか、およびその受信者が何を処理する準備ができているかによっても異なります。
& はビットごとの AND 演算子であり、AND はバイナリ システムの基本的な操作の 1 つです。
AND は「A と B の両方がオンの場合」を意味します。実世界の例は、直列の 2 つのスイッチです。電流は、両方が電流を通過できる場合にのみ通過します。
コンピューターでは、これらは物理的なスイッチではなく半導体であり、その機能は論理ゲートと呼ばれます。それらはスイッチと同じ種類のことを行います-電流に反応するか、電流なしに反応します。
整数に適用すると、一方の数値のすべてのビットが他方の数値のすべてのビットと結合されます。したがって、ビットごとの演算子 AND を理解するには、数値を 2 進数に変換してから、一致するビットのすべてのペアに対して AND 演算を実行する必要があります。
それが理由です:
00011011 (odd number)
AND
00000001 (& 1)
==
00000001 (results in 1)
一方
00011010 (even number)
AND
00000001 (& 1)
==
00000000 (results in 0)
したがって、(& 1) 演算は、AND ロジックを使用して右端のビットを 1 と比較します。他のすべてのビットは事実上無視されます。
これは、数値が奇数かどうかをチェックすることと同じです (すべての奇数の右端のビットは 1 です)。
上記は、私がこの質問に書いた同様の回答から改作されています。
これは、最後のビットがオンになっているかどうかをチェックしています(これにより奇妙になります)。linq専用ではないことに注意してください。これは、sqlまたはc#コードで実行できます。