ブール演算子の違い:&vs &&および| 対||


回答:


134

これらは、ビットごとのANDおよびビットごとのOR演算子です。

int a = 6; // 110
int b = 4; // 100

// Bitwise AND    

int c = a & b;
//   110
// & 100
// -----
//   100

// Bitwise OR

int d = a | b;
//   110
// | 100
// -----
//   110

System.out.println(c); // 4
System.out.println(d); // 6

Java言語仕様の該当するセクション(指摘してカルロスのおかげ15.22.115.22.2その入力に基づいてオペレータの異なる振る舞いについてを)。

実際、両方の入力がブール値である場合、演算子はブール論理演算子と見なされ、条件付きAND(&&)および条件付きOR(||)演算子と同様に動作しますが、これらは短絡しないので、以下は安全です:

if((a != null) && (a.something == 3)){
}

これではありません:

if((a != null) & (a.something == 3)){
}

「短絡」とは、オペレーターが必ずしもすべての状態を調べるわけではないことを意味します。上記の例で&&は、aはでない場合にのみ2番目の条件を検査しますnull(そうでない場合、ステートメント全体がfalseを返し、いずれにしても以下の条件を検査a.somethingすることはできません)。したがって、ステートメントは例外を発生させないか、「安全」

&オペレータは、常に、句内のすべての状態を検査するので、上記の例では、a.somethingときに評価することができるaという事実にあるnull値例外を発生させます。


1
明確にしたかった。&両方が1の場合にのみ1を返しますか?101と001は001になりますか?正しい?
ギデオン

@giddy @Jonathon-その状況をよりよく示すために値を更新しました。
Justin Niessner、2010年

不完全:論理演算子でもあります(ブール値の場合)。
user85421

1
@ Carlos-いいえ。これらはまだビット単位の演算子です。それらは、非短絡論理演算子と同じように動作します。違いがあります。
ジャスティンニースナー

4
そして、非短絡論理演算子とは何ですか?演算子&および| (OPから質問)は、「整数ビット演算子」(JLS 15.22.1)「ブール論理演算子」(JLS 15.22.2)です。それともJava言語仕様はそれについて間違っていますか?
user85421 10/10/25

108

私はあなたが両方の演算子の論理的な意味について話していると思います、ここにあなたはテーブル再開があります:

boolean a, b;

Operation     Meaning                       Note
---------     -------                       ----
   a && b     logical AND                    short-circuiting
   a || b     logical OR                     short-circuiting
   a &  b     boolean logical AND            not short-circuiting
   a |  b     boolean logical OR             not short-circuiting
   a ^  b     boolean logical exclusive OR
  !a          logical NOT

short-circuiting        (x != 0) && (1/x > 1)   SAFE
not short-circuiting    (x != 0) &  (1/x > 1)   NOT SAFE

短絡評価、最小評価、またはMcCarthy評価(John McCarthyの後)は、一部のプログラミング言語におけるいくつかのブール演算子のセマンティクスであり、2番目の引数が実行または評価されるのは、最初の引数では十分ではない場合のみです。式:AND関数の最初の引数がfalseと評価される場合、全体的な値はfalseでなければなりません。OR関数の最初の引数がtrueと評価される場合、全体的な値はtrueでなければなりません。

安全でないとは、演算子が句のすべての条件を常に検査することを意味します。したがって、上記の例では、xが実際には0の値である場合に1 / xが評価され、例外が発生します。


1
@Torres-「短絡」と「安全」について説明して、答えを広げてください。また、「排他的論理和」と「論理的否定」も「短絡しない」ですか?そして、なぜそれは「ブール論理否定」の代わりに「論理否定」と呼ばれるのですか?そして、なぜ「論理NOT」は「論理AND」および「論理OR」とグループ化されないのですか?良い答えですが、仕事が必要です。
tfmontague 2017年

@tfmontague、私は短絡の意味を説明しました(この回答を編集することによって)。私の編集が「ピアレビュー」されるのを待っています。
Taslim Oseni 2017

