为什么这个 Metapost while 循环不会终止?

为什么这个 Metapost while 循环不会终止?

以下循环无法终止,但我不知道原因。我要么违反了某些语法规则,要么中的 self 引用有问题n:= floor (n/2);,要么我错过了一些非常明显的问题。

\documentclass{article}
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}

def divtwo(expr n)=
    forever: exitunless n>1;
        n:= floor (n/2);
    endfor;
enddef;

divtwo(5);

end;

\end{mplibcode}
\end{document}

编辑:谢谢您的回答!实际用例是查找数字的二进制数字(顺序无关)。更正后的代码(可能仍然不好):

\documentclass{article}
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}
numeric k[];

def divtwo(expr n)=
  save m;
  m:=n;
  j = 1;
  forever: exitunless m>0;
    b:= m mod 2;
    m:= floor (m/2);
    k[j]:=b;
    j:=j+1;
  endfor;
enddef;

divtwo(5);

end;

\end{mplibcode}
\end{document}

答案1

代码是错误的,因为n定义主体中只是一个用实际参数替换的占位符;在你的情况下,你得到了毫无意义的语句

5:=floor(5/2)

返回值的正确函数可能是

vardef divtwo(expr n)=
  save m;
  m:=n;
  forever: exitunless m>1;
    show m;
    m:= floor (m/2);
  endfor;
m enddef;

x=divtwo(5);
show x;
show m;

end.

这些show命令仅用于调试:你得到

This is MetaPost, version 1.504 (kpathsea version 6.1.0)
(mpost.mp (/usr/local/texlive/2012/texmf-dist/metapost/base/plain.mp
Preloading the plain mem file, version 1.004)) (./scottloop.mp
>> 5
>> 2
>> 1
>> m )

因此您会看到,m在使用deftwovardef具有隐式begingroupendgroup标记)之后,它已经恢复了其原来的值。

当然结果永远是1。


你收集数字的想法几乎是正确的;我更喜欢一种变体:

numeric k[];

vardef divtwo(expr n)=
  save m; save j;
  m = n;
  j = 1;
  forever: exitunless m>0;
    k[j] = m mod 2;
    m:= floor (m/2);
    j:=j+1;
  endfor;
  k[0] = j-1;
enddef;

divtwo(257);
m=0;
forever: exitif m > k[0];
show k[m]; m:=m+1;
endfor;

end;

因此,k[0]您存储数字的数量。例如,输入显示

This is MetaPost, version 1.504 (kpathsea version 6.1.0)
(mpost.mp (/usr/local/texlive/2012/texmf-dist/metapost/base/plain.mp
Preloading the plain mem file, version 1.004)) (./scottloop.mp
>> 9
>> 1
>> 0
>> 0
>> 0
>> 0
>> 0
>> 0
>> 0
>> 1 )

在终端上。

答案2

不确定为什么你的代码不起作用。你显然打错了(existunless应该是exitunless),但即使修复后它仍然挂起。此外,你的“函数”没有“返回”任何结果。你应该使用 avardef而不是,并在 之前def用单独的表达式完成函数(这将是“返回”的值)。nenddef;

但是,我可以看到你正在尝试实现“除以二的余数”操作,但你不需要,因为 metapost 提供了运算符。因此,你可以简单地写mod而不是。divtwo(5)5 mod 2

以下代码证明这mod对于 metapost 来说是一个有效的运算符:

\documentclass{article}
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}
beginfig(1);
 n := 5 mod 2;            % Compute n
 label(decimal n, (0,0)); % Show its value as part of the figure
endfig;
\end{mplibcode}
\end{document}

生成的 pdf 显示“1”。

相关内容