OPERATOR PRECEDENCE DESCRIPTION + 5 add two numbers - 5 subtract two numbers, or negate one number. (The syntactic context is used to determine whether this is a binary subtraction operator or a unary negation operator) * 4 multiply two numbers ** 3 exponentiation: e.g. A ** 3 means A*A*A i.e. A cubed. / 4 divide first number by second (See note below) // 4 divide first number by second, produce remainder and quotient. X div Y 2 returns the number of times Y goes into X X rem Y 2 returns the remainder on dividing X by Y. X mod Y 2 returns the remainder on dividing X by Y. mod, unlike rem, requires both numbers to be real, i.e. non-complex. It always returns a result with the same sign as Y
Here are some expressions formed using arithmetic operators:
3 + 5 * 2 => ** 13 (3 + 5) * 2 => ** 16The expression:
(X + Y) * (99 - Z/3)has many sub-expressions, e.g. X, Y, 99, Z, 3, X + Y, Z/3, etc.
Notice how parentheses can affect the order in which operations are applied.
The operator // is unusual in that it produces two results. It takes two integers, and produces two integers, a remainder and a divisor, as in:
10 // 3 => ** 1 3 23 // 10 => ** 3 2Thus one can do things like
vars remainder, quotient; 223 // 10 -> (remainder, quotient); remainder, quotient => ** 3 22or, combinding the declaration with a multiple initialisation:
vars (remainder, quotient) = 223 // 10;To illustrate the use of // on different kinds of numbers:
Dividing integers 10 // 3 => ** 1 3 10 // -3 => ** 1 -3 -10 // 3 => ** -1 -3 -10 // -3 => ** -1 3 Dividing decimals (or ddecimals) 10.5 // -3.2 => ** 0.9 -3 Dividing ratios (7/3) // (11/23) => ** 29_/69 4 Dividing complexes (33 + sqrt(-57)) // sqrt(-5) => ** 1.69505_+:0.841633 3_-:14
Most of the above are `binary' operations. That is, they require TWO arguments. For example the expression
3 + 4applies the operation + to the two arguments 3 and 4. It denotes the number 7. The arguments may themselves be complex expressions, e.g.
(3 + 4) + (5 + 6)The operation - can be binary (two arguments) or unary (one argument), and Pop-11 works out from the context which it is. When it is unary, as in
- 4or
- (3 + 5)it produces a number by NEGATING its argument.
When it is a binary operator, as in
3 - 4or
(2 + 1) - (2 + 2)it subtracts the second argument from the first. So the latter denotes the number -1.
Roughly, the rule is that if "-" occurs as part of an expression in which it is immediately preceded by an expression, and not a comma, semicolon, or opening bracket of any kind, then it is treated as binary and represents a subtraction. Otherwise it is unary and represents a negation (change of sign).
The following are all binary (i.e. subtractions)
x - y, (33 * x) - sqrt(y), x + y - z, x * y - z - 1The following are all unary (i.e. negation)
-3 + 5, sqrt(- 22), if x > 0 then -x else x endifOne consequence of this is that although the other arithmetical operators can be used as normal functions, e.g.
+(3, 5), *(9, 10) => ** 8 90The minus symbol will normally be interpreted as a unary negation symbol in this sort of context, producing an unexpected result, e.g.
-(6, 3) => ** 6 -3which is equivalent to
6, -3 =>or
6, 3, - => ** 6 -3However, according to the rule given, the following will work as a binary negation, which may also be surprising:
6, 3 - => ** 3When unary negate is required, this can be specified unambiguously by invoking the procedure negate, e.g.
3 + negate(4) * 5 =>Compared with
3 + -4 * 5 =>Similarly, because "nonop -" is always taken to refer to the subtraction procedure, the name "negate" must be used when unary minus is to be given as argument to a procedure, e.g.
maplist([ 1 2 3 4 5 6], negate) => ** [-1 -2 -3 -4 -5 -6]Compare using the subtraction operator concatenated with the sqrt procedure:
define sqrt_sub = nonop - <> sqrt enddefine; sqrt_sub(8, 4) => ** 2.0Or the subtraction operator partially applied to 3:
define sub_3 = nonop - (% 3 %) enddefine; sub_3(66) => ** 63 sub_3(5.4) => ** 2.4
The division operator "/" when given two integers (or bigintegers) will will not produce a decimal or ddecimal as result, but an integer (or biginteger) or ratio. Thus
10/5 => ** 2 10/6 => ** 5_/3The reason for printing out ratios in this way, i.e. with the numerator and denominator joined by "_/" is that this will allow them to be read in again as ratios without violating Pop-11's syntactic rules for lexical items, mentioned briefly in chapter 1, and described fully in REF ITEMISE
This sort of result of integer division can cause confusion if you are used to a language which in which non-integer results of division are automatically converted (i.e. coerced) to decimals (reals, floats). This means that if you require such conversion you should ensure that one of the arguments to "/" is a decimal. e.g.
10/6.0 => ** 1.66667or
10.0/6 => ** 1.66667