2

Is there a way to perform compile time arithmetic with explicit functions that respect dimensions? Here is a strawman example of arithmetic functions:

\mul{4}{7}            % expands to 28
\mul{4}{6pt}          % expands to 24pt
\mul{0.3}{\linewidth} % expand into some kind of anonymous length-like value
                      %   storing 0.3 * the current value of \linewidth.
\add{0.3pt}{0.2pt}    % expands to 0.5pt

For instance, the following document uses scalar multiplication with widths:

% !TEX TS-program = lualatex

% \usepackage{lipsum}

\documentclass{article}

\usepackage{fontspec}
\setmainfont[Ligatures=TeX]{TimesNewRoman}
\setsansfont[Ligatures=TeX]{Arial}

\begin{document}

\hspace*{0.5 \linewidth}

\begin{minipage}{0.4 \linewidth}
The quick brown fox jumped
over the lazy dog
\end{minipage}


\end{document}

The notation 0.4 \linewidth is convenient and easy to read, but isn't composable. For instance, using \begin{minipage}{0.4 {0.8 \linewidth}} instead produces the error:

! Illegal unit of measure (pt inserted).
<to be read again> 
{
l.15 \begin{minipage}{0.4 {0.8 \linewidth}}

Using \usepackage{calc} doesn't make the 0.4 {0.8 \linewidth} construction valid, either.

Is there a way to perform arithmetic explicitly?

NB: this questions differs from this one here because it's asking for the most explicit way to perform arithmetic, rather than the most convenient.

Greg Nisbet
  • 151
  • 4
  • 1
    \dimexpr isn't explicit enough? Or features from expl3? –  Jan 18 '19 at 21:31
  • I just noticed your % !TEX TS-program = lualatex if you are using luatex then of course you have the full Lua math expression language available at all times. So you have arithmetic, trig, square roots etc. – David Carlisle Jan 18 '19 at 22:35

2 Answers2

2

You can use xfp to do floating point arithmetic.

\documentclass{article}
\usepackage{xfp}

\begin{document}

\noindent
X\hspace*{0.5 \linewidth}X

\noindent
X\hspace*{\fpeval{0.3*0.5}\linewidth}X

\noindent
X\hspace*{\fpeval{(sin(3))^2+(cos(3))^2}\linewidth}X

\noindent
\begin{minipage}[t]{\fpeval{0.4*0.8}\linewidth}
The quick brown fox jumped
over the lazy dog
\end{minipage}

\noindent\rule{0.32\linewidth}{0.4pt}

\noindent\rule{\fpeval{0.4*0.8}\linewidth}{0.4pt}

\end{document}

enter image description here

You can use pretty complex expressions (that one above is of course 1).

You can even mix calc syntax with this, where it is accepted: with \usepackage{calc} something like

\setlength{\foo}{\fpeval{sqrt(2)}\linewidth-45pt}

would be valid if \foo is a length parameter.

egreg
  • 1,121,712
1

There is no "compile time" in TeX as it isn't a compiler, there is no compile stage separate from execution however assuming you are using etex you have inline arithmetic expressions available

  \begin{minipage}{0.4 \dimexpr 0.8 \linewidth\relax}

or

   \setcounter{section}{\numexpr 4 * 7\relax}
David Carlisle
  • 757,742
  • I meant to use compile time somewhat metaphorically to distinguish the arithmetic I want from arithmetic operations appearing in typeset math. Compile time seemed like a decent analogy because all traces of the arithmetic are removed in the output document. What's the appropriate way to refer to it? – Greg Nisbet Jan 18 '19 at 22:24
  • "assuming you are using etex", doesn't LaTeX require it for some time? –  Jan 18 '19 at 23:13
  • @jfbu yes (it's good to assume things that are true) – David Carlisle Jan 18 '19 at 23:57