M[UMPS] Operators
interner Link
The M[UMPS] programming language knows a number of 'operators'. Some operators are the familiar arithmetic ones while others operate on strings or compare values. In M[UMPS], the operators can be mixed in any order, but keep in mind that some operators imply a specific interpretation of their operands. The only order of precedence for binary operators in M[UMPS] is the strict left-to-right evaluation, and unary operators only apply in a right-to-left order. If that order of precedence needs to be overridden, parentheses can be used to indicate that a sub-expression has to be evaluated first.
Depending on where one went to school, different schemes for the order of computations were taught. The main different 'schools' that I am aware of are:
| Central Europe | USA and Great Britain | ||
|---|---|---|---|
| 1. | Raising to a power | 1. | Raising to a power (including taking roots) |
| 2. | Multiplication | ||
| 3. | Division | ||
| 4. | Take root | 2. | Multiplication or division |
| 5. | Addition | ||
| 6. | Subtraction | 3. | Addition or subtraction |
So that the result of: 4/2*2 is equal to 1 in The Netherlands (multiplication takes precedence over division), but equal to 4 in England (multiplication and division have no difference in precedence, so the left-to-right evaluation prevails).
M[UMPS] evaluates strictly from left to right, so that 1+1*2 yields 4 and not 3.
When a different precedence is to be established, parentheses should be used: the expressions 1+(1*2) and 1*2+1 will both yield 3.
Assume that K=34; the expression "_11_22_33_"["_"_K_"_" will evaluate as "134_". The order of evaluation is: first evaluate "_11_22_33_"["_", which yields 1 (true), then the rest of the expression becomes: 1_K_"_", which leads to the value "134_".
"_11_22_33_"[("_"_K_"_") will return a true-or-false value (bve, boolean valued expression), which is only true when K has one of the values 11, 22 or 33.
Assume that L=29 and K=34; the series of commands
will result in the text "K=32" being printed, regardless of the value of K.
In this case, the order of evaluation is: first compare K=L, which will yield 0 (false), then the evaluation continues with 0+3, which yields 3 (true), so that the commands following the IF command will always be processed.
The formula that was intended could be either L+3=K or K=(L+3).
Arithmetic operator 'plus' (+)
Introduced in the 1977 ANSI M[UMPS] language standard.
| Reference | Value | |
|---|---|---|
| 1+1 | 2 | |
| 2+2 | 4 | |
| (-3)+(-4) | -7 |
Unary usage
| Reference | Value | |
|---|---|---|
| +1 | 1 |
Forced numeric interpretation
| Reference | Value | |
|---|---|---|
| +"27 apples" | 27 |
Resolve multiple leading signs
| Reference | Value | |
|---|---|---|
| +++---+--+3 | -3 |
Force numeric interpretation
| Reference | Value | |
|---|---|---|
| "2 apples"+"3 oranges" | 5 |
Arithmetic operator 'minus' (-)
Introduced in the 1977 ANSI M[UMPS] language standard.
| Reference | Value | |
|---|---|---|
| 3-1 | 2 | |
| 7-2 | 5 | |
| 2-7 | -5 | |
| (-3)-(-4) | 1 |
Unary usage
| Reference | Value | |
|---|---|---|
| -1 | -1 |
Resolve multiple leading signs
| Reference | Value | |
|---|---|---|
| +++---+--+3 | -3 |
Force numeric interpretation
| Reference | Value | |
|---|---|---|
| "5 apples"-"3 oranges" | 2 |
Arithmetic operator 'times' (*)
Introduced in the 1977 ANSI M[UMPS] language standard.
| Reference | Value | |
|---|---|---|
| 3*3 | 9 | |
| 7.5*2 | 15 | |
| -2.5*2.5 | -6.25 | |
| 2.5*-2.5 | -6.25 | |
| (-3)*(-4) | 12 |
Force numeric interpretation
| Reference | Value | |
|---|---|---|
| "5 apples"*"3 oranges" | 15 |
Arithmetic operator 'divided by' (/)
Introduced in the 1977 ANSI M[UMPS] language standard.
| Reference | Value | |
|---|---|---|
| 9/3 | 3 | |
| 5/2 | 2.5 | |
| 5/-2 | -2.5 | |
| -5/2 | -2.5 |
No leading zero in canonic representation of numbers between -1 and +1:
| Reference | Value | |
|---|---|---|
| 1/2 | .5 | |
| -1/2 | -.5 |
The number of digits is implementation-specific; 1977 ANSI standard guarantees 12 digits
| Reference | Value | |
|---|---|---|
| 1/2 | .5 | |
| 1/3 | .333333333333 | |
| 1/128 | .0078125 |
Definitely not equal to 1:
| Reference | Value | |
|---|---|---|
| 1/3*3 | .999999999999 |
Force numeric interpretation
| Reference | Value | |
|---|---|---|
| "15 apples"/"3 oranges" | 5 |
In 1995 standard:
The 1995 standard guarantees 15 digits
| Reference | Value | |
|---|---|---|
| 1/3 | .333333333333333 |
Added in the 1995 ANSI M[UMPS] language standard:
| Reference | Value | |
|---|---|---|
| X/0 |
Arithmetic operator 'integer divided by' (\)
Introduced in the 1977 ANSI M[UMPS] language standard.
| Reference | Value | |
|---|---|---|
| 9\3 | 3 | |
| 5\2 | 2 | |
| -5\2 | -2 | |
| 1\2 | 0 | |
| -1\2 | 0 |
Definitely not equal to 1
| Reference | Value | |
|---|---|---|
| 1\3*3 | 0 |
Added in the 1995 ANSI M[UMPS] language standard:
| Reference | Value | |
|---|---|---|
| X\0 |
Arithmetic operator 'modulo' (#)
Introduced in the 1977 ANSI M[UMPS] language standard.
This is probably the most mis-understood operator (or function) in many programming languages. FORTRAN and C have 'remainder' operators, Ada and M[UMPS] have a true 'modulo' operator. These two are not the same (although the result is identical when both operands are positive).
The definition of remainder depends on where you went to school. If you learned math in Europe, you will have a radically different opinion about the sign of a remainder than if you went to school in the USA (when either or both of the operands are negative, that is, when both operands are positive, everyone agrees).
Both 'schools' are correct, and, as long as you follow your definition consistently, you will have no problems.
In M[UMPS], however, there is no remainder operator. There is the modulo instead.
The definition of modulo is based on Abelian group theory, and the true mathematical definition is little known outside of mathematical graduate schools (see for instance Donald Knuth's The Art of Computer Programming, Volume 1, page 23 and further), but the following explanation is close enough for practical purposes:
The mathematical definition of Modulo maps a potentially infinitely large set of numbers onto a (usually finite) subset. The subset is repeated cyclically to map every number from the original set onto a member of the subset.
number#sub means: map the number on the left-hand side onto the subset [0,sub) (0, zero inclusive, sub exclusive). If sub is negative, this should be (sub,0], of course.
For example, number#5 and number#-5 would map as follows:
| number | -9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| number#(5) | 1 | 2 | 3 | 4 | 0 | 1 | 2 | 3 | 4 | 0 | 1 | 2 | 3 | 4 | 0 | 1 | 2 | 3 | 4 |
| number#(-5) | -4 | -3 | -2 | -1 | 0 | -4 | -3 | -2 | -1 | 0 | -4 | -3 | -2 | -1 | 0 | -4 | -3 | -2 | -1 |
Added in the 1995 ANSI M[UMPS] language standard:
| Reference | Value | |
|---|---|---|
| X#0 |
Arithmetic operator 'to the power of' (**)
Introduced in the 1995 ANSI M[UMPS] language standard.
| Reference | Value | |
|---|---|---|
| 2**5 | 32 | |
| 2**3 | 8 | |
| -2**3 | -8 | |
| 16**.25 | 2 | |
| -32**(1/5) | -2 | |
| -2**.5 | not specified | |
| -27**(1/3) | not specified | |
| 3**2 | 9 | |
| 2**3**4 | 4096 | |
| 4**0.5 | 2 | |
| 4**(-2) | .0625 | |
| 27**(1/3) | 3 (if 1/3 is that exact...) | |
| 2.5**2 | 6.25 | |
| -1**3 | -1 | |
| -8**(1/3) | -2 or error |
Square root:
| Reference | Value | |
|---|---|---|
| 4**.5 | 2 | |
| 2**.5 | 1.4142... |
The standard does not (yet) define any behavior in the case of imaginary or complex results
| Reference | Value | |
|---|---|---|
| -1**.5 | error or "0%1" |
This should always work
| Reference | Value | |
|---|---|---|
| 32**.2 | 2 |
But this depends on the precision that the implementation offers internally
| Reference | Value | |
|---|---|---|
| -32**.2 | -2 (or error) |
String operator 'concatenate' (_)
| Reference | Value | |
|---|---|---|
| 9_3 | 93 |
No separator remains
| Reference | Value | |
|---|---|---|
| "First"_"Second" | FirstSecond |
Unless embedded in either operand
| Reference | Value | |
|---|---|---|
| "First"_" Second" | First Second |
Or explicitly specified
| Reference | Value | |
|---|---|---|
| "First"_" "_"Second" | First Second |
Assignment operator 'becomes' (=)
Introduced in the 1977 ANSI M[UMPS] language standard.
SET X=1
SET X=A+B*23_" apples"
SET X=A=B
Note: the first "=" sign is an assignment operator, the second "=" sign is a relational operator.
Relational operator 'is equal to' (=)
Introduced in the 1977 ANSI M[UMPS] language standard.
IF A=123 SET X=1
SET Y=$SELECT(B=938457:124,1:23746)
Relational operator 'object is equal to' (==)
Approved for inclusion in a future ANSI M[UMPS] language standard.
This operator only returns a true value if both operands are pointers to objects, and both pointer identify the same instance of the same object.
IF docA==docB SET X=1
SET Y=$SELECT(graph1==graph4:124,1:23746)
Relational operator 'is greater than' (>)
Introduced in the 1977 ANSI M[UMPS] language standard.
IF A>123 SET X=1
SET Y=$SELECT(B>938457:124,1:23746)
Relational operator 'is less than' (<)
Introduced in the 1977 ANSI M[UMPS] language standard.
IF A<123 SET X=1
SET Y=$SELECT(B<938457:124,1:23746)
Relational operator 'is less than or equal to' (<=)
Approved for inclusion in a future ANSI M[UMPS] language standard.
IF A<=123 SET X=1
SET Y=$SELECT(B<=938457:124,1:23746)
Relational operator 'is greater than or equal to' (>=)
Approved for inclusion in a future ANSI M[UMPS] language standard.
IF A>=123 SET X=1
SET Y=$SELECT(B>=938457:124,1:23746)
Relational operator 'matches pattern' (?)
Introduced in the 1977 ANSI M[UMPS] language standard.
The pattern-codes to be used in pattern-matching are:
A : the 26 upper and 26 lower-case alphabetic characters
C : the 33 control-characters
E : the 128 characters in the ASCII set
L : the 26 lower-case characters
N : the 10 digits
P : the 33 punctuation-characters
U : the 26 upper-case characters
Modified for internationalization in the 1995 ANSI M[UMPS] language standard:
A : upper and lower-case characters
C : control-characters
E : all characters in the character set
L : lower-case characters
N : digits
P : punctuation-characters
U : upper-case characters
1 (true) when the value of variable X matches a pattern that "looks like" 3 digits, one point, 2 digits and any number of upper-case symbols, 0 (false) otherwise:
1 (true) when the value of variable X matches the pattern of a 1985 Dutch license plate, 0 (false) otherwise:
1 (true) when the value of variable X is a positive number, less than 1000 with at least 1 and at most 5 digits following the decimal point, 0 (false) otherwise:
Addition in the 1995 ANSI M[UMPS] language standard
In order to support the Japanese character sets, two new pattern identifiers are added:
Additions in the 1995 ANSI M[UMPS] language standard (and correction in a future) ANSI M[UMPS] language standard:
The concept of 'alternation' is introduced. An 'alternation' is a list of possible patterns that each are a valid match for a pattern.
is equivalent to
X?2N1"-"1(3N1"-"1N,1N1":"4N)
would match "12-345-6" and "12-3:4567".
X?.1(1"("3N1")".1(1"-",1"_"))3N.1(1"-",1"_")4N
would match any of:
555-1212
555_1212
(000)5551212
(000)555-1212
(000)555_1212
(000)-5551212
(000)-555-1212
(000)-555_1212
(000)_5551212
000)_555-1212
(000)_555_1212
Approved for addition in a future ANSI M[UMPS] language standard:
In order to support the character ISO-8859-1/USA, a new pattern identifier is added:
I : "International" characters (any non-ASCII characters in ISO-8859-1/USA).
It is made possible to exclude certain patterns:
1 (true) when the value of variable X does not contain any control characters, 0 (false) otherwise:
1 (true) when the value of variable X starts and ends with the letter "Y" , and no other occurrences of that letter are present in that value, 0 (false) otherwise:
The concept of "ranges" is introduced. It is made possible to specify that a pattern is matched when one of a set of specified characters occurs:
| Reference | Value | |
|---|---|---|
| "word"?.["aeiouAEIOU"] | 0 (false) | |
| "ff3a"?.["a":"f"]["A":"F"]N | 1 (true) |
The first pattern would be matched by strings that contain only vowels; the second pattern would be matched by purely hexadecimal numbers.
As a new feature, it has been made possible to extract the substring that matches a specific sub-pattern from the string that is being "matched". When using this new feature, the name of the variable that is to receive the string-segment in question is named between parentheses following the pattern-atom that it is intended to match.
Assume that the value of local variable X matches the following pattern: X?4N1","1.3N , i.e. 4 numeric digits, one comma and then between one and 3 more digits. The code segment:
IF '(X?4N(ITEM)1","1.3N(QUANT(ITEM)) DO ...
would cause the values of local variables ITEM and QUANT(ITEM) to be set to ITEM=$EXTRACT(X,1,4) (the part that matches 4N) and QUANT(ITEM)=$EXTRACT(X,6,$LENGTH(X)) (the part that matches .3N).
Note that the assignment occurs as the pattern is being matched (strict left-to-right), so that the value of local variable ITEM is well defined when the pattern matching processor will attempt to assign a value to QUANT(ITEM).
Relational operator 'contains' ([)
Introduced in the 1977 ANSI M[UMPS] language standard.
Assume that DIAGNOSIS="flu-patient".
| Reference | Value | |
|---|---|---|
| DIAGNOSIS["pat" | 1 (true) | |
| DIAGNOSIS["lu" | 1 (true) | |
| DIAGNOSE["flute" | 0 (false) | |
| DIAGNOSE["pantie" | 0 (false) |
Note that all characters of both "pantie" and "flute" do occur in "flu-patient"; those of "flute" even occur in the same order. The contains operator insists not only that the symbols in the substring occur in that order, but also as a 'solid' substring.
Relational operator 'follows' (])
Introduced in the 1977 ANSI M[UMPS] language standard.
Assume that TXT1="ABC" and TXT2="ABD".
| Reference | Value | |
|---|---|---|
| TXT2]TXT1 | 1 (true) | |
| "ABCD"]TXT1 | 1 (true) |
Note that the lexicographical order of the texts "1", "2" and "10" is: "1", "10", "2", i.e.:
| Reference | Value | |
|---|---|---|
| 10]1 | 1 (true) | |
| 2]1 | 1 (true) | |
| 10]2 | 0 (false) |
Relational operator 'follows or equal to' (]=)
Approved for inclusion in a future ANSI M[UMPS] language standard.
| Reference | Value | |
|---|---|---|
| 10]=10 | 1 (true) | |
| 2]=1 | 1 (true) | |
| 10]=2 | 0 (false) | |
| 10]=1 | 1 (true) | |
| 2]=2 | 1 (true) |
Relational operator 'collates after' (]])
Introduced in the 1995 ANSI M[UMPS] language standard.
Assume that TXT1="ABC" and TXT2="ABD".
| Reference | Value | |
|---|---|---|
| TXT2]]TXT1 | 1 (true) | |
| "ABCD"]]TXT1 | 1 (true) | |
| "ABCD"]]1 | 1 (true) | |
| TXT1]]2 | 1 (true) | |
| 10]]1 | 1 (true) | |
| 2]]1 | 1 (true) | |
| 10]]2 | 1 (true) |
A future ANSI M[UMPS] language standard introduces an override mechanism for collating purposes. See the library functions
Relational operator 'collates after or equal to'(]]=)
Approved for inclusion in a future ANSI M[UMPS] language standard.
| Reference | Value | |
|---|---|---|
| TXT2]]=TXT1 | 1 (true) | |
| "ABCD"]]=TXT1 | 1 (true) | |
| "ABCD"]]=1 | 1 (true) | |
| TXT1]]=2 | 1 (true) | |
| 10]]=10 | 1 (true) | |
| 2]]=2 | 1 (true) | |
| 10]]=2 | 1 (true) |
A future ANSI M[UMPS] language standard introduces an override mechanism for collating purposes. See the library functions
Logical operator 'and' (&)
Introduced in the 1977 ANSI M[UMPS] language standard.
| Reference | Value | |
|---|---|---|
| 0&0 | 0 (false) | |
| 0&1 | 0 (false) | |
| 1&0 | 0 (false) | |
| 1&1 | 1 (true) |
| Reference | Value | |
|---|---|---|
| "5 apples"&"3 pears" | 1 (true) | |
| 1&"3 pears" | 1 (true) | |
| "5 apples"&"trees" | 0 (false) | |
| "0.125"&1 | 1 (true) | |
| "5 apples"&0 | 0 (false) | |
| "apples"&0 | 0 (false) |
Careful with:
| Reference | Value | |
|---|---|---|
| A>3&B<6 | 1 (always true) |
(A>3&B is 0 or 1, both 0 and 1 are <6)
The value of (A>3)&(B<6) depends on the values of A and B
Logical operator 'or' (!)
Introduced in the 1977 ANSI M[UMPS] language standard.
| Reference | Value | |
|---|---|---|
| 0!0 | 0 (false) | |
| 0!1 | 1 (true) | |
| 1!0 | 1 (true) | |
| 1!1 | 1 (true) |
| Reference | Value | |
|---|---|---|
| "5 apples"!"3 pears" | 1 (true) | |
| 1!"3 pears" | 1 (true) | |
| "5 apples"!"trees" | 1 (true) | |
| "0.125"!1 | 1 (true) | |
| "5 apples"!0 | 1 (true) | |
| "apples"!0 | 0 (false) |
Careful with:
| Reference | Value | |
|---|---|---|
| A>3!B<6 | 1 (always true) |
(A>3!B is 0 or 1, both 0 and 1 are <6)
The value of (A>3)!(B<6) depends on the values of A and B
Logical operator 'exclusive or' (!!)
Approved for inclusion in a future ANSI M[UMPS] language standard.
| Reference | Value | |
|---|---|---|
| 0!!0 | 0 (false) | |
| 0!!1 | 1 (true) | |
| 1!!0 | 1 (true) | |
| 1!!1 | 0 (false) |
| Reference | Value | |
|---|---|---|
| "5 apples"!!"3 pears" | 0 (false) | |
| 1!!"3 pears" | 0 (false) | |
| "5 apples"!!"trees" | 1 (true) | |
| "0.125"!!1 | 0 (false) | |
| "5 apples"!!0 | 1 (true) | |
| "apples"!!0 | 0 (false) |
Careful with:
| Reference | Value | |
|---|---|---|
| A>3!!B<6 | 1 (always true) |
(A>3!!B is 0 or 1, both 0 and 1 are <6)
The value of (A>3)!!(B<6) depends on the values of A and B
Logical unary operator 'not' (')
Introduced in the 1977 ANSI M[UMPS] language standard.
| Reference | Value | |
|---|---|---|
| '12345 | 0 (false) | |
| '0 | 1 (true) | |
| '"Apples"< | 1 (true) |
The logical or Boolean value of X:
| Reference | Value | |
|---|---|---|
| ''X | 0 or 1 |
The exclusive or of two values:
| Reference | Value | |
|---|---|---|
| 'X'='Y | X xor Y |
This operator can also be used to modify the meaning of other operators:
'= is not equal to
'> is not greater than, i.e. is less than or equal to
'< is not less than, i.e. is greater than or equal to
'? does not match the pattern
'[ does not contain
'] does not follow
'& not and
'! not or
Added in 1995:
']] does not collate after
To be added in a future standard:
'<= is not less than or equal to, i.e. is greater than
'>= is not greater than or equal to, i.e. is less than
']= does not follow and is not equal to
']]= does not collate after and is not equal to
'!! not exclusive or
Indirection operator (@)
Introduced in the 1977 ANSI M[UMPS] language standard.
Three types of indirection:
Name indirection
SET X="ABC"
IF 123+@X=456
Argument indirection
SET SPACE="!!!",PAGE="#"
WRITE @$SELECT(ENOUGH:SPACE,1:PAGE)
Pattern indirection
SET CODE="3U"_$SELECT(SPECIAL:"2N",1:"")_"5L"
IF X?@CODE
Addition in 1984 ANSI M[UMPS] language standard.
Fourth type of indirection, subscripted reference indirection:
SET ARRAY="PRICES"
SET PRICE=(100+SALESTAX/100)*@ARRAY@(1,2,3)
SET ARRAY="^CUSTOMER(123,45)"
SET TOTAL=TOTAL+@ARRAY@(2,3,4)
Approved for addition in a future ANSI M[UMPS] Language standard.
Fifth type of indirection, "generic" indirection.
This new type of indirection involves a "catch-all" recovery after all other types of indirection have been attempted by a M[UMPS] language processor. When code is encountered that uses indirection, and none of the above forms of indirection leads to a valid interpretation of the code, the indirection operator and the expression on which it operates are to be replaced by the value of the expression in question, and then the line of code is to be re-evaluated. This may lead to some surprising possibilities:
SET X1="Y"
SET X2="Z="
SET X3="SecretAccnt=1E9,N"
SET X4="N=1 HALT"
SET Y="Example"
SET Y1="Example1"
SET Z1="Program"
SET Z2="TAG^Program"
SET Z3="(1,2,3)"
SET Z4=",2,3,4)"
With these values:
SET @X1="HELLO"
will be executed as: SET Y="HELLO"
SET @X2"HELLO"
will be executed as: SET Z="HELLO"
SET @X3="HELLO"
will be executed as: SET SecretAccnt=1E9,N="HELLO"
SET @(X1)1="Example"
will be executed as: SET Y1="Example1"
DO ^@(Z1)(1,2,3)
will be executed as: DO ^Program(1,2,3)
DO @(Z2)(1,2,3)
will be executed as: DO TAG^Program(1,2,3)
DO @(Z2)@Z3
will be executed as: DO TAG^Program(1,2,3)
DO @(Z2)("BLUE"@Z4
will be executed as: DO TAG^Program("BLUE",2,3,4)
This document is © Ed de Moel, 1995-2005.
It is part of a book by Ed de Moel that is published under the title "M[UMPS] by Example" (ISBN 0-918118-42-5).
Printed copies of the book are no longer available.
This document describes the various operators that are defined in the M[UMPS] language standard (ANSI X11.1, ISO 11756).
The information in this document is NOT authoritative and subject to be modified at any moment.
Please consult the appropriate (draft) language standard for an authoritative definition.
In this document, information is included that will appear in future standards.
The MDC cannot guarantee that these 'next' standards will indeed appear.
It is part of a book by Ed de Moel that is published under the title "M[UMPS] by Example" (ISBN 0-918118-42-5).
Printed copies of the book are no longer available.
This document describes the various operators that are defined in the M[UMPS] language standard (ANSI X11.1, ISO 11756).
The information in this document is NOT authoritative and subject to be modified at any moment.
Please consult the appropriate (draft) language standard for an authoritative definition.
In this document, information is included that will appear in future standards.
The MDC cannot guarantee that these 'next' standards will indeed appear.