Stella supports the standard mathematical operators for expressing formula along with a variety of useful Builtins The key operators are +, -, (lowest precedence) *, / (middle precedence) and ^ (highest precedence), but there are also a number of less commonly used operators including the logical comparatives as well as IF, THEN and ELSE.
All operators are listed by decreasing precedence below.
() can enclose any expression and are used to group that expression. This allows you to override precedence and clarify it for anyone reading equations.
[] are used for indicating array elements. Technically they are outside the precedence chain since they can only be used at the end of a name, or right after a closing ] when identifying a discrete stock element.
{} are used to enclose comments and are technically outside the precedence chain.
*.* is an inner product operator. It takes two arrays, which can each have 1 or 2 dimensions and returns the sum of the products of the elements of the first along its last dimension with the elements of the second along its first dimension. It operates directly on the arrays, ignoring any other operators and, for 2 dimensional arrays, a *.* b is the same as SUM(a[dim1,*],b[*,dim3]) where the * is in the dim2 position for both a and b.
' A matrix transpose is denoted by a ' at the end of the matrix name as in A'. The transpose is applied to the matrix directly before any other operations are done.
^ raises the left hand argument to the power of the right hand argument (as in x^2).
NOT can only be used in logical expressions, normally in an IF THEN ELSE construct. If the expression to its right is not 0, NOT will return 0, if the expression is 0, NOT will return 1.
- negates the argument to its right when used in a context other than a-b (for example, a + -b).
+ can be used as a unary operator the same way that - can, but it does nothing and is supported only for consistency.
The ^ operator is right associative, which means that the right argument is evaluated first, then the left. So, for example, 2^2^0.5 is the same as 2^SQRT(2) not SQRT(2^2) (which would be 2). Since the remaining operators only have a single augment, the left or right distinction is not important.
Next highest are the multiply and divide operators.
/ divides the first value by the second.
// is the same as / unless the result would be in which case it returns 0 (x//y is the same as SAFEDIV(<numerator>, <denominator>, [<onzero>])(x,y)).
Multiplication and division are left associative. Thus a/b/c first divides b into a, then divides c into the result so that 2/2/2 is (2/2)/2 or 0.5 and not 2/(2/2) which is 1.
+ adds the expressions on either side of it.
- subtracts the expressions on the right of it from that on the left.
MOD gives the remainder of the expression on the left when the expression on the right is divided into it as many times as possible. See the Mathematical builtins builtin for more detail.
These operators are all left associative. That means that 10-8-2 is the same as (10-8)-2 which is 0. It also means that 3 + 4 MOD 4 is (3+4) MOD 4 or 3.
Comparisons are used with logical expressions, normally inside the IF portion of Logical builtins.
= checks to see if two expressions are equal.
< checks to see if the left expression is less than the right.
<= checks to see if the left expression is less than or equal to the right.
> checks to see if the left expression is greater than the right.
>= checks to see if the left expression is greater than or equal to the right.
<> checks to see if the left expression is not equal to the right.
All of these operators result in a value of 1 if the evaluation is true and 0 if it is false.
The comparison operators are not associative. This means that the expression a = b = c is treated as a syntax error. You can force association using parentheses, but it is hard to imagine a situation where that would be useful.
AND is normally used in IF THEN ELSE constructs. It tests where both the left and right expressions are nonzero (true). Commonly in a form such as TIME > 20 AND TIME < 25. The higher precedence of the comparison operators means that this can be written with no parentheses. It evaluates to 1 for true and 0 for false.
AND is left associative, but also commutative so it that is not important.
OR is normally used in IF THEN ELSE constructs. It tests where either of the left or right expressions are nonzero (true). Commonly in a form such as TIME <= 20 OR TIME >= 25. The higher precedence of the comparison operators means that this can be written with no parentheses. It evaluates to 1 for true and 0 for false.
OR is left associative, but also commutative so it that is not important.
IF marks the beginning of a test condition. If that condition is nonzero (true) the expression directly following THEN will be used, otherwise the expression following ELSE will be used. See Logical builtins for more discussion.
THEN marks the transition from the condition to the expression that will be used in the condition is true (nonzero).
ELSE marks the transition from the expression that will be used when the condition is true, to the expression that will be used when the condition is false.
Note If you are using IF THEN ELSE with operators in the expression you should use (). For example, if you want to limit what is the ELSE portion use (IF a THEN b ELSE c) + d since IF a THEN b ELSE c + d is the same as IF a THEN b ELSE (c + d).