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 silently
return 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.
\pgfmathresult=0Y0.0e0]
, so not a good value for\ifnum
.