Synopsis, one of:
\numexpr expression \dimexpr expression \glueexpr expression \muglue expression
Any place where you may write an integer, or a TeX dimen, or TeX glue, or muglue, you can instead write an expression to compute that type of quantity.
An example is that \the\dimexpr\linewidth-4pt\relax
will
produce as output the length that is four points less than width of a
line (the only purpose of \the
is to show the result in the
document). Analogously, \romannumeral\numexpr6+3\relax
will
produce ‘ix’, and \the\glueexpr 5pt plus 1pt * 2 \relax
will produce ‘10.0pt plus 2.0pt’.
A convenience here over doing calculations by allocating registers and
then using \advance
, etc., is that the evaluation of expressions
does not involve assignments and can therefore be performed in places
where assignments are not allowed. The next example computes the width
of the \parbox
.
\newlength{\offset}\setlength{\offset}{2em} \begin{center} \parbox{\dimexpr\linewidth-\offset*3}{With malice toward none with charity for all with firmness in the right as God gives us to see the right let us strive on to finish the work we are in to bind up the nation's wounds, to care for him who shall have borne the battle and for his widow and his orphan \textasciitilde\ to do all which may achieve and cherish a just and lasting peace among ourselves and with all nations. ---Abraham Lincoln, Second Inaugural Address, from the memorial} \end{center}
The expression consists of one or more terms of the same type
(integer, dimension, etc.) that are added or subtracted. A term that is
a type of number, dimension, etc., consists of a factor of that type,
optionally multiplied or divided by factors. A factor of a type is
either a quantity of that type or a parenthesized subexpression. The
expression produces a result of the given type, so that \numexpr
produces an integer, \dimexpr
produces a dimension, etc.
In the quotation example above, changing to
\dimexpr\linewidth-3*\offset
gives the error Illegal unit
of measure (pt inserted)
. This is because for \dimexpr
and
\glueexpr
, the input consists of a dimension or glue value
followed by an optional multiplication factor, and not the other way
around. Thus \the\dimexpr 1pt*10\relax
is valid and produces
‘10.0pt’, but \the\dimexpr 10*1pt\relax
gives the
Illegal unit
error.
The expressions absorb tokens and carry out appropriate mathematics up
to a \relax
(which will be absorbed), or up to the first
non-valid token. Thus, \the\numexpr2+3px
will print
‘5px’, because LaTeX reads the \numexpr2+3
, which is
made up of numbers, and then finds the letter p
, which cannot
be part of a number. It therefore terminates the expression and
produces the ‘5’, followed by the regular text ‘px’.
This termination behavior is useful in comparisons. In
\ifnum\numexpr\parindent*2 < 10pt Yes\else No\fi
, the less than
sign terminates the expression and the result is ‘No’ (in a
standard LaTeX article).
Expressions may use the operators +
, -
, *
and
/
along with parentheses for subexpressions, (...)
. In
glue expressions the plus
and minus
parts do not need
parentheses to be affected by a factor. So \the\glueexpr 5pt plus
1pt * 2 \relax
results in ‘10pt plus 2pt’.
TeX will coerce other numerical types in the same way as it does when
doing register assignment. Thus \the\numexpr\dimexpr
1pt\relax\relax
will result in ‘65536’, which is 1pt
converted to scaled points (see sp
,
TeX’s internal unit) and then coerced into an integer. With a
\glueexpr
here, the stretch and shrink would be dropped. Going
the other way, a \numexpr
inside a \dimexpr
or
\glueexpr
will need appropriate units, as in
\the\dimexpr\numexpr 1 + 2\relax pt\relax
, which produces
‘3.0pt’.
The details of the arithmetic: each factor is checked to be in the
allowed range, numbers must be less than 2^{31} in absolute
value, and dimensions or glue components must be less than
2^{14} points, or mu
, or fil
, etc. The
arithmetic operations are performed individually, except for a scaling
operation (a multiplication immediately followed by a division) which
is done as one combined operation with a 64-bit product as
intermediate value. The result of each operation is again checked to
be in the allowed range.
Finally, division and scaling take place with rounding (unlike TeX’s
\divide
, which truncates). Thus
\the\dimexpr 5pt*(3/2)\relax
puts ‘10.0pt’ in the document,
because it rounds 3/2
to 2
, while
\the\dimexpr 5pt*(4/3)\relax
produces ‘5.0pt’.