# Calculate a floating point value to scale a length

As background, I was trying to write a macro that divides a page into columns given just a decimal scale factor. For example, given an input of .7 it should create columns of width .7*\textwidth and .3*\textwidth. Basically, I want to calculate (1-#1)*\textwidth.

It doesn't seem to be possible to use floating point values with \numexpr and \dimexpr, for example \dimexpr\textwidth*(1-#1) or \dimexpr\numexpr(1-#1)\textwidth. In this case there is a workaround, which is \dimexpr\textwidth-#1\textwidth. But it's easy to see how this would not work for more complex calculations.

Is there a way to do his using only (e)(La)TeX features? If not, what is the best alternative? Floating point calculations in LaTeX? gives some packages for floating point calculations but doesn't deal with lengths.

It's just a matter of importing a couple of expl3 kernel commands.

\documentclass{article}

\ExplSyntaxOn
\ProvideExpandableDocumentCommand{\fpeval}{m}{\fp_eval:n{#1}}
\ProvideExpandableDocumentCommand{\dimeval}{m}{\dim_eval:n{#1}}
\ExplSyntaxOff

\newlength{\testlena} % for testing
\newlength{\testlenb} % for testing

\newcommand{\process}[1]{%
\setlength{\testlena}{\fpeval{#1}\textwidth}%
\setlength{\testlenb}{\fpeval{1-#1}\textwidth}%
}

\begin{document}

\process{0.7}
\the\testlena\ --- \the\testlenb

\process{0.5}
\the\testlena\ --- \the\testlenb

\process{2^(-3)}
\the\testlena\ --- \the\testlenb

\setlength{\testlena}{\dimeval{(\textwidth+\textheight)/2}}
\the\testlena

\end{document}


For your application you just need \fpeval, but I showed also an example for \dimeval.

• Beautiful, and no extra packages needed. Thanks! Jun 28 at 23:59

As I was writing the question I found at least one possible solution using the package xintexpr:

\xinttheexpr(1-#1)\relax\textwidth

\relax is needed to terminate \xinttheexpr even though it wouldn't be needed for \numexpr in this context. It's not clear to me why \xinttheexpr must be used rather than the simpler \xintexpr.