考虑以下两个涉及VBScript中按位比较的条件:
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
等一下,the Not
operator is supposed to perform logical negation on an expression。据我所知,true
的逻辑否定是false
。我必须得出结论认为它不符合这一承诺吗?怎么样,为什么以及这里发生了什么?什么是理由,如果有的话?
答案 0 :(得分:14)
如果两个操作数都是布尔值(True,False),VBScript AND operator执行逻辑 AND操作 - 有点像C(样式)语言&&
运算符。
如果两个操作数都是数字,则它将执行按位 AND操作 - 有点像C语言&
运算符。
如果操作数是混合类型,则布尔值被强制转换为数字 - 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 operator是如何工作的,它会对像C语言!
运算符这样的布尔操作数执行逻辑否定,对像C语言{{3}这样的数字操作数执行按位补码} operator。
如果您想强制对操作数进行逻辑运算,请使用~
来转换操作数:
If Not(CBool(1) And CBool(3)) Then WScript.Echo "yes" Else WScript.Echo "no" ' no
注意:与大多数VBScript运算符一样,Null
操作数会导致运算符返回Null
。在Null
构造中使用时,If
以不寻常的方式运行。
答案 1 :(得分:6)
我在Eric Lippert's blog: Not Logical Is VBScript找到了我的问题的答案。事实上,Not
运算符与其兄弟一样,实际上并不是布尔运算符。
And
, Or
, Not
and Xor
are filed under Logical Operators。
但是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的数字比较不等同于布尔检查。
考虑以下代码,该代码采用Salman A的CBool
建议作为此问题的最终解决方案:
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