[英](Not 1) evaluates to -2 for some reason
1
不是True
的整数表示, -1
是。
Debug.Print CInt(True) 'prints -1
Debug.Print CInt(False) 'prints 0
布尔运算符( Not
, And
, Or
, XOr
)在其操作数为布尔值时表现为“逻辑运算符”。 当他们不是,他们表现为“按位运算符”但事实是,他们总是按位。
整数值1
转换为布尔值True
因为True
定义为Not False
,这意味着任何非零值都是布尔值True
。 但是,当您使用-1
表示True
时,您只能获得正确/预期的逻辑行为。
Integer
由16位表示,因此1
是这样的:
0000 0000 0000 0001
这使得Not 1
:
1111 1111 1111 1110
符号位打开,因此值为负 - 修剪无关紧要的数字,您得到:
10
这是2
的二进制表示。 因此, Not 1
是-2
。
相反, -1
将是:
1111 1111 1111 1111
因此Not -1
:
0000 0000 0000 0000
VBA / VBScript没有真正的逻辑运算符(AND,OR,NOT)。 您看到的逻辑运算符实际上是按位运算符,而这就是您所获得的。 VBA使用True
和False
值玩一些游戏,所以这大部分时间都有效,但偶尔你会找到一个“陷阱”。
在这种情况下,而不是If Not InStr() Then
你必须写If InStr() <= 0 Then
。
而不是If InStr() Then
你必须写If InStr() > 0 Then
换句话说: InStr()
返回一个数字 。 不要试图像布尔一样对待它。
由于其他答案已经解释了为什么 ,我想专注于编码实践。
正如您所发现的, Not x
不一定是您想要的。 在实践中,你想要更像Not CBool(x)
。 但是, CBool()
可能会抛出错误 - 例如, CBool(Null)
产生错误91(无效使用null)。
可能会声称您可以通过对变量进行强类型来避免这种情况,但即使不使用Variant
也不能保证在表达式中Boolean
将保持为Boolean
。 例:
?typename(true and 0)
Integer
在实践中,很容易让VBA意外地让你为你做隐伏的转换,所以出于这个原因,改变编码习惯可能会更适合你。
要测试truthy值,您需要以下表达式:
If x Then
对于虚假值,您需要以下表达式:
If x = False Then
这些工作无论x
的类型如何,无论是否是表达式,因此与If x = True Then
或If Not x Then
相比,它的行为被认为更加一致/可预测。 通过采用这种代码习惯,您可以帮助避免因意外转换而产生的细微错误远离Boolean
类型并获得按位操作而不是逻辑操作。
对于赋值,使用Boolean
变量将确保它始终强制为True
或False
而不是一些随机数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.