web-dev-qa-db-ja.com

Javaのブール演算に対するビット演算子の効果

ビット演算子は変数を移動し、ビットごとに操作することになっています。整数、long、charの場合、これは理にかなっています。これらの変数には、サイズによって強制される値の全範囲を含めることができます。

ただし、ブール値の場合、ブール値には2つの値しか含めることができません。 1 =真または0 =偽。ただし、ブール値のサイズは定義されていません。それは、1バイトと同じくらい大きい場合もあれば、少し小さい場合もある。

それでは、ブール演算でビット演算子を使用することの効果は何ですか? JVMは基本的にそれを通常の論理演算子に変換して先へ進みますか?操作の目的で、ブール値を単一ビットのエンティティとして扱いますか?または、結果はブール値のサイズとともに未定義ですか?

103
Daniel Bingham

演算子&、^、および|オペランドがプリミティブな整数型である場合、ビット単位の演算子です。オペランドがブールの場合、これらは論理演算子であり、後者の場合の動作が指定されます。詳細については、 Java言語仕様 のセクション15.22.2を参照してください。

109
Noel Ang

ビットごとの演算子を使用すると、短絡動作を回避できます。

_boolean b = booleanExpression1() && booleanExpression2();
boolean b = booleanExpression1() & booleanExpression2();
_

booleanExpression1()falseに評価される場合、
booleanExpression2()は最初のケースでは評価されません。
booleanExpression2()(およびそれが持つ可能性のある副作用)is 2番目の場合に評価され、

78
mob

他の回答で説明されていることを超えて、_&&_および_||_の優先順位が_&_および_|_と異なることに注意してください。

優先順位テーブル (最上位の優先順位)から抽出します。

_bitwise AND                 &
bitwise exclusive OR        ^
bitwise inclusive OR        |
logical AND                 &&
logical OR                  ||
_

これはあなたにとって何を意味しますか?

_&_と_|_のみ、または_&&_と_||_のみに固執する限り、まったく何もありません。

ただし、_|_は_&&_より優先順位が高いため(優先順位が低い_||_とは対照的です)、それらを自由に混在させると予期しない動作が発生する可能性があります。

_a && b | c && d_はa && (b | c) && dと同じですが、
_a && b || c && d_とは対照的に、_(a && b) || (c && d)_になります。

それらが同じではないことを証明するために、真理値表からの抜粋を検討してください。

_a | b | c | d | (b|c) | (a&&b) | (c&&d) | a && (b|c) && d | (a&&b) || (c&&d)
F | T | T | T |   T   |   F    |    T   |         F       |        T
                                                  ^                ^
                                                  |- not the same -|
_

ORにANDよりも高い優先順位を持たせたい場合、couldは_|_と_&&_を一緒に使用しますが、これは推奨されません。

ただし、異なるシンボルを使用するときはいつでも優先順位を明確にするために、括弧で囲む必要があります。つまり、_(a && b) || c_(優先順位を明確にする括弧)、_a && b && c_(括弧は不要です)。

18
Dukeling

動作する場合でも、実行しないでください。言語仕様は、両方のオペランドがプリミティブ整数型であるか、両方がブール型である場合にのみビット演算子を定義します。それ以外の場合、結果は定義されていません。

http://Java.Sun.com/docs/books/jls/second_edition/html/expressions.doc.html#5228

2
LeffeBrune