OPERATORS & PRECEDENCE ORDER Updated: Feb 10, 2009 STRING CONCATENATION: + or & examples and tips + and & are treated the same: b$ + c$ is the same as b$ & c$. For efficiency, HotBasic uses one of three buffers for the result of each concatenation statement. RAM is allocated only if concatenation is used in a program. Typically, the same RAM allocations can be used over and over again in string processing programs with many concatenation statements, eliminating an OS-dependent RAM allocation/deallocation cycle for each statement at run-time. In sum, string processing speed is traded for a limitation to three result buffers. There are three buffers to handle a moderate amount of "nested concatenation" such as a$ = MyFunction(b$ + c$) + ".bas" or a$ = MyFunction + ".bas" where MyFunction might itself contain one or more concatenation statements. If MyFunction contains concatenation statements and these cause "rotation" of the result buffers used, unexpected, unwanted results may be obtained. Therefore, if HotBasic finds a user function (MyFunction above) as an item in a concatenation statement, a WARNING message is produced, so you can focus on the correctness of your result string in this situation. Consider the special case a$ = a$ + b$ where concatenation is used to append b$ to a$. This is very slow compared to a$.write(b$) because the .Write method truly appends b$ directly to a$ without creating an intermediate result string which is then copied to a$. Likewise, with a$ = a$ + b$ + c$ 'and so on use of a$.append b$, c$ 'and so on is much faster. OPERATORS AND PRECEDENCE ORDER: higher to lower ^ * / \ SHL SHR MOD INV + - [relational] NOT AND OR XOR SHL is shift bits left. 5 SHL 3 = 40 = 5 * 8 SHR is shift bits right. 1000 SHR 2 = 250 = 1000 / 4 Please note that SHL and SHR may operate on floating values: 2.5 SHR 1 'is 1.25; same as 2.5 / 2 3.1 SHL 2 'is 12.4; same as 3.1 * 4 and also, values may be "shifted" by a floating amount: 2.5 SHR 1.3 In short, SHR and SHL operators can use floating values (SINGLE, DOUBLE, REAL10) and produce fractional, floating results. Most often, coders will think of "shifts" as "bit shifts" applied to non-floating values, e.g., 32-bit INTEGER (alias LONG) values. For conventional bit shifts, the ISHR and ISHL statements or functions should be used. MOD is modulus. 17 MOD 3 = 2 = remainder of 17 / 3 INV is inverse modulus. Please see examples in HotTypes.bas Relational operators used in conditional statements are = <> > >= < <= Each operator is located in a precedence order which is used only when a quantity is both preceeded and followed by an operator. For example, for b in a * b / c, precedence order determines whether * or / is processed first. Note: Some basic compilers have operators of "equal precedence". A quantity cannot be preceded and followed by relational operators; thus, there is no precedence question among the relational operators. a * b / c multiplies a * b first, then divides by c a / b * c multiplies b * c first, then divides a by (b * c) (a / b) * c divides a by b first, then multiplies by c The -P switch and the $EQUALPREC ON directive causes (*, /, \) and (+, -) to be evaluated with equal operator precedence. Default is OFF, as described above. Please see Directives and Switches. $EQUALPREC OFF (default): 12 - 4 + 4 = 4 1 / 2 * 2 = 0.25 $EQUALPREC ON 12 - 4 + 4 = 12 1 / 2 * 2 = 1 NECESSARY AND UNNECESSARY BRACKETS (parentheses) Brackets are necessary only to over-ride normal operator precedence as shown above. IF a = b AND a$ > b$ THEN needs no brackets since any relational operator has a higher precedence than any logical operator. If (a = b) AND (a$ > b$) were written, there should be no effect. IF (a OR b) AND (c OR d) THEN needs brackets since OR has lower precedence than AND. Indeed, without any brackets, the above is equivalent to (unnecessary brackets added for clarity): IF a OR (b AND c) OR d THEN 'same as a OR b AND c OR d NESTED PRECEDENCE OVER-RIDES An example of a nested operator precedence over-ride using () is: 2 * (6 + (4 AND 2)) = 12 Above the precedence of * over + is deferred. Further, nested in this precedence over-ride is another -- + should be processed after AND. Likewise, 2 * ((4 AND 2) + 6) = 12 Please also be aware that different compilers may return different results for the same numeric expression. And both compilers may be right! Why? The compilers may vary in many ways -- rules of precedence, how floating and non-floating values are handled, rules for rounding, etc. The only thing that matters is that *you* say the result is correct. So for any compiler, checking your work is essential. Copyright 2003-2009 James J Keene PhD Original Publication: Oct 8, 2003