![提高 \pgfmathsetmacro 的精度](https://linux22.com/image/276222/%E6%8F%90%E9%AB%98%20%5Cpgfmathsetmacro%20%E7%9A%84%E7%B2%BE%E5%BA%A6.png)
我想使用
\pgfmathprintnumber[/pgf/number format/frac]{\var}
\var
变量由哪里设置\pgfmathsetmacro
,我遇到了类似的困难这和这问题。我知道分形格式在数值上不稳定。
我的问题是,的精度\pgfmathsetmacro
似乎是五位数字,但对于以下最小示例,我需要七位数字。有什么技巧可以做到这一点吗?
编辑:
以下解决方案是可行的(我还没有决定哪一个是最好的..请投票!)
- 包裹xintexpr并
round(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。/frac
fp
您可以通过提供选项/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 ... \relax
xintexpr
xintfrac
。请参阅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}