我正在编写一个简单的命令来自动查找给定值列表的平均值。我创建了\findAverageFunction
它来处理所有逻辑(复制自这里)。问题是我无法使用以下方法获取计算结果并将其存储在变量中:
\fp_set:Nx \l_total_fp{\findAverageFunction:nn{#1}{#2}}
。请问这里的问题是什么,以及可能的解决方法是什么。谢谢!!
\documentclass{article}
\ExplSyntaxOn
\cs_generate_variant:Nn \fp_set:Nn { Nx }
\cs_new:Nn \findAverageFunction:nn {% #1=rounding precision, #2=list of values
\clist_set:Nx \l_tmpa_clist {#2}
\fp_zero:N \l_tmpa_fp
\clist_map_inline:Nn \l_tmpa_clist {
\fp_add:Nn \l_tmpa_fp {##1}
}
\fp_eval:n {round(\l_tmpa_fp/\clist_count:N \l_tmpa_clist, #1)}
}
\fp_new:N \l_total_fp % Declare a new float-point variable
\NewExpandableDocumentCommand{\myData}{O{10}m}{
\findAverageFunction:nn{#1}{#2}
% NOT WORKING:
%\fp_set:Nx \l_total_fp{\findAverageFunction:nn{#1}{#2}}
}
\ExplSyntaxOff
\begin{document}
\myData{1,2,3,4,5,6, 99}
\end{document}
答案1
您可以仅使用扩展来找到平均值,并使用不同的命令将结果存储在变量中。
使用 *-version 您可以输入一个扩展到列表的宏。
\documentclass{article}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\findAverage}{sO{10}m}
{
\IfBooleanTF { #1 } { \jumaily_average:nV { #2 } #3 } { \jumaily_average:nn { #2 } { #3 } }
}
\cs_new:Nn \jumaily_average:nn
{
\fp_eval:n
{
round( ( \clist_use:nn { #2 } { + } ) / ( \clist_count:n { #2 } ), #1 )
}
}
\cs_generate_variant:Nn \jumaily_average:nn { nV }
\NewDocumentCommand{\definevar}{mm}
{
\fp_zero_new:c { l_jumaily_var_#1_fp }
\fp_set:cn { l_jumaily_var_#1_fp } { #2 }
}
\NewDocumentCommand{\usevar}{m}
{
\fp_use:c { l_jumaily_var_#1_fp }
}
\ExplSyntaxOff
\begin{document}
\newcommand{\myData}{1,2,3,4,5,6, 99}
\findAverage{1,1}
\findAverage{1,2,4}
\findAverage[3]{1,2,4}
\findAverage{1,2,3,4,5,6, 99}
\findAverage*{\myData}
\definevar{test1}{\findAverage{1,2,3,4,5,6, 99}}
\usevar{test1}
\definevar{test2}{\findAverage*{\myData}}
\usevar{test2}
\end{document}
请注意,\definevar
可以与任何 fp 表达式一起使用。
答案2
为了比较,我们可以用 OpTeX 做什么:
\let\ima=\immediateassignment
\def\replcomma#1,{\ifx,#1,\else\ima\incr\tmpnum +#1\ea\replcomma\fi}
\def\findAverage#1{\ima\tmpnum=0 \expr{(0\ea\replcomma#1,,)/\the\tmpnum}}
\findAverage{1,2,4} % prints 2.333
\findAverage{1,2,3,4,5,6, 99} % prints 17.143
\def\mydata{1,2,3,4,5,6, 99}
\findAverage{\mydata} % prints 17.143
\edef\test{\findAverage{1,2,3,4,5,6, 99}}
\test % prints 17.143
\meaning\test % prints macro:->17.143
\bye