Previous: , Up: Lengths   [Contents][Index]

14.8 Expressions

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 (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’.