重複の可能性:
|の違いは何ですか および|| または演算子?
論理積と論理積:
(x & y)
(x | y)
条件付きANDおよびOR:
(x && y)
(x || y)
これまで、条件付きオペランドについてしか知りませんでした。私はそれが何をするのか、そしてそれをif文に適用する方法を知っています。しかし、論理オペランドの目的は何ですか?
重複の可能性:
|の違いは何ですか および|| または演算子?
論理積と論理積:
(x & y)
(x | y)
条件付きANDおよびOR:
(x && y)
(x || y)
これまで、条件付きオペランドについてしか知りませんでした。私はそれが何をするのか、そしてそれをif文に適用する方法を知っています。しかし、論理オペランドの目的は何ですか?
「論理的」の一般的な概念はどちらの場合にも当てはまるので、「論理的vs条件付き」ではなく、「ビット単位vs.条件付き」と考える方が好きです。
x & y // bitwise AND, 0101 & 0011 = 0001
x | y // bitwise OR, 0101 | 0011 = 0111
x && y // true if both x and y are true
x || y // true if either x or y are true
編集
一般の要望により、議論の評価も異なることにも言及する必要があります。条件付きバージョンでは、操作全体の結果が最初の引数で判別できる場合、2番目の引数は評価されません。これは短絡評価と呼ばれます。ビット単位の演算では、最終的な値を計算するために両側を評価する必要があります。
例えば:
x.foo() && y.bar()
これは、と評価されたy.bar()
場合にのみ呼び出されます。逆に、x.foo()
true
x.foo() || y.bar()
に評価されたy.bar()
場合にのみ呼び出します。x.foo()
false
(x && y)
怠惰です。xが真の場合にのみyを評価します。
(x & y)
怠惰ではありません。yは常に評価されます。
更新された回答-私のオリジナルは誤解を招き、不完全でした。
まず、この質問に対する私のコメントと回答の多くをお詫びする必要があります。
仕様を読んだ後、ビット演算子と条件演算子の違いはそれほど明確ではありません。
ECMA-334のセクション14.10によると:
&、^、および| 演算子は論理演算子と呼ばれます。
整数演算の場合:
1&演算子は、2つのオペランドのビット単位の論理積|を計算します。演算子は2つのオペランドのビット単位の論理ORを計算し、^演算子は2つのオペランドのビット単位の論理排他的論理和を計算します。2これらの操作によるオーバーフローは発生しません。
セクション14.11によると:
&&と|| 演算子は条件付き論理演算子と呼ばれます。2これらは「短絡」論理演算子とも呼ばれます。
14.11.1
1&&または||のオペランドが がbool型であるか、オペランドが該当する演算子および/または演算子|を定義しない型であるが、boolへの暗黙の変換を定義する場合、演算は次のように処理されます。2演算x && yはx?として評価されます。y:false。3つまり、xが最初に評価され、bool型に変換されます。4次に、xがtrueの場合、yが評価され、bool型に変換され、これが演算の結果になります。5それ以外の場合、操作の結果はfalseです。6操作x|| yはxとして評価されますか?true:y。7つまり、xが最初に評価され、bool型に変換されます。8次に、xが真の場合、演算の結果は真になります。9それ以外の場合、yは評価され、bool型に変換され、これが演算の結果になります。
14.11.2
1&&または||のオペランドが は、該当するユーザー定義演算子および/または演算子|を宣言する型であり、次の両方が真である必要があります。ここで、Tは、選択された演算子が宣言される型です。2戻り型と選択された各パラメーターの型演算子はTでなければなりません。3言い換えると、演算子はT型の2つのオペランドの論理積または論理ORを計算し、T型の結果を返す必要があります。4Tには、演算子trueおよび演算子falseの宣言が含まれている必要があります。パラグラフ21これらの要件のいずれかが満たされない場合、コンパイル時エラーが発生します。2それ以外の場合、&&または|| 演算は、ユーザー定義の演算子trueまたは演算子falseを、選択したユーザー定義の演算子と組み合わせて評価されます。3演算x && yはT.false(x)として評価されますか?x:T。&(x、y)、ここでT.false(x)はTで宣言された演算子falseの呼び出しであり、T。&(x、y)は選択された演算子&の呼び出しです。4つまり、xが最初に評価され、結果に対して演算子falseが呼び出されて、xが間違いなくfalseであるかどうかが判別されます。5次に、xが間違いなく偽の場合、演算の結果は、以前にxに対して計算された値になります。6それ以外の場合は、yが評価され、選択された演算子&が、以前にxに対して計算された値と、yに対して計算された値に対して呼び出され、演算の結果が生成されます。7操作x|| yはT.true(x)として評価されますか?x:T. |(x、y)、ここでT.true(x)はTで宣言された演算子trueの呼び出しであり、T。|(x、y)は選択された演算子|の呼び出しです。8言い換えれば、xが最初に評価され、結果に対して演算子trueが呼び出されて、xが確実にtrueであるかどうかが判別されます。9次に、xが確実に真である場合、演算の結果は、以前にxに対して計算された値になります。10それ以外の場合、yが評価され、選択された演算子| は、以前にxに対して計算された値と、yに対して計算された値に対して呼び出され、演算の結果を生成します。パラグラフ31これらの操作のいずれにおいても、xによって与えられた式は1回だけ評価され、yによって与えられた式は評価されないか、1回だけ評価されます。パラグラフ41演算子trueおよび演算子falseを実装するタイプの例については、§18.4.2を参照してください。演算の結果は、xに対して以前に計算された値です。10それ以外の場合、yが評価され、選択された演算子| は、以前にxに対して計算された値と、yに対して計算された値に対して呼び出され、演算の結果を生成します。パラグラフ31これらの操作のいずれにおいても、xによって与えられた式は1回だけ評価され、yによって与えられた式は評価されないか、1回だけ評価されます。パラグラフ41演算子trueおよび演算子falseを実装するタイプの例については、§18.4.2を参照してください。演算の結果は、xに対して以前に計算された値です。10それ以外の場合、yが評価され、選択された演算子| は、以前にxに対して計算された値と、yに対して計算された値に対して呼び出され、演算の結果を生成します。パラグラフ31これらの操作のいずれにおいても、xによって与えられた式は1回だけ評価され、yによって与えられた式は評価されないか、1回だけ評価されます。パラグラフ41演算子trueおよび演算子falseを実装するタイプの例については、§18.4.2を参照してください。xで指定された式は1回だけ評価され、yで指定された式は評価されないか、1回だけ評価されます。パラグラフ41演算子trueおよび演算子falseを実装するタイプの例については、§18.4.2を参照してください。xで指定された式は1回だけ評価され、yで指定された式は評価されないか、1回だけ評価されます。パラグラフ41演算子trueおよび演算子falseを実装するタイプの例については、§18.4.2を参照してください。