# LaTeX3: \dim_eval:n and e-TeX dimension expression

Why does the following code not yield the expected result 264pt? Are non-integers not allowed as factors in e-TeX dimension expressions?

\documentclass{article}
\usepackage{expl3}

\begin{document}

\ExplSyntaxOn

\tl_set:Nn\l_dimen_tl{120pt}
\tl_set:Nn\l_mult_tl{2.2}
\tl_set:Nx\l_result_tl{\dim_eval:n{\l_dimen_tl*\l_mult_tl}}

\l_result_tl %gives 240.0pt.2

\ExplSyntaxOff

\end{document}

-

e-TeX dimension expressions need the fractional part as the dimension: you can multiply by integers and integer ratios only. So

\tl_set:Nn\l_dimen_tl{120}
\tl_set:Nn\l_mult_tl{2.2pt}
\tl_set:Nx\l_result_tl{\dim_eval:n{\l_mult_tl*\l_dimen_tl}}


works fine. (This is of course a general e-TeX restriction, and is not unique to LaTeX3 code.)

-
I guess we need to give more detail on 'dimension expressions' in the documentation. –  Joseph Wright May 16 '11 at 10:04
so e-TeX dimexpr syntax is anything but intuitive and not usable for many, even the simplest purposes. Rational numbers must be hard coded as fractions of integers. As such fractions are impossible to be generated from arbitrary user provided input, I will have to return to calc or l3calc which provide the \real{} command. –  AlexG May 16 '11 at 10:32
@Alexander: Remember that \dim_eval:n is a code function, for setting dimensions which can reasonably be expected to be 'sane'. For user input, it may currently be necessary to do other things, but I'm not clear on the type of input you have. I'd personally do everything using l3fp as it looks like you want floating-point operations. –  Joseph Wright May 16 '11 at 11:53
Thank you for your interest. The rational number given by the user is to finally scale a box whose dimensions (after some other manipulations) are stored in tl variables instead of dim registers (to reduce use of the latters). To get the final values I simply wanted to have them multiplied by the scaling factor within \dim_eval:n{} which seems to be impossible after all. Now, as a workaround, I assign the current box dimension values to a temporary dim register and put the scale factor in front of it (in the traditional manner). –  AlexG May 16 '11 at 12:26
@Alexander: With 32k registers available, I'd encourage you to use dim for dimension data and not to worry about 'saving' stuff. Bruno Le Floch is currently working on an expandable fp implementation, which should allow arbitrary manipulations within expansion contexts, including \dim_eval:n. –  Joseph Wright May 16 '11 at 12:58

The new FPU, which will be available on CTAN around late june 2012, allows for expandable computations. So to take your example (using a proper dimension register rather than a token list),

\documentclass{article}
\usepackage{expl3}

\begin{document}

\ExplSyntaxOn

\dim_set:Nn \l_tmpa_dim { 120pt }
\tl_set:Nn \l_mult_tl { 2.2 }
\tl_set:Nx \l_result_tl
{ \fp_to_dim:n { \l_tmpa_dim * \l_mult_tl } }

\l_result_tl % gives 264pt

\ExplSyntaxOff

\end{document}

-

Although Alexander mentioned his work-around in a separate comment, I just wanted to mention for completeness the ‘simple’ solution here: \dim_eval:n can only do calculations with actual TeX dimension registers, so replacing the token list variable to hold the dimension by a real dim fixes the problem:

\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn

\dim_set:Nn \l_tmpa_dim {120pt}
\tl_set:Nn \l_mult_tl {2.2}
\tl_set:Nx \l_result_tl { \dim_eval:n { \l_mult_tl \l_tmpa_dim } }

\l_result_tl
\ExplSyntaxOff
\end{document}

-
Oops, so what I give above is a huge overkill :). –  Bruno Le Floch Jun 25 '12 at 15:50
@BrunoLeFloch — Depending on the type of input data he's working with, though, your solution is still better because it'll work in all circumstances! –  Will Robertson Jun 26 '12 at 4:11