(非1)由于某种原因求值为-2

时间:2019-03-07 17:14:24

标签: vba operators bitwise-operators bitwise-not

为什么(非1)评估为-2?我希望它的评估结果为0。

enter image description here

3 个答案:

答案 0 :(得分:5)

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

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

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

整数值1转换为布尔值True的原因仅在于True被定义为Not False,这意味着 any 非零值是布尔值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

答案 1 :(得分:3)

VBA / VBScript没有真正的逻辑运算符(AND,OR,NOT)。您看到的逻辑运算符实际上是按位运算符,仅此而已。 VBA玩一些带有TrueFalse值的游戏,因此在大多数情况下都可以使用,但是有时您会发现“陷阱”。

在这种情况下,您不必写If Not InStr() Then来代替If InStr() <= 0 Then
您不必写If InStr() Then

来代替If InStr() > 0 Then

换句话说:InStr()返回一个数字。不要试图将其视为布尔值。

答案 2 :(得分:2)

其他答案已经解释了为什么,因此,我想重点介绍编码实践。

您发现,Not x不一定是您想要的。实际上,您希望更像Not CBool(x)。但是,CBool()可能会引发错误-例如,CBool(Null)会产生错误91(无效使用null)。

可以声称可以通过强变量化变量来避免这种情况,但是即使不使用Variant也不保证在表达式中Boolean将保留Boolean。示例:

?typename(true and 0)
Integer

在实践中,意外地让VBA为您执行伏都教隐式转换太容易了,因此出于这个原因,改变编码习惯可能更适合您。

要测试真实值,您需要像这样的表达式:

If x Then

对于虚假值,您需要像这样的表达式:

If x = False Then

无论x的类型如何,无论它们是否是表达式,它们都可以工作,因此,与If x = True Then或{{1}相比,其行为更加一致/可预测。 }。通过采用这种代码习惯,可以帮助避免因意外转换而远离If Not x Then类型并产生按位运算而不是逻辑运算而引起的细微错误。

对于赋值,使用Boolean变量可以确保始终一致地将其强制转换为BooleanTrue而不是某些随机数。