无法使用 \pgfmathsetmacro 重用变量

无法使用 \pgfmathsetmacro 重用变量
\documentclass{article}
\usepackage{tikz}
\begin{document}

\newcommand\routine[1] {
    \pgfmathsetmacro\temp{0}
    \foreach[parse=true][remember=\temp] \i in {1,...,#1} {
        \pgfmathsetmacro\temp {
            \pgfmathparse{\temp+\i}\pgfmathresult
        }
    }
    \temp
}

\routine{5}
\end{document}

我创建了一个打印第 n 个三角数的命令。首先我将其设置为 0,然后在进入循环时\temp添加第 i 次。每次增加时都会更新。我添加了它,以便每次迭代后它都不会丢失。然后在循环结束后应该打印结果。但我遇到了错误。我该如何解决这个问题?\i\temp[remember=\temp]! Incomplete \iffalse; all text was ignored after line 16.

答案1

欢迎来到 TeX.SE!!!

你可以用选项来记住局部变量,\global\global\edef\xdef。例如,请参阅此帖子:\def、\edef、\gdef 和 \xdef 之间有什么区别?

因此,您可以执行类似以下代码的操作:

\documentclass{article}
\usepackage{tikz}

\newcommand\routine[1]
{%
  \pgfmathsetmacro\myfinaltemp{0}%
  \foreach\i in {1,...,#1}
  {%
    \pgfmathtruncatemacro\temp{\myfinaltemp+\i}%
    \xdef\myfinaltemp{\temp}% <-- remember \myfinaltemp, \xdef = \global\edef
  }%
  \myfinaltemp%
}

% anotehr, simpler version
\newcommand{\mytriangle}[1]{\pgfmathparse{int(#1*(1+#1)/2)}\pgfmathresult}

\begin{document}
\noindent
\foreach\j in  {1,...,10}
  {\routine{\j} = \mytriangle{\j}\\}
\end{document}

其结果为:

在此处输入图片描述

答案2

我认为这\foreach不是完成这项工作的最佳工具。

但是您可能会这样做:打印应该在循环内,在最后一步,并且您想要int

\documentclass{article}
\usepackage{pgffor}

\newcommand\routine[1]{%
  \pgfmathsetmacro\temp{0}%
  \foreach[parse=true][remember=\temp] \i in {1,...,#1} {%
    \pgfmathsetmacro\temp{int(\temp+\i)}%
    \ifnum#1=\i\relax\temp\fi
  }%
}

\begin{document}

\routine{5}

\end{document}

这是一个可扩展的实现。

\documentclass{article}

\makeatletter
\newcommand{\triangular}[1]{%
  \@triangular{0}{0}{#1}%
}
\newcommand{\@triangular}[3]{%
  % #1 is the current step
  % #2 is the accumulated total
  % #3 is the step we want to get at
  \ifnum#1=#3
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {\the\numexpr#2+#1}%
  {\expanded{\noexpand\@triangular{\the\numexpr#1+1}{\the\numexpr#2+#1}{#3}}}%
}
\makeatother

\begin{document}

\triangular{0}\par
\triangular{1}\par
\triangular{2}\par
\triangular{3}\par
\triangular{4}\par
\triangular{5}\par
\triangular{6}

\edef\test{\triangular{10}}
\texttt{\meaning\test}

\end{document}

在此处输入图片描述

不需要\expanded稍微复杂一点的版本

\newcommand{\@triangular}[3]{%
  % #1 is the current step
  % #2 is the accumulated total
  % #3 is the step we want to get at
  \ifnum#1=#3
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {\the\numexpr#2+#1}%
  {\expandafter\@triangular
      \expandafter{\the\numexpr#1+1\expandafter}%
      \expandafter{\the\numexpr#2+#1}{#3}%
  }
}

最后,expl3代码:

\documentclass{article}

\ExplSyntaxOn

\NewExpandableDocumentCommand{\triangular}{m}
 {
  \acter_triangular:nnn { 0 } { 0 } { #1 }
 }

\cs_new:Nn \acter_triangular:nnn
 {
  % #1 is the current step
  % #2 is the accumulated total
  % #3 is the step we want to get at
  \int_compare:nTF { #1 = #3 }
   {% reached
    \int_eval:n { #2 + #1 }
   }
   {% restart
    \acter_triangular:een { \int_eval:n { #1 + 1 } } { \int_eval:n { #2 + #1 } } { #3 }
   }
 }
\cs_generate_variant:Nn \acter_triangular:nnn { ee }

\ExplSyntaxOff

\begin{document}

\triangular{0}\par
\triangular{1}\par
\triangular{2}\par
\triangular{3}\par
\triangular{4}\par
\triangular{5}\par
\triangular{6}

\edef\test{\triangular{10}}
\texttt{\meaning\test}

\end{document}

相关内容