Пакет L3fp предлагает диапазон параметров randint
; +- 10^16 - 1
однако, похоже, я ограничен +-2^31 - 1
, любое значение выше этого вызывает Number too big
ошибку компиляции. С другой стороны, я получаю ожидаемую полную точность в 16 десятичных знаков для fp
значений. Почему?
\documentclass{article}
% RN. 15 April 2017
% BRIEF DESCRIPTION:
%=======================
\usepackage[check-declarations]{expl3}
\usepackage{xparse}
%-----------------------
\ExplSyntaxOn
\int_new:N \l_rn_someInteger_int
\fp_new:N \l_rn_someFp_fp
\NewDocumentCommand\mySetInteger{m}
{
\int_set:Nn \l_rn_someInteger_int {#1}
some~integer:~\int_use:N \l_rn_someInteger_int\\
\int_set:Nn \l_rn_someInteger_int {\fp_eval:n {randint(#1)}}
some~random~integer:~\int_use:N \l_rn_someInteger_int\\
\fp_set:Nn \l_rn_someFp_fp {\fp_eval:n {rand()}}
some~random~real:~\fp_use:N \l_rn_someFp_fp\\
-------------------------------------------\\
}
\ExplSyntaxOff
%-----------------------
\begin{document}
\mySetInteger{1234}
\mySetInteger{2147483647}
% \mySetInteger{2147483648}
% \mySetInteger{9999999999999999}
\end{document}
решение1
Давайте посмотрим, как l3fp
хранится выражение с плавающей точкой:
\documentclass{article}
\usepackage{xfp}
\begin{document}
\ttfamily
\ExplSyntaxOn % we want to do tests
\fp_set:Nn \l_tmpa_fp { randint(10^15,10^15+10^12) }
\fp_eval:n { \l_tmpa_fp }
\par
\cs_meaning:N \l_tmpa_fp
\ExplSyntaxOff
\end{document}
В одном эксперименте я получаю
это показывает, что случайное целое число не хранится как целое число в исходном значении TeX, поскольку диапазон ограничен диапазоном от –2 31 до 2 31 –1.
Целочисленной переменной просто невозможно присвоить значение, выходящее за пределы указанного выше диапазона.
Работа с «целыми числами с плавающей точкой» подчиняется стандартным ограничениям арифметики с плавающей точкой при выполнении операций.
Аналогично, после изменения randint
на rand
, я получил
Число хранится с показателем степени и четырьмя группами по четыре цифры для мантиссы. Две внутренние функции \s__fp
и \__fp_chk:w
используются для манипулирования (расширяемого) числом. Терминатор ;
завершает внутреннее представление.
решение2
Число 2147483648
равно 2^31
точно, а \int_...
переменные на самом деле являются регистрами-счетчиками TeX, которые имеют «ограниченный» диапазон чисел, как и обычные LaTeX
счетчики, которые равны - 2^{31} to 2^{31} - 1
точно 2^32
числам.
Если вы посмотрите в файл .log файла с загруженным expl3, вы увидите, что \int...
макросы на самом деле являются \countXYZ
определениями.
Попытка сохранить 2147483648
приведет к переполнению, как \setcounter{foo}{2147483648}
и в случае с .
Числа с плавающей точкой хранятся иначе, как в регистрах измерений, и допускают большие числа, но точность не выше.
Пожалуйста, посмотритеКакое максимальное целое число можно сохранить в счетчике LaTeX?также.