The syntax <factor><internal dimen>
or <factor><internal glue>
for a dimen value is supported by classical TeX, see TeXbook pages 269-271. Because <factor>
can be decimal constant and <internal glue>
can be a token declared by \skipdef
primitive, the following example is valid in classical TeX:
\newskip\twolen
\newskip\threelen \threelen=5em\relax
\twolen=2.5\threelen \relax
This is an extraction of your example, because the LaTeX macro \newlength
does \neswkip
and this macro does \skipdef
, so the declared token is "skipdef token" from TeXbook's point of view. The <factor>
is 2.5
here and <internal glue>
is \threelen
. Because \threelen
was set to 5em, the resulting assignment to \twolen
is 2.5*5em = 12.5em.
We can interpret the \threelen
as "a declared unit" of measure and read the syntax 2.5\threelen
as <factor>
*<unit>
.
Classical TeX supports no more calculation with dimen values, only the mentioned <factor>
*<unit>
.
eTeX gives a new primitive \dimexpr <dimen expression> <optional relax>
which allows to do more dimen calculations, like 2em-4ex+.5\hsize
.
The accepted answer here doesn't explain why the "puzzling error message" occurs here. The example does, in fact:
\newskip\test
\test=\dimexpr 3pt+1cm\relax plus something else
The \dimexpr
primitive creates a <dimen>
value and consumes the \relax
expanded from LaTeX macro \setlength
. So, we get
\test=<dimen value> plus something else
Because \test
was declared as \newskip
(i.e. using \skipdef
primitive), the assignment has syntax
\test <optional equal> <dimen> <optional plus followed by stretch value> <optional minus followed by shrink value>
If there is no plus
after the <dimen>
, the assignment is finalized with zero stretch value. But we have plus
here in egreg's example, then TeX excepts the <stretch value>
which must begin by <number>
. The number isn't present here, so TeX reports missing number
error.
\dimexpr
, but this requires to load package calc that redefines\setlength
to support some simple arithmetic.\dimexpr … \relax
does not make sense in your example. But if you have something like\newcommand*{\foo}[1]{…\setlength{\bar}{#1}…}
you could add extra functionality using\dimexpr #1\relax
— if you want and if it makes sense. See the eTeX manual section 3.5 for more information about\dimexpr
,\numexpr
and\glueexpr
.