11

VBScript でのビットごとの比較を含む次の 2 つの条件について考えてみましょう。

If     1 And 3  Then WScript.Echo "yes" Else WScript.Echo "no"
If Not(1 And 3) Then WScript.Echo "yes" Else WScript.Echo "no"

出力は次のようになるはずです。

yes
no

しかし、実際の出力は次のとおりです。

yes
yes

ちょっと待ってください。演算子Not式に対して論理否定を実行することになっています。私の知る限り、の論理否定はtrueです。falseその約束を果たせていないと結論付けなければなりませんか?ここで、どのように、なぜ、何が起こっているのでしょうか? あるとすれば、その根拠は何ですか?

4

2 に答える 2

15

VBScriptのAND 演算子は、両方のオペランドがブール値 (True、False) の場合に論理AND 演算を実行します。これは、C (スタイル) 言語の&&演算子と似ています。

両方のオペランドが数値の場合、C 言語の演算子のように、代わりにビットごとのAND 演算を実行し&ます。

オペランドの型が混在している場合、ブール値は数値にキャストされます -- False = 0、True = -1 (驚き!) の後に、ビットごとの AND 演算が続きます。

したがって、あなたの例は次のように評価されます。

'   1 And 3
' = &h0001 And &h0003 <- bitwise AND
' = 1
If 1 Then WScript.Echo "yes" Else WScript.Echo "no" ' Yes

'   Not(1 And 3)
' = Not(1) <- see above
' = Not(&h0001) <- bitwise NOT
' = &hFFFE
If -2 Then WScript.Echo "yes" Else WScript.Echo "no" ' Yes

VBScript の NOT 演算子がどのように機能するか疑問に思われている場合は、C 言語演算子のようなブール オペランドに対して論理否定を実行し、C 言語!演算子のような数値オペランドに対してビットごとの補数を実行します~

オペランドに論理演算を強制する場合は、VBScript CBool​​ 関数を使用してオペランドをキャストします。

If Not(CBool(1) And CBool(3)) Then WScript.Echo "yes" Else WScript.Echo "no" ' no

注: ほとんどの VBScript 演算子と同様に、Nullオペランドによって演算子は を返しNullます。コンストラクトNull内で使用すると、通常とは異なる動作をします。If

于 2012-06-03T20:16:38.083 に答える
6

Eric Lippertのブログで私の質問に対する答えを見つけました:論理的ではありませんVBScriptです。演算子Notは、その兄弟のように、実際にはブール演算子ではないことがわかります。

And、、、およびは、MSDNの論理演算子の下OrNotXorファイルされます

しかし、Eric Lippertはそれらをビット単位でラベル付けします。これは、MSDNのように論理的なものよりも優れた説明です。論理的なものは実際にどのように機能しているかを示していないため、私のような人々は、彼らがブール演算子であると信じ込んでしまいます。再しないでください。そして、これは大きな罠です。

ステートメントを次のように書き直して、自分のやりたいことを実行させる必要があります。

If     (1 And 3) > 0  Then WScript.Echo "yes" Else WScript.Echo "no"
If Not((1 And 3) > 0) Then WScript.Echo "yes" Else WScript.Echo "no"

これは、印刷yesしてから必要に応じて印刷しnoます。

更新:上記はこの場合は機能するように見えますが、それは間違いなく進むべき道ではありません。問題は、私がチェックしたいことが何であるかを理解することです。上記のコードはそれを明確にしません。結果の0より大きいビット単位の比較と数値の比較は、ブールチェックと同等ではありません。

CBoolこの問題の最終的な解決策としてSalmanAの提案を採用した次のコードについて考えてみます。

Option Explicit
Dim a, b
a = -3 : b = -2

If  a And b       Then WScript.Echo "ja" Else WScript.Echo "nein" ' bad
If (a And b) > 0  Then WScript.Echo "ja" Else WScript.Echo "nein" ' bad
If CBool(a And b) Then WScript.Echo "ja" Else WScript.Echo "nein" ' good
于 2012-06-03T16:36:55.533 に答える