如何在 expl3 中输出序列元素和总数

如何在 expl3 中输出序列元素和总数

假设我有一个数字序列:{1,2,3}。我想像这样输出它:

1 + 2 + 3 = 6

我创建了这个代码:

\documentclass{article}
\usepackage{xparse}
\usepackage{expl3}
\setlength{\parindent}{0cm}
\begin{document}
\makeatletter
\ExplSyntaxOn
% The following three macros are well defined
\NewDocumentCommand{\newfpvar}{m}{\fp_new:N #1}
\NewDocumentCommand{\setfpvar}{mm}{\fp_set:Nn #1 { #2 }}
\NewDocumentCommand{\getfpvar}{m}{\fp_use:N #1}

 \cs_new_protected:Npn \mmmmxxxv_define_fp_var:Nn #1 #2
 {
     \cs_if_exist:NF #1
     {
         \fp_new:N #1
         \fp_set:Nn { #1 } { #2 }
     }
 }

%#1 - sequence name
%#2 - value
\cs_new_protected:Npn \mmmmxxxv_seq_put_fp_var_right:Nn #1 #2
 {
  \seq_put_right:Nx #1 { \fp_eval:n { #2 } }
 }

\seq_new:N \l_mmmmxxxv_fp_seq
\mmmmxxxv_seq_put_fp_var_right:Nn \l_mmmmxxxv_fp_seq { 1 }
\mmmmxxxv_seq_put_fp_var_right:Nn \l_mmmmxxxv_fp_seq { 2 }
\mmmmxxxv_seq_put_fp_var_right:Nn \l_mmmmxxxv_fp_seq { 3 }

\tl_new:N \__text
\mmmmxxxv_define_fp_var:Nn{\Total}{0}
\seq_map_inline:Nn \l_mmmmxxxv_fp_seq
 {
   %here I don't understand, how to check that we are processing the last
   %element of sequence and don't put '+'
   \tl_put_right:Nx \__text {\getfpvar{#1} +}
   \fp_add:Nn \Total #1
 }
\show\__text
\ExplSyntaxOff
\makeatother
%want to show here: 1 + 2 + 3 = 6 --- \__text = \getfpvar{\Total}
\getfpvar{\Total}
\end{document}

它创建一个序列,计算总数并尝试将数字存储在 __text 变量中。\show__text 打印以下内容:

> \__text=macro:
->\getfpvar {1}+\getfpvar {2}+\getfpvar {3}+.

\总计正确

但是当我尝试输出__text时,它出现错误:

! Use of \__fp_to_decimal_dispatch:w doesn't match its definition.
<recently read> 1

答案1

这是您想要的实现。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
% user level commands
\NewDocumentCommand{\storefpvalues}{mm}
 {
  \mmmmxxxv_store_fpvalues:nn {#1}{#2}
 }
\NewDocumentCommand{\sumfpsequence}{m}
 {
  \mmmmxxxv_sum_fp_sequence:n {#1}
 }

% internal functions

\cs_new_protected:Npn \mmmmxxxv_store_fpvalues:nn #1 #2
 {
  % if the sequence doesn't exist, define it
  \seq_if_exist:cF { l__mmmmxxxv_store_#1_seq }
   { \seq_new:c { l__mmmmxxxv_store_#1_seq } }
  % add the values
  \clist_map_inline:nn { #2 }
   {
    \seq_put_right:cx { l__mmmmxxxv_store_#1_seq } { \fp_eval:n { ##1 } }
   }
 }

\cs_new:Npn \mmmmxxxv_sum_fp_sequence:n #1
 {% evaluate the sum of the entries
  \fp_eval:n { 0 + \seq_use:cnnn { l__mmmmxxxv_store_#1_seq } { + } { + } { + } }
 }

% since \seq_use:cnnn doesn't exist, we create it
\cs_generate_variant:Nn \seq_use:Nnnn { c }

\ExplSyntaxOff
\begin{document}

\storefpvalues{test}{1,2,3}

\sumfpsequence{test}

\end{document}

您可以使用\storefpvalues(本地)添加到符号命名的序列test;内部名称将是\l__mmmmxxxv_store_test_seq,但在用户级别这并不重要,因此我使用了带前缀 的“私有”名称l__。添加是增量的,因此调用

\storefpvalues{test}{1,2}
\storefpvalues{test}{3}

将是等效的。

您还可以致电

\storefpvalues{testb}{1+2,sin(pi/2)}

结果\sumfpsequence{testb}将为 4。

计算\sumfpsequence{test}所有存储条目的总和。

您还可以调用,例如,

\storefpvalues{testb}{1+2,sin(pi/2)}

结果\sumfpsequence{testb}将为 4。


如果您还想显示被加数,可以进行以下修改:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
% user level commands
\NewDocumentCommand{\storefpvalues}{mm}
 {
  \mmmmxxxv_store_fpvalues:nn {#1}{#2}
 }
\NewDocumentCommand{\sumfpsequence}{m}
 {
  \mmmmxxxv_sum_fp_sequence:n {#1}
 }

% internal functions

\cs_new_protected:Npn \mmmmxxxv_store_fpvalues:nn #1 #2
 {
  % if the sequence doesn't exist, define it
  \seq_if_exist:cF { l__mmmmxxxv_store_#1_seq }
   { \seq_new:c { l__mmmmxxxv_store_#1_seq } }
  % add the values
  \clist_map_inline:nn { #2 }
   {
    \seq_put_right:cx { l__mmmmxxxv_store_#1_seq } { \fp_eval:n { ##1 } }
   }
 }

\cs_new:Npn \mmmmxxxv_sum_fp_sequence:n #1
 {% print the summands with `+` in between
  $
  \group_begin:
  % detach the first item and print it
  \seq_pop_left:cN { l__mmmmxxxv_store_#1_seq } \l_tmpa_tl
  \l_tmpa_tl
  % now print the next value preceded by + if non negative
  \seq_map_inline:cn { l__mmmmxxxv_store_#1_seq }
   {
    \fp_compare:nF { ##1 < 0 } { + }
    ##1
   }
  \group_end: % this will revert the change to the sequence
  =
  % evaluate the sum of the entries
  \fp_eval:n { 0 + \seq_use:cnnn { l__mmmmxxxv_store_#1_seq } { + } { + } { + } }
  $
 }

% since \seq_use:cnnn doesn't exist, we create it
\cs_generate_variant:Nn \seq_use:Nnnn { c }

\ExplSyntaxOff
\begin{document}

\storefpvalues{test}{1,-2,sin(pi/2)}

\sumfpsequence{test}

\end{document}

在此处输入图片描述

相关内容