在 TikZ `\foreach` 循环内设置标志时出现问题

在 TikZ `\foreach` 循环内设置标志时出现问题

我绞尽脑汁想弄明白为什么下面的代码不起作用。目的是计算给定的数字是否#1为素数,并将其设置\isprime1(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

这里的问题是\isprime0

\def\isprime{0}

是在团体内部进行的。因此,它是本地的,不会在团体之外“生存”。使用

\global\def\isprime{0}

而不是(或简称)。初始化时\gdef不需要此定义,因为它与最终的素数测试处于同一深度。\global\isprime

相关内容