Search code examples
vbscriptvb6operator-precedence

VBscript operator precedence inconsistency with VB6


I am running an old VB6.0 program in interpretive mode (i.e. not as a .exe) on Win-7 32-bit.

The program accesses VBScript via an MSScriptControl.ScriptControl (as illustrated in the code block below) in function calc which here is called by the test function tc which itself can be called from another sub or function or from the immediate pane by typing tc <expression>. Here <expression> is a numeric math expression like 2+3^2*(9-3.5)^3.

When the input expression includes a pattern like -a^b the results are sometimes surprising to me. (Here a,b are placeholders for real numbers - I do not expect calc to handle expressions containing variable names.)

From the rules of operator precedence, based on VB6 behavior I would expect -a^b --> -(a^b) but often -a^b --> +(a^b). Spaces inside the expression have no discernible effect, as expected.

In the different Cases shown below I label consistent results by "ok" and inconsistent results by "?".

I could address the problem by bracketing every case of a^b thus (a^b). But, given I am working with long complicated equations, this will (i) be tedious to implement and (ii) impair the readability of the code.

Is this behavior known about? Is there a "behind-the-scenes" fix (e.g. a software patch or version upgrade)?

vb6

Public Function calc(ipEqtn$)
    Set objScript = CreateObject("MSScriptControl.ScriptControl")
    objScript.Language = "VBScript"
    calc = objScript.eval(ipEqtn$)
End Function '... calc

Public Function tc(n)

Select Case (n)
    Case (1):  eqtn$ = "-(5 ^ 2)         ": VB6 = -(5 ^ 2)              ' --> -25,-25 ok
    Case (2):  eqtn$ = "(- 5 ^ 2)        ": VB6 = (-5 ^ 2)              ' -->  25,-25 ?
    Case (3):  eqtn$ = "(-5^2)           ": VB6 = (-5 ^ 2)              ' -->  25,-25 ?
    Case (4):  eqtn$ = "- 5 ^ 2          ": VB6 = -5 ^ 2                ' -->  25,-25 ?
    
    Case (5):  eqtn$ = "( 5^2 -5^2 )     ": VB6 = (5 ^ 2 - 5 ^ 2)       ' -->  0,0 ok
    Case (6):  eqtn$ = "( -5^2 + 5^2 )   ": VB6 = (-5 ^ 2 + 5 ^ 2)      ' --> 50,0 ?
    Case (7):  eqtn$ = "  5^2 -5^2       ": VB6 = 5 ^ 2 - 5 ^ 2         ' -->  0,0 ok
    Case (8):  eqtn$ = " -5^2 + 5^2      ": VB6 = -5 ^ 2 + 5 ^ 2        ' --> 50,0 ?
    
    Case (9):  eqtn$ = " + 5^2  -5^2     ": VB6 = 5 ^ 2 - 5 ^ 2         ' --> 0,0
    Case (10): eqtn$ = " + 5^2 + -5^2    ": VB6 = 5 ^ 2 + -5 ^ 2        ' -->50,0
    Case (11): eqtn$ = " + 5^2 + -1*5^2  ": VB6 = 5 ^ 2 + -1 * 5 ^ 2    ' --> 0,0
    
End Select
vbs = calc(eqtn$)
Debug.Print vbs, VB6
    
End Function '... tc()

Solution

  • It's worth noting that VBScript and Visual Basic are different languages, one is a scripting language while the other is a fully-fledged programming language.

    The Visual Basic Operator Precedence is well documented across the various versions of Visual Basic (VB, VBA, VB.Net etc) - See What is the operator precedence order in Visual Basic 6.0? and Operator Precedence in Visual Basic.

    When you compare this with the VBScript Operator Precedence you see a major difference between the Arithmetic Operation Precedence Order.

    VBScript favours Negation over Exponentiation, while Visual Basic favours Exponentiation over Negation, which explains why you see different results.

    The obvious workaround is to use brackets to be explicit about your intent (which you mention in the original question).

    Without brackets

    'VBScript
    -5^2 '-5 * -5 = 25
    'Visual Basic
    -5^2 '-5 * 5 = -25
    

    With brackets, we can force the intent

    'VBScript
    -(5^2) '-(5 * 5) = -25
    'Visual Basic
    -(5^2) '-(5 * 5) = -25