論理演算子は Boolean
式を比較し、 Boolean
結果を返します。
And
、Or
、AndAlso
、OrElse
、およびXor
演算子は 2 つのオペランドを受け取るためバイナリですが、Not
演算子は単一オペランドを受け取るため単項です。 これらの演算子の一部では、整数値に対してビットごとの論理演算を実行することもできます。
単項論理演算子
Not 演算子は、Boolean
式に対して論理否定を実行します。 オペランドの論理的な反対が生成されます。 式が True
に評価された場合、 Not
は False
を返します。式が False
に評価された場合、 Not
は True
を返します。 この例を次に示します。
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
と評価された場合、 And
は True
を返します。 少なくとも 1 つの式が False
と評価された場合、 And
は False
を返します。
Or 演算子は、2 つのBoolean
式に対して論理和演算または包含を実行します。 いずれかの式が True
に評価されるか、両方が True
に評価された場合、 Or
は True
を返します。 どちらの式も True
に評価されていない場合、 Or
は False
を返します。
Xor 演算子は、2 つのBoolean
式に対して論理除外を実行します。 1 つの式が True
に評価されるが、両方では評価されない場合、 Xor
は True
を返します。 両方の式が True
評価されるか、両方が False
に評価された場合、 Xor
は False
を返します。
次の例は、 And
、 Or
、および 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 番目の式は最終的な結果を変更できないため評価されず、AndAlso
はFalse
を返します。
同様に、 OrElse 演算子 は、2 つの Boolean
式に対して短絡論理和演算を実行します。
OrElse
式の最初の式がTrue
と評価された場合、2 番目の式は最終的な結果を変更できないため評価されず、OrElse
はTrue
を返します。
Short-Circuiting Trade-Offs
ショートサーキットでは、論理演算の結果を変更できない式を評価しないことで、パフォーマンスを向上させることができます。 ただし、その式が追加のアクションを実行する場合、ショートサーキットはそれらのアクションをスキップします。 たとえば、式に Function
プロシージャの呼び出しが含まれている場合、そのプロシージャは、式がショートサーキットされていて、 Function
に含まれる追加のコードが実行されない場合は呼び出されません。 そのため、関数はたまにしか実行されず、正しくテストされない可能性があります。 または、プログラム ロジックは、 Function
のコードに依存する場合があります。
次の例では、 And
、 Or
、およびそれらのショートサーキットの違いを示します。
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 > 45
がFalse
を返しても、最初のIf
ステートメントはcheckIfValid()
を呼び出します。これは、And
がショートサーキットしないためです。 2 番目の If
ステートメントは checkIfValid()
を呼び出しません。 12 > 45
が False
を返すと、2 番目の式 AndAlso
ショートサーキットするためです。 3 番目の If
ステートメントは、12 < 45
がTrue
を返してもcheckIfValid()
を呼び出します。これは、Or
がショートサーキットしないためです。 4 番目の If
ステートメントは checkIfValid()
を呼び出しません。これは、 12 < 45
が True
を返すときに、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
演算子はビットごとの演算をサポートしていません。
注
ビットごとの演算は整数型でのみ実行できます。 ビットごとの演算を続行するには、浮動小数点値を整数型に変換する必要があります。
こちらも参照ください
.NET