Логический оператор Not в VBScript

рассмотрим следующие два условия, включающие побитовые сравнения в 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 оператор должен выполнить логическое отрицание выражения. Логическое отрицание true is false, насколько мне известно. Должен ли я заключить, что он не соответствует этому обещанию? Как и почему и что здесь происходит? Какова логика, если таковая имеется?

2 ответов


на VBScript и оператор выполняет логическое и операция, если оба операнда являются логическими (True, False) - что-то вроде языка C (style)&& оператора.

если оба операнда числовые, он будет вместо этого выполнять побитовое и операция -- что-то вроде языка C & оператора.

если операнды имеют смешанные типы, то логическое значение приводится к число -- False = 0, True = -1 (сюрприз!) с последующим побитовым и операцией.

так что ваш пример оценивает следующим образом:

'   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 не оператор работает, он выполняет логическое отрицание на логическом операнде, таком как язык C ! оператор и побитовое дополнение на числовом операнде, таком как язык C ~ оператора.

в случае, если вы хотите принудительные логические операции над операндами, используйте функция VBScript CBool для приведения операндов:

If Not(CBool(1) And CBool(3)) Then WScript.Echo "yes" Else WScript.Echo "no" ' no

Примечание: как и большинство операторов VBScript, a Null операнд заставляет оператора вернуть Null. Null ведет себя необычным образом при использовании внутри If строительство.


я нашел ответ на свой вопрос на блог Эрика Липперта:Не Логично VBScript. Получается Not оператор, как и его братья, на самом деле не логический оператор.

And, Or, Not и Xor поданы под Логические Операторы на MSDN.

но Эрик Липперт называет их побитовое, и это лучшее описание, чем просто логическое как на MSDN, потому что логическое не говорит, как они на самом деле работают, поэтому такие люди, как я, обманываются, полагая, что они boolean операторы, которыми они не являются. И это большая ловушка.

мне пришлось бы переписать мои заявления следующим образом, чтобы они делали то, что я хочу:

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 не эквивалентны логической проверке.

рассмотрим следующий код, который принимает Сальман а 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