第一步,我要计算一系列数字的总和。然后我想计算总和的根,但我不知道如何使用结果。
所以我尝试使用\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 的回答这种方法稍微改变界面但只需要一个文档命令。