长话短说,

长话短说,

考虑以下 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}

失败并出现以下错误:

! 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)}

? 

相比之下,

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

或者

\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}

按预期工作。

然而,看起来避免在全球范围内启动FPU并不总是那么容易。

虽然您可能希望软件包作者能够小心地限制此类潜在破坏性更改的影响,方法是将它们包含在本地组中,这个问题表明情况并非总是如此。

那么,如何\pgfkeys{/pgf/fpu=false}使用来逆转全局调用\pgfkeys{/pgf/fpu=true}

这是一个错误还是我遗漏了什么?

答案1

至少对于这种情况(Mod以及fracrandomsetseedreal),TiZ 确实备份了该函数。这可以在pgflibraryfpu.code.tex第 169-172 行中看到:

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

这里,#1Mod。第一行备份 的功能Mod。第二行重新定义Mod以显示您看到的错误消息。

但是很容易看出一个不一致,一个宏是\pgfmath@Mod@,另一个是\pgfmathMod@。事实证明后者是该函数的正确名称。因此备份和恢复的是一个空宏。

长话短说,

正确的定义是

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

将其复制并粘贴在\usetikzlibrary{fpu}和之间\pgfkeys{/pgf/fpu=true}将解决此问题。


以下是一些测试代码

\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}

相关内容