假设我有一个数字序列:{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}