Changes
→Error messages: LOL
{{h:h}}[[Category:Editor handbook]]
The MediaWiki extension [[m:ParserFunctions|ParserFunctions]] enables users to perform simple mathematical computations.
The <tt>expr</tt> function evaluates numerical expressions, and also boolean expressions involving numbers and booleans (not strings). The syntax is:
:<nowiki>{{</nowiki> #expr: ''expression'' }}
The spaces are not needed. Inside numbers no spaces are allowed.
The supported operators (roughly in order of precedence) are
'''<tt>not</tt>''',
'''<tt>*</tt>''', '''<tt>/</tt>''', '''<tt>div</tt>''', '''<tt>mod</tt>''',
'''<tt>+</tt>''', '''<tt>-</tt>''',
'''<tt>round</tt>''',
'''<tt>=</tt>''', '''<tt><></tt>''', '''<tt>!=</tt>''', '''<tt><=</tt>''', '''<tt>>=</tt>''',
'''<tt>and</tt>''', and
'''<tt>or</tt>'''.
== Operators ==
{| cellpadding="6px" border=1 style="border:1px solid #C0C0C0; border-collapse:collapse;"
! ''Operator''
! ''Operation''
! ''Example''
|-
| colspan="2" align="center"| none
||{{evaldemo|#expr: 123456789012345|=}}<br />{{evaldemo|#expr: 0.000001|=}}
|-
! +
|| Unary '''<tt>+</tt>''' sign
||{{evaldemo|#expr: +30 * +7|=}}
|-
! -
|| Unary '''<tt>-</tt>''' sign (negation)
||{{evaldemo|#expr: -30 * -7|=}}
|-
! not
|| Unary NOT, logical NOT
||{{evaldemo|#expr: not 0 * 7|=}}<br />{{evaldemo|#expr: not 30 +7|=}}
|-
! *
|| Multiplication
||{{evaldemo|#expr: 30*7|=}}
|-
! /
|| Division, same as '''div'''
||{{evaldemo|#expr: 30/7|=}}
|-
! [[w:en:Division_%28mathematics%29#Division_of_integers|div]]
|| Division, same as '''/''',<br />no integer division
||{{evaldemo|#expr: 30 div 7|2==}} (should be 4)<br />{{evaldemo|#expr: 5 div 2 * 2 + 5 mod 2|2==}} (should be 5)
|-
! [[w:en:Modulo operation|mod]]
|| "Modulo", remainder of division after truncating both operands to an integer.<br /><br />Caveat, '''div''' and '''mod''' are different from all programming languages. This has been fixed (but needs to be committed), see [[bugzilla:6068]].
||{{evaldemo|#expr: 30 mod 7|=}}<br />{{evaldemo|#expr: -8 mod -3|=}}<br />{{evaldemo|#expr: -8 mod +3|=}}<br />{{evaldemo|#expr: 8 mod 2.7|=}} (should be 2.6)<br />{{evaldemo|#expr: 8 mod 3.2|=}} (should be 1.6)<br />{{evaldemo|#expr: 8.9 mod 3|=}} (should be 2.9)
|-
! <tt>+</tt>
|| Addition
||{{evaldemo|#expr: 30+7|=}}
|-
! <tt>-</tt>
|| Subtraction
||{{evaldemo|#expr: 30-7|=}}
|-
! round
|| Rounds off the number on the left to the power of 1/10 given on the right
||{{evaldemo|#expr: 30/7 round 3|=}}<br />{{evaldemo|#expr: 30/7 round 0|=}}<br />{{<small> </small><code>#expr: 3456 round -2</code>}} = {{#expr: 3456 round -2}}
|-
! =
|| Equality (numerical incl. logical)
||{{evaldemo|1=#expr: 30 = 7|2==}}
|-
! <>
|| Inequality, same as '''!='''
||{{evaldemo|#expr: 30 <> 7|=}}
|-
!| !=
|| Inequality, same as '''<>''', logical ''xor''
||{{evaldemo|1=#expr: 1 != 0|2==}}
|-
! <
|| Less than
||{{evaldemo|#expr: 30 < 7|=}}
|-
! >
|| Greater than
||{{evaldemo|#expr: 30 > 7|=}}
|-
! <=
|| Less than or equal to
||{{evaldemo|1=#expr: 30 <= 7|2==}}
|-
! >=
|| Greater than or equal to
||{{evaldemo|1=#expr: 30 >= 7|2==}}
|-
! and
|| Logical AND
||{{evaldemo|#expr: 4<5 and 4 mod 2|=}}
|-
! or
|| Logical OR
||{{evaldemo|#expr: 4<5 or 4 mod 2|=}}
|}
The boolean operators consider 0 to be false and any other number to be true. An intermediate or final result "true" is identified with 1. Thus {{evaldemo|#expr: (2 < 3) + 1|=}}.
Precedence:
*{{evaldemo|#expr: 2 - 3 + 4 / 5 * 6|=}}
(+ and - have equal precedence, * and / also, both higher than the former two).
*{{evaldemo|1=#expr: 2 = 5 < 3 + 4|2==}}
(first +, then =, then <).
*{{evaldemo|#expr:1.234 + 1.234 round 1 + 1 }}
(first additions, then round)
*{{evaldemo|#expr:3 * 4 mod 10 * 10 }}
(mod and multiplication have equal precedence, evaluation from left to right)
Parentheses can force a different precedence: {{evaldemo|#expr: (2 + 3) * 4|=}}
Blank spaces are good for readability but not needed for working properly, except between not and an adjacent and/div/mod/not/or/round operator, and within numbers not allowed:
*{{evd|#expr:7mod3}}
*{{evd|#expr:7.5round0}}
*{{evd|#expr:0and1}}
*{{evd|#expr:0or not0}}
*{{evd|#expr:0ornot0}}
*{{evd|#expr:123 456}}
*{{evd|#expr:not not3}}
*{{evd|#expr:notnot3}}
*{{evd|#expr:---2}}
*{{evd|#expr:-+-2}}
*{{evd|#expr:2*-3}}
*{{evd|#expr:-not-not-not0}}
*{{evd|#expr:2*/3}}
==Numbers as input==
Leading zeros are allowed, as well as a trailing decimal point (for an integer) and trailing zeros in a number with a decimal point.
*{{evaldemo|#expr: +01.20}}
*{{evaldemo|#expr: 12.}}
These equivalences are also relevant for #ifeq and #switch, see below.
Scientific notation and group separators are not accepted in input for expressions:
*{{evaldemo|#expr: 2E-05 }}.
*{{evdn|#expr:|#expr:2/100000}}.
*{{evaldemo|#expr: 123,456}}
Due to the specifier R ("raw"), {{evd|NUMBEROFARTICLES|R|s==}} etc. produce numbers without group separators, which can be used in computations.
==Numbers as output==
A non-integer result has a decimal point in it. Scientific notation is produced for numbers with absolute value less than 1E-4 and for numbers with absolute value greater than or equal to 1E+12. Thus numbers produced include:
*{{evaldemo|#expr: -1234567890*10|2==}}
*{{evaldemo|#expr: +1234567890*100|2==}}
*{{evaldemo|#expr: -1234567890*1000|2==}}
*{{evaldemo|#expr: +1234567890*10000|2==}}
*{{evaldemo|#expr: -0.1234567890/100|2==}}
*{{evaldemo|#expr: +0.1234567890/1000|2==}}
*{{evaldemo|#expr: -0.1234567890/10000|2==}}
*{{evaldemo|#expr: +0.1234567890/100000|2==}}
Since scientific notation is not accepted as input, nested use of #expr may fail in cases where the same composite computation with a single #expr works.
;Thus:
:{{evaldemo|#expr: 1/10000 *2|2==}},
:{{evdn|#expr:|#expr: 1/10000| *2|4==}},
:{{evaldemo|#expr: 1/100000 *2|2==}}, '''but'''
:{{evdn|#expr:|#expr: 1/100000| *2|4==}}.
;Long <tt>YYYYMMDDhhmmss</tt> timestamps can run into the same problem:
:{{evaldemo|CURRENTTIMESTAMP}},
:{{evdn|#expr:|CURRENTTIMESTAMP}}.
;Timestamps without seconds are 12 digits, just short enough:
:{{evaldemo|#expr:{{CURRENTTIMESTAMP}}/100}}
See {{tim|evalint}} for producing output of large integers in non-scientific notation, suitable as input in another computation.
For producing numbers with commas as group separators, see {{tim|csn}}.
If the result of rounding a negative number is zero, the result is "-0". To avoid that, an expression ''x'' can be replaced by 0 + ( ''x'' ):
*{{evaldemo|#expr: ( -0.2 round 0 )|2==}}
*{{evaldemo|#expr: 1*(-0.2 round 0)|2==}}
*{{evaldemo|#expr: 0+(-0.2 round 0)|2==}}
==Accuracy==
Accuracy of the result of #expr is less than internally used within the computation of an expression:
*{{evaldemo|#expr:(2/3)}}
*{{evaldemo|#expr:(2/3)*1000000-666666}}
*{{evdn|#expr:|#expr:(2/3)| *1000000-666666}}
*{{evaldemo|#expr:1234567890.1234567890-1234567890}} (conclusion: <font color="red">'''16'''</font> or 17 digits of 1234567890.1234567890 used)
*{{evaldemo|#expr:1234567890.1234567890}} (result is rounded to a total of <font color="red">'''12'''</font> digits)
*{{evdn|#expr:(|#expr:1234567890.1234567890| -1234567890)}}
;The [[w:en:Machine epsilon|macheps]] or smallest '''x''' such that '''1+x != 1''' appears to be near <tt>0.5^53 + 0.5^106</tt> or 1.1102230246251566636831481088739149080825883E-<font color="red">'''16'''</font> (see above):
;<small>{{evaldemo|1=#expr:1=1+0.00000000000000011102230246251566636831481088739149080826|2=</small> =}}
;<small>{{evaldemo|1=#expr:1=1+0.00000000000000011102230246251566636831481088739149080825|2=</small> =}}
;That's the normal behaviour for [http://www.math.byu.edu/~schow/work/IEEEFloatingPoint.htm 64=1+52+11] bits (52 mantissa, 11 exponent). As explained above it is unrelated to the smallest expression result greater than '''1''':
;{{evaldemo|#expr:1+0.000000000004999889392|=}}
;{{evaldemo|#expr:1+0.000000000004999889391|=}} below about 1 + 5E-<font color="red">'''12'''</font>.
==Branching depending on an expression==
The function [[m:ParserFunctions#.23ifexpr:|#ifexpr]] produces one of two specified results, depending on the value of a boolean expression involving numbers and booleans (not strings). Example:
;<nowiki>{{#ifexpr: {{CURRENTDOW}} = 0 or {{CURRENTDOW}} = 6 | weekend | Mo-Fr}}</nowiki> yields '''{{#ifexpr: {{CURRENTDOW}} = 0 or {{CURRENTDOW}} = 6|weekend|Mo-Fr}}''' because today is {{CURRENTDAYNAME}} with {{evd|CURRENTDOW|s==}}.
==Comparisons==
#The function [[m:ParserFunctions#.23ifeq:|#ifeq:]] compares numbers and strings for equality (equal if both represent the same number or both are equal strings).
#The function [[m:ParserFunctions#.23switch:|#switch:]] compares one string with multiple others, and correspondingly produces one of multiple specified results.
*{{evd|#switch:FR|2=UK=London|3=FR=Paris|4=NL=Amsterdam}}
*{{evd|#switch:UK|UK|3=GB=London|4=FR=Paris}}
*{{evd|#switch:ZZ|2=UK=London|3=FR=Paris|4=no match}}
*{{evd|#ifeq:3|3.0|1|0}}
*{{evd|#ifeq:3|03|1|0}}
*{{evd|#ifeq:0.00003456|3.456E-05|1|0}}
*:Note that '''#ifeq:''' unlike '''#expr:''' accepts exponential notation on input.
*{{evd|#ifeq:1234567890123|1234567890120|1|0}}
*{{evd|#ifeq:1234567890123|1.23456789012E+12|1|0}}
*{{evd|#ifeq:1234567890120|1.23456789012E+12|1|0}}
*{{evd|#ifeq:1.234567890120E12|1.23456789012E+12|1|0}}
*:Numerical comparisons don't depend on the output format, compare:
*{{evd|#expr:1234567890123}}
*{{evd|#expr:1234567890120}}
[[ParserFunctions#.23ifeq:|#ifeq:]] allows to compare strings containing equal signs:
{|
!#switch:
!result
!#ifeq:
!result
|-
|{{evd|#switch:-1.0|2=-1=okay|3=fail|s=</td><td>}}
|{{evd|#ifeq:-1.0|-1|okay|fail|s=</td><td>}}
|-
|{{evd|1=#switch:a=b|2=a=b=okay|3=fail|s=</td><td>}}
|{{evd|1=#ifeq:a=b|2=a=b|3=okay|4=fail|s=</td><td>}}
|-
|{{evd|1=#switch:a=c|2=a=b=fail|3=okay|s=</td><td>}}
|{{evd|1=#ifeq:a=c|2=a=b|3=fail|4=okay|s=</td><td>}}
|}{{-}}
==Length of expressions==
To find the absolute value of a numeric expression x without using a separate template at least doubles the length of the expression:
*''x''<tt>*(1-2*(</tt>''x''<tt><0))</tt>
*x*<nowiki>{{#ifexpr:x>0|1|-1}}</nowiki>
(The first is not only shorter but has also the advantage that for substitution one less "subst:" or <nowiki>{{{subst|}}}</nowiki> is needed.)
Do not use
*<nowiki>{{#ifexpr:x>0|x|-x}}</nowiki>
for long expressions as it triples the length.
Similarly do not use mod to round or conversely, because it doubles the length of the expression.
Also providing a leading zero for the result of an expression if it is less than 10 doubles its length:
*<nowiki>{{#ifexpr:x<10|0}}x</nowiki>
This "exponential" growth of expressions, with much repetition, is due to the lack of variables (in the computer programming sense). Templates (subroutines) provide some of the functionality that variables offer, but fetching them from the database can be slower than evaluating even a long expression.
If the number of possible results of a long expression is small, a switch allows arbitrary conversion, including the absolute value and providing a leading zero, etc., without repeating the expression.
==Error messages==
{| cellspacing="0" cellpadding="0"
|+ Examples for all known [[m:ParserFunctions#.23expr:|#expr:]] and [[m:ParserFunctions#.23ifexpr:|#ifexpr:]] error messages
|-
||'''Expression'''
||'''Error message'''
|-
||{{evaldemo|#expr:1/0|s=</td><td>}}
|-
||{{evaldemo|#expr:2*|s=</td><td>}}
|-
||{{evaldemo|#expr:1 2|s=</td><td>}}
|-
||{{evaldemo|#ifexpr:1*/2|s=</td><td>}}
|-
||{{evaldemo|#expr: 1 (2)|s=</td><td>}}
|-
||{{evaldemo|#expr: (1 |s=</td><td>}}
|-
||{{evaldemo|#expr: 1) |s=</td><td>}}
|-
||{{evaldemo|#expr:2*123,456|s=   </td><td>}}
|-
||{{evaldemo|#expr:{{{a}}}|s=</td><td>}}
|-
||{{evaldemo|#ifexpr:3%2|s=</td><td>}}
|-
||{{evaldemo|#ifexpr:abc|s=</td><td>}}
|-
||{{evaldemo|#expr:abc.def|s=</td><td>}}
|-
|colspan="2"|{{<small> </small><tt>#expr:</tt>{{<small> </small><tt>x|102|1000*</tt>}}<tt><small> </small>18</tt><small> </small>}} gives {{#ifeq:{{ns:4}}|Meta|{{#expr:{{x|102|1000*}}18}}|{{#expr:1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*18}}}}
|-
|colspan="2"|{{<small> </small><tt>#expr:</tt>{{<small> </small><tt>x|102|1000*</tt>}}<tt><small> </small>179</tt><small> </small>}} gives {{#ifeq:{{ns:4}}|Meta|{{#expr:{{x|102|1000*}}179}}|{{#expr:1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*179}}}}
|-
|colspan="2"|{{<small> </small><tt>#expr:</tt>{{<small> </small><tt>x|102|1000*</tt>}}<tt><small> </small>180</tt><small> </small>}} gives {{#ifeq:{{ns:4}}|Meta|{{#expr:{{x|102|1000*}}180}}|{{#expr:1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*180}}}}
|-
|colspan="2"|{{<small> </small><tt>#expr:</tt>{{<small> </small><tt>x|33|(1+(</tt>}}<small> </small><tt>1</tt><small> </small>{{<small> </small><tt>x|33|))</tt>}} }} gives {{#ifeq:{{ns:4}}|Meta|{{#expr:{{x|33|(1+(}}1{{x|33|))}}}}|{{#expr:(1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+(1))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))}}}}
|-
|colspan="2"|{{<small> </small><tt>#expr:</tt>{{<small> </small><tt>x|34|(1+(</tt>}}<small> </small><tt>1</tt><small> </small>{{<small> </small><tt>x|34|))</tt>}} }} gives {{#ifeq:{{ns:4}}|Meta|{{#expr:{{x|34|(1+(}}1{{x|34|))}}}}|{{#expr:(1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+(1))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))}}}}
|-
|colspan="2"|{{evaldemo|#expr:3.4.5.6}}   <small>(no feature, only an oddity)</small>
|}
Note: {{tim|x}} copies a given string, here parts of an expression, for the specified times (max. 120), this help page shown on other projects actually evaluate its substituted output like 102 factors "1000" times "180" to get '''INF''' (infinity).
Wikitext without error message from the parser functions, but typically an error while using or attempting to use them:
{| cellspacing="0" cellpadding="0"
|-
|valign="top"|<nowiki>{{{#expr:2*3}}}</nowiki>  
|valign="top"| {{{#expr:2*3}}}  
||(triple braces, the whole is interpreted as parameter tag with parameter name "#expr:2*3")
|-
|valign="top"|<nowiki>{{#expr:2*3}}}</nowiki>
|valign="top"| {{#expr:2*3}}}
|(one closing brace too many; the last of the three is interpreted as plain text, so that the rest works fine)
|-
|valign="top"|<nowiki>{{{#expr:2*3}}</nowiki>
|valign="top"| {{{#expr:2*3}}
|(one opening brace too many; the first of the three is interpreted as plain text, so that the rest works fine)
|-
|valign="top"|<nowiki>{{#expr:2*3}</nowiki>
|valign="top"| {{#expr:2*3}
|(too few braces, the whole is interpreted as plain text)
|}
;A crude but informative "unrecognised word" error message can be generated intentionally. Only the first identified error is shown:
:{{<tt> #expr: 2*</tt>{{<tt> #ifexpr: 3*4>10|toolarge|3*4 </tt>}} }} gives
::{{#expr:2*{{#ifexpr:3*4>10|toolarge|3*4}}}},
:{{<tt> #expr: 2*</tt>{{<tt> #ifexpr: 3*4>10|too large|3*4 </tt>}} }} gives
::{{#expr:2*{{#ifexpr:3*4>10|too large|3*4}}}}.
==See also==
*[[m:ParserFunctions]]
*[[Help:Modulo and round]]
*[[Help:Colon function]] (general considerations)
*[[Help:Substitution]]
*[[m:Category:Mathematical templates]]
*[[w:en:Category:Mathematical templates]]
{{h:f|enname=Calculation}}
The MediaWiki extension [[m:ParserFunctions|ParserFunctions]] enables users to perform simple mathematical computations.
The <tt>expr</tt> function evaluates numerical expressions, and also boolean expressions involving numbers and booleans (not strings). The syntax is:
:<nowiki>{{</nowiki> #expr: ''expression'' }}
The spaces are not needed. Inside numbers no spaces are allowed.
The supported operators (roughly in order of precedence) are
'''<tt>not</tt>''',
'''<tt>*</tt>''', '''<tt>/</tt>''', '''<tt>div</tt>''', '''<tt>mod</tt>''',
'''<tt>+</tt>''', '''<tt>-</tt>''',
'''<tt>round</tt>''',
'''<tt>=</tt>''', '''<tt><></tt>''', '''<tt>!=</tt>''', '''<tt><=</tt>''', '''<tt>>=</tt>''',
'''<tt>and</tt>''', and
'''<tt>or</tt>'''.
== Operators ==
{| cellpadding="6px" border=1 style="border:1px solid #C0C0C0; border-collapse:collapse;"
! ''Operator''
! ''Operation''
! ''Example''
|-
| colspan="2" align="center"| none
||{{evaldemo|#expr: 123456789012345|=}}<br />{{evaldemo|#expr: 0.000001|=}}
|-
! +
|| Unary '''<tt>+</tt>''' sign
||{{evaldemo|#expr: +30 * +7|=}}
|-
! -
|| Unary '''<tt>-</tt>''' sign (negation)
||{{evaldemo|#expr: -30 * -7|=}}
|-
! not
|| Unary NOT, logical NOT
||{{evaldemo|#expr: not 0 * 7|=}}<br />{{evaldemo|#expr: not 30 +7|=}}
|-
! *
|| Multiplication
||{{evaldemo|#expr: 30*7|=}}
|-
! /
|| Division, same as '''div'''
||{{evaldemo|#expr: 30/7|=}}
|-
! [[w:en:Division_%28mathematics%29#Division_of_integers|div]]
|| Division, same as '''/''',<br />no integer division
||{{evaldemo|#expr: 30 div 7|2==}} (should be 4)<br />{{evaldemo|#expr: 5 div 2 * 2 + 5 mod 2|2==}} (should be 5)
|-
! [[w:en:Modulo operation|mod]]
|| "Modulo", remainder of division after truncating both operands to an integer.<br /><br />Caveat, '''div''' and '''mod''' are different from all programming languages. This has been fixed (but needs to be committed), see [[bugzilla:6068]].
||{{evaldemo|#expr: 30 mod 7|=}}<br />{{evaldemo|#expr: -8 mod -3|=}}<br />{{evaldemo|#expr: -8 mod +3|=}}<br />{{evaldemo|#expr: 8 mod 2.7|=}} (should be 2.6)<br />{{evaldemo|#expr: 8 mod 3.2|=}} (should be 1.6)<br />{{evaldemo|#expr: 8.9 mod 3|=}} (should be 2.9)
|-
! <tt>+</tt>
|| Addition
||{{evaldemo|#expr: 30+7|=}}
|-
! <tt>-</tt>
|| Subtraction
||{{evaldemo|#expr: 30-7|=}}
|-
! round
|| Rounds off the number on the left to the power of 1/10 given on the right
||{{evaldemo|#expr: 30/7 round 3|=}}<br />{{evaldemo|#expr: 30/7 round 0|=}}<br />{{<small> </small><code>#expr: 3456 round -2</code>}} = {{#expr: 3456 round -2}}
|-
! =
|| Equality (numerical incl. logical)
||{{evaldemo|1=#expr: 30 = 7|2==}}
|-
! <>
|| Inequality, same as '''!='''
||{{evaldemo|#expr: 30 <> 7|=}}
|-
!| !=
|| Inequality, same as '''<>''', logical ''xor''
||{{evaldemo|1=#expr: 1 != 0|2==}}
|-
! <
|| Less than
||{{evaldemo|#expr: 30 < 7|=}}
|-
! >
|| Greater than
||{{evaldemo|#expr: 30 > 7|=}}
|-
! <=
|| Less than or equal to
||{{evaldemo|1=#expr: 30 <= 7|2==}}
|-
! >=
|| Greater than or equal to
||{{evaldemo|1=#expr: 30 >= 7|2==}}
|-
! and
|| Logical AND
||{{evaldemo|#expr: 4<5 and 4 mod 2|=}}
|-
! or
|| Logical OR
||{{evaldemo|#expr: 4<5 or 4 mod 2|=}}
|}
The boolean operators consider 0 to be false and any other number to be true. An intermediate or final result "true" is identified with 1. Thus {{evaldemo|#expr: (2 < 3) + 1|=}}.
Precedence:
*{{evaldemo|#expr: 2 - 3 + 4 / 5 * 6|=}}
(+ and - have equal precedence, * and / also, both higher than the former two).
*{{evaldemo|1=#expr: 2 = 5 < 3 + 4|2==}}
(first +, then =, then <).
*{{evaldemo|#expr:1.234 + 1.234 round 1 + 1 }}
(first additions, then round)
*{{evaldemo|#expr:3 * 4 mod 10 * 10 }}
(mod and multiplication have equal precedence, evaluation from left to right)
Parentheses can force a different precedence: {{evaldemo|#expr: (2 + 3) * 4|=}}
Blank spaces are good for readability but not needed for working properly, except between not and an adjacent and/div/mod/not/or/round operator, and within numbers not allowed:
*{{evd|#expr:7mod3}}
*{{evd|#expr:7.5round0}}
*{{evd|#expr:0and1}}
*{{evd|#expr:0or not0}}
*{{evd|#expr:0ornot0}}
*{{evd|#expr:123 456}}
*{{evd|#expr:not not3}}
*{{evd|#expr:notnot3}}
*{{evd|#expr:---2}}
*{{evd|#expr:-+-2}}
*{{evd|#expr:2*-3}}
*{{evd|#expr:-not-not-not0}}
*{{evd|#expr:2*/3}}
==Numbers as input==
Leading zeros are allowed, as well as a trailing decimal point (for an integer) and trailing zeros in a number with a decimal point.
*{{evaldemo|#expr: +01.20}}
*{{evaldemo|#expr: 12.}}
These equivalences are also relevant for #ifeq and #switch, see below.
Scientific notation and group separators are not accepted in input for expressions:
*{{evaldemo|#expr: 2E-05 }}.
*{{evdn|#expr:|#expr:2/100000}}.
*{{evaldemo|#expr: 123,456}}
Due to the specifier R ("raw"), {{evd|NUMBEROFARTICLES|R|s==}} etc. produce numbers without group separators, which can be used in computations.
==Numbers as output==
A non-integer result has a decimal point in it. Scientific notation is produced for numbers with absolute value less than 1E-4 and for numbers with absolute value greater than or equal to 1E+12. Thus numbers produced include:
*{{evaldemo|#expr: -1234567890*10|2==}}
*{{evaldemo|#expr: +1234567890*100|2==}}
*{{evaldemo|#expr: -1234567890*1000|2==}}
*{{evaldemo|#expr: +1234567890*10000|2==}}
*{{evaldemo|#expr: -0.1234567890/100|2==}}
*{{evaldemo|#expr: +0.1234567890/1000|2==}}
*{{evaldemo|#expr: -0.1234567890/10000|2==}}
*{{evaldemo|#expr: +0.1234567890/100000|2==}}
Since scientific notation is not accepted as input, nested use of #expr may fail in cases where the same composite computation with a single #expr works.
;Thus:
:{{evaldemo|#expr: 1/10000 *2|2==}},
:{{evdn|#expr:|#expr: 1/10000| *2|4==}},
:{{evaldemo|#expr: 1/100000 *2|2==}}, '''but'''
:{{evdn|#expr:|#expr: 1/100000| *2|4==}}.
;Long <tt>YYYYMMDDhhmmss</tt> timestamps can run into the same problem:
:{{evaldemo|CURRENTTIMESTAMP}},
:{{evdn|#expr:|CURRENTTIMESTAMP}}.
;Timestamps without seconds are 12 digits, just short enough:
:{{evaldemo|#expr:{{CURRENTTIMESTAMP}}/100}}
See {{tim|evalint}} for producing output of large integers in non-scientific notation, suitable as input in another computation.
For producing numbers with commas as group separators, see {{tim|csn}}.
If the result of rounding a negative number is zero, the result is "-0". To avoid that, an expression ''x'' can be replaced by 0 + ( ''x'' ):
*{{evaldemo|#expr: ( -0.2 round 0 )|2==}}
*{{evaldemo|#expr: 1*(-0.2 round 0)|2==}}
*{{evaldemo|#expr: 0+(-0.2 round 0)|2==}}
==Accuracy==
Accuracy of the result of #expr is less than internally used within the computation of an expression:
*{{evaldemo|#expr:(2/3)}}
*{{evaldemo|#expr:(2/3)*1000000-666666}}
*{{evdn|#expr:|#expr:(2/3)| *1000000-666666}}
*{{evaldemo|#expr:1234567890.1234567890-1234567890}} (conclusion: <font color="red">'''16'''</font> or 17 digits of 1234567890.1234567890 used)
*{{evaldemo|#expr:1234567890.1234567890}} (result is rounded to a total of <font color="red">'''12'''</font> digits)
*{{evdn|#expr:(|#expr:1234567890.1234567890| -1234567890)}}
;The [[w:en:Machine epsilon|macheps]] or smallest '''x''' such that '''1+x != 1''' appears to be near <tt>0.5^53 + 0.5^106</tt> or 1.1102230246251566636831481088739149080825883E-<font color="red">'''16'''</font> (see above):
;<small>{{evaldemo|1=#expr:1=1+0.00000000000000011102230246251566636831481088739149080826|2=</small> =}}
;<small>{{evaldemo|1=#expr:1=1+0.00000000000000011102230246251566636831481088739149080825|2=</small> =}}
;That's the normal behaviour for [http://www.math.byu.edu/~schow/work/IEEEFloatingPoint.htm 64=1+52+11] bits (52 mantissa, 11 exponent). As explained above it is unrelated to the smallest expression result greater than '''1''':
;{{evaldemo|#expr:1+0.000000000004999889392|=}}
;{{evaldemo|#expr:1+0.000000000004999889391|=}} below about 1 + 5E-<font color="red">'''12'''</font>.
==Branching depending on an expression==
The function [[m:ParserFunctions#.23ifexpr:|#ifexpr]] produces one of two specified results, depending on the value of a boolean expression involving numbers and booleans (not strings). Example:
;<nowiki>{{#ifexpr: {{CURRENTDOW}} = 0 or {{CURRENTDOW}} = 6 | weekend | Mo-Fr}}</nowiki> yields '''{{#ifexpr: {{CURRENTDOW}} = 0 or {{CURRENTDOW}} = 6|weekend|Mo-Fr}}''' because today is {{CURRENTDAYNAME}} with {{evd|CURRENTDOW|s==}}.
==Comparisons==
#The function [[m:ParserFunctions#.23ifeq:|#ifeq:]] compares numbers and strings for equality (equal if both represent the same number or both are equal strings).
#The function [[m:ParserFunctions#.23switch:|#switch:]] compares one string with multiple others, and correspondingly produces one of multiple specified results.
*{{evd|#switch:FR|2=UK=London|3=FR=Paris|4=NL=Amsterdam}}
*{{evd|#switch:UK|UK|3=GB=London|4=FR=Paris}}
*{{evd|#switch:ZZ|2=UK=London|3=FR=Paris|4=no match}}
*{{evd|#ifeq:3|3.0|1|0}}
*{{evd|#ifeq:3|03|1|0}}
*{{evd|#ifeq:0.00003456|3.456E-05|1|0}}
*:Note that '''#ifeq:''' unlike '''#expr:''' accepts exponential notation on input.
*{{evd|#ifeq:1234567890123|1234567890120|1|0}}
*{{evd|#ifeq:1234567890123|1.23456789012E+12|1|0}}
*{{evd|#ifeq:1234567890120|1.23456789012E+12|1|0}}
*{{evd|#ifeq:1.234567890120E12|1.23456789012E+12|1|0}}
*:Numerical comparisons don't depend on the output format, compare:
*{{evd|#expr:1234567890123}}
*{{evd|#expr:1234567890120}}
[[ParserFunctions#.23ifeq:|#ifeq:]] allows to compare strings containing equal signs:
{|
!#switch:
!result
!#ifeq:
!result
|-
|{{evd|#switch:-1.0|2=-1=okay|3=fail|s=</td><td>}}
|{{evd|#ifeq:-1.0|-1|okay|fail|s=</td><td>}}
|-
|{{evd|1=#switch:a=b|2=a=b=okay|3=fail|s=</td><td>}}
|{{evd|1=#ifeq:a=b|2=a=b|3=okay|4=fail|s=</td><td>}}
|-
|{{evd|1=#switch:a=c|2=a=b=fail|3=okay|s=</td><td>}}
|{{evd|1=#ifeq:a=c|2=a=b|3=fail|4=okay|s=</td><td>}}
|}{{-}}
==Length of expressions==
To find the absolute value of a numeric expression x without using a separate template at least doubles the length of the expression:
*''x''<tt>*(1-2*(</tt>''x''<tt><0))</tt>
*x*<nowiki>{{#ifexpr:x>0|1|-1}}</nowiki>
(The first is not only shorter but has also the advantage that for substitution one less "subst:" or <nowiki>{{{subst|}}}</nowiki> is needed.)
Do not use
*<nowiki>{{#ifexpr:x>0|x|-x}}</nowiki>
for long expressions as it triples the length.
Similarly do not use mod to round or conversely, because it doubles the length of the expression.
Also providing a leading zero for the result of an expression if it is less than 10 doubles its length:
*<nowiki>{{#ifexpr:x<10|0}}x</nowiki>
This "exponential" growth of expressions, with much repetition, is due to the lack of variables (in the computer programming sense). Templates (subroutines) provide some of the functionality that variables offer, but fetching them from the database can be slower than evaluating even a long expression.
If the number of possible results of a long expression is small, a switch allows arbitrary conversion, including the absolute value and providing a leading zero, etc., without repeating the expression.
==Error messages==
{| cellspacing="0" cellpadding="0"
|+ Examples for all known [[m:ParserFunctions#.23expr:|#expr:]] and [[m:ParserFunctions#.23ifexpr:|#ifexpr:]] error messages
|-
||'''Expression'''
||'''Error message'''
|-
||{{evaldemo|#expr:1/0|s=</td><td>}}
|-
||{{evaldemo|#expr:2*|s=</td><td>}}
|-
||{{evaldemo|#expr:1 2|s=</td><td>}}
|-
||{{evaldemo|#ifexpr:1*/2|s=</td><td>}}
|-
||{{evaldemo|#expr: 1 (2)|s=</td><td>}}
|-
||{{evaldemo|#expr: (1 |s=</td><td>}}
|-
||{{evaldemo|#expr: 1) |s=</td><td>}}
|-
||{{evaldemo|#expr:2*123,456|s=   </td><td>}}
|-
||{{evaldemo|#expr:{{{a}}}|s=</td><td>}}
|-
||{{evaldemo|#ifexpr:3%2|s=</td><td>}}
|-
||{{evaldemo|#ifexpr:abc|s=</td><td>}}
|-
||{{evaldemo|#expr:abc.def|s=</td><td>}}
|-
|colspan="2"|{{<small> </small><tt>#expr:</tt>{{<small> </small><tt>x|102|1000*</tt>}}<tt><small> </small>18</tt><small> </small>}} gives {{#ifeq:{{ns:4}}|Meta|{{#expr:{{x|102|1000*}}18}}|{{#expr:1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*18}}}}
|-
|colspan="2"|{{<small> </small><tt>#expr:</tt>{{<small> </small><tt>x|102|1000*</tt>}}<tt><small> </small>179</tt><small> </small>}} gives {{#ifeq:{{ns:4}}|Meta|{{#expr:{{x|102|1000*}}179}}|{{#expr:1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*179}}}}
|-
|colspan="2"|{{<small> </small><tt>#expr:</tt>{{<small> </small><tt>x|102|1000*</tt>}}<tt><small> </small>180</tt><small> </small>}} gives {{#ifeq:{{ns:4}}|Meta|{{#expr:{{x|102|1000*}}180}}|{{#expr:1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*1000*180}}}}
|-
|colspan="2"|{{<small> </small><tt>#expr:</tt>{{<small> </small><tt>x|33|(1+(</tt>}}<small> </small><tt>1</tt><small> </small>{{<small> </small><tt>x|33|))</tt>}} }} gives {{#ifeq:{{ns:4}}|Meta|{{#expr:{{x|33|(1+(}}1{{x|33|))}}}}|{{#expr:(1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+(1))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))}}}}
|-
|colspan="2"|{{<small> </small><tt>#expr:</tt>{{<small> </small><tt>x|34|(1+(</tt>}}<small> </small><tt>1</tt><small> </small>{{<small> </small><tt>x|34|))</tt>}} }} gives {{#ifeq:{{ns:4}}|Meta|{{#expr:{{x|34|(1+(}}1{{x|34|))}}}}|{{#expr:(1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+((1+(1))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))}}}}
|-
|colspan="2"|{{evaldemo|#expr:3.4.5.6}}   <small>(no feature, only an oddity)</small>
|}
Note: {{tim|x}} copies a given string, here parts of an expression, for the specified times (max. 120), this help page shown on other projects actually evaluate its substituted output like 102 factors "1000" times "180" to get '''INF''' (infinity).
Wikitext without error message from the parser functions, but typically an error while using or attempting to use them:
{| cellspacing="0" cellpadding="0"
|-
|valign="top"|<nowiki>{{{#expr:2*3}}}</nowiki>  
|valign="top"| {{{#expr:2*3}}}  
||(triple braces, the whole is interpreted as parameter tag with parameter name "#expr:2*3")
|-
|valign="top"|<nowiki>{{#expr:2*3}}}</nowiki>
|valign="top"| {{#expr:2*3}}}
|(one closing brace too many; the last of the three is interpreted as plain text, so that the rest works fine)
|-
|valign="top"|<nowiki>{{{#expr:2*3}}</nowiki>
|valign="top"| {{{#expr:2*3}}
|(one opening brace too many; the first of the three is interpreted as plain text, so that the rest works fine)
|-
|valign="top"|<nowiki>{{#expr:2*3}</nowiki>
|valign="top"| {{#expr:2*3}
|(too few braces, the whole is interpreted as plain text)
|}
;A crude but informative "unrecognised word" error message can be generated intentionally. Only the first identified error is shown:
:{{<tt> #expr: 2*</tt>{{<tt> #ifexpr: 3*4>10|toolarge|3*4 </tt>}} }} gives
::{{#expr:2*{{#ifexpr:3*4>10|toolarge|3*4}}}},
:{{<tt> #expr: 2*</tt>{{<tt> #ifexpr: 3*4>10|too large|3*4 </tt>}} }} gives
::{{#expr:2*{{#ifexpr:3*4>10|too large|3*4}}}}.
==See also==
*[[m:ParserFunctions]]
*[[Help:Modulo and round]]
*[[Help:Colon function]] (general considerations)
*[[Help:Substitution]]
*[[m:Category:Mathematical templates]]
*[[w:en:Category:Mathematical templates]]
{{h:f|enname=Calculation}}