![PGFmathprint 分数精度问题](https://linux22.com/image/334053/PGFmathprint%20%E5%88%86%E6%95%B0%E7%B2%BE%E5%BA%A6%E9%97%AE%E9%A2%98.png)
我尝试使用pgf
数字排版制作此表,但存在精度问题。摘自手册:
如果您仍然遇到稳定性问题,请在序言中使用 \usepackage{fp}。然后,frac 样式将自动采用 fp 的更高绝对精度来计算 1/r。
但是还是提醒一个问题。
\documentclass[french]{article}
\usepackage{tikz,array,tabularx,luacode,xparse,ragged2e}
\usepackage{amsmath,amsfonts,amssymb,calc}
\usepackage{fp}
\usepackage{siunitx} % \num{} ...
\sisetup{%
unit-mode = text,%
locale=FR,%
detect-all,% Problème avec euro, utiliser \text{€} en mode math
inter-unit-product = \ensuremath{{}\cdot{}},%
group-minimum-digits=4,
text-angstrom={Å},math-angstrom={\text{Å}}
}
\usetikzlibrary{calc,fpu}
\directlua{require ("Maths")}
\NewDocumentCommand{\Frac}{sm}{%
\IfBooleanTF{#1}{%
\directlua{Frac(#2,1)}
}{%
\directlua{Frac(#2)}}
}
\NewDocumentCommand{\Around}{mm}{%
\directlua{Around(#1,#2)
}
}
\NewDocumentCommand{\pgfAround}{mm}{%
{\pgfkeys{/pgf/number format/.cd,fixed,precision=#2,use comma}
\pgfmathprintnumber{#1}}
}
\NewDocumentCommand{\pgfFrac}{sm}{%
\IfBooleanTF{#1}{%
{\pgfkeys{/pgf/number format/.cd,frac,frac whole = false}
\pgfmathprintnumber{#2}}
}{%
{\pgfkeys{/pgf/number format/.cd,%
frac,frac whole = false,frac TeX={\dfrac}}
\pgfmathprintnumber{#2}}
}
}
\newcommand{\vtab}[1][1.2]{\rule[-0.9em*\real{#1}]{0pt}{2.3em*\real{#1}}}
\begin{document}
Lua -- Version
\medskip
{\small\setlength{\tabcolsep}{0pt}
\begin{tabularx}{\linewidth}{|*{13}{>{\Centering}X|}}\hline
Do$_1$&
Ré$_1$&
Mi$_1$&
Fa$_1$&
Sol$_1$&
La$_1$&
Si$_1$&
Do$_2$&
Ré$_2$&
Mi$_2$&
Fa$_2$&
Sol$_2$&
La$_2$\\\hline
\num{20}&
\Around{17.7777777778}{-1}&
\Around{15.8024691358}{-1}&
\Around{14.0466392318}{-1}&
\Around{13.3333333333}{-1}&
\Around{11.8518518519}{-1}&
\Around{10.5349794239}{-1}&
\num{10}&
\Around{8.8888888889}{-1}&
\Around{7.9012345679}{-1}&
\Around{7.0233196159}{-1}&
\Around{6.6666666667}{-1}&
\Around{5.9259259259}{-1}\\\hline
\vtab\num{20}&
\Frac{17.7777777778}&
\Frac*{15.8024691358}&
\Frac*{14.0466392318}&
\Frac{13.3333333333}&
\Frac{11.8518518519}&
\Frac*{10.5349794239}&
\Frac{10}&
\Frac{8.8888888889}&
\Frac{7.9012345679}&
\Frac*{7.0233196159}&
\Frac{6.6666666667}&
\Frac{5.9259259259}\\\hline
\end{tabularx}
}
\bigskip
PGF -- Version
\medskip
{\small\setlength{\tabcolsep}{0pt}
\begin{tabularx}{\linewidth}{|*{13}{>{\Centering}X|}}\hline
Do$_1$&
Ré$_1$&
Mi$_1$&
Fa$_1$&
Sol$_1$&
La$_1$&
Si$_1$&
Do$_2$&
Ré$_2$&
Mi$_2$&
Fa$_2$&
Sol$_2$&
La$_2$\\\hline
\num{20}&
\pgfAround{17.7777777778}{1}&
\pgfAround{15.8024691358}{1}&
\pgfAround{14.0466392318}{1}&
\pgfAround{13.3333333333}{1}&
\pgfAround{11.8518518519}{1}&
\pgfAround{10.5349794239}{1}&
\num{10}&
\pgfAround{8.8888888889}{1}&
\pgfAround{7.9012345679}{1}&
\pgfAround{7.0233196159}{1}&
\pgfAround{6.6666666667}{1}&
\pgfAround{5.9259259259}{1}\\\hline
\vtab\num{20}&
\pgfFrac*{17.7777777778}&
\pgfFrac{15.8024691358}&
\pgfFrac*{14.0466392318}&
\pgfFrac{13.3333333333}&
\pgfFrac*{11.8518518519}&
\pgfFrac*{10.5349794239}&
\pgfFrac{10}&
\pgfFrac{8.8888888889}&
\pgfFrac{7.9012345679}&
\pgfFrac*{7.0233196159}&
\pgfFrac{6.6666666667}&
\pgfFrac*{5.9259259259}\\\hline
\end{tabularx}
}
\end{document}
和Maths.lua
-- ####################################
-- Transforme un décimal en fraction #
-- ####################################
function Frac( n , sf)
local s = ""
if n<0 then n,s = -n,"-" end
local tolerance = 1.e-8
local h1=1
local h2=0
local k1=0
local k2=1
local b = 1/n
local aux
local a
while math.abs(n-h1/k1) > n*tolerance
do
b = 1/b
a = math.floor(b)
aux = h1
h1 = a*h1+h2
h2 = aux
aux = k1
k1 = a*k1+k2
k2 = aux
b = b-a
end
if k1 == 1
then
tex.print ("\\num{"..s..h1.."}")
else
if sf == 1
then
tex.print ("\\ensuremath{\\frac{\\num{"
..s..h1.."}}{\\num{"..k1.."}}}")
else
tex.print ("\\ensuremath{\\dfrac{\\num{"
..s..h1.."}}{\\num{"..k1.."}}}")
end
end
end
function Around ( n , prec )
tex.print("\\num{"..math.floor(n/10^prec+0.5)*10^prec.."}")
end