writeout 与 pgfmathprintnumber 崩溃

writeout 与 pgfmathprintnumber 崩溃
% 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}

相关内容