
Существует ли команда, которая содержит наибольшее положительное целое число, которое \newcount
может быть сохранено?
решение1
Максимальное целое число, допустимое в \count
регистре TeX, составляет 2147483647.
Вы можете получить к нему доступ как к \number\numexpr2*\maxdimen+1\relax
, если используете расширения e-TeX.
решение2
В ходе небольшого расследования я обнаружил несколько интересных вещей (по крайней мере для меня) и способ получить максимальное значение регистра счетчика. (В этом ответе будет использоваться Knuth TeX, так что нет, \numexpr
или что-то еще, но, конечно, это работает и с e-TeX.)
TeX использует внутри себя 32-битные целые числа со знаком. В 32-битном целом числе со знаком числа располагаются в диапазоне от до , а их порядок с шагом в единицу:-231
231-1
% sign change V
0, 1, ..., 2147483646, 2147483647, -2147483648, -2147483647, ..., -1
Однако TeX не позволяет вводить число больше, чем :231-1
Однако если вы храните в и вы получаете231-1
\counter
\advance\counter by 1
-231
. Как говорит Фрэнк в комментарии ниже и Карл вего ответ, Кнут не добавил проверку арифметического переполнения в TeX's \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
отрицательным (то есть,он становится меньше \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
Фрэнк прав. В разделе 104 tex.web есть такой текст:
Текущая реализация \TeX\ не проверяет переполнение при добавлении или вычитании измерений. Это можно было бы сделать с помощью ..., но вероятность переполнения настолько мала, что такие проверки не кажутся стоящими.
То же самое утверждение содержится на странице 660 статьи «Цифровая типографика: последние ошибки TeX».
Думаю, Кнут уже где-то поднимал эту тему, возможно, в одном из отчетов по настройке, где ставился вопрос о сбое TeX с помощью мошеннической арифметики, но сейчас я не могу его найти...