简体   繁体   English

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

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

Why does (Not 1) evaluate as -2? 为什么(Not 1)评估为-2? I would expect it to evaluate as 0. 我希望它评估为0。

在此输入图像描述

1 is not the integer representation of True , -1 is. 1不是True的整数表示, -1是。

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

Boolean operators ( Not , And , Or , XOr ) behave as "logical operators" when their operands are Boolean values. 布尔运算符( NotAndOrXOr )在其操作数为布尔值时表现为“逻辑运算符”。 When they're not, they behave as "bitwise operators" but the truth is, they're always bitwise. 当他们不是,他们表现为“按位运算符”但事实是,他们总是按位。

The integer value 1 converts to the Boolean value True only because True is defined as Not False , which means any non-zero value is a Boolean True . 整数值1转换为布尔值True因为True定义为Not False ,这意味着任何非零值都是布尔值True But you only get the correct/expected logical behavior when you use -1 for True . 但是,当您使用-1表示True时,您只能获得正确/预期的逻辑行为。

An Integer is represented by 16 bits, so 1 is this: Integer由16位表示,因此1是这样的:

0000 0000 0000 0001

This makes Not 1 this: 这使得Not 1

1111 1111 1111 1110

The sign bit is on, so the value is negative - trim the insignificant digits and you get: 符号位打开,因此值为负 - 修剪无关紧要的数字,您得到:

10

Which is the binary representation for 2 . 这是2的二进制表示。 Hence, Not 1 is -2 . 因此, Not 1-2

Inversely, -1 would be: 相反, -1将是:

1111 1111 1111 1111

And Not -1 is thus: 因此Not -1

0000 0000 0000 0000

VBA/VBScript does not have real logical operators (AND, OR, NOT). VBA / VBScript没有真正的逻辑运算符(AND,OR,NOT)。 The logical operators you see are actually bitwise operators, and that's all you get. 您看到的逻辑运算符实际上是按位运算符,而这就是您所获得的。 VBA plays some games with the True and False values so this works most of the time, but occasionally you'll find a "gotcha". VBA使用TrueFalse值玩一些游戏,所以这大部分时间都有效,但偶尔你会找到一个“陷阱”。

In this case, instead of If Not InStr() Then you have to write If InStr() <= 0 Then . 在这种情况下,而不是If Not InStr() Then你必须写If InStr() <= 0 Then
Instead of If InStr() Then you have to write If InStr() > 0 Then 而不是If InStr() Then你必须写If InStr() > 0 Then

In other words: InStr() returns a number . 换句话说: InStr()返回一个数字 Don't try to treat it like a boolean. 不要试图像布尔一样对待它。

As the other answers have already explained about the why , I want to focus on the coding practices. 由于其他答案已经解释了为什么 ,我想专注于编码实践。

As you found out, Not x is not necessarily what you want. 正如您所发现的, Not x不一定是您想要的。 In practice you want more like Not CBool(x) . 在实践中,你想要更像Not CBool(x) However, CBool() can throw errors - for example, CBool(Null) yields error 91 (invalid use of null). 但是, CBool()可能会抛出错误 - 例如, CBool(Null)产生错误91(无效使用null)。

It might be claimed that you can avoid this by strong-typing your variables but even not using a Variant does not guarantee that in an expression a Boolean will stay a Boolean . 可能会声称您可以通过对变量进行强类型来避免这种情况,但即使不使用Variant也不能保证在表达式中Boolean将保持为Boolean Example: 例:

?typename(true and 0)
Integer

In practice, it's too easy to accidentally allow VBA to do the voodoo implicit conversions for you, so for that reasons, altering coding habits might suit you better. 在实践中,很容易让VBA意外地让你为你做隐伏的转换,所以出于这个原因,改变编码习惯可能会更适合你。

For testing truthy values, you want expressions like: 要测试truthy值,您需要以下表达式:

If x Then

And for falsy values, you want expressions like: 对于虚假值,您需要以下表达式:

If x = False Then

Those works regardless of the type of the x , whether it's an expression or not and thus is said to be much more consistent/predictable in its behavior compared to the If x = True Then or If Not x Then . 这些工作无论x的类型如何,无论是否是表达式,因此与If x = True ThenIf Not x Then相比,它的行为被认为更加一致/可预测。 By adopting this code habit, you can help avoid creating subtle bugs arising from accidental conversion away from Boolean types and getting a bitwise operation rather than logical operation. 通过采用这种代码习惯,您可以帮助避免因意外转换而产生的细微错误远离Boolean类型并获得按位操作而不是逻辑操作。

For assignments, using a Boolean variable will work in ensuring that it's consistently coerced into either True or False and not some random numbers. 对于赋值,使用Boolean变量将确保它始终强制为TrueFalse而不是一些随机数。

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

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