% Density Show Test
\pgfmathdeclarefunction{DensityShowTest}{2}{%
\pgfmathparse{dim("#1")==3}%
\ifnum\pgfmathresult=1%
\pgfmathparse{1000*#2}%
\pgfmathparse{"\pgfmathprintnumber[fixed, precision=2]{\pgfmathresult}"}%
\else%
\pgfmathparse{#2==-1 ? "?" : "\pgfmathprintnumber[fixed, precision=2]{#2}"}%
\fi}
% usage:
% \pgfmathparse{DensityShowTest("gas", 0.0008)}\pgfmathresult
我有一个 pgfmathdeclarefunction DensityShowTest
,它测试是否\Phase
等于“gas”,然后该值\Density
必须乘以 1000(否则不乘以)。
如果 \Phase 等于“未知”,则 \Density 等于“-1”(也表示未知)。
并且密度的值(如果不是“?”)必须四舍五入为 2 位数字(在所有情况下);这似乎是有问题的。
我的问题是,我无法写出该函数;它一定与该部分有关\pgfmathprintnumber[fixed, precision=2]{\pgfmathresult}
评论:如果 TikZ 具有算术舍入函数,那么一切都会变得简单得多,但是数字的舍入版本必须保留用于 TikZ 的书面输出......
\documentclass[]{article}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\pgfplotstableread[col sep = semicolon, header=true]{
Z; Symbol; Phase; Density; EXPECTED OUTPUT
1; H; gas; 0.0000899; 0.09
3; Li; solid; 0.53; 0.53
118; Og; unknown; -1; ?
}{\psetable}
% Density Show Test
\pgfmathdeclarefunction{DensityShowTest}{2}{%
\pgfmathparse{dim("#1")==3}%
\ifnum\pgfmathresult=1%
\pgfmathparse{1000*#2}%
\pgfmathparse{"\pgfmathprintnumber[fixed, precision=2]{\pgfmathresult}"}%
\else%
\pgfmathparse{#2==-1 ? "?" : "\pgfmathprintnumber[fixed, precision=2]{#2}"}%
\fi}
% usage:
% \pgfmathparse{DensityShowTest("gas", 0.0008)}\pgfmathresult
\def\Filename{densityshowtest.txt}
\newwrite\MyPSE
\immediate\openout\MyPSE=\Filename
\begin{document}
\foreach \row in {0,...,2}{%%
% In:
\pgfplotstablegetelem{\row}{Z}\of{\psetable}
\xdef\Z{\pgfplotsretval}
\pgfplotstablegetelem{\row}{Symbol}\of{\psetable}
\xdef\Symbol{\pgfplotsretval}
%% Phase
\pgfplotstablegetelem{\row}{Phase}\of{\psetable}
\xdef\Phase{\pgfplotsretval}
% Density Test
\pgfplotstablegetelem{\row}{Density}\of{\psetable}%
\xdef\Density{\pgfplotsretval}%
\pgfmathsetmacro\DensityShowTest{DensityShowTest("\Phase", \Density)}
% OUT:
% This works:
\noindent \Z;~~~\Symbol;~~\Density; ~~\Phase; ~~\DensityShowTest \\
%
% Problem here =======================
%
% This works not: ======================
%\immediate\write\MyPSE{\Z; \Symbol; \Density; \Phase; \DensityShowTest}
}%%
\immediate\closeout\MyPSE
% So this does not work too:
\pgfplotstableread[col sep=semicolon, header=true,]{\Filename}{\mytable}
\pgfplotstabletypeset[string type]{\mytable}
\end{document}
答案1
您可以尝试使用 在函数内急切地格式化结果\pgfmathprintnumberto
。请注意,这实际上不是这些函数应该使用的方式。
\documentclass[]{article}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\pgfplotstableread[col sep = semicolon, header=true]{
Z; Symbol; Phase; Density
1; H; gas; 0.0000899
3; Li; solid; 0.53
118; Og; unknown; -1
}{\psetable}
% Density Show Test
\pgfmathdeclarefunction{DensityShowTest}{2}{%
\ifnum\pdfstrcmp{#1}{gas}=0
\pgfmathparse{1000*#2}%
\pgfmathprintnumberto[fixed, precision=2]{\pgfmathresult}{\pgfmathresult}%
\else%
\pgfmathparse{#2==-1 ? "\unexpanded{\def\pgfmathresult{?}}" : "\unexpanded{\pgfmathprintnumberto[fixed, precision=2]{#2}{\pgfmathresult}}"}%
\pgfmathresult % evaluate the result to perform formatting
\fi
}
% usage:
% \pgfmathparse{DensityShowTest("gas", 0.0008)}\pgfmathresult
\def\Filename{densityshowtest.txt}
\newwrite\MyPSE
\immediate\openout\MyPSE=\Filename
\begin{document}
\foreach \row in {0,...,2}{%%
% In:
\pgfplotstablegetelem{\row}{Z}\of{\psetable}
\xdef\Z{\pgfplotsretval}
\pgfplotstablegetelem{\row}{Symbol}\of{\psetable}
\xdef\Symbol{\pgfplotsretval}
%% Phase
\pgfplotstablegetelem{\row}{Phase}\of{\psetable}
\xdef\Phase{\pgfplotsretval}
% Density Test
\pgfplotstablegetelem{\row}{Density}\of{\psetable}%
\xdef\Density{\pgfplotsretval}%
\pgfmathparse{DensityShowTest("\Phase", \Density)}%
\xdef\DensityShowTest{\pgfmathresult}%
% OUT:
% This works:
\noindent \Z;~~~\Symbol;~~\Density; ~~\Phase; ~~\DensityShowTest \\
%
% Problem here =======================
%
% This works not: ======================
\immediate\write\MyPSE{\Z; \Symbol; \Density; \Phase; \DensityShowTest}
}%%
\immediate\closeout\MyPSE
% So this does not work too:
\pgfplotstableread[col sep=semicolon, header=true,]{\Filename}{\mytable}
\pgfplotstabletypeset[string type]{\mytable}
\end{document}
答案2
下面不使用pgfmath
函数,因为您想要返回字符串等,而这不是这些函数的用途。
它会做你想做的事(我猜):
编辑:前一个版本没有从结果中剥离数学模式\pgfmathprintnumberto
。
\documentclass[]{article}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\pgfplotstableread[col sep = semicolon, header=true]
{
Z; Symbol; Phase; Density
1; H; gas; 0.0000899
3; Li; solid; 0.53
118; Og; unknown; -1
}
{\psetable}
\makeatletter
\newcommand\cisstrcmp[2]
{%
\begingroup
\edef\tmpa{\detokenize{#1}}%
\edef\tmpb{\detokenize{#2}}%
\expandafter
\endgroup
\ifx\tmpa\tmpb
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\makeatother
\newcommand*\parseDensityShowTest
{%
\expandafter\cisstrcmp\expandafter{\Phase}{gas}%
{%
\pgfmathparse{1000*\Density}%
\pgfmathprintnumberto[fixed, precision=2]\pgfmathresult\DensityShowTest
}
{%
\pgfmathparse{\Density==-1}%
\ifnum\pgfmathresult=1
\def\DensityShowTest{"?"}%
\else
\pgfmathprintnumberto[fixed, precision=2]{\Density}\DensityShowTest
\fi
}%
\stripensuremath\DensityShowTest
}
\makeatletter
\newcommand*\stripensuremath[1]
{%
\edef#1%
{%
\unexpanded\expandafter\expandafter\expandafter
{\expandafter\@secondoftwo#1}%
}%
}
\makeatother
\def\Filename{densityshowtest.txt}
\newwrite\MyPSE
\immediate\openout\MyPSE=\Filename
\begin{document}
\foreach \row in {0,...,2}
{%%
% In:
\pgfplotstablegetelem{\row}{Z}\of{\psetable}%
\let\Z\pgfplotsretval
\pgfplotstablegetelem{\row}{Symbol}\of{\psetable}%
\let\Symbol\pgfplotsretval
%% Phase
\pgfplotstablegetelem{\row}{Phase}\of{\psetable}%
\let\Phase\pgfplotsretval
% Density Test
\pgfplotstablegetelem{\row}{Density}\of{\psetable}%
\let\Density\pgfplotsretval
\parseDensityShowTest
% OUT:
% This works:
%\noindent \Z;~~~\Symbol;~~\Density; ~~\Phase; ~~\DensityShowTest \\
%
% Problem here =======================
%
% This works not: ======================
\immediate\write\MyPSE{\Z; \Symbol; \Density; \Phase; \DensityShowTest}
}%%
\immediate\closeout\MyPSE
% So this does not work too:
\pgfplotstableread[col sep=semicolon, header=true,]{\Filename}{\mytable}
\pgfplotstabletypeset[string type]{\mytable}
\end{document}