Is there a simple way of improving the precision of pgfmath for trig functions?

I wanted to build a table of trig values using pgfmath. However, the precision is a bit off. Is there a way to improve this within TikZ?

This is related to a similar question I just posted: Is there a way to pad zeros to the end of a rounded number with Expl3?

Here's my current working example:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc,fixedpointarithmetic}

\def\mynum{0}
\def\myvoffset{0pt}

\usepackage[margin=0.5in]{geometry}

\begin{document}

Using \texttt{TikZ}

\begin{tikzpicture}[/pgf/number format/.cd,fixed,precision=4,verbatim]

\coordinate(UL) at (0,0);

\node at (UL) {Degrees};
\node[anchor=west] at ($(UL.west)+(1cm,0)$) {$\sin$};
\node[anchor=west] at ($(UL.west)+(2.75cm,0)$) {$\cos$};
\node[anchor=west] at ($(UL.west)+(4.50cm,0)$) {$\tan$};

\foreach \myn in {1,2,3,...,45}
{
\pgfmathparse{int(mod(\myn-1,5))}
\ifnum\pgfmathresult=0\relax
\xdef\myvoffset{\dimexpr\myvoffset+1.350\baselineskip}%%
\else
\xdef\myvoffset{\dimexpr\myvoffset+1.00\baselineskip}%%
\fi

\coordinate (DEG/\myn)   at ($(UL.west)-(0,\myvoffset)$);
\coordinate (DEG/S/\myn) at ($(DEG/\myn)+(1cm,0)$);
\coordinate (DEG/C/\myn) at ($(DEG/S/\myn)+(1.75cm,0)$);
\coordinate (DEG/T/\myn) at ($(DEG/C/\myn)+(1.75cm,0)$);

\node[anchor=east] at (DEG/\myn) {$\myn^\circ$};
\pgfmathparse{sin(\myn)} \node[anchor=west] at (DEG/S/\myn) {\texttt{\pgfmathprintnumber{\pgfmathresult}}};
\pgfmathparse{cos(\myn)} \node[anchor=west] at (DEG/C/\myn) {\texttt{\pgfmathprintnumber{\pgfmathresult}}};
\pgfmathparse{tan(\myn)} \node[anchor=west] at (DEG/T/\myn) {\texttt{\pgfmathprintnumber{\pgfmathresult}}};

}

\end{tikzpicture}

\end{document}


-

I don't know with pgfmath; with expl3 you can compile your table like this:

\documentclass{article}
\usepackage[margin=1cm]{geometry}

\usepackage{array,siunitx}

\sisetup{
round-precision=5,
round-mode=places,
round-integer-to-decimal,
group-digits=false,
detect-all,
}

\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\trigtable}{ }
{
\__aellett_do_trig:
\begin{tabular}{r *{3}{ >{\ttfamily}r }}
& \multicolumn{1}{c}{$\sin$}
& \multicolumn{1}{c}{$\cos$}
& \multicolumn{1}{c}{$\tan$}
\\
\tl_use:N \l__aellett_body_tl
\end{tabular}
}

\tl_new:N \l__aellett_body_tl

