web-dev-qa-db-ja.com

ブール演算子とビット単位演算子

ブール演算子とビット演算子のどちらを使用すべきかについて混乱しています

  • and vs &
  • or vs |

誰かがそれぞれをいつ使用し、いつ他のものを使用すると結果に影響するかについて私に啓発できますか?

62
Jiew Meng

ガイドラインは次のとおりです。

  • 通常、ブール演算子はboolean値で使用されますが、ビット単位の演算子は通常integer値で使用されます。
  • ブール演算子は短絡ですが、ビット単位の演算子はnot短絡です。

短絡動作は、次のような式で役立ちます。

if x is not None and x.foo == 42:
    # ...

これは、両側が常に評価され、&を与えるため、ビット単位のAttributeError: 'NoneType' object has no attribute 'foo'演算子では正しく機能しません。ブール値のandoperatorを使用すると、最初の式がFalseの場合、2番目の式は評価されません。同様に、orは、最初の引数がTrueの場合、2番目の引数を評価しません。

59
Mark Byers

理論的には、andおよびorはブールロジックから直接派生します(したがって、2つのブールを操作してブールを生成します)が、_&_および_|_はブールおよび/または整数の個々のビットに適用されます。ここでは、後者が正確に機能する方法について多くの質問があります。

結果に影響を及ぼす可能性のある実際的な違いを次に示します。

  1. andorの短絡、つまりTrue or sys.exit(1)は終了しません。これは、最初のオペランドの特定の値(_True or ..._、_False and ..._)に対して、2番目のオペランドが変更されないためですresult =を評価する必要はありません。しかし、_|_と_&_は短絡しません-True | sys.exit(1)はREPLから抜け出します。
  2. (Pythonを含む、演算子のオーバーロードがある一部の言語にのみ適用されます。)_&_および_|_は通常の演算子であり、オーバーロードできます-andおよびorは言語に偽造されます(少なくともPythonでは、ブールへの強制のための特別な方法には副作用があります)。
  3. (いくつかの言語にのみ適用されます[KennyTMのコメントを参照] :) andおよびorは、(常にこれを本当に理解することも、必要とすることもありません)TrueまたはFalseの代わりにオペランドの値を返します。これは条件内のブール式の意味を変更しません-_1 or True_は_1_ですが、_1_もtrueです。しかし、かつて条件演算子をエミュレートするために使用されていました(C構文の_cond ? true_val : false_val_、Python数年前から)_true_val if cond else false_val_。_&_および_|_、結果の型は、オペランドがそれぞれの特別なメソッドをオーバーロードする方法に依存します(_True & False_はFalse、_99 & 7_は_3_で、集合の和集合/交差点については...)。

しかし、たとえ_a_boolean & another_boolean_は同じように機能しますが、正しい解決策はandを使用することです-単にandorがブール式と条件に関連付けられているのに対し、_&_と_|_はビット調整を表します。

20
user395760

ここにさらなる違いがありますが、今しばらく困惑していました:_&_(および他のビット演算子)はand(および他のブール演算子)より高い優先順位を持っているため、次の式は異なると評価されます値:

_0 < 1 & 0 < 2
_

versus

_0 < 1 and 0 < 2
_

つまり、最初のFalse0 < (1 & 0) < 2と同等であり、したがって_0 < 0 < 2_、したがって_0 < 0 and 0 < 2_になります。

16
Arend

numpyで要素単位のブール演算を実行しようとしている場合、答えは多少異なります。要素単位のブール演算には&|を使用できますが、andorは値エラーを返します。

安全のために、 numpy logic functions を使用できます。

np.array([True, False, True]) | np.array([True, False, False])
# array([ True, False,  True], dtype=bool)

np.array([True, False, True]) or np.array([True, False, False])
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

np.logical_or(np.array([True, False, True]), np.array([True, False, False]))
# array([ True, False,  True], dtype=bool)
4
C8H10N4O2

ブール演算は論理演算です。

ビット演算は、バイナリビットの演算です。

ビット演算:

>>> k = 1
>>> z = 3
>>> k & z  
1
>>> k | z  
3

操作:

And & 1 if both bits are 1, 0 otherwise
Or  | 1 if either bit is 1
Xor ^ 1 if the bits are different, 0 if they're the same
Not ~ Flip each bit

ビット演算の使用法のいくつか:

1)ビットの設定とクリア

ブール演算:

>>> k = True
>>> z = False
>>> k & z  # and
False
>>> k | z  # or
True
>>> 
2
pyfunc

ヒントは名前にあります:

  • ブール演算子は、論理演算を実行するためのものです(プログラミングおよび形式論理で一般的な真理のテスト)
  • ビット単位の演算子は、 "bit-twiddling"(バイトおよび数値データ型のビットの低レベル操作)用です。

ビット効率演算子を使用して論理演算を実行することは可能ですが、実際には(通常は効率上の理由で)望ましい場合もありますが、微妙なバグや望ましくない副作用を防ぐために、一般的にそのような目的でそれらを回避する必要があります。

ビットを操作する必要がある場合、ビットごとの演算子は専用です。楽しい本: Hackers Delight には、ビットトゥイドリングで達成できることのクールで真に有用な例が含まれています。

2
Tendayi Mawushe

一般的な規則は、既存のオペランドに適切な演算子を使用することです。ブールオペランドでブール(論理)演算子を使用し、(より広い)整数オペランドでビット単位演算子を使用します(注:Falseはと同等、およびTrueから1)。唯一の「つまらない」シナリオは、ブール演算子を非ブールオペランドに適用することです。
[SO]:Python-'and'と '&'の違い[duplicate]5 & 7で説明されている簡単な例を見てみましょう。 vs。5 and 7

bitwiseand)の場合、物事は簡単です。

5     = 0b101
7     = 0b111
-----------------
5 & 7 = 0b101 = 5

論理andの場合、次のようになります [Python 3]:ブール演算 状態(emphasisは私の):

andor も値とタイプを制限しないことに注意してくださいFalseTrueではなく、最後に評価された引数を返す

Example

>>> 5 and 7
7
>>> 7 and 5
5

もちろん、vs。orにも同じことが当てはまります。

1
CristiFati

ブール値の「and」とビット単位の「&」:

擬似コード/ Pythonは、これらの違いを理解するのに役立ちました。

def boolAnd(A, B):
    # boolean 'and' returns either A or B
    if A == False:
        return A
    else:
        return B

def bitwiseAnd(A , B):
    # binary representation (e.g. 9 is '1001', 1 is '0001', etc.)

    binA = binary(A)
    binB = binary(B)



    # perform boolean 'and' on each pair of binaries in (A, B)
    # then return the result:
    # equivalent to: return ''.join([x*y for (x,y) in Zip(binA, binB)])

    # assuming binA and binB are the same length
    result = []
    for i in range(len(binA)):
      compar = boolAnd(binA[i], binB[i]) 
      result.append(compar)

    # we want to return a string of 1s and 0s, not a list

    return ''.join(result)
0

論理演算

通常、条件文に使用されます。例えば:

if a==2 and b >10 then /*Do something...*/ endifこれは、両方の条件((a == 2)(b> 10))が同時に真である場合、条件文の本体を実行できることを意味します。

ビット演算

ビット操作は、データの操作と抽出に使用できます。たとえば、整数の4つのLSB(最下位ビット)を抽出する場合は、次の操作を実行できます。

抽出:

poo & 0x000F

マスキング:

poo | 0xFFF0

0
pooria