10

Consider the following MNWE:

\documentclass[border=10pt,multi,tikz]{standalone}
\usetikzlibrary{fpu}
\pgfkeys{/pgf/fpu=true}
\pgfkeys{/pgf/fpu=false}
\begin{document}
\pgfmathsetmacro\myresult{Mod(-100,30)}
\tikz{\node {\myresult};}
\end{document}

which fails with the following error:

! Package PGF Math Error: Sorry, the operation 'Mod' has not yet been implement
ed in the floating point unit :-( (in 'Mod(-100,30)').

See the PGF Math package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.119 \pgfmathsetmacro\myresult{Mod(-100,30)}

? 

In contrast,

\documentclass[border=10pt,multi,tikz]{standalone}
\usetikzlibrary{fpu}
\begin{document}
\pgfmathsetmacro\myresult{Mod(-100,30)}
\tikz{\node {\myresult};}
\end{document}

or

\documentclass[border=10pt,multi,tikz]{standalone}
\usetikzlibrary{fpu}
\begin{document}
\begingroup
  \pgfkeys{/pgf/fpu=true}
\endgroup
\pgfmathsetmacro\myresult{Mod(-100,30)}
\tikz{\node {\myresult};}
\end{document}

work as expected.

However, it seems that it is not always easy to avoid activating the FPU globally.

While you might hope that package authors would take care to limit the effects of such potentially disruptive changes by containing them within local groups, this question shows that this is not always the case.

How, then, can \pgfkeys{/pgf/fpu=false} be used to reverse a global invocation of \pgfkeys{/pgf/fpu=true}?

Is this a bug or am I missing something?

3
  • 3
    IMHO, this is a bug! Extract from pgfmanual: Use fpu=false to deactivate the FPU. This will restore any change. Please note that this is not necessary if the FPU is used inside of a TEX group -- it will be deactivated afterwards anyway. Sep 11, 2016 at 9:24
  • @PaulGaborit Yes, that's what I was wondering because that's how I understood the manual, too.
    – cfr
    Sep 11, 2016 at 13:54
  • For the record: I agree that this is a bug which was reported to the PGFPlots Tracker and solved in v1.15. So if you have this version and load it as well then your MWE works as expected. I assume, that this bug is also fixed in TikZ, but there we have to wait until the next release, too ... Jun 25, 2017 at 6:21

1 Answer 1

6

At least for this case (Mod as well as frac, random, setseed, and real), TikZ does backup the function. This can be seen in pgflibraryfpu.code.tex line 169-172:

\def\pgfmathfloat@install@unimplemented#1{%
    \expandafter\pgfmathfloat@prepareuninstallcmd\csname pgfmath@#1@\endcsname%
    \expandafter\def\csname pgfmath#1@\endcsname##1{\pgfmathfloat@notimplemented{#1}}%
}

Here, #1 is Mod. The first line backups the function of Mod. The second line redefines Mod to show the error message you saw.

However one can easily see an inconsistency that one macro is \pgfmath@Mod@ and the other is \pgfmathMod@. It turns out that the later is the correct name of the function. So what is backuped and restored is an empty macro.

TL;DR,

the correct definition is

\def\pgfmathfloat@install@unimplemented#1{%
    \expandafter\pgfmathfloat@prepareuninstallcmd\csname pgfmath#1@\endcsname%
    \expandafter\def\csname pgfmath#1@\endcsname##1{\pgfmathfloat@notimplemented{#1}}%
}

Copy and paste this between \usetikzlibrary{fpu} and \pgfkeys{/pgf/fpu=true} will solve this problem.


Here is some test code

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fpu}
\makeatletter
\begin{document}
\ttfamily

\def\pgfmathfloat@install@unimplemented#1{%
    \expandafter\pgfmathfloat@prepareuninstallcmd\csname pgfmath#1@\endcsname%
    \expandafter\def\csname pgfmath#1@\endcsname##1{\pgfmathfloat@notimplemented{#1}}%
}


\def\pgfmathfloat@prepareuninstallcmd#1{%
    % and store backup information (globally - I don't want to do that
    % all the time when the FPU is used!):
    \message{^^J^^J backuping \string#1^^J\meaning#1}
    \expandafter\global\expandafter\let\csname pgfmathfloat@backup@\string#1\endcsname=#1%
    \expandafter\gdef\expandafter\pgfmathfloat@uninstall\expandafter{\pgfmathfloat@uninstall
        \expandafter\let\expandafter#1\csname pgfmathfloat@backup@\string#1\endcsname%
    }%
}

---

Mod@: \meaning\pgfmathMod@

--- Turn on \pgfkeys{/pgf/fpu=true}

Mod@:\meaning\pgfmathMod@

backup @Mod: \expandafter\meaning\csname pgfmathfloat@backup@\string\pgfmathMod@\endcsname

-- Turn off \pgfkeys{/pgf/fpu=false}

Mod@:\meaning\pgfmathMod@

\pgfmathsetmacro\myresult{Mod(-100,30)}
\tikz{\node[draw]{\myresult};}

\end{document}
7
  • So definitely a bug, then? Thanks for hunting ....
    – cfr
    Sep 28, 2016 at 23:16
  • @cfr Perhaps I was not clear. The code under TL;DR is the correct definition. Paste it between \usetikzlibrary{fpu} and \pgfkeys{/pgf/fpu=true} will make your code compilable.
    – Symbol 1
    Sep 28, 2016 at 23:20
  • I understand that. But that is surely a bug.
    – cfr
    Sep 28, 2016 at 23:27
  • @cfr well... the manual (p27) says something about bug report and this links is somewhere bugs goes. But you probably already know that. So I am a little bit confused :(
    – Symbol 1
    Sep 28, 2016 at 23:34
  • Look at your linked question for Christian's answer
    – percusse
    Sep 28, 2016 at 23:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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