短絡しないことについて「安全でない」とは何ですか?短絡回路を使用するよりも安全であるべきではありませんか?ところで、あなたは「短絡」という用語を本当に説明していません。これは、「短絡ではない」ですべての部品が最初に評価され、次にブール演算が適用されることを意味します。一方、短絡では、最初の式が(a || b)のような条件を満たさない場合、評価は停止されます。 aがtrueで、or演算がtrueを返す場合、bが何であってもbを評価します。
SCI

26

私はここにたくさんの答えがあることを知っていますが、それらはすべて少し混乱しているようです。そこで、Java oracleスタディガイドからいくつかの調査を行った後、&&または&を使用する場合の3つの異なるシナリオを考え出しました。3つのシナリオは、論理ANDビットごとのAND、およびブールANDです。

論理AND: 論理AND(別名条件AND)は&&演算子を使用します。これは短絡的な意味です。左のオペランドがfalseの場合、右のオペランドは評価されません。
例:

int x = 0;
if (false && (1 == ++x) {
    System.out.println("Inside of if");
}
System.out.println(x); // "0"

上記の例では、ifステートメントの最初のオペランドがfalseであるため、xのコンソールに出力される値は0です。したがって、javaは計算する必要がないため(1 == ++ x)、xは計算されません。

ビットごとのAND: ビットごとのANDでは、演算子を使用します。値にビット演算を実行するために使用されます。次のように2進数の演算を見ると、何が起こっているのかを簡単に確認できます。

int a = 5;     //                    5 in binary is 0101
int b = 12;    //                   12 in binary is 1100
int c = a & b; // bitwise & preformed on a and b is 0100 which is 4

例でわかるように、数値5と12のバイナリ表現が並んでいる場合、ビットごとのANDは、両方の数値の同じ数字が1である2進数のみを生成します。したがって、0101&1100 == 0100。10進数で5&12 == 4です。

ブールAND: ブールAND演算子は、ビット単位のANDと論理ANDの両方と同様に動作します。私はそれを2つのブール値(またはビット)の間でビットごとのANDを実行すると考えるのが好きなので、演算子を使用します。ブール値は、論理式の結果にもなります。

論理ANDと同様に、trueまたはfalseのいずれかの値を返しますが、論理ANDとは異なり、短絡されません。その理由は、ビット単位のANDを実行するためには、左と右の両方のオペランドの値を知っている必要があるためです。これが元です:

int x = 0;
if (false & (1 == ++x) {
    System.out.println("Inside of if");
}
System.out.println(x); //"1"

ifステートメントが実行されると、左側のオペランドがfalseであっても、式(1 == ++ x)が実行されます。したがって、xに出力される値は1になります。

これは、論理OR(||)、ビットごとのOR(|)、ブールOR(|)にも適用されます。これで混乱が解消されることを願っています。


to preform that bitwise AND, it must know the value of both left and right operandsこれは私には正しく聞こえません。を実行するためにBITWISE AND、左のオペランドがである場合の結果を把握するために、右のオペランドを知る必要はありませんFALSE。何を説明することは正しいですが、あなたの状態の推論は...少なくとも私には、そうは思えない
Koray Tugay

7

演算子&&および|| ショートサーキットです。つまり、左側の式の値が結果を決定するのに十分である場合、右側の式を評価しません。


7
-1は、彼がすでに知っていることをOPに伝え、彼が実際に尋ねた質問に答えなかった場合。
Alnitak

5

&および| &&と同じ結果を提供します|| 演算子。違いは、式の両側が常に評価されることです。最初の条件が結果を決定するのに十分かどうかの評価を停止します。


1
Wrong .... 最初の条件がtrueの場合にのみ戻りますが&&、両方の結果を評価し||ます。
Buhake Sindi、

1
え?&&は、左側がすでにtrueに評価されている場合にのみ、式の右側を評価します。それ以外の場合、最初の偽が暗黙的に結果が真ではないことを意味するため、評価が停止します。jguru.com/faq/view.jsp?EID=16530を
ブライアンスコット

1
( 2 & 4 )はに評価されますがfalse、には( 2 && 4 )評価されtrueます。どのように正確に同じ結果ですか?
Piskvorが

1
@Piskvor-Javaではありません! 2 & 4結果はブール値ではなく整数になります(この場合はゼロ)。2 && 4&&はコンパイルせず、ブール値のみを受け入れます。Javaはブール値とint型の混合許可しない:ゼロではないがfalsefalseゼロではない...
user85421

1
@BuhakeSindi間違い。以下のための&&最初のオペランドがある場合にのみ第二オペランドを評価しますtrue
ローン侯爵

2

Javaでは、単一の演算子&、|、^ 、! オペランドによって異なります。両方のオペランドがintの場合、ビットごとの演算が実行されます。両方がブール値の場合、「論理」操作が実行されます。

両方のオペランドが一致しない場合、コンパイル時エラーがスローされます。

二重演算子&&、|| 単一の対応物と同様に動作しますが、両方のオペランドは条件式でなければなりません。次に例を示します。

if((a <0)&&(b <0)){...}または同様に、if((a <0)||(b <0)){...}

ソース:Javaプログラミング言語4版



1

おそらく、同じ式で条件付きANDおよび条件付きORを使用する前に、ビットごとのANDおよびビットごとのOR演算子が常に評価されることを知っておくと便利です。

if ( (1>2) && (2>1) | true) // false!

1
評価の順序ではなく、演算子の優先順位を意味しますか?実際のコードで使用されている優先順位の違いは見たくありません。この目的には、ビットごとの演算子ではなく括弧を使用してください。
John Dvorak

1

&&; || 論理演算子です...短絡

&; | ブール論理演算子です...非短絡

式の実行の違いに移動します。ビットごとの演算子は、左側の結果に関係なく、両側を評価します。ただし、論理演算子を使用して式を評価する場合、右側の式の評価は左側の条件によって異なります。

例えば:

int i = 25;
int j = 25;
if(i++ < 0 && j++ > 0)
    System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);

これはi = 26を出力します。j = 25、最初の条件がfalseであるため、右側の条件に関係なく、結果がfalseになるため、右側の条件はバイパスされます。(短絡)

int i = 25;
int j = 25;
if(i++ < 0 & j++ > 0)
    System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);

