The functions #expr: and #ifexpr: of MediaWiki extension ParserFunctions evaluate numerical expressions, and also boolean expressions involving numbers and booleans (not strings). The syntax is
- {{ #expr: expression }}
Spaces are not needed, except between words (for operators and constants). Inside numbers no grouping separators (spaces, commas, apostrophes) are allowed, the only decimal separator supported is the period (dot, full stop, excluding commas), and currently the only supported digits are the European decimal digits 0-9.
In calculation expressions embedded within templates, be careful when using magic words for date and time elements, such as {{CURRENTHOUR}}
as their return value may be formatted differently on translated pages and will break expressions (instead, use the parser function #time
with the appropriate xg
flags before each formatting element). Similar errors will occur with some other magic words that return quantities (make sure you include the appropriate raw formatting flag).
Operators, numbers, and constants
Since literal numbers are of type float, trunc
is sometimes used in the examples to construct an integer-type argument, to demonstrate the result of an operator for this case.
Operator
|
Args
|
Operation
|
PHP
|
Data type
|
Prec
|
Examples
|
(number) |
0
|
unsigned number in ordinary decimal notation (unary plus and minus and e are treated as operators, see elsewhere in this table) |
floatval |
float |
n.a.
|
{{#expr:1234567890123456789}} |
1.2345678901235E+18
|
{{#expr:123456789.0123456789}} |
123456789.01235
|
|
+ |
1
|
unary + sign
|
(nothing) |
same as argument |
n.a. |
{{#expr:+1}} |
1
|
{{#expr:+-1}} |
-1
|
{{#expr:+trunc1}} |
1
|
|
- |
1
|
unary - sign (negation)
|
- |
same as argument |
10 |
{{#expr:-12}} |
-12
|
{{#expr:-trunc12}} |
-12
|
{{#expr:-trunc(-2^63)}} |
9.2233720368548E+18
|
|
pi |
0
|
constant π |
pi() |
float |
n.a.
|
{{#expr:pi}} |
3.1415926535898
|
|
e as subexpression |
0
|
constant e |
exp(1) |
float |
n.a.
|
{{#expr:e}} |
2.718281828459
|
|
e between subexpressions |
2 |
*10^ |
* pow (10,..) |
float unless the factor on the left is of type integer and the exponent is non-negative and of type integer |
10
|
{{#expr:2e3}} |
2000
|
{{#expr:-2.3e-4}} |
-0.00023
|
{{#expr:(trunc2)e(trunc-3)}} |
0.002
|
{{#expr:(trunc2)e(trunc0)}} |
2
|
{{#expr:(trunc2)e(trunc18)}} |
2000000000000000000
|
{{#expr:(trunc2)e(trunc19)}} |
2.0E+19
|
{{#expr:6e(5-2)e-2}} |
60
|
{{#expr:1e.5}} |
3.1622776601684
|
Wrong:
{{#expr:e4}} |
Expression error: Unexpected number.
|
|
exp |
1
|
exponential function ex
|
exp |
float |
9 |
{{#expr:exp43}} |
4.7278394682293E+18
|
{{#expr:exp trunc0}} |
1
|
{{#expr:exp709}} |
8.218407461555E+307
|
{{#expr:exp-744}} |
9.8813129168249E-324
|
Compare:
{{#expr:e^43}} |
4.7278394682293E+18
|
{{#expr:trunc exp43}} |
4727839468229346304
|
|
ln |
1
|
natural logarithm
|
log |
float |
9 |
{{#expr:ln2}} |
0.69314718055995
|
{{#expr:ln trunc1}} |
0
|
{{#expr:ln8.9e307}} |
709.07967482591
|
{{#expr:ln.5e-323}} |
-744.44007192138
|
Hence, the common logarithm of e.g. 2:
{{#expr:ln2/ln10}} |
0.30102999566398
|
|
abs |
1
|
absolute value
|
abs |
same as argument, but never negative |
9 |
{{#expr:abs-2}} |
2
|
{{#expr:abs trunc-2}} |
2
|
{{#expr:abs trunc-2^63}} |
9.2233720368548E+18
|
|
sqrt |
1
|
square root
|
sqrt |
float |
9 |
{{#expr:sqrt 4}} |
2
|
{{#expr:sqrt 2}} |
1.4142135623731
|
{{#expr:sqrt 1e19}} |
3162277660.1684
|
Negative arguments are not permitted:
{{#expr:sqrt-1}} |
In sqrt: Result is not a number.
|
|
trunc |
1
|
truncation
|
(int), i.e. type-casting to integer |
integer |
9 |
{{#expr:trunc1.2}} |
1
|
{{#expr:trunc1.8}} |
1
|
{{#expr:trunc-1.2}} |
-1
|
{{#expr:trunc(-2^64+1e5)}} |
98304
|
{{#expr:trunc(-2^63+1e5)}} |
-9223372036854675456
|
{{#expr:trunc(2^63)}} |
-9223372036854775808
|
{{#expr:trunc(2^63+1e5)}} |
-9223372036854675456
|
{{#expr:trunc(2^64+1e5)}} |
98304
|
|
floor |
1
|
floor function
|
floor |
float |
9 |
{{#expr:floor1.2}} |
1
|
{{#expr:floor-1.2}} |
-2
|
{{#expr:floor trunc3}} |
3
|
|
ceil |
1
|
ceiling function
|
ceil |
float |
9 |
{{#expr:ceil1.2}} |
2
|
{{#expr:ceil-1.2}} |
-1
|
{{#expr:ceil trunc3}} |
3
|
|
sin |
1
|
sine
|
sin |
float |
9 |
{{#expr:sin.1}} |
0.099833416646828
|
{{#expr:sin trunc1}} |
0.8414709848079
|
With an angle in degrees, e.g. 30°:
{{#expr:sin(30*pi/180)}} |
0.5
|
|
cos |
1
|
cosine
|
cos |
float |
9 |
{{#expr:cos.1}} |
0.99500416527803
|
{{#expr:cos trunc1}} |
0.54030230586814
|
|
tan |
1
|
tangent
|
tan |
float |
9 |
{{#expr:tan.1}} |
0.10033467208545
|
{{#expr:tan trunc1}} |
1.5574077246549
|
|
asin |
1
|
arcsine
|
asin |
float |
9 |
{{#expr:asin.1}} |
0.10016742116156
|
{{#expr:asin trunc1}} |
1.5707963267949
|
|
acos |
1
|
arccosine
|
acos |
float |
9 |
{{#expr:acos.1}} |
1.4706289056333
|
{{#expr:acos trunc1}} |
0
|
{{#expr:2*acos 0}} |
3.1415926535898
|
|
atan |
1
|
arctangent
|
atan |
float |
9 |
{{#expr:atan.1}} |
0.099668652491162
|
{{#expr:atan trunc1}} |
0.78539816339745
|
{{#expr:4*atan 1}} |
3.1415926535898
|
|
not |
1
|
negation, logical NOT
|
! |
integer (1 or 0) |
9 |
{{#expr:not0}} |
1
|
{{#expr:not1}} |
0
|
{{#expr:not2}} |
0
|
{{#expr:not trunc1}} |
0
|
|
^ |
2
|
exponentiation (power)
|
pow |
float unless the base is of type integer and the exponent is non-negative and of type integer |
8 |
{{#expr:2^3}} |
8
|
{{#expr:-2^3}} |
-8
|
{{#expr:-2^4}} |
16
|
{{#expr:(trunc2)^(trunc-3)}} |
0.125
|
{{#expr:(trunc2)^(trunc0)}} |
1
|
{{#expr:(trunc2)^(trunc62)}} |
4611686018427387904
|
{{#expr:(trunc2)^(trunc63)}} |
9.2233720368548E+18
|
{{#expr:(-2)^1.2}} |
NAN
|
{{#expr:(-2)^.5}} |
NAN
|
|
* |
2
|
multiplication
|
* |
integer if both arguments are integer, otherwise float |
7 |
{{#expr:2*3}} |
6
|
{{#expr:(trunc2)*3}} |
6
|
{{#expr:2*trunc3}} |
6
|
{{#expr:(trunc2)*trunc3}} |
6
|
{{#expr:(trunc1e10)*trunc1e9}} |
1.0E+19
|
|
/ (also written div) |
2
|
division (div is not integer division[1])
|
/ |
float, unless both arguments are integer and the mathematical result is an integer |
7 |
{{#expr:6/3}} |
2
|
{{#expr:(trunc6)/3}} |
2
|
{{#expr:2/trunc6}} |
0.33333333333333
|
{{#expr:(trunc6)/trunc3}} |
2
|
{{#expr:(trunc6)/trunc4}} |
1.5
|
|
mod |
2
|
modulo operation, remainder of division after truncating both operands to an integer.[1]
|
% |
integer |
7 |
{{#expr:30mod7}} |
2
|
{{#expr:-30mod7}} |
-2
|
{{#expr:30mod-7}} |
2
|
{{#expr:-30mod-7}} |
-2
|
{{#expr:30.5mod7.9}} |
2
|
May give unexpected results for some values of the second argument (see this section):
{{#expr:123mod2^64}} |
Division by zero.
|
|
fmod |
2
|
modulo operation, floating point. Returns first argument after subtracting an integer multiple of the second argument.
|
fmod |
float |
7 |
{{#expr:5.7fmod1.3}} |
0.5
|
{{#expr:99.9fmod60}} |
39.9
|
{{#expr:2.99fmod1}} |
0.99
|
{{#expr:-2.99fmod1}} |
-0.99
|
{{#expr:2.99fmod-1}} |
0.99
|
{{#expr:-2.99fmod-1}} |
-0.99
|
|
+ |
2
|
addition
|
+ |
integer if both arguments are integer, otherwise float |
6 |
{{#expr:2+3}} |
5
|
{{#expr:(trunc2)+3}} |
5
|
{{#expr:2+trunc3}} |
5
|
{{#expr:(trunc2)+trunc3}} |
5
|
{{#expr:(trunc7e18)+trunc4e18}} |
1.1E+19
|
|
- |
2
|
subtraction
|
- |
integer if both arguments are integer, otherwise float |
6 |
{{#expr:3-2}} |
1
|
{{#expr:(trunc3)-2}} |
1
|
{{#expr:2-trunc2}} |
0
|
{{#expr:(trunc3)-trunc2}} |
1
|
{{#expr:(trunc-7e18)-trunc4e18}} |
-1.1E+19
|
|
round |
2
|
rounds off the number on the left to a multiple of 1/10 raised to a power, with the exponent equal to the truncated value of the number given on the right
|
round |
float |
5 |
{{#expr:9.876round2}} |
9.88
|
{{#expr:(trunc1234)round trunc-2}} |
1200
|
{{#expr:4.5round0}} |
5
|
{{#expr:-4.5round0}} |
-5
|
{{#expr:46.857round1.8}} |
46.9
|
{{#expr:46.857round-1.8}} |
50
|
|
= |
2
|
equality (numerical incl. logical, not for strings)
|
== |
integer (1 or 0) |
4 |
{{#expr:3.0=3}} |
1
|
{{#expr:3.1=3}} |
0
|
{{#expr:3.0=trunc3}} |
1
|
{{#expr:3.1=trunc3}} |
0
|
{{#expr:1e16=trunc(1e16)}} |
1
|
{{#expr:1e16=trunc(1e16)+trunc1}} |
1
|
{{#expr:trunc(1e16)=trunc(1e16)+trunc1}} |
0
|
wrong:
{{#expr:a=a}} |
Expression error: Unrecognised word "a".
|
|
<> (also written !=) |
2
|
inequality, logical xor; not for strings (negation of =)
|
!= |
integer (1 or 0) |
4 |
{{#expr:3<>3}} |
0
|
{{#expr:3<>4}} |
1
|
|
< |
2
|
less than (not for ordering of strings)
|
< |
integer (1 or 0) |
4 |
{{#expr:3<3}} |
0
|
{{#expr:3<4}} |
1
|
{{#expr:2.9<3}} |
1
|
{{#expr:3.0<3}} |
0
|
{{#expr:2.9<trunc3}} |
1
|
{{#expr:3.0<trunc3}} |
0
|
{{#expr:1e16<trunc(1e16)+trunc1}} |
0
|
wrong:
{{#expr:a<b}} |
Expression error: Unrecognised word "a".
|
|
> |
2
|
greater than (same as <, with arguments reversed)
|
> |
integer (1 or 0) |
4 |
{{#expr:4>3}} |
1
|
{{#expr:3>3}} |
0
|
|
<= |
2
|
less than or equal to (same as >=, with arguments reversed)
|
<= |
integer (1 or 0) |
4 |
{{#expr:3<=4}} |
1
|
{{#expr:3<=3}} |
1
|
|
>= |
2
|
greater than or equal to (negation of <)
|
>= |
integer (1 or 0) |
4 |
{{#expr:4>=3}} |
1
|
{{#expr:3>=3}} |
1
|
|
and |
2
|
logical AND
|
&& |
integer (1 or 0) |
3 |
{{#expr:3and4}} |
1
|
{{#expr:-3and0}} |
0
|
{{#expr:0and4}} |
0
|
{{#expr:0and0}} |
0
|
|
or |
2
|
logical OR
|
|| |
integer (1 or 0) |
2 |
{{#expr:3or4}} |
1
|
{{#expr:-3or0}} |
1
|
{{#expr:0or4}} |
1
|
{{#expr:0or0}} |
0
|
|
The logical operators and
, or
, and not
interpret an input value of 0 as false and any other number as true, and return 0 for a false result and 1 for true. These output values also apply to the relation operators; thus {{#expr: (2 < 3) + 1}}
gives 2.
To use and
, or
, and not
in #if
, #ifeq
, or #ifexist
contexts, one can use 1 as then-text (true case) and 0 as else-text (false case), then combine the results with the logical operators provided by #expr
or #ifexpr
. Note that negation can also be achieved by subtracting the result from 1 (inside of #expr
or #ifexpr
) or by simply switching the then- and else-text(s) of #if
#ifeq
#ifexists
or #ifexpr
. Also, note that the construct {{#expr: {{#if:{{{a|}}}|1|0}} or {{#if:{{{b|}}}|1|0}} }}
is equivalent to the simpler {{#if:{{{a|}}}{{{b|}}}|1|0}}}}
.
Precedence is indicated in the "Prec" column above, a higher number means that the operator is applied earlier. Examples (">" refers to going before, "~" means application from left to right):
e
> floor
, not
, etc.: {{#expr:floor1.5e1}}
→ 15, {{#expr:not0e1}}
→ 1
floor
> ^
: {{#expr:floor1.5^2}}
→ 1
^
> *
: {{#expr:2*3^2}}
→ 18
*
~ /
~ mod
: {{#expr:12/3*2}}
→ 8, {{#expr:111/3mod10}}
→ 7, {{#expr:358mod10*2}}
→ 16,
*
> +
, -
: {{#expr:2+3*4}}
→ 14, {{#expr:2-3*4}}
→ -10
+
~ -
: {{#expr:6-2+3}}
→ 7, {{#expr:-2+3}}
→ 1
+
, -
> round
: {{#expr:1.234round2-1}}
→ 1.2
round
> =
etc.: {{#expr:1.23=1.234round2}}
→ 1
=
etc. > and
: {{#expr:1 and 2=1}}
→ 0
and
> or
: {{#expr:1 or 1 and 0}}
→ 1
In the case of equal precedence number, evaluation is from left to right:
{{#expr:12/2*3}}
→ 18
{{#expr:3^3^3}}
→ 19683
Parentheses can force a different precedence: {{#expr:(2+3)*4}}
→ 20
Blank spaces are good for readability but not needed for working properly, except between words (including "e
"), and not allowed within numbers:
"{{#expr:7mod3}}"
gives "1" [1]
"{{#expr:7.5round0}}"
gives "8" [2]
"{{#expr:0and1}}"
gives "0" [3]
"{{#expr:0or not0}}"
gives "1" [4]
"{{#expr:0ornot0}}"
gives "Expression error: Unrecognised word "ornot"." [5]
"{{#expr:123 456}}"
gives "Expression error: Unexpected number." [6]
"{{#expr:not not3}}"
gives "1" [7]
"{{#expr:notnot3}}"
gives "Expression error: Unrecognised word "notnot"." [8]
"{{#expr:---2}}"
gives "-2" [9]
"{{#expr:-+-2}}"
gives "2" [10]
"{{#expr:2*-3}}"
gives "-6" [11]
"{{#expr:-not-not-not0}}"
gives "-1" [12]
"{{#expr:2*/3}}"
gives "Expression error: Unexpected / operator." [13]
"{{#expr:sinln1.1}}"
gives "Expression error: Unrecognised word "sinln"." [14]
"{{#expr:sin ln1.1}}"
gives "0.095165945236752" [15]
For scientific notation e
is treated as an operator. An e
between subexpressions works just like *10^
, except that together with the unary minus it has the highest precedence (e.g., before a separate ^
), and that the implicit 10 is of type integer, not float. An e
as subexpression (i.e., with each side either nothing or an operator) is Euler's constant. An e
with nothing or an operator on one side and a subexpression on the other gives an error message.
Rounding operators
The following rounding operators are supported:
- Symmetric with respect to 0 and non-strictly monotonic on each side of 0:
- Otherwise related to 0 and periodic on each side of 0:
Trunc
Trunc converts a float to an integer by cutting off the decimal part. For values in the range 2^63 ≤ x ≤ 2^64
, it returns x - 2^64
. Values larger than 2^64
returns 0
, and values less than -2^63
returns -2^63
.
See the below examples:
{{#expr:trunc(-2*2^63-2^12)}}
→ -4096
{{#expr:trunc(-2*2^63+2^12)}}
→ 4096
{{#expr:trunc(-1*2^63-2^12)}}
→ 9223372036854771712
{{#expr:trunc(-1*2^63+2^12)}}
→ -9223372036854771712
{{#expr:trunc(0*2^63-2^12)}}
→ -4096
{{#expr:trunc(0*2^63+2^12)}}
→ 4096
{{#expr:trunc(1*2^63-2^12)}}
→ 9223372036854771712
{{#expr:trunc(1*2^63+2^12)}}
→ -9223372036854771712
{{#expr:trunc(2*2^63-2^12)}}
→ -4096
{{#expr:trunc(2*2^63+2^12)}}
→ 4096
{{#expr:trunc(2^64+1024)}}
→ 0
{{#expr:trunc(3*2^63-2^12)}}
→ 9223372036854771712
{{#expr:trunc(3*2^63+2^12)}}
→ -9223372036854771712
Converting a number to an integer type ensures precise display without rounding to 14 decimal places.
x is truncated, x = trunc x
, if it is an integer or a floating-point number representing an integer value.
The expression p mod 0
results in an error message when used in MediaWiki, not the PHP operator %:
{{#expr:-27mod0}}
→ Division by zero.
In PHP, when using the % operator, if p % 0
is calculated and conditions are met where 0 < |q| < 1
and q >= 2^64
, the result is an empty string.
{{formatnum:{{#expr:-123 mod .9}}}}
→ Division by zero.
{{formatnum:{{#expr:-123 mod -.9}}}}
→ Division by zero.
{{formatnum:{{#expr:-123 mod (2^64)}}}}
→ Division by zero.
{{formatnum:{{#expr:-123 mod 1e20}}}}</nowki> → {{formatnum:{{#expr:-123 mod 1e20}}}}
* Compare:
** <nowki>{{formatnum:{{#expr:-123 mod (2^64-2048)}}}}
→ −123
Floor and ceil
When using floor or ceil with an integer, it's first converted to a floating-point number before the function is applied.
Use Template:Floor and Template:Ceil to get in such a case the integer-type expression for the exact result:
To check whether the internal result of an expression x is mathematically an integer one can simply test "(x) = floor (x)", or similarly with ceil (not with trunc because for large floats we would get false negatives, and not with round0, because for odd numbers between 2^52 and 2^53, we would get false negatives).
Safety margins
To round an integer x down to the nearest multiple of 7, you can do the following:
- 7*((x-3)/7 round 0)
- 7*floor((x+.5)/7)
- 7*ceil((x-6.5)/7)
To round x to the nearest multiple of 7, you can do the following:
- 7*((x/7) round 0)
- 7*floor((x+3.5)/7)
- 7*ceil((x-3.5)/7)
In these cases, the sign of x doesn't matter, even for rounding, because the value is never exactly halfway between integers.
All methods provide the same safety margin of 0.5 in x, or 1/14 after dividing by 7, to allow for rounding errors.
[[#ref_{{{1}}}|^]]
Precedence
Additions before round:
Modulo and multiplication operations have equal precedence and they are evaluated from left-to-right:
When using spaces in expressions with precedence, the layout can sometimes be confusing:
Instead, you can write:
Or you can parenthesis:
Related
References
- ↑ 1.0 1.1
div
and mod
are different from all programming languages, see phab:T8068
|
If this page has been recently modified, it may not reflect the most recent changes. Please purge this page to view the most recent changes. |