Help:Calculation

From Saintapedia
Revision as of 23:09, 7 October 2024 by Tom (talk | contribs) (Text replacement - "Category:HelpCategory:Help under review" to "Category:Help")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
Manual:Expr parser function syntax on Mediawiki
Help
Getting Started
Picking a UsernameTeach Yourself Wiki
Policies and guidelines
Saintapedia:Copyrights
The Saintapedia Interface
Left NavigationToolbox Discussion/Talk PageEdit & HistorySearchLog in & Create an Account
Editing Saintapedia
Creating a new pageCreating your user page • Editors (Visual/Enhanced) • Editing toolbarCheat SheetMagic wordsTable of Contents
Links
Internal linkExternal linkInterWiki linkCategory link Reference links
Images and Media
File Upload Guidelines for SaintapediaHow to upload new versions of filesImage mapNaming Conventions for FilesUpload documents
Tracking Changes
Recent Edits on SaintapediaArticle historyReverting to an earlier versionWatchlistHow to add a page to your watchlist
Asking Questions
Using talk pagesHelp:CommentStreams
Resources and Lists
Categories InfoboxHelp:Templates
Account settings and maintenance
Change your preferences Confirm your email address
Technical information
The MediaWiki softwareParser functions
All topics
view · talk · edit

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:
    • trunc
    • round
  • Otherwise related to 0 and periodic on each side of 0:
    • mod

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. 1.0 1.1 div and mod are different from all programming languages, see phab:T8068