使用 LaTeX3 FPU 进行求和计算的结果

使用 LaTeX3 FPU 进行求和计算的结果

第一步,我要计算一系列数字的总和。然后我想计算总和的根,但我不知道如何使用结果。

所以我尝试使用\def\test{\calcsum{\one,\two,\three}}并调用它 \calcroot{\test},但它不起作用。(此代码来自LATEX3:超过 9 个参数

它给了我错误信息:

You can't use \edef after \the. \cs_set_nopar_Npx

有人知道如何解决这个问题吗?提前致谢!

\documentclass[a4paper,12pt]{article}
\usepackage{xparse}
\usepackage{fp}

\def\one{1}
\def\two{2}
\def\three{3}
\def\four{4}
\def\five{5}
\def\six{6}
\def\seven{}
\def\eight{8}
\def\nine{9}
\def\ten{1}

\ExplSyntaxOn
\NewDocumentCommand{\calcsum}{m}
{
\clist_set:Nx \l_tmpa_clist { #1 }
\fp_to_decimal:n { \clist_use:Nn \l_tmpa_clist { + } }
}
\ExplSyntaxOff

 \def\test{\calcsum{\one,\two,\three}}


\ExplSyntaxOn
\NewDocumentCommand{\calcroot}{m}
 { \fp_eval:n {sqrt(#1)}}               
 \ExplSyntaxOff

 \begin{document}

 \calcroot{\test}


 \end{document}

答案1

您不能将其用作\calcsum计算的一部分,因为它会进行赋值;由于您似乎在不同的地方使用各个部分,因此您可以\calcsum使用可选参数来定义表示存储结果的变量的位置;如果不存在,则仅打印该值。

\documentclass[a4paper,12pt]{article}
\usepackage{xparse}
\usepackage{fp}

\def\one{1}
\def\two{2}
\def\three{3}
\def\four{4}
\def\five{5}
\def\six{6}
\def\seven{}
\def\eight{8}
\def\nine{9}
\def\ten{1}

\ExplSyntaxOn
\NewDocumentCommand{\calcsum}{om}
 {
  \clist_set:Nx \l_tmpa_clist { #2 }
  \IfNoValueTF{#1}
   {
    \fp_to_decimal:n { \clist_use:Nn \l_tmpa_clist { + } }
   }
   {
    \fp_if_exist:cF { g_chrisf_calc_#1_fp }
     {
      \fp_new:c { g_chrisf_calc_#1_fp }
     }
    \fp_gset:cn { g_chrisf_calc_#1_fp } { \clist_use:Nn \l_tmpa_clist { + } }
   }
 }
\DeclareExpandableDocumentCommand{\fpvar}{m}
 {
  \fp_use:c { g_chrisf_calc_#1_fp }
 }
\cs_set_eq:NN \fpeval \fp_eval:n
\ExplSyntaxOff

\begin{document}

Result: \calcsum{\one,\two,\three,\four,\five,\six,\seven,\eight,\nine,\ten}

Store: \calcsum[mysum]{\one,\two,\three,\four,\five,\six,\seven,\eight,\nine,\ten}

Compute square root: \fpeval{sqrt(\fpvar{mysum})}

\end{document}

在此处输入图片描述

另一方面,你可以更轻松地逃脱:

\documentclass[a4paper,12pt]{article}
\usepackage{xparse}
\usepackage{fp}

\def\one{1}
\def\two{2}
\def\three{3}
\def\four{4}
\def\five{5}
\def\six{6}
\def\seven{}
\def\eight{8}
\def\nine{9}
\def\ten{1}

\ExplSyntaxOn
\cs_set_eq:NN \fpeval \fp_eval:n
\ExplSyntaxOff

\begin{document}

Result: \fpeval{\one+\two+\three+\four+\five+\six+\seven+\eight+\nine+\ten}

Store and compute: 
\newcommand\mysum{\one+\two+\three+\four+\five+\six+\seven+\eight+\nine+\ten}%
\fpeval{\mysum}

Compute square root: \fpeval{sqrt(\mysum)}

\end{document}

在此处输入图片描述

答案2

你不能使用\calcsum问题中定义的,因为它不是可扩展:任何带有赋值的东西都会有这个问题。我们可以保留逗号列表接口,并使代码可扩展,例如

\documentclass{article}
\usepackage{xparse}

\def\one{1}
\def\two{2}
\def\three{3}
\def\four{4}
\def\five{5}
\def\six{6}
\def\seven{}
\def\eight{8}
\def\nine{9}
\def\ten{1}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand \calcsum { m }
  {
    \fp_to_decimal:n
      { 0 \clist_map_function:nN {#1} \__calcsum:n }
  }
\cs_new:Npn \__calcsum:n #1 { + #1 }
\ExplSyntaxOff

\def\test{\calcsum{\one,\two,\three}}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand \calcroot { m }
   { \fp_to_decimal:n { sqrt(#1) } }               
\ExplSyntaxOff

\begin{document}

\calcroot{\test}

\end{document}

我通常倾向于不为每个计算设置单独的函数,除非有语义含义:这对于和有争议,但对于根没有争议。所以也许更好的是

\documentclass[a4paper,12pt]{article}
\usepackage{xparse}


\def\one{1}
\def\two{2}
\def\three{3}
\def\four{4}
\def\five{5}
\def\six{6}
\def\seven{}
\def\eight{8}
\def\nine{9}
\def\ten{1}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand \calcsum { m }
  {
    \fp_to_decimal:n
      { 0 \clist_map_function:nN {#1} \__calcsum:n }
  }
\DeclareExpandableDocumentCommand \fpeval { m }
  { \fp_to_decimal:n {#1} }
\cs_new:Npn \__calcsum:n #1 { + #1 }
\ExplSyntaxOff

\def\test{\calcsum{\one,\two,\three}}

\begin{document}

\fpeval{sqrt(\test)}

\end{document}

egreg 的回答这种方法稍微改变界面但只需要一个文档命令。

相关内容