Логический оператор 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