Arithmetic expressions include the following types:
|
Expression |
Result |
|
exprA + exprB |
Add exprA to exprB |
|
exprA – exprB |
Subtract exprB from exprA |
|
exprA * exprB |
Mulitply exprA by exprB |
|
exprA / exprB |
Divide exprA by exprB |
|
exprA % exprB |
Modulo division of exprA by exprB (i.e the remainder) |
|
- exprA |
Change the sign of exprA |
Some examples of arithmetic expressions are as follows:
1+2
a-2
4/a+b
etc.
However the above definition leaves some ambiguity about the order of evaluation. For example in the following expression is ambiguous:
1-2+4
It is not clear whether this should be evaluated as (1-2)+4=3 or as 1-(2+4)=-5. To clear up this ambiguity then all mathematical operators are given a level of precedence (i.e. a definition of the order of evaluation of operators). The order of precedence for mathematical operators is as follows (strongest first):
|
Operator |
Associativity |
Name |
|
- |
Left (unary) |
Change sign |
|
+ - |
Left (binary) |
Add and Subtract |
|
* / % |
Left (binary) |
Mulitply, divide and modulo |
The operators that appear on the same line have equal precedence to each other and it is their associativity that defines the order that they are evaluated. Left associativity means that they are evaluated in order from left to right in the expression (right associativity means that they are evaluated from right to left in the expression (non of the arithmetic operators have this)).
This clears up the ambiguity of expressions like:
1-2+4*3
since the precedence and associativity defines that this will be evaluated as
(1-2)+(4*3)
The higher precedence of the multiply operator forces the (4*3) to be carried out first and the left associativity forces the (1-2) to be carried out before the addition.
However it is often better to use brackets to explicitly define the evaluation order than to try and remember the precedence and associativity of all the operators.
The result of an arithmetic expression is always a signed 32 bit integer value. Provision has been made to allow for 64 bit integer expressions in the future (hence the fact that 21 bytes is set aside for an int variable type).
32 bit signed integers range from -2147483648 to 2147483647 so no value higher or lower than these two limits can be returned from an arithmetic expression. The values will ‘wrap around’ so for example if you add 1 to 2147483647 you will get -2147483648 and if you subtract 1 from -2147483648 you will get 2147483647.
The result of an arithmetic expression is always evaluated to a null terminated ASCII string so it is important to make sure that a variable is long enough to store the result.
For example in the following code:
var a:2;
main
a=99+1;
end
Since a is only two bytes long and the expression 99+1 evaluates to a three character string “100” then the result will be truncated to “10” when it is stored in the variable a. Care should always be taken that data is not lost when assigning values or strings to variables if the variable is not long enough to hold the value and it is advisable to assign at least 22 bytes for any variable that will hold a numeric value (or define it as type int).
Note that if a non-numeric string is used in an arithmetic expression the string will be converted to a numeric value using the following rules:
a) Trailing spaces are ignored.
b) Conversion starts from the first numeric character (or sign (+ or -)) and stops when the first non-numeric character is encounter.
Below are some examples of what each of the following strings is evaluated to:
|
String |
Evaluated to |
|
“ 12” |
12 |
|
“12 13” |
12 |
|
“12abc” |
12 |
|
“ -12a” |
-12 |
|
“abc” |
0 |
Notice that any string whose first character (after any trailing spaces) is a non-numeric value is always evaluated as zero. As well as for arithmetic expressions these conversion are always carried out before assigning a value to a int type variable.