Unfortunately, both of the existing answers have drawbacks.
Heiko Oberdiek's answer: it exactly undoes the fix in the linked question. In this case \addplot
just happens to not evaluate the function at x=0
, but if it does...
\documentclass{article}\usepackage{pgfplots}\pgfplotsset{compat=1.17}\begin{document} \pgfmathdeclarefunction{sincf}{1}{% \pgfmathparse{(abs(#1)<0.01) ? 1 : sin(pi*#1 r)/(pi*#1)}% } \pgfmathparse{sincf(0)}\end{document}
you got an error.
Cryptc's answer works, but only if the FPU is currently enabled and the output format is float.
\documentclass{article}\usepackage{pgfplots}\pgfplotsset{compat=1.17}\begin{document}\pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed}\pgfmathparse{1} % stores 1.0000000000 to \pgfmathresult\pgfmathfloattofixed{\pgfmathresult} % \pgfmathfloattofixed, as with other \pgfmathfloat... functions, expect input in low-level PGF FPU representation\end{document}
Error.
One way I can find to convert anything to an int is to round-trip through PGF's FPU:
\documentclass{article}\usepackage{tikz}% don't need fpu library!\begin{document}% works with both internal representation and "normal" representation\pgfmathfloatparsenumber{1Y1.0e6]}\pgfmathfloattoint\pgfmathresult% now \pgfmathresult is always an integer\pgfmathfloatparsenumber{1000000}\pgfmathfloattoint\pgfmathresult\end{document}
You can try \pgfmathtruncatemacro
, but this will silentlyreturn the wrong error if the FPU is enabled and output format is float!
So for this problem, the fix is
\documentclass{scrreprt}\usepackage{pgfplots}\pgfplotsset{compat=1.12}\begin{document}\pgfmathdeclarefunction{sinc}{1}{% \pgfmathparse{abs(#1)<0.01 ? 1 : 0}% % ======== add these 2 lines ======== \pgfmathfloatparsenumber\pgfmathresult \pgfmathfloattoint\pgfmathresult % ======== end ======== \ifnum\pgfmathresult>0 % \pgfmathparse{1}% \else% \pgfmathparse{sin(3.14159*#1 r)/(3.14159*#1)}% \fi%}\begin{tikzpicture} \begin{axis} \addplot {sinc(\x)}; \end{axis}\end{tikzpicture}% ======== double check it works with normal \draw plot\begin{tikzpicture} \draw (-1,0) -- (1,0); \draw[domain=0:0.5, samples=250] plot (\x,{sinc(20*\x)});\end{tikzpicture}\end{document}
works both with TikZ \draw plot
and \addplot
.
Alternatively, staying completely within the FPU, there's \pgfmathfloatifflags
:
\pgfmathdeclarefunction{sinc}{1}{% \pgfmathparse{abs(#1)<0.01}% \pgfmathfloatparsenumber\pgfmathresult \pgfmathfloatifflags{\pgfmathresult}{1}{% "less than" is true \pgfmathparse{1}% }{% "less than" is false \pgfmathparse{sin(3.14159*#1 r)/(3.14159*#1)}% }%}
Also a bit faster.
Another alternative, although specific to this question, is
\pgfmathdeclarefunction{sinc}{1}{% \pgfmathparse{(#1==0 ? 1: sin(3.14159*#1 r))/(#1==0 ? 1: 3.14159*#1)}%}
(just stare at the code for a while you'll see why it works.)
I tried to make ifthenelse
short-circuits, but evaluate-immediately-while-parsing behavior is quite hard-wired into the behavior of \pgfmathparse
, so it seems difficult to fix.