如何获取 \newcount 可以容纳的最大数量?

如何获取 \newcount 可以容纳的最大数量?

是否存在包含可容纳的最大正整数的命令\newcount

答案1

TeX 寄存器中允许的最大整数\count是 2147483647。

\number\numexpr2*\maxdimen+1\relax如果您使用 e-TeX 扩展,则可以按 方式访问它。

答案2

在进行一些调查时,我发现了一些有趣的事情(至少对我来说)以及一种获取计数寄存器最大值的方法。 (这个答案将使用 Knuth TeX,所以没有\numexpr或任何东西,但它当然也可以与 e-TeX 一起使用。)

TeX 内部使用有符号的 32 位整数。在有符号的 32 位整数中,数字的范围从和,其以 1 为增量的顺序为:-231231-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 崩溃,但我现在找不到那个……

相关内容