# Simple float-point calculations with comparison inside own macro

I currently have the command \aeq{} to easily print the equivalents used in a chemical reaction in my experimental section. I use numbers rounded to one decimal place.

However, in some reactions, I need to have numbers smaller than 0.1 and I would like to have \aeq{} do the following: multiply by 100 and print the result followed by mol-%.

\documentclass{scrbook}

\usepackage{chemmacros} % this loads xparse, which supplies \NewDocumentCommand{func}{argspec}{code}

\NewDocumentCommand{\aeq}{m}{#1~eq.} % equivalents

\begin{document}
\aeq{2.5} % prints 2.5~eq.

\aeq{0.03} % prints 0.03~eq., but I want to have it print 3~mol-%
\end{document}


You can use the floating point module of expl3 (loaded along with xparse):

\documentclass{scrbook}

\usepackage{chemmacros} % this loads xparse, which supplies \NewDocumentCommand{func}{argspec}{code}

\ExplSyntaxOn

\NewDocumentCommand{\aeq}{m}
{
\fp_compare:nTF { #1 < 1 }
{
\fp_eval:n { #1 * 100 }\nobreakspace\textnormal{mol-\%}
}
{
#1\nobreakspace eq\@.
}
}

\ExplSyntaxOff

\begin{document}

\aeq{2.5} % prints 2.5~eq.

\aeq{0.03} % prints 3~mol-%

\end{document}


• I was very happy when I got to my answer. But this is so much more elegant and spares me the loading of two packages! – basseur Oct 18 '17 at 14:26
• One more thing, though: I am actually using the acronyms package and have one acronym defined as eq.. I would need to call \acs{eq.} in this macro, which of course does not work here as \acs{eq\@.} How can I add this? – basseur Oct 18 '17 at 14:36
• @basseur Probably \@ is not needed in that context. However, if you're using \frenchspacing it's irrelevant if you add \@ or not. – egreg Oct 18 '17 at 14:43

This compound \def will work.

EDITED to handle integer arguments as well as indefinite number of decimal places.

\documentclass{scrbook}
\usepackage{chemmacros} % this loads xparse, which supplies \NewDocumentCommand{func}{argspec}{code}

\makeatletter
\newcommand\aeq[1]{\aeqaux#1\relax.\relax.\aeqauxend}
\def\aeqaux#1.#2#3.\aeqauxend{%
\ifx\relax#2#1~eq.\else
\expandafter\ifx\expandafter\relax\@firstoftwo#3#1.#2~eq.\else\aeqauxaux#3~mol-\%\fi%
\fi%
}
\def\aeqauxaux#1#2.{#1\ifx#2\relax\else.#2\fi}
\makeatother

\begin{document}
\aeq{12}\par
\aeq{5}\par
\aeq{3.}\par
\aeq{2.5}\par
\aeq{0.3}\par
\aeq{0.03}\par
\aeq{0.003}\par
\aeq{0.0003}\par
\aeq{0.00023}
\end{document}


• Also a very nice solution. But I chose egregs version, as it was easier for me to follow the steps in the macro. – basseur Oct 18 '17 at 15:11
• @basseur You and me both, LOL! – Steven B. Segletes Oct 18 '17 at 15:17

While writing the question I did some digging and came to the following solution using calculator and ifthen.

\documentclass{scrbook}

\usepackage{xparse}
\usepackage{calculator}
\usepackage{ifthen}

\NewDocumentCommand{\aeq}{m}{%
\ifthenelse{\lengthtest{#1pt > 0.1pt}}{#1~eq.}{%
\MULTIPLY{#1}{100}{\myaeq} % multiply #1 by 100 and store into \myaeq
\ROUND[0]{\myaeq}{\myaeq} % round \myaeq to 0 decimal places, because \multiply does weird calculations
\myaeq~mol-\%% print result
}%
} % equivalents

\begin{document}
\aeq{2.5} % prints 2.5~eq

\aeq{0.03} % prints 3~mol-\%

\aeq{0.9} % prints 0.9~eq

\aeq{0.1} % prints 10~mol-\%
\end{document}


This will give you

As you can see, everything bigger than 0.1 gets printed as is followed by ~eq., while 0.1 and smaller is multiplied by 100, rounded to 0 decimal places and printed with ~mol-%* appended.

Notice: You have to do the test as a \lengthtest because \ifthenelse does not work with float-point values and for \lengthtest you need to append pt to not get an error. Also: % behind parentheses and \% are needed to prevent unwanted spaces after and before the macro.