Rounding a value from a function

Is possible I define a mathematical function f(x), for example, f(x) = sqrt(x), evaluate this function in a given point p=2 and round the result with 4 decimal places? I prefer use this code inside a tikz environment. My difficult is calculate the number m =1/2*f(p) with my function defined and provide the result with a given precision (4 or 5 exact decimal places). The following code does not round.

Here I provide my code:

\documentclass[tikz, border=.5cm]{article}
\usepackage{tkz-fct}
\usepackage{multido}
\usetikzlibrary{calc,math}
\pgfkeys{/pgf/number format/.cd,fixed,fixed zerofill,precision=5}
\usepackage{xfp}
\usepackage{float}
\usepackage{amsmath}

\begin{document}

\tikzmath{
real \a;
real \b;
\a = 0;
\b = 4;
}

\foreach \p in {2,1}{
\begin{tikzpicture}[declare function = {f(\x) = (\x)^0.5;}]
\clip (-1.5,-1.5) rectangle (4.5,3.5);
\draw[help lines] (-1,-1) grid (4,3);
\draw[->,>=stealth'] (-1,0) -- (4,0) node[right] {$x$};
\draw[->,>=stealth'] (0,-1) -- (0,3) node[above] {$y$};
\foreach \j in {-1,0,1,2,3,4}{
\draw (\j,2pt)--(\j,-2pt) node[below,fill=white]{{\footnotesize $\j$}};
}
\foreach \j in {-1,0,1,2,3,}{
\draw (2pt,\j)--(-2pt,\j) node[left,] {{\footnotesize $\j$}};
}
\draw[samples=1000,thick,blue] plot[domain=\a:\b](\x,{f(\x)}) node[right]{$f$};
\draw[samples=1000,thick,red] plot[domain=-1.5+\p:1.5+\p]({\x},{f(\p) + ( 1/(2*f(\p))*(\x - \p)}) node[above] {$t$};
\draw[fill] (\p,{f(\p)}) circle (1pt);
\draw[dotted] (\p,0) -- (\p,{f(\p)}) node[above,rotate=atan(1/(2*f(\p)))]{{\scriptsize $(\fpeval{round(\p,1)},\fpeval{round(\p^0.5,2)})$}} -- (0,{f(\p)});
\node[above] (2) at (1.5,3)  {$m = \pgfmathparse{1/(2*f(\p)) }\pgfmathresult$};
\end{tikzpicture}
}

\end{document}


In order for your

\pgfkeys{/pgf/number format/.cd, fixed, fixed zerofill, precision=5}


to be used, you need to call \pgfmathprintnumber or \pgfmathprintnumberto, as in \pgfmathprintnumber{\pgfmathresult}. However, pgfmath is not very accurate and as you can see below, xfp (l3fp) gives a much better result:

\documentclass{article}
\usepackage{tkz-fct}
\usetikzlibrary{math}
\pgfkeys{/pgf/number format/.cd, fixed, fixed zerofill, precision=5}
\usepackage{xfp}

\begin{document}

\tikzmath{
real \a;
real \b;
\a = 0;
\b = 4;
}

\foreach \p in {2,1}{
\begin{tikzpicture}[declare function = {f(\x) = (\x)^0.5;}]
\clip (-1.5,-1.5) rectangle (4.5,3.5);
\draw[help lines] (-1,-1) grid (4,3);
\draw[->,>=stealth'] (-1,0) -- (4,0) node[right] {$x$};
\draw[->,>=stealth'] (0,-1) -- (0,3) node[above] {$y$};
\foreach \j in {-1,0,1,2,3,4}{
\draw (\j,2pt)--(\j,-2pt) node[below,fill=white]{{\footnotesize $\j$}};
}
\foreach \j in {-1,0,1,2,3,}{
\draw (2pt,\j)--(-2pt,\j) node[left,] {{\footnotesize $\j$}};
}
\draw[samples=1000,thick,blue] plot[domain=\a:\b](\x,{f(\x)}) node[right]{$f$};
\draw[samples=1000,thick,red] plot[domain=-1.5+\p:1.5+\p]({\x},{f(\p) + ( 1/(2*f(\p))*(\x - \p)}) node[above] {$t$};
\draw[fill] (\p,{f(\p)}) circle (1pt);
\draw[dotted] (\p,0) -- (\p,{f(\p)}) node[above,rotate=atan(1/(2*f(\p)))]{{\scriptsize $(\fpeval{round(\p,1)},\fpeval{round(\p^0.5,2)})$}} -- (0,{f(\p)});
\node[above] (2) at (1.5,3)
{$m \approx \pgfmathparse{1/(2*f(\p))} \pgfmathprintnumber{\pgfmathresult}$};
\end{tikzpicture}
}

\foreach \p in {2,1}{
\begin{tikzpicture}[declare function = {f(\x) = (\x)^0.5;}]
\clip (-1.5,-1.5) rectangle (4.5,3.5);
\draw[help lines] (-1,-1) grid (4,3);
\draw[->,>=stealth'] (-1,0) -- (4,0) node[right] {$x$};
\draw[->,>=stealth'] (0,-1) -- (0,3) node[above] {$y$};
\foreach \j in {-1,0,1,2,3,4}{
\draw (\j,2pt)--(\j,-2pt) node[below,fill=white]{{\footnotesize $\j$}};
}
\foreach \j in {-1,0,1,2,3,}{
\draw (2pt,\j)--(-2pt,\j) node[left,] {{\footnotesize $\j$}};
}
\draw[samples=1000,thick,blue] plot[domain=\a:\b](\x,{f(\x)}) node[right]{$f$};
\draw[samples=1000,thick,red] plot[domain=-1.5+\p:1.5+\p]({\x},{f(\p) + ( 1/(2*f(\p))*(\x - \p)}) node[above] {$t$};
\draw[fill] (\p,{f(\p)}) circle (1pt);
\draw[dotted] (\p,0) -- (\p,{f(\p)}) node[above,rotate=atan(1/(2*f(\p)))]{{\scriptsize $(\fpeval{round(\p,1)},\fpeval{round(\p^0.5,2)})$}} -- (0,{f(\p)});
\node[above] (2) at (1.5,3)
{$m \approx \fpeval{round(1/(2*sqrt(\p)), 5)}$};
\end{tikzpicture}
}

\end{document}


By using:

• \fpeval inside \pgfmathparse followed by \pgfmathprintnumber{\pgfmathresult}, or;

• more directly, \pgfmathprintnumber{\fpeval{1/(2*sqrt(\p))}},

you can print a fixed number of decimal places with great precision (14 correct digits here, and the 15th is correctly rounded according to what follows!):

\documentclass{article}
\usepackage{pgffor}
\usepackage{pgfmath}
\usepackage{pgf}
\usepackage{xfp}

\pgfkeys{/pgf/number format/.cd, fixed, fixed zerofill, precision=15}

\begin{document}

\foreach \p in {2,1} {%
When $p = \p$,
$m \approx \pgfmathprintnumber{\fpeval{1/(2*sqrt(\p))}}$.\par
}

\end{document}


Another way to format numbers (here computed with \fpeval, but this is not necessary) is to use the siunitx package:

\documentclass{article}
\usepackage{pgffor}
\usepackage{siunitx}
\sisetup{round-mode = places, round-precision=15}
\usepackage{xfp}

\begin{document}

\foreach \p in {2,1} {%
When $p = \p$,
$m \approx \num{\fpeval{1/(2*sqrt(\p))}}$.\par
}

\end{document}


• Is possible use \fpeval using the function f, instead sqrt(\p)? – Angelo Aliano Filho Oct 24 '20 at 22:13
• I don't know of any clean, reliable way to do this. 1) Computing the value of a general pgfmath function requires executing code in TeX's stomach (in particular, assigning \pgfmathresult), whereas the argument of \fpeval only supports expansion (which allows \fpeval to be fully expandable). 2) pgfmath expressions don't have exactly the same syntactic and semantic rules as expressions understood by l3fp or \fpeval, therefore just replacing \x from a pgfmath expression with a number and feeding that to \fpeval wouldn't work reliably for arbitrary expressions. – frougon Oct 24 '20 at 22:15
• @AngeloAlianoFilho with some restrictions it is possible to use \fpeval inside of a pgfmath-function (provided pgfmath can handle the result in its current mode, meaning that \fpeval could return numbers too big for pgfmath without the FPU). See here: tex.stackexchange.com/a/585016/117050 – Skillmon 2 days ago