# pgfmath rounding error?

I am doing a specific pgfmath calculation involving logs and trig functions.

Pgfmath evaluates: log10(-cot(97.1)) = -0.90466. My calculator gives the "true" answer of −0.904633, which is close enough.

Pgfmath evaluates: log10(-cot(97.2)) = −0.88753. My calculator gives the "true" answer of −0.898495, which is quite different.

I assume this is some kind of weird rounding error- can I do something to fix this? (I am using these values to draw a diagram, and I can see visually that something is wrong with the values.)

MWE:

\documentclass{article}
\usepackage{pgfmath}
\begin{document}

\pgfmathparse{log10(-cot(97.1))}
$\log(-\cot 97.1) = \pgfmathresult$

(true answer: $-0.904633$)

\pgfmathparse{log10(-cot(97.2))}
$\log(-\cot 97.2)= \pgfmathresult$

(true answer: $-0.898495$)

\end{document}

• If you run the equivalent expression -log10(-tan(97.2)) you get instead -0.89848 which is much closer. This is probably because by default pgfmath uses fixed-point arithmetic, and since cot(97.2) = -0.126... and tan(97.2)=-7.9158 so the tangent expression has higher accuracy. But you ask why cot(97.1) is more accurate: it is probably just an accident that it has less rounding error. Jun 24, 2023 at 15:13
• Normally you can solve accuracy issues using the fpu library for pgf, but somehow it seems that the logarithms are not usable in \pgfmathparse when using the fpu library; maybe I am doing something wrong (not an expert on the inner workings here). // If fpu doesn't work, you can try using log10(abs(cosec(97.2))) - log10(abs(sec(97.2))) instead; since cosec and sec always outputs values bigger than 1, it should ameliorate fixed-point arithmetic related issues somewhat. Jun 24, 2023 at 15:23

pgfmath is inherently very approximate, by default; it uses fixed point arithmetic, as explained/suggested in the manual (this is around page 1027 of the TikZ manual):

If you want a more precise (IEEE precise) computation, you can use the new latex3 math engine, available in any recentish LaTeX:

\documentclass{article}
\usepackage{pgfmath}
\begin{document}

\pgfmathparse{log10(-cot(97.1))}
$\log(-\cot 97.1) = \pgfmathresult$ fpeval: \fpeval{ln(-cotd(97.1))/ln(10)}

(true answer: $-0.904633$)

\pgfmathparse{log10(-cot(97.2))}
$\log(-\cot 97.2)= \pgfmathresult$ fpeval: \fpeval{ln(-cotd(97.2))/ln(10)}

(true answer: $-0.898495$)

\end{document}


(your second result has a wrongfunny rounding)

You can also use the nice (although "stopgap" in its author's word) package pgfmath-xfp:

\documentclass{article}
\usepackage{pgfmath}
\usepackage{pgfmath-xfp}

\pgfmxfpdeclarefunction{myfun}{1}{ln(-cotd(#1))/ln(10)}

\begin{document}

\pgfmathparse{myfun(97.1)}
$\log(-\cot 97.1) = \pgfmathresult$

(true answer: $-0.904633$)

\pgfmathparse{myfun(97.2)}
$\log(-\cot 97.2)= \pgfmathresult$

(true answer: $-0.898495$)

\end{document}


• I had to upgrade my tex installation, but \fpeval worked great! Thanks- Jun 24, 2023 at 16:32