PHPの理解& (アンパサンド、ビット単位のand)演算子
-
03-07-2019 - |
質問
よく使用するコードでは($ var& 1)
を使用します。 $ var
が奇数の場合はtrueを返し、偶数の場合はfalseを返します。
しかし、"&"の機能実際にそうしますか?
解決
&バイナリの and
です。バイナリ値があり、別のバイナリ値を使用して and
した場合、結果は2つのビット単位の and
になります。例:
01101010
& 01011001
= 01001000
右端のビットは1(その場合は数値が奇数)または0(その場合は数値)です。 1の数字を&
した場合、最下位ビットのみを調べ、ifが数字が1か0かをチェックします。他の人が述べたように、仕組みに関する情報。
他のヒント
バイナリシステムの基本となる2つの操作はORとANDです。
ORは、「AがオンまたはBがオンの場合」を意味します。実際の例は、2つのスイッチを並列に接続することです。どちらかが電流の通過を許可している場合、電流は通過します。
ANDは、「AとBの両方がオンの場合」を意味します。実際の例は、直列の2つのスイッチです。両方が電流の通過を許可している場合にのみ、電流が通過します。
コンピューターでは、これらは物理スイッチではなく半導体であり、その機能は論理ゲート。彼らはスイッチと同じ種類のことをします-電流に反応するか、電流が流れません。
整数に適用すると、1つの数値のすべてのビットが他の数値のすべてのビットと結合されます。したがって、ビット演算子ORおよびANDを理解するには、数値をバイナリに変換してから、一致するビットのすべてのペアに対してORまたはAND演算を行う必要があります。
だからこそ:
00011011 (odd number)
AND
00000001 (& 1)
==
00000001 (results in 1)
理由
00011010 (even number)
AND
00000001 (& 1)
==
00000000 (results in 0)
したがって、(& 1)演算は、ANDロジックを使用して右端のビットを1と比較します。他のすべてのビットは事実上無視されます。何も何もないということはないからです。バイナリの偶数は、10進表記の偶数でもあります(10は2の倍数です)。
バイナリシステムに対するその他の基本的な操作には、NOTおよびXORが含まれます。 NOTは、「Aがオフの場合」を意味し、2つではなく1つの信号または「パラメータ」のみを受け取る唯一の論理ゲートです。 XORは、「AまたはBのいずれかがオンで、両方ではない場合」を意味します。そして、NAND、NOR、およびNXORがありますが、これらは基本的にAND、OR、およびXORとは組み合わせられません。つまり、NANDは「AとBが両方ともオンではない場合」を意味します。
プログラミングでは、演算子
& means AND,
| means OR,
~ means NOT, and
^ means XOR.
その他は、これらを組み合わせることで構成できます。例:
~ (a & b) is equivalent to a NAND operation
PHP固有のメモ
ビット単位の演算子は浮動小数点値では機能せず、PHPでは浮動小数点値が暗黙的に最初に整数に変換されます。整数として表現できる範囲外の数値はゼロに切り捨てられます。つまり、PHP_INT_MAXを超えるすべての数値は「偶数」になります。式($ num& 1)
)で。 PHP_INT_MIN / PHP_INT_MAX以外の数値をサポートするには、 fmod($ num、2)
が必要です。ただし、64ビットPHPを使用している場合、整数はとにかく浮動小数点数よりも精度が高くなります。
これは、ビット単位とPHPについて知るのも興味深いです:
/**
* Regular
*/
echo (true && true); // 1
echo (true && false); // nothing
echo (true || false); // 1
echo (false || false); // nothing
echo (true xor false); // 1
echo (false xor false); // nothing
/**
* Bitwise
*/
echo (true & true); // 1
echo (true & false); // 0
echo (true | false); // 1
echo (false | false); // 0
echo (true ^ false); // 1
echo (false ^ false); // 0
他の回答に加えて、注目に値する
if(func1() && func2())
func1()
がtrueを返す場合("遅延評価")のみ func2()
を呼び出しますが、
if(func1() & func2())
関係なく両方の関数を呼び出しますが、両方の真理値表は同じです(ブール値を返すと仮定)。
thomasrutterは、(実際には後者を行うべきではないことを(下記のコメントで)指摘しています。 (A& B)
は必ずしも(A&& B)
と同じ真実性を持つわけではありません。特に A
および< code> B は整数です。例:A = 1およびB = 2(両方とも真実)の場合、A&amp; Bは偽物ですが、A&amp;&amp; Bは真実です。また、別の開発者はこれがタイプミスであると考え、2つのアンパサンドに「修正」します。
あなたの質問はビットごとの演算子を理解することであり、受け入れられた答えがそれをよく説明していることを知っています。しかし、あなたが与える例では、代わりにモジュロ演算子を使用することをお勧めします:
($var % 2) /* instead of */ ($var & 1)
数が奇数である(2で割り切れない)ことを確認していることを明確にするため、より一般的であるため、($ var%3)を同じ方法で使用して、その動作を推測できます任意のN。