我绞尽脑汁想弄明白为什么下面的代码不起作用。目的是计算给定的数字是否#1
为素数,并将其设置\isprime
为1
(true) 或0
(false)。循环和条件都正确,但标志\isprime
设置不正确。
\newcommand{\setisprime}[1]{
\def\isprime{1}
\foreach \i in {2, 3,5,...,#1} {
\pgfmathparse{\i*\i>#1? 1:0}
\ifthenelse{\pgfmathresult=1}{
% Early-out if \i^2 > #1
\breakforeach
}{
% Otherwise test if \i divides #1
\pgfmathparse{Mod(#1,\i)==0? 1:0}
\ifthenelse{\pgfmathresult=1}{
\def\isprime{0}
\breakforeach
}{}
}
}
}
事情的经过如下:
显然,它失败得很惨!
以下是带有调试语句的 MWE:
\documentclass{article}
\pagestyle{empty}
\usepackage{tikz}
\usepackage{ifthen}
\begin{document}
\newcommand{\debugsetisprime}[1]{
Testing #1 for primeness.\par
\def\isprime{1}
\foreach \i in {2, 3,5,...,#1} {
\pgfmathparse{\i*\i>#1? 1:0}
\ifthenelse{\pgfmathresult=1}{
Exiting loop because $\i^2 > #1$.\par
\breakforeach
}{
Testing whether \i\ divides #1...
\pgfmathparse{Mod(#1,\i)==0? 1:0}
\ifthenelse{\pgfmathresult=1}{
Yes.\par Exiting loop because divisor found.\par
\def\isprime{0}
\breakforeach
}{
No.\par
}
}
}
\ifnum\isprime=1
#1 is prime.\par\vskip1em
\else
#1 is not prime.\par\vskip1em
\fi
}
\debugsetisprime{97}
\debugsetisprime{15}
\end{document}
答案1
这里的问题是\isprime
,0
\def\isprime{0}
是在团体内部进行的。因此,它是本地的,不会在团体之外“生存”。使用
\global\def\isprime{0}
而不是(或简称)。初始化时\gdef
不需要此定义,因为它与最终的素数测试处于同一深度。\global
\isprime