While creating some pgfmathsetmacro arithmetic macros, I stumbled upon a very perplexing result. Take the following example:

\documentclass{article}
\usepackage{tikz}
\usepackage{xstring}

\begin{document}

\begin{tikzpicture}
    \newcommand{\boxWidth}{6cm};
    \newcommand{\boxHeight}{1cm};

    \pgfmathsetmacro{\boxOffset}{\boxWidth / 2cm * 1cm} %%%wtf
    \coordinate (Title) at (1cm + \boxOffset,0);

    \draw [red] (0,0) -- (1,0);

    \node[draw, rounded corners=.3cm, color=red, minimum width=\boxWidth, minimum height=\boxHeight, text=black] at (Title) {Hello};
    \end{tikzpicture}
\end{document}

This outputs a very predictable result: predictable result

However, if you remove * 1cm from my \boxOffset macro, a totally unexpected result occurs: unexpected output

What?! On the surface, this appears to be saying that 2 * 1 != 2 is a true statement!

To add to this, while I was playing around with creating an example LaTeX script for the following question on this forum, I stumbled upon a similar bamboozling arithmetic:

\documentclass{article}
\usepackage{tikz}
\usepackage{xstring}

\begin{document}
\begin{tikzpicture}
    \newcommand{\str}{hello};

    \pgfmathsetmacro{\numOne}{width("\str") * 1pt / 4cm}; %%%wtf

    \node at (0, 0) {\str};
    \draw [color=black] (\numOne, 0cm) -- (\numOne,-1cm);

\end{tikzpicture}
\end{document}

The following example creates the very predictable output:

another predictable output

However, if I change the \numOne to compute the following width("\str") * 1pt / 2cm / 2cm, then I get a very unpredictable output:

another very unpredictable output

What?! This is telling me that the ridiculous statement x / 2 / 2 != x / 4 is true.

Can anyone shed some light on what is happening here? This is not the only time I have run into this bamboozling arithmetic and I am lost at what is happening.

bamboozle doggo

^This is how I feel right now.

  • All arithmetic is performed internally in pt, so the 1cm is converted to 28.45274pt. – Phelype Oleinik Oct 11 at 22:00
  • The result is stored in unit pt; with *1cm you get 85.35823, without it is 3.0; the quotient is 28.45274, which is the number of points in 1cm. – egreg Oct 11 at 22:00
up vote 16 down vote accepted

Your assumption that multiplying by 1cm is the same as multiplying by 1 is wrong.

What about multiplying by 1in or 1mm?

The function \pgfmathresult returns a number, not a dimension. For implementation reasons, the number 1 is stored as a length, precisely 1pt.

Therefore 3*1 is 3, but 3*1cm is 85.35823, because 1cm=28.45275pt (and then TeX’s rounding applies).

The easiest way to address this is to see what the difference between the two calculations yield for \boxOffset:

enter image description here

\documentclass{article}

\usepackage{tikz}

\begin{document}

\newcommand{\boxWidth}{6cm}
\newcommand{\boxHeight}{1cm}

\pgfmathsetmacro{\boxOffset}{\boxWidth / 2cm}%
\verb|\boxOffset| 1: \boxOffset

\pgfmathsetmacro{\boxOffset}{\boxWidth / 2cm * 1cm}%
\verb|\boxOffset| 2: \boxOffset

\end{document}

In performing the division 6cm / 2cm, tikz converts the quantities to a uniform unit of measure (pts). However, in this case with similar measurements in the division, it results in merely "striping" the measurement, yielding in 3. This is understandable. Multiplying this result by 1cm, the value is first converted to pts (there are 28.45274 pts in every cm; see \newlength{\templen} \setlength{\templen}{1cm} \the\templen), yielding the desired result (3 x 28.45274 = 85.35822), with some floating point error.

A similar argument would hold for your other calculations as lengths are converted to pts before performing the arithmetic.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.