提高 \pgfmathsetmacro 的精度

提高 \pgfmathsetmacro 的精度

我想使用

\pgfmathprintnumber[/pgf/number format/frac]{\var}

\var变量由哪里设置\pgfmathsetmacro,我遇到了类似的困难问题。我知道分形格式在数值上不稳定。

我的问题是,的精度\pgfmathsetmacro似乎是五位数字,但对于以下最小示例,我需要七位数字。有什么技巧可以做到这一点吗?


编辑:

以下解决方案是可行的(我还没有决定哪一个是最好的..请投票!)

  • 包裹xintexprround(x,10)得到精度为 10 的结果 (by @jfbu)
    • 改变的只是分工
  • frac shift=2(作者:@Qrrbrbirlbel)
    • 简单加法
    • 没有额外的包裹
  • 定点运算tikz 来计算更精确的结果(也是由@Qrrbrbirlbel 提供的)
    • newcommand,但除此之外也只是改变了部门

原帖继续 看看这个例子:

  • 蓝色我的第一次尝试
  • 黑色,带 FPU
  • 红色:我想要的。

在此处输入图片描述

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fpu}
\usepackage{fp} % uncommenting results in the following warning, but no change in output
%! Package pgf /pgf/number format/frac warning=true: /pgf/number format/frac of
%`3.3333e-1' = 100009 / 300030 might be large due to instabilities. Try \usepack
%age{fp} to improve accuracy.

\begin{document}
\begin{tikzpicture}
\def\nu{4}
\def\w{5}
\pgfmathsetmacro{\nn}{\nu-1}
\foreach \i in {0,1,...,\nn}{
  \pgfmathsetmacro{\xi}{\i*\w/(\nu-1)}
  % first test
  \pgfmathsetmacro{\xival}{\i/(\nu-1)}
  \draw[blue] (\xi, -1.1 cm) -- (\xi,2pt)  node[above,align=center] 
     {\pgfmathprintnumber[fixed, precision=10]{\xival} \\ 
     \pgfmathprintnumber[/pgf/number format/frac]{\xival}};

  % second test (fpu)
  \pgfkeys{/pgf/fpu}
  \pgfmathparse{\i/(\nu-1)}
  \edef\tmp{\pgfmathresult}
  \pgfkeys{/pgf/fpu=false}
  \draw (\xi,2pt) -- (\xi, -1.1 cm) node[below,align=center] 
      {\pgfmathprintnumber[fixed, precision=10]{\tmp} \\ 
      \pgfmathprintnumber[/pgf/number format/frac]{\tmp}};
  } % end foreach

% this works (two digits '3' added)
\node[red] at (1,-.5) {\pgfmathprintnumber[/pgf/number format/frac]{0.3333333}};

\end{tikzpicture}
\end{document}

答案1

对于和提供的0.33333高精度来说,这实在是太不精确了,因为 100009/300030(即 0.3¯33330000)更接近 0.33333 而不是 1/3。/fracfp

您可以通过提供选项/pgf/number format/frac shift=2(最初4)或使用fp除法来解决此问题。

代码

\documentclass{standalone}
\usepackage{fp,tikz}
\usetikzlibrary{fpu,fixedpointarithmetic}
\newcommand*{\pgfMathsetmacro}[2]{\pgfmathparse{#2}\let#1\pgfmathresult}
\begin{document}
\begin{tikzpicture}[x=1.5cm]
\def\nu{4} \def\w{5}
\foreach \i in {0,1,...,\the\numexpr\nu-1}{
  \pgfmathsetmacro\xival{\i/(\nu-1)}
  \draw (\i,0pt) node[above,align=center] 
    {{\tiny\pgfmathprintnumber[fixed, precision=10]{\xival}} \\ 
           \pgfmathprintnumber[/pgf/number format/.cd, frac, frac shift=2]{\xival}};

  \tikzset{fixed point arithmetic}
  \pgfMathsetmacro\xival{\i/(\nu-1)}
  \draw (\i,-1) node[above,align=center] 
    {{\tiny\pgfmathprintnumber[fixed, precision=10]{\xival}} \\ 
           \pgfmathprintnumber[/pgf/number format/frac]{\xival}};
}
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

答案2

使用包可以进行分数的精确或任意精确计算,并且使用包提供的函数xintfrac可以更轻松地进行计算(该函数加载\xintexpr ... \relaxxintexprxintfrac。请参阅xint 束

所以这里我们使用round(x,10)里面的函数xinttheexpr...\relax来定义一个宏\tmp,将\edef分数四舍五入到小数点后10位。

但请注意,除了sqrt加法之外,还可以进行乘法、除法、减法和整数指数的幂。

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fpu}
\usepackage{xintexpr} % http://ctan.org/pkg/xint

\begin{document}
\begin{tikzpicture}
\def\nu{4}
\def\w{5}
\pgfmathsetmacro{\nn}{\nu-1}
\foreach \i in {0,1,...,\nn}{
  \pgfmathsetmacro{\xi}{\i*\w/(\nu-1)}
  % first test
  \pgfmathsetmacro{\xival}{\i/(\nu-1)}
  \draw[blue] (\xi, -1.1 cm) -- (\xi,2pt)  node[above,align=center] 
     {\pgfmathprintnumber[fixed, precision=10]{\xival} \\ 
     \pgfmathprintnumber[/pgf/number format/frac]{\xival}};

  % second test (fpu)
  \pgfkeys{/pgf/fpu}
  \pgfmathparse{\i/(\nu-1)}
  \edef\tmp{\pgfmathresult}
  \pgfkeys{/pgf/fpu=false}
  \draw (\xi,2pt) -- (\xi, -1.1 cm) node[below,align=center] 
      {\pgfmathprintnumber[fixed, precision=10]{\tmp} \\ 
      \pgfmathprintnumber[/pgf/number format/frac]{\tmp}};

  % third test (xintexpr)
  \edef\tmp{\xinttheexpr round(\i/(\nu-1),10)\relax}
  \pgfkeys{/pgf/fpu=false}
  \draw[blue] (\xi,-2.1cm)
           -- (\xi, -3.2cm) node[below,align=center] 
      {\pgfmathprintnumber[fixed, precision=10]{\tmp} \\ 
      \pgfmathprintnumber[/pgf/number format/frac]{\tmp}};

} % end foreach

% this works (two digits '3' added)
\node[red] at (1,-.5) {\pgfmathprintnumber[/pgf/number format/frac]{0.3333333}};

\end{tikzpicture}
\end{document}

xint 的使用

相关内容