4

I want to calculate some numbers, basically for some layout stuff. However, I am stuck a this point because it seems you can not write something like this in latex:

\newcommand{\MyNewWidthValueA}{{0.6666 + 0.075} \textwidth}
\newcommand{\MyNewWidthValueB}{\MyNewWidthValueA + 2cm}

Is there a way to do these quite basic things? I assume this is a very standard function that should work as I need this for defining position of frames and boxes for some specific layout things.

  • 1
    Calculation of real numbers is not so easy. However you can use \dimexr to calculate with lengths, e.g., \newlength{\MyNewWidthValueA}\setlength{\MyNewWidthValueA}{\dimexpr 0.6666\textwidth+0.075\textwidth}. You can also use package calc for calculations like this without need of using \dimexpr. See a good LaTeX introduction about the distinction of lengths/skips/dimensions and commands/macros. Another alternative for experienced users would be to use expl3. – cabohah Nov 12 '22 at 16:58

2 Answers2

6

Latex cannot directly handle expressions or calculations. I am far from an expert but I believe there are ways to achieve what you want.

You can keep numbers as dimensions and use \dimexpr in calculations: e.g. \the\dimexpr12pt + 13.5pt to get 25.5pt. This works in both macros and new length names. In this case, the \the is used if you want to extract and print a dimension.

You can also calculate expressions directly inside \fpeval{<expression>}, which returns a number (without units), has access to mathematical functions, and allows formatting the results, s.a. rounding (requires xfp package before 2022/01/06)

Similarly to \fpeval{}, pgfmath package adds the following macros (among many others): \pgfmathparse{expression} and \pgfmathresult. The latter returns the last expression parsed by \pgfmathparse{}.

Finally, there's calc but I have the least experience with this one.

Here's one example based on your code:

\documentclass{article}
\usepackage{pgfmath}
% \usepackage{xfp}   % Required before 2022/01/06 of latex

\newlength{\MyNewWidthValueA} \newlength{\MyNewWidthValueB} \setlength{\MyNewWidthValueA}{\dimexpr0.6666\textwidth + 0.075\textwidth} \setlength{\MyNewWidthValueB}{\dimexpr\MyNewWidthValueA+2cm}

\newcommand{\Vala}{\dimexpr0.6666\textwidth + 0.075\textwidth} \newcommand{\Valb}{\dimexpr\MyNewWidthValueA + 2cm}

\begin{document} \the\dimexpr12pt +13.5pt

Length names:

\the\MyNewWidthValueA, \the\MyNewWidthValueB

\bigskip

Macros expanding to lengths:

\the\Vala, \the\Valb

\bigskip

A macro to print a formatted result from an expression:

\fpeval{round((0.6666 + 0.075)\textwidth,1)} \end{document}

Celdor
  • 9,058
6

You may use \fpeval.

\documentclass{article}

\newcommand{\MyNewWidthValueA}{} \newcommand{\MyNewWidthValueB}{}

\begin{document}

\edef\MyNewWidthValueA{\fpeval{(0.6666 + 0.075)*\textwidth}pt}

\MyNewWidthValueA

\edef\MyNewWidthValueB{\fpeval{\MyNewWidthValueA+2cm}pt}

\MyNewWidthValueB

\end{document}

enter image description here

You may want to do

\fpeval{round(<expression>,5)}

but TeX will not bother if you use many decimal digits and will ignore the surplus ones.

egreg
  • 1,121,712