しかし、これはi = 26を出力します。j = 26、


0

ブール演算子を含む式が評価される場合、両方のオペランドが評価されます。次に、&演算子がオペランドに適用されます。

&&演算子を含む式が評価されると、最初のオペランドが評価されます。最初のオペランドの評価がfalseの場合、2番目のオペランドの評価はスキップされます。

最初のオペランドがtrueの値を返す場合、2番目のオペランドが評価されます。2番目のオペランドがtrueの値を返す場合、&&演算子が1番目と2番目のオペランドに適用されます。

同様の| そして||。


0

基本的な違いは、&ビット単位の演算で主にlongintまたはbyteマスクの種類に使用できる場所で使用されることですが、logicalの代わりに使用しても結果が異なる場合があります&&

一部のシナリオでは、違いがより顕著になります。

  1. 一部の式の評価には時間がかかります
  2. 前の式が真である場合にのみ、式の1つを評価できます
  3. 式にはいくつかの副作用があります(意図されているかどうかにかかわらず)

最初のポイントは非常に簡単です。バグは発生しませんが、時間がかかります。1つの条件ステートメントに複数の異なるチェックがある場合は、コストが低いか、失敗する可能性が高いチェックを左に置きます。

2番目のポイントについては、次の例を参照してください。

if ((a != null) & (a.isEmpty()))

null2番目の式を評価するとが生成されるため、これは失敗しますNullPointerException。論理演算子&&は遅延です。左のオペランドがfalseの場合、右のオペランドが何であっても結果はfalseになります。

3番目のポイントの例-トリガーやカスケードなしでDBを使用するアプリがあるとします。Buildingオブジェクトを削除する前に、Departmentオブジェクトの建物を別の建物に変更する必要があります。また、操作のステータスがブール値(true =成功)として返されるとします。次に:

if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))

これは両方の式を評価するため、何らかの理由で部門の更新が失敗した場合でも建物の削除を実行します。を使用&&すると、意図したとおりに機能し、最初の失敗後に停止します。

についてはa || b、と同等で!(!a && !b)atrueの場合は停止します。これ以上の説明は必要ありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.