
是否有一個指令包含\newcount
可以容納的最大正整數?
答案1
TeX 暫存器中允許的最大整數\count
是 2147483647。
如果您使用 e-TeX 擴展,則可以將其存取為\number\numexpr2*\maxdimen+1\relax
。
答案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 中,並且確實得到了.正如弗蘭克在下面的評論中所說的和卡爾在231-1
\counter
\advance\counter by 1
-231
他的回答\advance
出於效率原因,Knuth 沒有向 TeX 添加算術溢位檢查。然而,這會讓你做一些狡猾的伎倆:-)
您可以利用它來暴力破解最大整數的值。您可以向計數器新增 1,直到其符號變更。當符號改變時,先前的值為最大整數。為了使速度更快,您可以從較大的步長開始,然後縮小步長,直到找出最大值。下面的程式碼可以做到這一點(很快):
\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
弗蘭克是正確的。 tex.web 的第 104 節有這樣的文字:
目前 \TeX\ 的實作在增加或減去維度時不檢查溢位。這可以透過...來完成,但是溢出的可能性是如此之小,以至於這樣的測試似乎不值得。
Digital Typography, The Final Errors of TeX 文章的第 660 頁上也有同樣的陳述。
我認為 Knuth 在其他地方也重申了這一點,也許是在一份調整報告中,其中的問題是關於使用不正當的算術使 TeX 崩潰,但我現在找不到那個......