是否存在包含可容纳的最大正整数的命令\newcount
?
答案1
TeX 寄存器中允许的最大整数\count
是 2147483647。
\number\numexpr2*\maxdimen+1\relax
如果您使用 e-TeX 扩展,则可以按 方式访问它。
答案2
在进行一些调查时,我发现了一些有趣的事情(至少对我来说)以及一种获取计数寄存器最大值的方法。 (这个答案将使用 Knuth TeX,所以没有\numexpr
或任何东西,但它当然也可以与 e-TeX 一起使用。)
TeX 内部使用有符号的 32 位整数。在有符号的 32 位整数中,数字的范围从和,其以 1 为增量的顺序为:-231
231-1
% sign change V
0, 1, ..., 2147483646, 2147483647, -2147483648, -2147483647, ..., -1
但是 TeX 不允许您输入大于的数字:231-1
但是如果你存储在 a 中,你确实得到了。正如 Frank 在下面的评论中所说,以及 Karl 在231-1
\counter
\advance\counter by 1
-231
他的回答出于效率原因,Knuth 没有在 TeX 中添加算术溢出检查\advance
。然而,这让你有机会做一些狡猾的把戏 :-)
您可以利用这一点,通过暴力手段找出最大整数的值。您可以将计数器加一,直到其符号发生变化。当符号发生变化时,前一个值就是最大整数。为了加快速度,您可以从较大的步长开始,然后减小步长,直到找出哪个值是最大值。下面的代码可以做到这一点(非常快):
\newcount\maxcount
\newcount\tmp
\def\gobble#1{}
\def\addloop#1{%
\advance\maxcount by #1 % Add to the counter
\ifnum\maxcount<\tmp % If it is negative
\advance\maxcount by -#1 % undo
\expandafter\gobble % and return
\else
\tmp\maxcount % otherwise save the value
\expandafter\addloop % and try again
\fi{#1}}
\def\getmaxcount{%
\maxcount=0
\tmp=0
\addloop{1000000}% Faster
\addloop{1000}% Slower
\addloop{1}% Slowest
}
\getmaxcount
\showthe\maxcount
\bye
首先,我们将两个计数器初始化为零,然后我们开始将\maxcount
计数器步进某个值。如果步进值使\maxcount
负数(IE,如果小于\tmp
),则我们越过了符号变化边界,需要回溯。否则,请重试。我们可以开始对较大的值执行此操作,以便它更快地到达极限,然后减少步骤以找出精确匹配。
上述代码的终端输出是:
C:\Users\Phelype\tex.sx>tex test.tex
This is TeX, Version 3.14159265 (TeX Live 2019/W32TeX) (preloaded format=tex)
(./test.tex
> 2147483647.
l.25 \showthe\maxcount
?
)
No pages of output.
Transcript written on test.log.
答案3
Frank 是对的。tex.web 的第 104 节中有这样的文字:
\TeX\ 的当前实现不会在增加或减少维度时检查溢出。这可以通过 ... 来完成,但溢出的可能性非常小,因此这种测试似乎不值得。
同样的陈述也出现在《数字排版,TeX 的最终错误》一文的第 660 页中。
我认为 Knuth 也在其他地方重申了这一点,也许是在某一份调整报告中,问题是关于使用狡猾的算法导致 TeX 崩溃,但我现在找不到那个……