\cs_new:Npn \aellett_compute:nn #1 #2
{
\num { \fp_to_decimal:n { \fp_eval:n { round ( #1(#2) , 5 ) } } }
}

\cs_new_protected:Npn \__aellett_do_trig:
{
\tl_clear:N \l__aellett_body_tl
\int_step_inline:nnnn { 1 } { 1 } { 89 }
{
\tl_put_right:Nn \l__aellett_body_tl { $##1^\circ$ & }
\tl_put_right:Nx \l__aellett_body_tl
{
\aellett_compute:nn { sind } { ##1 } &
\aellett_compute:nn { cosd } { ##1 } &
\aellett_compute:nn { tand } { ##1 }
}
\int_compare:nTF { \int_mod:nn { ##1 } { 5 } == 0 }
{
\tl_put_right:Nn \l__aellett_body_tl { \$1ex] } } { \tl_put_right:Nn \l__aellett_body_tl { \\ } } } % 90 degrees \tl_put_right:Nx \l__aellett_body_tl { 90^\circ & \aellett_compute:nn { sind } { 90 } & \aellett_compute:nn { cosd } { 90 } & --- } } \ExplSyntaxOff \begin{document} \tiny \trigtable \end{document}  Here's the start: And here's the end, just to show what happens at 89 degrees: I used five digits for comparison with the value bc returns for the tangent of 89 degrees: 57.28996163075942465214 - You could also substitute ##1^\circ with \ang{##1} to use siunitx. – Manuel Mar 22 at 11:20 @Manuel You're right; but I almost never use angles in degree, so I resorted to the old school method. ;-) – egreg Mar 22 at 11:21 This is for high school students' first exposure to trigonometry. They won't learn about radians until much later. – A.Ellett Mar 22 at 14:01 @A.Ellett Why? The sooner they get away with degrees, the better. – egreg Mar 22 at 14:07 Unlike university teaching, I don't have much say about the how, what, or when of math content. The benefit of degrees though is that the students are already familiar with them and so they can focus on what is new, the trig functions. – A.Ellett Mar 22 at 14:18 Extend your options with fixed zerofill. \documentclass{article} \pagestyle{empty} \usepackage{tikz} \usetikzlibrary{calc,fixedpointarithmetic} \def\mynum{0} \def\myvoffset{0pt} \usepackage[margin=0.5in]{geometry} \begin{document} %Using \texttt{TikZ} \begin{tikzpicture}[/pgf/number format/.cd,fixed,precision=4,verbatim, fixed zerofill] \coordinate(UL) at (0,0); \node at (UL) {Degrees}; \node[anchor=west] at ((UL.west)+(1cm,0)) {\sin}; \node[anchor=west] at ((UL.west)+(2.75cm,0)) {\cos}; \node[anchor=west] at ((UL.west)+(4.50cm,0)) {\tan}; \foreach \myn in {1,2,3,...,45} { \pgfmathparse{int(mod(\myn-1,5))} \ifnum\pgfmathresult=0\relax \xdef\myvoffset{\dimexpr\myvoffset+1.350\baselineskip}%% \else \xdef\myvoffset{\dimexpr\myvoffset+1.00\baselineskip}%% \fi \coordinate (DEG/\myn) at ((UL.west)-(0,\myvoffset)); \coordinate (DEG/S/\myn) at ((DEG/\myn)+(1cm,0)); \coordinate (DEG/C/\myn) at ((DEG/S/\myn)+(1.75cm,0)); \coordinate (DEG/T/\myn) at ((DEG/C/\myn)+(1.75cm,0)); \node[anchor=east] at (DEG/\myn) {\myn^\circ}; \pgfmathparse{sin(\myn)} \node[anchor=west] at (DEG/S/\myn) {\texttt{\pgfmathprintnumber{\pgfmathresult}}}; \pgfmathparse{cos(\myn)} \node[anchor=west] at (DEG/C/\myn) {\texttt{\pgfmathprintnumber{\pgfmathresult}}}; \pgfmathparse{tan(\myn)} \node[anchor=west] at (DEG/T/\myn) {\texttt{\pgfmathprintnumber{\pgfmathresult}}}; } \end{tikzpicture} \end{document}  - With the standard TeX arithmetic, precision is very limited.If you need more accurate results, you may need to use some external program or any extension of TeX, such as luatex. Using my package calculator I get results similar to what you get with Tikz: \documentclass{article} \usepackage{calculator} \usepackage{ifthen} \begin{document} \newcounter{angle} \newcommand{\trigfunctions}[1]{% #1^{\mathrm{o}} & \DEGREESSIN{#1}{\sine} \ROUND[4]{\sine}{\sine} \sine & \DEGREESCOS{#1}{\cosine} \ROUND[4]{\cosine}{\cosine} \cosine & \DEGREESTAN{#1}{\tangent} \ROUND[4]{\tangent}{\tangent} \tangent& \DEGREESCOT{#1}{\cotangent} \ROUND[4]{\cotangent}{\cotangent} \cotangent \\} \small \[ \begin{array}{*{5}{r}} \multicolumn{1}{c}{\alpha} & \multicolumn{1}{c}{\sin\alpha} & \multicolumn{1}{c}{\cos \alpha} & \multicolumn{1}{c}{\tan\alpha} & \multicolumn{1}{c}{\cot\alpha} \\ \whiledo{\value{angle}<45}{\stepcounter{angle}\trigfunctions{\theangle}} \end{array}$
\end{document}


-