次の方法で共有


Visual Basic の論理演算子とビット演算子

論理演算子は Boolean 式を比較し、 Boolean 結果を返します。 AndOrAndAlsoOrElse、およびXor演算子は 2 つのオペランドを受け取るためバイナリですが、Not演算子は単一オペランドを受け取るため単項です。 これらの演算子の一部では、整数値に対してビットごとの論理演算を実行することもできます。

単項論理演算子

Not 演算子は、Boolean式に対して論理否定を実行します。 オペランドの論理的な反対が生成されます。 式が Trueに評価された場合、 NotFalseを返します。式が Falseに評価された場合、 NotTrueを返します。 この例を次に示します。

Dim x, y As Boolean
x = Not 23 > 14
y = Not 23 > 67
' The preceding statements set x to False and y to True.

二項論理演算子

And 演算子は、2 つのBoolean式で論理結合を実行します。 両方の式が Trueと評価された場合、 AndTrueを返します。 少なくとも 1 つの式が Falseと評価された場合、 AndFalseを返します。

Or 演算子は、2 つのBoolean式に対して論理演算または包含を実行します。 いずれかの式が Trueに評価されるか、両方が Trueに評価された場合、 OrTrueを返します。 どちらの式も Trueに評価されていない場合、 OrFalseを返します。

Xor 演算子は、2 つのBoolean式に対して論理除外を実行します。 1 つの式が Trueに評価されるが、両方では評価されない場合、 XorTrueを返します。 両方の式が True 評価されるか、両方が Falseに評価された場合、 XorFalseを返します。

次の例は、 AndOr、および Xor 演算子を示しています。

Dim a, b, c, d, e, f, g As Boolean

a = 23 > 14 And 11 > 8
b = 14 > 23 And 11 > 8
' The preceding statements set a to True and b to False.

c = 23 > 14 Or 8 > 11
d = 23 > 67 Or 8 > 11
' The preceding statements set c to True and d to False.

e = 23 > 67 Xor 11 > 8
f = 23 > 14 Xor 11 > 8
g = 14 > 23 Xor 8 > 11
' The preceding statements set e to True, f to False, and g to False.

Short-Circuiting 論理操作

AndAlso 演算子は、2 つのBoolean式でも論理結合を実行するという点で、And演算子によく似ています。 2 つの主な違いは、AndAlsoが短絡動作を示す点です。 AndAlso式の最初の式がFalseと評価された場合、2 番目の式は最終的な結果を変更できないため評価されず、AndAlsoFalseを返します。

同様に、 OrElse 演算子 は、2 つの Boolean 式に対して短絡論理和演算を実行します。 OrElse式の最初の式がTrueと評価された場合、2 番目の式は最終的な結果を変更できないため評価されず、OrElseTrueを返します。

Short-Circuiting Trade-Offs

ショートサーキットでは、論理演算の結果を変更できない式を評価しないことで、パフォーマンスを向上させることができます。 ただし、その式が追加のアクションを実行する場合、ショートサーキットはそれらのアクションをスキップします。 たとえば、式に Function プロシージャの呼び出しが含まれている場合、そのプロシージャは、式がショートサーキットされていて、 Function に含まれる追加のコードが実行されない場合は呼び出されません。 そのため、関数はたまにしか実行されず、正しくテストされない可能性があります。 または、プログラム ロジックは、 Functionのコードに依存する場合があります。

次の例では、 AndOr、およびそれらのショートサーキットの違いを示します。

Dim amount As Integer = 12
Dim highestAllowed As Integer = 45
Dim grandTotal As Integer
If amount > highestAllowed And checkIfValid(amount) Then
    ' The preceding statement calls checkIfValid().
End If
If amount > highestAllowed AndAlso checkIfValid(amount) Then
    ' The preceding statement does not call checkIfValid().
End If
If amount < highestAllowed Or checkIfValid(amount) Then
    ' The preceding statement calls checkIfValid().
End If
If amount < highestAllowed OrElse checkIfValid(amount) Then
    ' The preceding statement does not call checkIfValid().
End If
Function checkIfValid(ByVal checkValue As Integer) As Boolean
    If checkValue > 15 Then
        MsgBox(CStr(checkValue) & " is not a valid value.")
        ' The MsgBox warning is not displayed if the call to
        ' checkIfValid() is part of a short-circuited expression.
        Return False
    Else
        grandTotal += checkValue
        ' The grandTotal value is not updated if the call to
        ' checkIfValid() is part of a short-circuited expression.
        Return True
    End If
End Function

前の例では、 checkIfValid() 内のいくつかの重要なコードは、呼び出しがショートサーキットされると実行されないことに注意してください。 12 > 45Falseを返しても、最初のIfステートメントはcheckIfValid()を呼び出します。これは、Andがショートサーキットしないためです。 2 番目の If ステートメントは checkIfValid()を呼び出しません。 12 > 45Falseを返すと、2 番目の式 AndAlso ショートサーキットするためです。 3 番目の If ステートメントは、12 < 45Trueを返してもcheckIfValid()を呼び出します。これは、Orがショートサーキットしないためです。 4 番目の If ステートメントは checkIfValid()を呼び出しません。これは、 12 < 45Trueを返すときに、2 番目の式 OrElse ショートサーキットするためです。

ビットごとの演算

ビットごとの演算では、2 つの整数値がバイナリ (ベース 2) 形式で評価されます。 対応する位置のビットを比較し、比較に基づいて値を割り当てます。 次の例は、 And 演算子を示しています。

Dim x As Integer
x = 3 And 5

前の例では、 x の値を 1 に設定します。 これは、次の理由で発生します。

  • 値はバイナリとして扱われます。

    バイナリ形式の 3 = 011

    バイナリ形式の 5 = 101

  • And演算子は、バイナリ表現 (一度に 1 つのバイナリ位置 (ビット) を比較します。 指定した位置の両方のビットが 1 の場合、結果のその位置に 1 が配置されます。 いずれかのビットが 0 の場合、結果のその位置に 0 が配置されます。 前の例では、これは次のように動作します。

    011 (バイナリ形式の 3)

    101 (バイナリ形式で 5)

    001 (結果はバイナリ形式)

  • 結果は 10 進数として扱われます。 値 001 は 1 のバイナリ表現であるため、 x = 1 です。

ビットごとの Or 演算は似ていますが、比較されるビットの一方または両方が 1 の場合、結果ビットに 1 が割り当てられる点が異なります。 Xor 比較されたビットの 1 つ (両方ではない) が 1 の場合、結果ビットに 1 が割り当てられます。 Not は 1 つのオペランドを受け取り、符号ビットを含むすべてのビットを反転し、その値を結果に割り当てます。 つまり、符号付きの正の数値の場合、 Not は常に負の値を返し、負の数の場合は常に正またはゼロの値を返 Not

AndAlso演算子とOrElse演算子はビットごとの演算をサポートしていません。

ビットごとの演算は整数型でのみ実行できます。 ビットごとの演算を続行するには、浮動小数点値を整数型に変換する必要があります。

こちらも参照ください