# \dimexpr with multiplication by real number and with parenthesis

I wish to draw an object with tikz by a macro, therefore I have to calculate expressions like:

defined by:

\newcommand{\myhexagon}{2}{...}

\newcommand{\myobject}{2}{
\myheaxgon{#1}{0.5*#2}
\myhexagon{0.89*#1-4mm}{0.79*(#1-(0.89*#1-4mm))+#2}}
}


called by (e.g):

\myobject{2cm}{3mm}
\myobject{12mm}{3mm}


I've tried to solve with

\newcommand{\myobject}{2}{
\def\const{0.89}
\def\constII{0.79}

\myheaxgon{#1}{0.5*#2}
\myheaxgon{\the\dimexpr \const#1 -4mm\relax}{\the\dimexpr\constII\the\dimexpr#1-\the\dimexpr\const#1-4mm\relax\relax+#2\relax}
}


(viz. replace '0.89*' by '\const' and '()' by '\the\dimexpr ... \relax') but I failed. Does anyone have some idea?

• Can you provide an MWE? – jon Dec 29 '16 at 6:08

Let's analyze what happens with \myobject{2cm}{3mm}. First the inner \dimexpr:

\the\dimexpr\const#1-4mm\relax


Macro parameter substitution is just that: text substitution. So when #1=2cm this becomes

\the\dimexpr\0.892cm-4mm\relax


not a multiplcation. If you want to multiply \const with #1, use \const\dimexpr#1\relax, like you have done with \constII. So the inner one becomes:

\the\dimexpr\const\dimexpr#1\relax-4mm\relax


With these parameters the value becomes 39.26477pt.

Now we substitute this is the outer expression. This will become then:

\the\dimexpr\constII\the\dimexpr#1-39.26477pt\relax+#2\relax


Now substitute the parameters and you get:

\the\dimexpr0.79\the\dimexpr2cm-39.26477pt\relax+3mm\relax


Now again we have an inner expression:

\the\dimexpr2cm-39.26477pt\relax


This gives 42.9589pt. But note: because you use \the, you get a text, not a length value. So with the textual substitution in the outer expression, you get:

\the\dimexpr0.7942.9589pt+3mm\relax


And instead of a multiplication, you get an illegal number with two decimal points. Lesson: don't use \the inside expressions.

With these corrections the final expression becomes:

\the\dimexpr\constII\dimexpr#1-\dimexpr\const\dimexpr#1\relax-4mm\relax\relax+#2\relax


which gives 22.47186pt. Whether that is the expected answer, I don't know.

A solution with xparse and expl3, which features a powerful and expandable module for floating point computations.

\documentclass{article}

\usepackage{tikz}
\usepackage{xparse}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\fpdim}{m}
{
\fp_to_dim:n { round(#1,5) }
}
\ExplSyntaxOff

\newcommand{\const}{0.89}
\newcommand{\constII}{0.79}

\setlength\parindent{0pt}

\begin{document}

\section{Henri}

\newcommand\henriobject[2]{%
\henrihexagon{#1}{0.5*#2}%
\henrihexagon{\const*#1-4mm}{\constII*(#1-(\const*#1-4mm))+#2}%
}
\newcommand\henrihexagon[2]{%
\pgfmathparse{#1}\pgfmathresult\
and
\pgfmathparse{#2}\pgfmathresult\par
}

\henriobject{2cm}{3mm}
\henriobject{12mm}{3mm}

\section{Piet}

\newcommand{\pietobject}[2]{%
\piethexagon{\the\dimexpr#1\relax}{\the\dimexpr0.5\dimexpr#2\relax\relax}%
\piethexagon{%
\the\dimexpr\const\dimexpr#1\relax-4mm\relax
}{%
\the\dimexpr\constII\dimexpr#1-(\const\dimexpr#1\relax-4mm)\relax+#2\relax
}%
}
\newcommand{\piethexagon}[2]{%
#1 and #2\par
}

\pietobject{2cm}{3mm}
\pietobject{12mm}{3mm}

\section{\texttt{expl3}}

\newcommand{\myobject}[2]{%
\myhexagon{\fpdim{#1}}{\fpdim{0.5*#2}}%
\myhexagon
{\fpdim{\const*#1-4mm}}
{\fpdim{\constII*(#1-(\const*#1-4mm))+#2}}%
}
\newcommand{\myhexagon}[2]{%
#1 and #2\par
}

\myobject{2cm}{3mm}
\myobject{12mm}{3mm}

\end{document}


Note that the results are much alike to each other, with differences only at the fourth decimal digit.

The big differences is that the solutions with xparse and \dimexpr are fully expandable, whereas the one with \pgfmathparse isn't.

The xparse syntax is much more friendly than \dimexpr, essentially identical to the one for \pgfmathparse.

Just use pgfmath if you are using TikZ anyway. Just insert your mathematical expression in \pgfmathparse (even including dimensions) and retrieve the result from \pgfmathresult (in pt).

\documentclass{article}
\usepackage{tikz}
\begin{document}

\newcommand\myhexagon[2]{%
\pgfmathparse{#1}\pgfmathresult\
and
\pgfmathparse{#2}\pgfmathresult\par
}

\newcommand\myobject[2]{%
\myhexagon{#1}{0.5*#2}%
\myhexagon{0.89*#1-4mm}{0.79*(#1-(0.89*#1-4mm))+#2}%
}

\myobject{2cm}{3mm}
\myobject{12mm}{3mm}

\end{document}