繁体   English   中英

(不是1)由于某种原因评估为-2

[英](Not 1) evaluates to -2 for some reason

为什么(Not 1)评估为-2? 我希望它评估为0。

在此输入图像描述

1不是True的整数表示, -1是。

Debug.Print CInt(True) 'prints -1
Debug.Print CInt(False) 'prints 0

布尔运算符( NotAndOrXOr )在其操作数为布尔值时表现为“逻辑运算符”。 当他们不是,他们表现为“按位运算符”但事实是,他们总是按位。

整数值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使用TrueFalse值玩一些游戏,所以这大部分时间都有效,但偶尔你会找到一个“陷阱”。

在这种情况下,而不是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 ThenIf Not x Then相比,它的行为被认为更加一致/可预测。 通过采用这种代码习惯,您可以帮助避免因意外转换而产生的细微错误远离Boolean类型并获得按位操作而不是逻辑操作。

对于赋值,使用Boolean变量将确保它始终强制为TrueFalse而不是一些随机数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM