}
\calxresetflag{InvalidOperation}
\calxresetflags
\end{everbatim}
The flag test is expandable; the reset commands are assignments and are
not expandable. Flags are local to \TeX\ groups. Examine flags raised
inside a group before leaving it. Reset commands obey the prevailing
\csbxint{globaldefs} setting, as do assignments by |\calxsetup|.
The default handlers for \texttt{InvalidOperation} and its subordinate
conditions return internal \texttt{I?}; the
\texttt{DivisionByZero} and \texttt{Overflow} handlers return
\texttt{I+} or \texttt{I-}, according to the sign.
The default handlers for \texttt{Clamped}, \texttt{Inexact},
\texttt{Rounded}, \texttt{Subnormal} and \texttt{Underflow}
leave the computed result unchanged.
Traps and handlers are configured with |\calxsetup|:
\begin{everbatim}
\calxsetup{InvalidOperation.trap=true}
\calxsetup{Overflow.trap=false}
\calxsetup{ControversialOperation.handler=\myHandler}
\end{everbatim}
The value of a \texttt{.handler} key is a single control sequence
denoting an expandable one-argument handler. An unknown setup key or
invalid trap value is a configuration error and is reported by \TeX,
regardless of the arithmetic-trap settings.
\section {Introduction to the rest of this manual (which is the legacy 1.4 documentation)}
\localtableofcontents
\subsection{This documentation}
Whenever you see
\textcolor{macrocodelinktosectioncolor}{\textbf{\textit{code}}} above
some control sequence \textbf{\string\foo}, it is an hyperlink to its
coding in the second part of this document. You should find there,
near your landing point, the control sequence
\textcolor{macrocodelinktouserdoccolor}{\textbf{\string\foo}} in orange:
this is a hyperlink to go back to its documentation in the user manual
part. Within the source code, other colored control sequences should
link back to the location of first definition.
And throughout the user manual part, blue color such as \csbxint{eval}
signals an hyperlink to the documentation of the macro. You can try it
now.
\subsection{Compatible engines and formats}
The components of the \xintbundlename can be used indifferently with
Plain \TeX{} (and other formats, as mentioned next) or with \LaTeX{}.
The sole difference being that with the latter the loading must be done
by \cs{usepackage} whereas with any non-\LaTeX{} format it has to be via
\cs{input} (using |.sty| filename extension, not |.tex|).
The engine can be PDF\TeX, Xe\TeX, or Lua\TeX.
With release |1.4n| you can also use the packages with Con\TeX t (only
latest one, with LuaMeta\TeX{} engine), and Op\TeX.
You can't use the \xintbundlename with Knuth's original |tex| binary,
because its functionalities require \cs{numexpr} and other e-\TeX{}
extensions as well as the more recent \cs{expanded} engine primitive
(and \cs{pdfstrcomp} or \cs{strcmp}).
\xintexprname will be probably the main entry point, and it actually
automatically loads most other components. The aim of \xintexprname is
to provide expandable parsers of numerical expressions, either floating
point numbers or fractions.
\subsection{Usage}
Here is an example:
\begin{everbatim*}
\xintfloateval{cos(3Pi/17)*sin(1)^0.123 + log(3.42e5)}
\end{everbatim*}
You can get the result with more digits:
\begingroup
\begin{everbatim*}
\xintSetDigits*{32}
\xintfloateval{cos(3Pi/17)*sin(1)^0.123 + log(3.42e5)}
\end{everbatim*}
\endgroup
\noindent And with still more digits (the |[-2]| rounds away the two least
significant ones):
\begingroup
\begin{everbatim*}
\xintSetDigits*{62}
\xintfloateval[-2]{cos(3Pi/17)*sin(1)^0.123 + log(3.42e5)}
\end{everbatim*}
\endgroup
Here is now an example with fractions:
\begin{everbatim*}
\xinteval{reduce(add(1/i^3, i=1..25))}
\end{everbatim*}
And two examples with large integers:
\begin{everbatim*}
$2^{1000}=\printnumber{\xinteval{2^1000}}$.\newline
$100!^3=\printnumber{\xintiieval{100!^3}}$.
\end{everbatim*}
The \hyperref[ssec:printnumber]{\string\printnumber} utility to wrap
very long output is not part of the package. It is documented in
\autoref{ssec:printnumber} next.
The table of \hyperref[tab:functions]{built-in functions}
and the one of \hyperref[tab:precedences]{built-in operators}
will give a quick overview of the available syntax.
\subsection{\ctanpackage{xintsession}}
The simplest way\footnote{I am assuming here in the displayed example a
Unixen system, i.e. Mac OS or Linux, adapt to your environment.} to
test the syntax is to work interactively on the command line (this
feature is available since April 2021, the version of
\ctanpackage{xintsession} used here is |1.3a|). Beware though that
ill-formed inputs will trigger \TeX{} famously antiquated error handling,
from which it is hard to recover, altough hitting |S| may sometimes
miraculously bring you back to the \ctanpackage{xintsession} prompt.
\begin{everbatim}
rlwrap etex xintsession
[...welcome banner...]
Magic words: `&pause' (or `;'), `&help', `&bye',
`&exact', `&fp', `&int', `&pol'.
\jobname is xintsession
Transcript will go to log and to xintsession-210609_12h00.tex
Starting in exact mode (floating point evaluations use 16 digits)
>>> 2^100;
@_1 1267650600228229401496703205376
>>> cos(1);
@_2 0.5403023058681397
>>> &fp=32
(/usr/local/texlive/2021/texmf-dist/tex/generic/xint/xintlog.sty)
(/usr/local/texlive/2021/texmf-dist/tex/generic/xint/xinttrig.sty)
fp mode (log and trig reloaded at Digits=32)
>>> cos(1);
@_3 0.54030230586813971740093660744298
>>> 3^1000;
@_4 1.3220708194808066368904552597521e477
>>> &exact
exact mode (floating point evaluations use 32 digits)
>>> 3^1000;
@_5 13220708194808066368904552597521443659654220327521481676649203682268285
9734670489954077831385060806196390977769687258235595095458210061891186534272525
7953674027620225198320803878014774228964841274390400117588618041128947815623094
4380615661730540866744905061781254803444055470543970388958174653682549161362208
3026856377858229022841639830788789691855640408489893760937324217184635993869551
6765018940588109060426089671438864102814350385648747165832010614366132173102768
902855220001
>>> &bye
Did I say something wrong?
Session transcript written on xintsession-210609_12h00.tex
)
No pages of output.
Transcript written on xintsession.log.
\end{everbatim}
\subsection{\ctanpackage{zeckendorf}}
This package enriches the \csbxint{eval} interface with tools related
to Fibonacci numbers and Bergman $\phi$-representation. In particular,
it implements the Knuth Fibonacci multiplication. It can be used
either as a \LaTeX{} package, or with Plain \eTeX{}, or also on the
command line via \verb+rlwrap etex zeckendorf+.
\subsection{\ctanpackage{polexpr}}
The package \ctanpackage{polexpr} enriches the \csbxint{eval} syntax
(but not the one of \csbxint{floateval}) with a polynomial type with
associated constructor |pol([c0,c1,...])|, and polynomial specific
functions such as |polgcd(pol1, pol2, ...)|.
Full usage of polynomials (and algebraic notations |c_0 + c_1 x + c_2
x^2 + ...| for input and also output) goes through a dedicated |\poldef|
parser which is based upon \csbxint{defvar}/\csbxint{deffunc} and is a
necessary step to then access via a dedicated macro interface operations
such as identifying all rational roots and isolating all real roots to
arbitrary precision.
The simplest manner to experiment with \ctanpackage{polexpr} is via the
|&pol| mode of \ctanpackage{xintsession}.
\subsection{\ctanpackage{bnumexpr}}
This \LaTeX{} package loads \xintcorename and \xintbinhexname and
provides \cs{bnumeval} which is a scaled-down \csbxint{iieval} (omitting
support for nested structures, functions, variables, boolean branching,
etc...). It can be used with Plain e\TeX, thanks to
\ctanpackage{miniltx}. For this, use |\input miniltx.tex| followed by
|\input bnumexpr.sty| (remark: \ctanpackage{miniltx} is not needed for
\xintexprname).
\cs{bnumeval} is thus a boosted \cs{inteval} which addition of support
for arbitrarily large integers, powers with |**| and |^|, rounded
division with |/|, floored division with |//| and associated modulo
|/:|, factorials via |!| postfix operator, comma separated multi-item
expressions.
It also supports as \csbxint{iieval} does the |'|, |"|, |0b|, |0o| and
|0x| input prefixes and the optional arguments |[b]|, |[o]|, or |[h]|.
Further, it provides an interface (which does not exist with
\xintexprname) to let all operations be done by macros of one's own
choosing, as replacement for some or all of the operations by default
implemented via the help of \xintcorename and \xintbinhexname. It even
makes it possible to add to the syntax extra infix or postfix operators
and to modify the precedence levels of those already defined.
\subsection{Printing big numbers on the page}\label{ssec:printnumber}
When producing very long numbers there is the question of printing them on
the page, without going beyond the page limits. In this document, I have most
of the time made use of a ``|\printnumber|'' macro, which is not provided by
the package. A primitive form would be:
\everb|@
\def\allowsplits #1{\ifx #1\relax \else #1\hskip 0pt plus 1pt\relax
\allowbreak
\expandafter\allowsplits\fi}%
\def\printnumber #1{\expandafter\allowsplits \romannumeral-`0#1\relax }%
|
This macro triggers ``\fexpan sion'' of its argument (and indeed
\csbxint{eval} and friends expand completely under such trigger), then
it goes through the computation result character by character inserting
some stretchable glue in-between them. The |\allowbreak|'s (which is
known both to Plain \TeX{} and to \LaTeX{} and perhaps other formats,
else use |\penalty0\relax|) are here only for the case of usage in
inline math mode (they are ineffective in display math mode). The
actual |\printnumber| used for building this documentation is a more
sophisticated variant (never used in math mode), which handles comma
separated lists without gobbling spaces and prints continuation symbols
at line endings.
\subsection{Repository}
It is at \url{https://github.com/jfbu/xint}. At this stage, it does not
serve for real-time development but only proposes all actual successive
\href{https://ctan.org}{CTAN} releases since 2013. Use it to report
issues. Don't forget to include |@jfbu| in the ticket else I will not
be pinged.
A front page at \url{https://jfbu.github.io/xint} provides, in addition
to the present |xint.pdf| and to |README.md| a file |CHANGES.html|,
which contains the complete list of changes relevant to user level
since the initial release of the package:
%
\centeredline{\url{https://jfbu.github.io/xint/CHANGES.html}}
Its version |xintchanges.md| in Markdown format is included in the
\href{https://ctan.org/pkg/xint}{CTAN} upload,
%
\centeredline{|texdoc xintchanges.md|}
Warning: I don't have the time to maintain perfectly such large
documentation. It combines old documentation which never really got
updated and may be locally obsolete with more recent stuff mostly
written on occasion of the |1.4| release of January 2020 and the |1.4e|
one of May 2021, and the intervening changes might also have made some
of it not completely accurate, despite my best efforts.
\subsection{License and installation instructions}
\label{ssec:install}
The \xintbundlename components are made available under the
\href{http://www.latex-project.org/lppl/lppl-1-3c.txt}{LaTeX Project
Public License 1.3c}.
They are available at \href{https://ctan.org/pkg/xint}{CTAN}. They are
included in all major \TeX\ distributions, thus there is probably no
need for a custom install: just use the package manager to update from
time to time to latest version.
\clearpage
\expandafter\let\csname Start herenameUp\endcsname\undefined
\csname xintexprnameUp\endcsname
\section{Syntax reference and user guide}
\RaisedLabel{sec:expr}
\localtableofcontents
\subsection{Introduction: the three-parsers way}
\begin{framed}
\textbf{WARNING:} this documentation goes sometimes into too much
details, and does need some improvements. But there is no time for
that at |1.4n|. Although people do not believe me when I say that,
there is ample intellectual reward in actually reading the documentation,
and it would be nice if at least, at last someone on Earth did,
once (as \textsc{Jürgen Gilg} some years back).
\end{framed}
\xintexprname provides three numerical expression parsers corresponding to
these three respective tasks:
\begin{description}[noitemsep]
\item[\csa{xintfloateval}:] evaluations with floating point numbers; the default precision is with 16 digits, it can be set via \csbxint{SetDigits*},
\item[\csa{xinteval}:] exact evaluations with fractions, decimal fixed point numbers, numbers
in scientific notation, with no size limitation,
\item[\csa{xintiieval}:] evaluations allowing only integers with no size limitation.
\end{description}
% They are designed to be compatible with expansion only context. All
% computations ultimately rely on (and reduce to) usage of the |\numexpr|
% primitive from \eTeX{}%
% %
% \footnote{It can handle only integers, and they must be at most
% $2^{31}-1={}$\dtt{\the\numexpr"7FFFFFFF\relax}. Thus some work has to be done
% to handle arbitrarily big integers or arbitrary float precision.}.
% %
% These \eTeX{} extensions date
% back to 1999 and are by default incorporated into the |pdftex|
% etc...\@{} executables from major modern \TeX{} installations for more than
% fifteen years now.
The interface is:
\begin{itemize}
\item \csbxint{floateval}\oarg{Q}\marg{expression} does floating point
computations with a given precision, which defaults to |16|. The precision
|P| can be set using \csbxint{Digits*}|:=P\relax| or \csbxint{SetDigits*}|{P}|
syntaxes.
Its optional argument |[Q]|, if present, means to do a \emph{final} float
rounding to a mantissa of |Q| digits (this thus makes sense only if
|Q0|: the nearest fixed point number with |D| digits after the
decimal mark,
\item if |D=0|: the nearest integer (as for \csbxint{ieval} with no optional argument),
\item if |D<0|: the rounded quotient by |10^(-D)|.
\end{itemize}
The optional argument \oarg{D} can also be located
\emph{within} the braces at the start of the expression (this was actually
the legacy syntax until |1.4k|).
\item \csbxint{iieval}\marg{expression} executes computations \emph{on (big)
integers only.} It is (only slightly) faster than \csbxint{eval} for
the same expression.
Attention: the forward slash \oper{/} does the \emph{rounded} integer
division to match behaviour of |\numexpr|. The \oper{//} operator does
floored division as in \csbxint{eval}. The \oper{/:} is the associated
modulo operator (we could easily let the catcode 12 |%|
character be an alias, but using such an unusual percent character
would be a bit cumbersome in a \TeX{} workflow, if only for matters of
syntax highlighting in \TeX-aware text editors).
\begin{everbatim*}
% add the i^5 only if i is a multiple of 7
\xintiieval{add((i/:7)?{omit}{i^5}, i=1000..1020)}
\end{everbatim*}
An\NewWith{1.4n} optional argument |[h]|, |[o]|, or |[b]| says to convert the output
to hexadecimal, octal or binary:
\begin{everbatim*}
\xintiieval[h]{3^100}
\end{everbatim*}
\end{itemize}
% The user can define variables and functions. Definition of functions is either
% per parser (\csbxint{deffunc}, \csbxint{deffloatfunc}, ...), but there are
% some restrictions, or generic (\csbxint{NewFunction}) but the latter is only
% syntactic sugar for function-like disguise of a \TeX{} macro having not done
% any pre-parsing.
\begin{framed}
Please note:
\begin{itemize}[noitemsep]
\item If you find that \csbxint{floateval} is too much of a mouthful,
you can create an alias named, for example, |\fpeval|. Oops, no,
that is \LaTeX3 very efficient floating point engine (for 16 decimal
digits of precision). It is faster than \csbxint{floateval} due to
the excellent coding and algorithms it employs, but also for reasons
having to do in part with the fact that \xintname initially was
created to handle big integers only, and support for arbitrary
precision floating point was added on top of that, via some
expedients which have never been refactored, yet.
\item Although \csbxint{eval} manipulates arbitrarily long integers or
fractions it also accepts scientific notation on input, as well as
all the mathematical functions (evaluated using the prevailing
digits precision), and (depending on customization) can thus produce
also scientific notation on output. But be careful that for example
a multiplication will then automatically roughly double the number
of digits in general (some operations avoid extending mantissas,
so short mantissas may remain short).
\item So far, individual operations and the printing routine of
\csbxint{eval} do not automatically reduce fractions to their lowest
terms.
\end{itemize}
\end{framed}
There is a core syntax:
\begin{itemize}[nosep]
\item \csbxint{expr}\meta{expression}|\relax|,
\item \csbxint{iexpr}\meta{expression}|\relax|,
\item \csbxint{iiexpr}\meta{expression}|\relax|,
\item \csbxint{floatexpr}\meta{expression}|\relax|,
\item \csbxint{boolexpr}\meta{expression}|\relax|.
\end{itemize}
\csbxint{boolexpr}\meta{expression}|\relax| does all computations like
\csbxint{expr} then converts all (non-empty) leaves%
%
\footnote{Currently, empty leaves are output using \csbxint{exprEmptyItem},
i.e.\@{} default to \dtt{\xintexprEmptyItem}. This may change.}
%
to |true| or |false| (cf.\@{} \csbxint{boolexprPrintOne}). There is no
|\xintbooleval|.\CHANGED{1.4m}\footnote{This was |True| and |False| prior
to |1.4m|.}
Formerly the \csbxint{expr}|...\relax| legacy syntax had to be prefixed
by |\xintthe| if in typesetting context, else an error was raised
(deliberately). The |\xintthe| prefix was made optional at |1.4|.
In an |\edef| these constructs expand to some braced nested data, all
computations having been completely done, which is prefixed with some
|\protected| \myenquote{typesetter} macros.
In an |\edef|, \csbxint{eval} (in contrast to \csbxint{expr}), or
\csbxint{floateval} (in contrast to \csbxint{floatexpr}) expand the
\myenquote{typesetting macros} and the final complete expansion consists of
explicit digits and other characters such as those of scientific
notation or square brackets.%
%
\footnote{\csbxint{eval} and \csbxint{expr} both expand completely in exactly
two steps. And \csbxint{expr} expands fully under \fexpan sion (of the
|\romannumeral0| or |-`0| type). As per \csbxint{eval} attention that it may
expand to nothing, then naturally \fexpan sion propagates to tokens
following up in the input stream.}
In \LaTeX\ it is possible to use the core syntax
\csbxint{expr}\meta{expression}|\relax| also in so-called moving arguments,
because when written out to a file the final expansion outcome uses only
standard catcodes and thus will get retokenized and expand as expected if
it has been written to an external file which is then reloaded.
One needs \csbxint{eval} et al.\@{} only if one really wants the final digits
(and other characters), for example in a context where \TeX{} expects a number
or a dimension.
As alternative to \csbxint{eval}\marg{expression}, an equivalent is
\csbxint{the}\csbxint{expr}\meta{expression}|\relax|. Similarly \csbxint{the}
can prefix all other core parsers. And one can also use \csbxint{theexpr} as
shortcut for \csbxint{the}\csbxint{expr}.
Doing exact computations with fractions leads very quickly to very big results
(and furthermore one needs to use explicitly the |reduce()| function to
convert the fractions into smallest terms). Thus most probably what you want
is \csbxint{floateval} and \csbxint{floatexpr}.
\subsection{Output customization}
\subsubsection{\csh{xintfloatexprPrintOne} et al{.} for numerical values}
\label{xintexprEmptyItem}
\label{xintexprPrintOne}
\label{xintiiexprPrintOne}
\label{xintiiexprPrintOneHex}
\label{xintiiexprPrintOneOct}
\label{xintiiexprPrintOneBin}
\label{xintiexprPrintOne}
\label{xintfloatexprPrintOne}
\label{xintboolexprPrintOne}
The package provides only minimal facilities for formatting the output
from \csbxint{eval} or \csbxint{floateval} or\dots. And this output may
well consist of comma separated values, even nested ones with, by
default, square brackets. First we explain how to influence the handling
of individual \myenquote{leaves}.
Here are the default definitions to this effect:
\begin{everbatim}
\def\xintexprEmptyItem{[]} % (all parsers)
\def\xintexprPrintOne #1{\xintFracToSci{#1}} % \xinteval
\def\xintiexprPrintOne #1{\xintDecToString{#1}} % \xintieval
\def\xintiiexprPrintOne#1{#1} % \xintiieval
\def\xintfloatexprPrintOne [#1]#2{\xintPFloat[#1]{#2}} % \xintfloateval
\def\xintboolexprPrintOne#1{\xintiiifNotZero{#1}{true}{false}}
\end{everbatim}
They can be re-defined to one's wishes. If configured to do anything
non expandable they must be |\protected|. \LaTeX\ users will want to use
|\RenewDocumentCommand| for this.
\begin{TeXnote}
\begin{itemize}
\item Actually, the defaults are more done in the style
\begin{everbatim}
\let\xintexprPrintOne\xintFracToSci
\end{everbatim}
thus sparing grabbing the argument |#1|. And one can do
\begin{everbatim}
\def\xintexprPrintOne{\xintFracToSci}
\end{everbatim}
too.
\item |\xintexprPrintOne| defaults in truth to some private variant of
\csbxint{FracToSci} with exactly the same output but able to understand
only certain limited types of inputs as used internally.
\item |\xintiiexprPrintOne| is used with \csbxint{iieval}. But it
gets replaced with |\xintiiexprPrintOneHex|,
|\xintiiexprPrintOneOct|, or |\xintiiexprPrintOneOct| if the
optional argument |[h]|, |[o]|, or |[b]| is used.\NewWith{1.4n} These macros
default to respectively \csbxint{DecToHex}, \csbxint{DecToOct} and
\csbxint{DecToBin}.
\item |\xintfloatexprPrintOne| defaults in fact to a private variant of
\csbxint{PFloat} which assumes the optional argument |[P]| is present as
it will be the case always in this context. This optional argument
|[P]| is the optional argument |[Q]| of \csbxint{floateval} (or
|Digits+Q| if |Q<0|).
\item The typesetter for \csbxint{iiexpr} simply prints ``as is'', but this
may change in future, if some internal format is used requiring a
conversion step.
\end{itemize}
\end{TeXnote}
Here is a possibly not up-to-date list of macros of interest, whose
documentations you might consider reading (the first two require math
mode):
\begin{itemize}[nosep]
\item \csbxint{TeXFromSci},
\item \csbxint{TeXFrac},
\item \csbxint{DecToString},
\item \csbxint{PRaw},
\item \csbxint{FracToSci},
\item \csbxint{FracToDecimal},
\item \csbxint{PFloat},
\item and \csbxint{FloatToDecimal}.
\end{itemize}
Naming scheme, as one can see, has been pretty much incoherent, apologies.
Among packages providing macros formatting numeric values, there are
\ctanpackage{numprint} and its macro |\np| (or |\numprint| without the
option |np|), and \ctanpackage{siunitx}
and its |\num|, and possibly more packages not known to the author.%
%
\footnote{There does not seems to be yet a \LaTeX\ user level interface to the
\liiistrformat\ package, part of |l3experimental|, which provides an
implementation of the Python |format| function.}
%
These macros are suitable in combination with \csbxint{Float} as in the
example below to customize the \csbxint{floateval} output.
% 27 mai 2022, en effet \num{1/7} ne marche pas et \numprint{1/7} non plus
Numerical output from \csbxint{eval} is more challenging as
individual values may naturally contain the |/| character for fractions which the
above mentioned packages will not know how to handle, as far as I know.
Here an example, with \LaTeX{} and |\num| from \ctanpackage{siunitx}:
\begin{everbatim}
\RenewDocummentCommand\xintfloatexprPrintOne{o m}{\num{\xintFloat[#1]{#2}}}
\end{everbatim}
We could have used here simply |\def| with delimited parameters |[#1]#2| because:
\begin{itemize}[nosep]
\item the optional argument will always be present at time of use,
\item |\num| is a |\protected| macro.
\end{itemize}
Note that when using only |\def| for the definition, the argument of |\num|
is getting to be expanded first, but |\num| would have done that anyhow.
With \ctanpackage{numprint}, one can similarly do:
\begin{everbatim}
\RenewDocumentCommand\xintfloatexprPrintOne{o m}{\numprint{\xintPFloat[#1]{#2}}}
\end{everbatim}
This used \csbxint{PFloat} rather than \csbxint{Float} as with |\num|.
This is because (in my limited testing) |\numprint| with not silently
remove a zero scientific exponent but it will typeset it, for example as
$1.5\cdot10^0$. So we use our own \csbxint{PFloat} poor man
\myenquote{prettifier}.
Maybe you want to use a macro which is unable to have
|\xintPFloat[#1]{#2}| as argument because it needs to see only a number
in scientific notation and nothing else. If that macro is |\protected|,
do the definition with |\def|. It it is not |\protected| and not
purely expandable either, one can do this:
\begin{everbatim}
\protected\def\myfoo{\foo}%<<<--- with options perhaps
\def\xintfloatexprPrintOne[#1]#2{\myfoo{\xintPFloat[#1]{#2}}}
\end{everbatim}
Then when |\myfoo| finally expands, its argument has been expanded already.
The current behaviour of \csbxint{floateval} corresponds to this set-up:
\begin{everbatim}
\def\xintfloatexprPrintOne [#1]#2{\xintPFloat[#1]{#2}}
\end{everbatim}
and to this default configuration of \csbxint{PFloat}:
\begin{everbatim}
\def\xintPFloatE{e}
\def\xintPFloatZero{0}
\def\xintPFloatIntSuffix{}
\def\xintPFloatLengthOneSuffix{}
\def\xintPFloatNoSciEmax{5}
\def\xintPFloatNoSciEmin{-4}
\def\xintPFloatMinTrimmed{4}
\end{everbatim}
With the custom replacement
\begin{everbatim}
\def\xintfloatexprPrintOne{\xintFloatToDecimal}
\end{everbatim}
the \csbxint{floateval} output will use decimal fixed point notation,
i.e.\@{} no scientific exponents, and as many zeros as are needed (but no
more, as trailing zeros will be removed from the significant digits).
Here is an example comparing outputs from the
default configuration and custom ones:
\begingroup % DÉBUT DU GROUPE POUR DES EXEMPLES
\begin{everbatim*}
\xintfloateval{exp(-32.456)/2000} (default, i.e. PFloat)\newline
\def\xintfloatexprPrintOne{\xintFloatToDecimal}%
\xintfloateval{exp(-32.456)/2000} (FloatToDecimal)\newline
\def\xintfloatexprPrintOne[#1]#2{\xintTeXFromSci{\xintFloat[#1]{#2}}}%
$\xintfloateval{exp(-32.456)/2000}$ (TeXFromSci on Float)\par % math mode required
\end{everbatim*}
Some examples showing now the effect of sensible customizations on \csbxint{eval}:
\begin{everbatim*}
\xinteval{exp(-32.456)/2000} (default, i.e. FracToSci)\newline
\def\xintexprPrintOne{\xintFracToDecimal}%
\xinteval{exp(-32.456)/2000} (FracToDecimal)\newline
\def\xintexprPrintOne#1{\xintTeXFromSci{\xintFracToSci{#1}}}%
$\xinteval{exp(-32.456)/2000}$ (TexFromSci on FracToSci)\par % math mode required
\end{everbatim*}
Notice that the |/2000| denominator remains ``as is'' in the
output, in conformity with the documented behaviour of
\csbxint{FracToSci} in the first example and of \csbxint{FracToDecimal}
for the second example. This has not changed since |1.4| (the handling
of the numerator part has changed at |1.4e| and again slightly at
|1.4k|, the zero value being now always printed as \dtt{0} and not
\dtt{0} or \dtt{0.0} depending on the input) but is to be considered
unstable and undecided so far.
A slightly more costly typesetter could be for example:
\begin{everbatim}
\def\xintexprPrintOne#1{\xintDecToStringREZ{\xintIrr{#1}}}
\end{everbatim}
Then
\begin{itemize}[nosep]
\item the fraction (inclusive of its power of ten part) will be reduced
to lowest terms (see \csbxint{Irr}),
\item next the trailing zeros will be moved as an exponent (positive or
negative) to the numerator,
\item this numerator with a power of ten part will be printed in decimal
fixed point notation, with as few zeros as are needed,
\item and finally the denominator |B|, which has been trimmed of trailing
zeros, will be printed as |/B| or not at all if |B=1|.
\end{itemize}
With the
use case above:
\begin{everbatim*}
\def\xintexprPrintOne#1{\xintDecToStringREZ{\xintIrr{#1}}}
\xinteval{exp(-32.456)/2000}\par
\end{everbatim*}
This trailing |/2| is somewhat of a pain, but as documented and
mentioned already \csbxint{DecToStringREZ} currently has not been
educated to identify its presence and handle it. Slightly faster (see
\csbxint{PIrr}) is
\begin{everbatim}
\def\xintexprPrintOne#1{\xintDecToStringREZ{\xintPIrr{#1}}}
\end{everbatim}
which with the used example produces the same output.
One can also consider this for math mode:
\begin{everbatim*}
\def\xintexprPrintOne#1{\xintTeXFromSci{\xintDecToStringREZ{\xintIrr{#1}}}}
$\xinteval{exp(-32.456)/2000}$\par
\end{everbatim*}
See our hesitations about what \csbxint{TeXFromSci} should do with
denominators.
\begin{TeXnote}
One can hope that in future \csbxint{DecToString} will identify
denominators being products of only two's and five's, but even then of
course \csbxint{TeXFromSci} will have to decide how to handle other
denominators.
\end{TeXnote}
\endgroup % FIN DU GROUPE POUR LES EXEMPLES
\begin{TeXnote}
The macro used as customization of \csbxint{exprPrintOne} (whose default is
a private variant of \csbxint{FracToSci} with exactly same output) must
understand the internal \xintfracname format |A/B[N]|, but with the |/B| and
|[N]| parts being only optional. This is not a problem when using for this
task (nested) macros of \xintfracname, as they of course accept such
inputs as argument and in fact much more general ones.
In particular one can benefit from \csbxint{Raw}, or \csbxint{RawBraced}, to
convert the argument into a well defined shape (|A/B[N]| for the former and
|{N}{A}{B}| for the latter) and then work from there.
The macro used by \csbxint{floatexprPrintOne} has the guarantee that the
|[P]| will be always present at expansion time.
The customization should be compatible with being exposed to |\expanded|
(which is like expansion in an |\edef|), either from being completely
expandable or at the opposite from being |\protected|. \LaTeX2e commands
defined via |\newcommand| as macros with one optional parameter are not
compatible with this requirement.
Attention! The interface requirements described above for the macros
customizing the behaviours of \csbxint{exprPrintOne} and
\csbxint{floatexprPrintOne} may change at any release... as they
depend on some internal structures and it is not certain backwards
compatiblity will be maintained systematically in case of evolution.
\end{TeXnote}
\subsubsection{\csh{xintthealign} for output of general oples}
\label{xintthealign}
With \csbxint{thealign} one can get nested data use a \TeX{} alignment in the
output. Here is an example :
\begin{everbatim*}
\xintthealign\xintexpr ndseq(1/(i+j), i = 1..10; j=1..10)\relax
\end{everbatim*}
Attention, this \csa{xintthealign} must be a prefix to \csbxint{expr},
or \csbxint{floatexpr} etc..., but there will be low-level \TeX\ errors
if it is used to prefix \csbxint{eval} et al. or \csbxint{theexpr} et al.
It is possible to customize the behaviour of |\xintthealign|. For example:
\begin{everbatim}
\protected\def\xintexpralignbegin {\halign\bgroup\tabskip2ex\hfil##&#\hfil\cr}%
\def\xintexpralignend {\crcr\egroup}% removed \protected at 1.4c
\protected\def\xintexpralignlinesep {,\cr}% separates "lines"
\protected\def\xintexpralignleftsep {&}% at left of first item in a "line"
% (after "left bracket")
\protected\def\xintexpraligninnersep {,&}% at the left of non-first items
\protected\def\xintexpralignrightsep {&}% at right of last item in a "line"
% (before "right bracket")
\protected\def\xintexpralignleftbracket {[}%
\protected\def\xintexpralignrightbracket{]}%
\end{everbatim}
The above definitions use |\protected| with no strong reason, as the
replacement tokens are not expanding anyhow, but the idea is that this
allows to execute a computation via an |\edef| and later one can change
the meaning of the auxiliary macros depending on what one wants to do
with the expansion result.
\begin{TeXnote}
\csa{xintexpralignend} is expanded once, after the body has been submitted
to exhaustive expansion (|\expanded| induced), and prior to the expansion of
\csa{xintexpralignbegin}.
\end{TeXnote}
Although we will try to keep stable the way \myenquote{regular arrays} as in the
above example are rendered by default,\UNSTABLE{} the |\xintthealign|
macro (and its associated customizability) is to be considered
work-in-progress and may experience breaking changes.
Use for example this for outputting to a file or a terminal:%
%
{\catcode`^ 12
\footnote{With the |xetex| engine this will need its |-8bit| option else
the |^^J| in |\xintexpralignlinesep| will be printed literally instead
of being converted into a line separator in the file or terminal output.}}
\begin{everbatim}
% Better here without \protected.
% We assume here \newlinechar has the LaTeX setting.
\def\xintexpralignbegin {}%
\def\xintexpralignend {}%
\def\xintexpralignlinesep {,^^J}% separates "lines"
\def\xintexpralignleftsep { }% at left of first item in a "line" (after brackets)
\def\xintexpraligninnersep {, }% at the left of non-first items
\def\xintexpralignrightsep { }% at right of last item in a "line" (before brackets)
\def\xintexpralignleftbracket {[}%
\def\xintexpralignrightbracket{]}%
\end{everbatim}
In the \LaTeX{} example next using a |pmatrix| environment, |\noexpand|
rather than |\protected| is used. This environment will not break
across pages, contrarily to the display produced by the default
\csbxint{thealign} configuration which uses \TeX{}'s |\halign|.
%\kern10\baselineskip
%\hbox{Big empty space here}
%\kern-11\baselineskip
\begin{everbatim*}
\[
\def\xintexpralignbegin {\begin{pmatrix}}%
\def\xintexpralignend {\end{pmatrix}}%
\def\xintexpralignlinesep {\noexpand\\}% needed to counteract an internal \expanded
\def\xintexpraligninnersep {&}%
\let\xintexpralignleftbracket\empty \let\xintexpralignleftsep\empty
\let\xintexpralignrightbracket\empty \let\xintexpralignrightsep\empty
% by default amsmath matrices can have 10 columns at most
% (cf amsmath documentation for what to do to allow more)
l.c.m.=\xintthealign\xintiiexpr ndmap(lcm, 1..12; 1..10)\relax
\]
\end{everbatim*}
\subsection{Built-in operators and their precedences}
The parser implements precedence rules based on concepts which are summarized
below (only for binary infix operators):
\begin{itemize}[noitemsep]
\item an infix operator has two associated precedence levels, say |L| for left
and
|R| for right,
\item the parser proceeds from left to right, pausing each time it has found a
new number and an operator following it,
\item the parser compares the left-precedence |L| of the new found operator to
the right-precedence |R_last| of the last delayed operation (which already
has one argument and would like to know if it can use the new found one): if
|L| is at most equal to it, the delayed operation is now executed, else the
new-found operation is kept around to be executed first, once it will have
gathered its arguments, of which only one is known at this stage.
\end{itemize}
This means for example in the case of the multiplication \oper{\lowast} and the
division operators \oper{/}, \oper{//}, \oper{/:} that they are parsed in a
left-associative way because they all share the same (left and right)
precedence level. This is the case with the analogous operators from the
Python language, as well.
At |1.4g| the power operators were changed to act in a right associative
way. Again, this matches the behaviour of e.g.\@{} Python:%
\begin{everbatim*}
\xinteval{2^-3^4}
\end{everbatim*}
\makeatletter
\def\@floatboxreset{\@setminipage}% faudra contrôler celui-là
\makeatother
\begin{table}[p]
\edef\Ampersand{\string&}%
\edef\restorehtdpstrutbox
{\ht\strutbox\the\ht\strutbox\dp\strutbox\the\dp\strutbox}
\ht\strutbox12pt\dp\strutbox5pt
\capstart
\centering\begin{tabular}{|c|p{.5\textwidth}|}
\hline
\multicolumn{2}{|p{.6\textwidth}|}{\prec{$\infty$}:
at this top level the syntax elements whose
execution
is done prior to operators preceding them:
\begin{itemize}[nosep]
\item
\hyperref[ssec:builtinfunctions]{built-in} or
\hyperref[ssec:userfunctions]{user-defined} functions,
\item \hyperref[ssec:uservariables]{variables},
\item the \oper{\empty\lowast} unpacking operator,
\item intrinsic constituents of numbers: decimal mark \oper{\strut.},
\oper{e} and \oper{E} of scientific notation, hexadecimal prefix
\oper{"}.
\end{itemize}\par}%
\\\hline\hline
Precedence&``Operators'' at this level\strut\\
\hline
\prec{20}& postfix \oper{!} and branching \oper{?}, \oper{??} operators\strut\\\hline
%
\prec{-}& minus sign as unary operator inherits the right-\hskip0pt precedence of
the infix operator it follows, if that precedence is higher than the one of
binary \oper{+} and \oper{-}, else it inherits the latter\strut\\\hline
%
\prec{18} (17)& \oper{\string^} and \oper{\lowast\lowast} are synonymous;
they act in a right-associative way (\textcolor[named]{Red}{\bfseries Changed at 1.4g!})\strut\\\hline
%
\prec{16} (14)& \hyperref[ssec:tacit multiplication]{Tacit
multiplication} has an elevated (left) precedence\strut\\\hline
%
\prec{14}& \oper{\lowast}, \oper{/}, \oper{//} (floored division),
and \oper{/:} (associated modulo, alias
\oper{'mod'})\strut\\\hline
%
\prec{12}& \oper{+}, \oper{-}\strut\\\hline
%
\prec{10}& \oper{<}, \oper{>}, \oper{==}, \oper{<=}, \oper{>=},
\oper{!=} (they can be chained)\strut\\\hline
%
\prec{8}& Boolean conjunction \oper{\Ampersand\Ampersand} and
its alias \oper{'and'}\strut\\\hline
%
\prec{6}& Boolean disjunction \oper{\string|\string|} and
its alias \oper{'or'}. Also \oper{'xor'} and
\oper{\strut..}, \oper{..[},
\oper{{]..}}, and \oper{:} have
this precedence\strut\\\hline
%
\prec{4}& the brackets for slicers and extractors \oper{\empty[},
\oper{\empty]}\strut\\\hline
%
\prec{3}& the comma \oper{,}\strut\\\hline
%
\prec{2}& the bracketers \oper{[}, \oper{]} construct nestable \myenquote{arrays}\strut\\\hline
%
\prec{1}& the parentheses \oper{(}, \oper{)}, and the semi-colon
\oper{;} in \func{iter}, \func{rseq}, and further structures\strut\\\hline
%
\hline
%
\multicolumn{2}{|p{.6\textwidth}|}{%
\begin{itemize}[nosep]
\item Binary operators have a left and a right precedence, which for
most coincide. The right precedence is indicated within parentheses.
\item
\hyperref[ssec:tacit multiplication]{Tacit multiplication} has an elevated
left precedence level: |(1+2)/(3+4)5|
is computed as |(1+2)/((3+4)*5)| and |x/2y| is interpreted as |x/(2*y)|
when using variables.
\end{itemize}
}\\\hline
\end{tabular}
\caption{Precedence levels}
\label{tab:precedences}
\etoctoccontentsline {xinttable}{\protect\emph{Table of precedence levels of operators}}
\restorehtdpstrutbox
\end{table}
The entries of \autoref{tab:precedences} are hyperlinked to the more detailed
discussion at each level. In these entries the number within parentheses
indicates the right-\hskip0pt precedence, if it differs from the left.
\begin{description}
%[parsep=0pt, listparindent=\leftmarginiii]
% [parsep=0pt,align=left,itemindent=0pt,
% leftmargin=\leftmarginii, labelwidth=\leftmarginii, labelsep=0pt,
% labelindent=0pt, listparindent=\leftmarginiii]
\edef\Ampersand{\string&}%
\precdesc{$\infty$} At this highest level of precedence, one finds:
\begin{description}
\item[{\hyperref[ssec:builtinfunctions]{functions} and
\hyperref[ssec:uservariables]{variables}}]
Functions (even the logic functions
\func{!} and \func{?} whose names consist of a single non-letter character)
must be used with parentheses. These parentheses may arise from expansion
after the function name is parsed (there are exceptions which are documented
at the relevant locations.)
\operdesc{\empty\lowast} Python-like \myenquote{unpacking} prefix operator. Sometimes one
needs to use it as function |*()| (but I can't find an example right now)
but most of the time parentheses are unneeded.
\operdesc{\strut.} is decimal mark; the number scanner treats it as an inherent,
optional and unique component of a being formed number.
|\xintexpr 0.^2+2^.0\relax| is interpreted as |0^2+2^0| and
thus produces \dtt{\xintexpr 0.^2+2^.0\relax}.
Since release |1.2| an isolated decimal mark is illegal
input in the \xintexprname parsers (it remains legal as argument to the
macros of \xintfracname).
\operdesc{e} scientific notation.
\operdesc{E} scientific notation. For output, see \csbxint{PFloatE}.
\operdesc{"} prefix for hexadecimal input. Only uppercase letters, and
one optional |.| separating integer and fractional hexadecimal parts.
\begin{everbatim*}
\xintexpr "FEDCBA9876543210\relax\newline
\xintexpr ".FEDCBA9876543210\relax\newline
\xintexpr 16^5-("F75DE.0A8B9+"8A21.F5746+16^-5)\relax
\end{everbatim*}
It is possible that in future the |"| prefix could be dropped in favour of
|0x| prefix. This would free |"| to be used for input of \myenquote{string}-like
entities.
\end{description}
\precdesc{20}
The postfix operators |!| and the branching conditionals |?|, |??|.
\begin{description}
\operdesc{!} computes the factorial of an integer.
\operdesc{?} is used as |(stuff)?{yes}{no}|. It
evaluates |stuff| and chooses the |yes| branch if the result is
non-zero, else it executes |no|. After evaluation of |stuff| it acts as
a macro with two mandatory arguments within braces, chooses the
correct branch \emph{without evaluating the wrong one}. Once the braces
are removed, the parser scans and expands the uncovered material.
% so for
% example
% %
% \leftedline{|\xinttheiexpr (3>2)?{5+6}{7-1}2^3\relax|}
% %
% is legal and computes
% |5+62^3=|\dtt{\xinttheiexpr(3>2)?{5+(6}{7-(1}2^3)\relax}. It would be
% better practice to include here the |2^3| inside the branches. The
% contents of the branches may be arbitrary as long as once glued to what is
% next the syntax is respected: {|\xintexpr (3>2)?{5+(6}{7-(1}2^3)\relax|
% also works.}
\operdesc{??} is used as |(stuff)??{<0}{=0}{>0}|,
where |stuff| is anything, its sign is evaluated and depending on the sign
the correct branch is un-braced, the two others are discarded with no
evaluation of their contents.
% The un-braced branch will then be parsed as
% usual.
% %
% \leftedline{|\def\x{0.33}\def\y{1/3}|}
% %
% \leftedline{|\xinttheexpr (\x-\y)??{sqrt}{0}{1/}(\y-\x)\relax|%
% \dtt{=\def\x{0.33}\def\y{1/3}%
% \xinttheexpr (\x-\y)??{sqrt}{0}{1/}(\y-\x)\relax }}
% %
\end{description}
\precdesc{-} As unary operator, the minus sign inherits as precedence the
minimum of |12| (which is the precedence for addition and subtraction) and
of the (right-) precedence of the operators preceding it (if any).
\begin{everbatim*}
\xintexpr -3-4*-5^-7, (-3)-(4*(-(5^(-7))))\relax\newline
\xintexpr -3^-4*-5-7, (-((3^(-4))*(-5)))-7\relax\newline
|2^-10| gives \xintexpr 2^-10\relax\space
\end{everbatim*}and is thus perfectly legal, no need for parentheses.
The |+| character as prefix unary operator is simply ignored during
input parsing.
\precdesc{18}
\begin{description}
\operdesc{\string^}
\operdesc{\lowast\lowast} Both compute powers. They act in a right associative
way.
\begin{everbatim*}
\xintiiexpr 2^3^4\relax
\end{everbatim*}
\end{description}
% et:
% *2^-3^-4;
% (@_1) 0.991479137495678
% *2**-3**-4;
% (@_2) 0.991479137495678
% Python:
% >>> 2**-3**-4;
% 0.9914791374956781
\precdesc{16} see \hyperref[ssec:tacit multiplication]{Tacit multiplication}.
\precdesc{14}
\begin{description}
\operdesc{\lowast} multiplication
\operdesc{/} division:
\begin{itemize}
\item in \csbxint{eval}: exact division in the field of rational numbers (not
automatically reduced to lowest terms),
\item in \csbxint{floateval}: correct rounding of the exact division; the two
operands are, if necessary, float-rounded before the fraction is
evaluated and rounded (to obtain the correcty rounded |A/B|
without prior rounding of |A| and |B| see \func{qfloat}),
\item in \csbxint{iieval}: for compatibility with the legacy behaviour of
|/| in |\numexpr|, it rounds the exact fraction \emph{with half-integers
going towards the infinity of the same sign}.
\end{itemize}
The division is left-associative. Example:
\begin{everbatim*}
\xintexpr reduce(100/50/2)\relax
\end{everbatim*}
\operdesc{//} floored division (and thus produces an integer, see
\func{divmod} for details)
\operdesc{/:} the associated modulo (see \func{divmod} and \func{mod})
Left-associativity applies to the division operators:
\begin{everbatim*}
\xintexpr 100000/:13, 100000 'mod' 13\relax, \xintexpr 100000/:13/13\relax
\end{everbatim*}
Nothing special needs to be done in contexts such as \LaTeX3
|\ExplSyntaxOn| where |:| is of catcode letter, but if |:| is an
active character one needs to use input such as |/\string :|
(or replace it with usage of the function \func{mod}).
Bulky workarounds such as |/\string :| are \fbox{\emph{unneeded}} if activation
is due to Babel.\NewWith{1.4n} See also \csbxint{exprSafeCatcodes} and
a framed note found in \autoref{xintexpr}.
\operdesc{'mod'} is same as \oper{/:}.
\fbox{Attention:}\IMPORTANTf{} with \ctanpackage{polexpr} loaded, which
allows |'| in variable and function names, |'mod'| can not follow
a variable name. Add parentheses around the variable, or use |/:|.
\end{description}
\precdesc{12}
\begin{description}
\operdesc{+} addition
\operdesc{-} subtraction. According to the general left-associativity rule in
case of equal precedence, it is
left associative:
\begin{everbatim*}
\xintiiexpr 100-50-2\relax
\end{everbatim*}
\end{description}
\precdesc{10} Comparison operators are (as in Python) all at the same level of
precedence, use parentheses for disambiguation.
\begin{description}
\operdesc{<} |a} |a>b| evaluates to \dtt{1} if the strict inequality holds to \dtt{0}
if not.
\operdesc{==} |a==b| evaluates to \dtt{1} if equality holds to \dtt{0}
if not.
\operdesc{<=} |a<=b| evaluates to \dtt{1} if left hand side is at most equal
to right hand side, to \dtt{0}
if not.
\operdesc{>=} |a>=b| evaluates to \dtt{1} if left hand side is at least equal
to right hand side, to \dtt{0}
if not.
\operdesc{!=} |a!=b| evaluates to \dtt{1} if they differ, to \dtt{0}
if not.
\end{description}
Comparisons can be chained arbitrarily, e.g., |x < y <= z !=
t| is equivalent to |x < y 'and' y <= z 'and' z != t| (and also to |all(x1}{true}{\error},
\xintifboolexpr{1<=2>=3<4>1}{\error}{false},
\xintifboolexpr{3 != 3! == 6 != 4! == 24}{true}{\error}
\end{everbatim*}
\precdesc{8}
\begin{description}
\operdesc{\Ampersand\Ampersand} logical conjunction. Evaluates to \dtt{1} if
both sides are non-zero, to \dtt{0} if not.
\operdesc{'and'} same as \verb+&&+. See
also the \func{all} multi-arguments function.
\fbox{Attention:}\IMPORTANTf{} with \ctanpackage{polexpr} loaded, which
allows |'| in variable and function names, |'and'| can not follow
a variable name. Add then parentheses around the variable name.
\begin{snugframed}
\noindent\centeredline{\xintReplicate{17}{\cautionsign[20pt]}\IMPORTANTf}
The character |&| has a special meaning to \TeX{} inside alignments
(this includes \LaTeX's |tabulars| and all similar environments).
As soon as \TeX{} considers that the cell typesetting starts, it
switches to a mode where as soon as it sees a |&|, even if it was
originally nested into some macros, \TeX{} will complain if it is
not a cell delimiter (possibly via some mysterious unrelated error
such as \emph{Missing number, treated as zero}). This issue used to
apply to \LaTeX's floating point engine as well see
\url{https://github.com/latex3/latex2e/issues/1958}. \xintexprname
users have a number of work-arounds:
\begin{itemize}[nosep]
\item Use |'and'|,
\item or define some token |\edef\myAND{\string&\string&}| and use it,
\item or use the \func{any} function.
\end{itemize}
For package authors creating macros with no control where they can
end up being used, it is best to avoid |&&|. Use one of the above
work-arounds. Read the above caveat about |'and'| though.
For time being (March 4, 2026), upper-management has decided not to
apply a similar fix as was done in the \LaTeX{} kernel (see above
GitHub issue). If such a fix was applied (up to the prize of some
very small overhead), upper-management would not have the pleasure
to write this advisory notice and show they care.
\end{snugframed}
\end{description}
\precdesc{6}
\begin{description}
\operdesc{\string|\string|} logical (inclusive) disjunction. Evaluates to
\dtt{1} if one or both sides are non-zero, to \dtt{0} if not.
\operdesc{'or'} same as as \verb+||+. See also the \func{any} multi-arguments
function.
\fbox{Attention:}\IMPORTANTf{} with \ctanpackage{polexpr} loaded, which
allows |'| in variable and function names, |'or'| can not follow
a variable name. Add parentheses around the variable, or use \verb=||=.
\operdesc{'xor'} logical (exclusive) disjunction.
\fbox{Attention:}\IMPORTANTf{} with \ctanpackage{polexpr} loaded, which
allows |'| in variable and function names, |'xor'| can not follow a variable
name. Add parentheses around the variable, or use the \func{xor} function syntax.
\operdesc{\strut..}
\operdesc{..[}
\operdesc{{]..}} Syntax for arithmetic
progressions. See \autoref{ssec:arithseq}.
\operdesc{:} This is a separator involved in |[a:b]| Python-like slicing syntax.
\end{description}
\precdesc{4}
\begin{description}
\operdesc{\empty[}
\operdesc{\empty]}
Involved in Python-like slicing |[a:b]| and extracting |[N]| syntax. And its
extension à la NumPy |[a:b,N,c:d,...,:]|. Ellipsis |...| is not yet implemented.
The \myenquote{step} parameter as in |[a:b:step]| is not yet implemented.
\end{description}
\precdesc{3}
\begin{description}
\operdesc{,}
The comma separates expressions (or function arguments).%
%
\footnote{The comma
is really like a binary operator, which may be called ``join''. It has
lowest precedence of all (apart the parentheses) because when it is
encountered all postponed operations are executed in order to finalize its
\emph{first} operand; only a new comma or a closing parenthesis or the end
of the expression will finalize its \emph{second} operand.}
%
\begin{everbatim*}
\xintiiexpr 2^3,3^4,5^6\relax
\end{everbatim*}
\end{description}
\precdesc{2}
\begin{description}
\operdesc{[}
\operdesc{]} The bracketers construct nestable \myenquote{array-like}
structures. Arbitrary (heterogeneous) nesting is allowed. For output related
matters see \csbxint{thealign} (its usage is optional, without it rendering
is \myenquote{one-dimensional}). Output shape of non-homogeneous arrays is to
be considered unstable at this time.
\end{description}
\precdesc{1}
\begin{description}
\operdesc{(}
\operdesc{)}
The parentheses serve as mandatory part of the syntax for functions, and to
disambiguate precedences.%
%
\footnote{It is not apt to describle the
opening parenthesis as an operator, but the closing parenthesis is analogous
to a postfix unary operator. It has lowest precedence which means
that when it is encountered all postponed operations are executed to finalize
its operand. The start of this operand was decided by the opening
parenthesis.}
%
They do not construct any nested structure.
\operdesc{;} The semi-colon as involved as part of the syntax of \func{iter},
\func{rseq}, \func{ndseq}, \func{ndmap} has the same
precedence as a closing parenthesis.
\end{description}
\item[|\relax|] This is the expression terminator for \csbxint{expr} et al.
It may arise from expansion during the parsing itself. As alternative to
\csbxint{expr} (et al.) use
\csbxint{eval} (et al.) which have the usual macro interface (with one mandatory
argument).
\end{description}
The |;| also serves as syntax terminator for \csbxint{defvar} and
\csbxint{deffunc}. It can in this rôle not arise from expansion as the
expression body up to it is fetched by a delimited macro. But this is done in
a way which does not require any specific hiding for inner semi-colons as
involved in the syntax of \func{iter}, etc...
\subsection{Built-in functions}\label{ssec:builtinfunctions}
See \autoref{tab:functions} whose elements are hyperlinked to the
corresponding definitions.
Functions are at the same top level of priority. All functions even
\func{?} and \func{!} require parentheses around their arguments.
% Table of functions
\begin{table}[btp]
\capstart
\centering
\xintAssignArray\xintCSVtoList{!, ?, `\lowast`, `+`,
Arg,
Argd,
abs,
acos,
acosd,
acosh,
acoth,
acsc,
acsch,
add,
all,
any,
arccos,
arccsc,
arcsec,
arcsin,
arctg,
argch,
argcoth,
argcsch,
argsech,
argsh,
argth,
asec,
asech,
asin,
asind,
asinh,
atan,
atan2,
atan2d,
atand,
atanh,
binomial,
bool,
ceil,
ch,
cos,
cosd,
cosh,
cot,
cotd,
cotg,
coth,
csc,
cscd,
csch,
divmod,
even,
exp,
expm1,
factorial,
first,
flat,
float,
float\string_dgt,
floor,
frac,
gcd,
if,
ifint,
ifone,
ifsgn,
ilog10,
inv,
iquo,
irem,
isint,
isone,
iter,
iterr,
last,
lcm,
len,
ln,
log,
log10,
log1p,
max,
min,
mod,
mul,
ndfillraw,
ndmap,
ndseq,
not,
num,
nuple,
odd,
pArg,
pArgd,
pfactorial,
pow,
pow10,
preduce,
qfloat,
qfrac,
qint,
qrand,
qraw,
random,
randrange,
rbit,
reduce,
reversed,
round,
rrseq,
rseq,
sec,
secd,
sech,
seq,
sgn,
sh,
sin,
sinc,
sind,
sinh,
sqr,
sqrt,
sqrtr,
subs,
subsm,
subsn,
tan,
tand,
tanh,
tg,
th,
togl,
trunc,
unpack,
xor,
zip
}
\to\Functions
\cnta\Functions{0}
\cntb\xinttheexpr ceil(\cnta/7)\relax\space
\newcommand\builtinfunction[1]{\expandafter\expandafter\expandafter\func
\expandafter\expandafter\expandafter{\Functions{#1}}}%
\centeredline{\begin{tabular}{|*{7}{p{2cm}|}}
\hline
\xintFor* #1 in {\xintSeq{1}{\cntb}}\do
{\builtinfunction{#1}&
\builtinfunction{#1+\cntb}&%
\builtinfunction{#1+2*\cntb}&%
\builtinfunction{#1+3*\cntb}&%
\builtinfunction{#1+4*\cntb}&%
\builtinfunction{#1+5*\cntb}&%
\ifnumgreater{#1+6*\cntb}{\cnta}
{}
{\builtinfunction{#1+6*\cntb}}%
\\\hline}%
\end{tabular}}
\caption{Functions (click on names)}\label{tab:functions}
\etoctoccontentsline {xinttable}{\protect\emph{Table of functions in expressions}}
\etocsetnexttocdepth{subsubsection}
\localtableofcontents
\end{table}
Miscellaneous notes:
\begin{itemize}[nosep]
\item since release |1.3d| \func{gcd} and \func{lcm} are extended to apply
to fractions too, and do NOT require the loading of \xintgcdname,
\item The randomness related functions \func{random}, \func{qrand} and
\func{randrange} require that the \TeX\ engine provides the
\csa{uniformdeviate} or \csa{pdfuniformdeviate} primitive. This primitive
is abstracted into \csa{xinttexuniformdeviate}, but the functions
use a wrapper \csbxint{UniformDeviate} which provides more randomness.
\item \func{togl} is provided for the case |etoolbox| package is loaded,
\item \func{bool}, \func{togl} use delimited macros to fetch their argument and the
closing parenthesis must be explicit, it can not arise from
on the spot expansion. The same holds for \func{qint}, \func{qfrac},
\func{qfloat}, \func{qraw}, \func{random} and \func{qrand}.
\item Also \hyperlink{ssec:dummies}{functions with dummy variables} use
delimited macros for some tasks. See the relevant explanations there.
\item Functions may be called with \emph{oples} as arguments as long as
the total length is the number of arguments the function expects.
\end{itemize}
\subsubsection{Functions with no argument}
\begin{description}
% [parsep=0pt,align=left,
% leftmargin=0pt, itemindent=0pt,
% labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt,
% listparindent=\leftmarginiii]
\funcdesc[]{random} returns a random float |x| verifying |0 <= x < 1|. It
obeys the prevailing precision as set by \csbxint{Digits}: i.e.\@{} with |P|
being the precision the random float multiplied by |10^P| is an integer,
uniformly distributed in the |0..10^P-1| range.
This description implies that if |x| turns out to be |<0.1| then
its (normalized) mantissa has |P-1| digits and a trailing zero, if |x<0.01|
it has |P-2| digits and two trailing zeros, etc... This is what is observed
also with Python's |random()|, of course with |10| replaced there by radix
|2|.%
\begin{everbatim*}
\xintsetrandomseed 12345
\xintDigits:=37\relax
\xintthefloatexpr random()\relax\newline
\xintthefloatexpr random()\relax\par
\end{everbatim*}
\funcdesc[]{qrand} returns a random float |0 <= x < 1| using \dtt{16} digits of
precision (i.e.\@{} |10^{16}x| is an integer). This is provided when speed is a
at premium as it is optimized for precision being precisely \dtt{16}.%
\begin{everbatim*}
% still with 37 digits as prevailing float precision
\xintthefloatexpr qrand(), random()\relax\newline
\xintDigits:=16\relax
\xintthefloatexpr qrand(), random()\relax\par
\end{everbatim*}
One can use both |qrand()| and |random()| inside the |\xintexpr| parser too.
But inside the integer only |\xintiiexpr| parser they will cause some
low-level error as soon as they get involved in any kind of computation as
they use an internal format not recognized by the integer-only parser.
See further \func{randrange}, which generates random integers.
Currently there is no |uniform()| function%
%
\footnote{Because I am not sure how to handle rounding issues: should the
computation proceed exactly and a rounding be done only at very end?}
%
but it can be created by user:
\begin{everbatim*}
\xintdeffloatfunc uniform(a, b):= a + (b-a)*random();
\romannumeral\xintreplicate{10}%
{%
\xintthefloatexpr uniform(123.45678, 123.45679)\relax\newline
}%
\end{everbatim*}
\funcdesc[]{rbit} returns a random |0| or |1|.
\end{description}
\subsubsection{Functions with one argument}
\begin{framed}
The trigonometric and exponential functions are not included here. See the
\calxtrigname and \calxlogname chapters.
\end{framed}
\begin{description}
% [parsep=0pt,align=left,
% leftmargin=0pt, itemindent=0pt,
% labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt,
% listparindent=\leftmarginiii]
\funcdesc{num} truncates to the nearest integer (truncation towards zero). It
has the same sign as |x|, except of course with |-1>> 29/5 % 3/5, 11/3 % 17/19, 11/57
(0.5599999999999999, 0.19298245614035087, 0.19298245614035087)
>>> (29/5) % (3/5), (11/3) % (17/19), 5/57
(0.4, 0.08771929824561386, 0.08771929824561403)
\end{everbatim}
For comparison (observe on the last lines how |\xintfloatexpr| is more accurate than
Python!):
\begin{everbatim*}
\noindent\xinttheexpr 29/5 /: 3/5, 11/3 /: 17/19\relax\newline
\xinttheexpr (29/5) /: (3/5), (11/3) /: (17/19)\relax\newline
\xintthefloatexpr 29/5 /: 3/5, 11/3 /: 17/19, 11/57\relax\newline
\xintthefloatexpr (29/5) /: (3/5), (11/3) /: (17/19), 5/57\relax\newline
5/57 = \xinttheexpr trunc(5/57, 20)\relax\dots\newline
\end{everbatim*}%
Regarding some details of behaviour in |\xintfloatexpr|, see discussion of
|divmod| function next.
\funcdesc[f, g]{divmod} computes the two mathematical values |floor(f/g)| and
|mod(f,g)=f - g*floor(f/g)| and produces them as a bracketed
pair
in
other terms it is analogous to the Python |divmod| function. Its output is
equivalent to using |f//g, f/:g| but its implementation avoids doing twice
the needed division.
In |\xintfloatexpr...\relax| the modulo is rounded to the prevailing
precision. The quotient is like in the other parsers an exact integer. It
will be rounded as soon as it is used in further operations, or via the global
output routine of |\xintfloatexpr|. \emph{Those examples behave as in |1.3f|
because assignments to multiple variables tacitly unpack if this is
necessary.}
\begin{everbatim*}
\xintdefvar Q, R := divmod(3.7, 1.2);%
\xinttheexpr Q, R, 1.2Q + R\relax\newline
\xintdefiivar Q, R := divmod(100, 17);%
\xinttheiiexpr Q, R, 17Q + R\relax\newline
\xintdeffloatvar Q, R := divmod(100, 17e-20);%
\xintthefloatexpr Q, R, 17e-20 * Q + R\relax\newline
% show Q exactly, although defined as float it can be used in iiexpr:
\xinttheiiexpr Q\relax\ (we see it has more than 16 digits)\par
\xintunassignvar{Q}\xintunassignvar{R}%
\end{everbatim*}
Again: |f//g| or the first item output by |divmod(f, g)| is an integer |q|
which when computed inside |\xintfloatexpr..\relax| is not yet rounded to
the prevailing float precision; the second item |f-q*g| is the rounding to
float precision of the exact mathematical value evaluated with this exact
|q|. \emph{This behaviour may change in future major release;\IMPORTANT{}
perhaps |q| will be rounded and |f-q*g| will correspond to usage of this
rounded |q|.}
As |\xintfloatexpr| rounds its global result, or rounds operands at
each arithmetic operation, it requires special circumstances to show that
the |q| is produced unrounded. Either as in the above example or this one
with comparison operators:
\begin{everbatim*}
\xintDigits := 4\relax
\xintthefloatexpr if(12345678//23==537000, 1, 0), 12345678//23\relax\newline
\xintthefloatexpr if(float(12345678//23)==537000, 1, 0)\relax\par
\xintDigits := 16\relax
\end{everbatim*}
In the first line, the comparison is done with
|floor(12350000/23)|\dtt{=\xinttheiiexpr12350000/23\relax} (notice in
passing that |12345678//23| was evaluated as |12350000//23| because the
operands are first rounded to \dtt{4} digits of floating point precision), hence the conditional
takes the "False" branch. In the second line the |float| forces rounding of
the output to \dtt{4} digits, and the conditional takes the "True" branch.
% pour mémoire, Python :
% >>> divmod(100,17e-20)
% (5.88235294117647e+20, 1.4756182441723705e-19)
% mais faudra voir avec le module Decimal
This example shows also that comparison operators in
|\xintfloatexpr..\relax| act on unrounded operands.
\funcdesc[x, y]{binomial} computes binomial coefficients.
It returns zero if |y<0| or |x99999999|.)
\begin{everbatim*}
\xinttheexpr seq(binomial(20, i), i=0..20)\relax
\end{everbatim*}
\begin{everbatim*}
\printnumber{\xintthefloatexpr seq(binomial(100, 50+i), i=-5..+5)\relax}%
\end{everbatim*}
The arguments must be (expand to) short integers.
\funcdesc[a, b]{pfactorial} computes partial factorials i.e.\@
|pfactorial(a,b)| evaluates the product |(a+1)...b|.
\begin{everbatim*}
\xinttheexpr seq(pfactorial(20, i), i=20..30)\relax
\end{everbatim*}
The arguments must (expand to) short integers. See \autoref{xintiiPFactorial}
for the behaviour if the arguments are negative.
\funcdesc[\TeX-macro, n-uple]{ndfillraw} The second argument is |[N1, N2, ...,
Nk]|. The construct fills an |N1xN2x...xNk| hyperrectangular
nested list by evaluating the given |macro| as many times as needed. The
expansion result goes directly into internal data and must thus comply with
what is expected internally for an individual numeric leaf (at |1.4|,
\xintfracname raw format worked for |\xintexpr| or |\xintfloatexpr|, but not
|\xintiiexpr|, and this may have changed since).\DNU{} This is an experimental
function serving to generate either constant or random arrays. Attention that
%
% BORDEL \textbf{\sffamily...} NON, {\bfseries\sffamily ...} NON
% LaTeX Font Warning: Font shape `T1/cmss/b/n' undefined
% (Font) using `T1/cmss/m/n' instead on input line 1826.
%
% ceci est ok {\fontseries{bx}\sffamily\TeX-macro}
% https://github.com/latex3/latex2e/issues/277
{\fontseries{bx}\sffamily \TeX-macro}
stands here for any expandable \TeX{}
\emph{macro}, and an |\xintexpr|-ession at this location thus requires an
explicit |\xinteval| wrapping.
\end{description}
\subsubsection{Functions with 3 or 4 arguments}
\begin{description}
% [parsep=0pt,align=left,
% leftmargin=0pt, itemindent=0pt,
% labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt,
% listparindent=\leftmarginiii]
\funcdesc[cond,yes,no]{if} (twofold-way conditional)\mbox{}
checks if |cond| is true or false and takes the corresponding
branch. Any non zero number or fraction is logical true. The zero
value is logical false. Both ``branches'' are evaluated (they are
not really branches but just numbers). See also the \oper{?} operator.
\funcdesc[x,yes,no]{ifint} (twofold-way conditional)\mbox{}
checks if |x| is an integer and in that case chooses the ``yes'' branch.%
See also \func{isint}.
\funcdesc[x,yes,no]{ifone} (twofold-way conditional)\mbox{}
checks if |x| is equal to one and in that case chooses the ``yes'' branch.%
Slightly more efficient than |if(x==1,..,..)|. See also \func{isone}.
\funcdesc[cond,<0,=0,>0]{ifsgn} (threefold-way conditional)\mbox{}
checks the sign of |cond| and
proceeds correspondingly. All three are evaluated. See also the \oper{??}
operator.
\end{description}
\subsubsection{Functions with an arbitrary number of arguments}
The functions \func{all}, \func{any}, \func{xor},
\func{`+`},
\func{`\lowast`},
\func{max}, \func{min}, \func{gcd}, \func{lcm}, \func{first}, \func{last},
\func{reversed} and \func{len} work both with \myenquote{open} and \myenquote{packed} lists (aka |nutples|).
Since |1.4|, when used with a single argument which is a |nutple|, it is automatically unpacked.
But from |1.4| to |1.4h| these functions could not be used with a single numeric argument: either they had at least two arguments, or only one and it had to be a |nutple|. At |1.4i| it is again possible to use them with a lone numeric argument.
In the specific case of \func{reversed} with a |nutple| argument the output is then repacked so that
the output is a |nutple| if and only if the input was one (the reversal does
not propagate to deeper nested |nutple|'s, it applies only at depth one).
\begin{description}
% [parsep=0pt,align=left,
% leftmargin=0pt, itemindent=0pt,
% labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt,
% listparindent=\leftmarginiii]
\funcdesc[stuff]{qraw} It\DNU{} injects directly tokens to represent
internally numerical data. Will break at any release modifying the internal
data format specifications (which are not always documented).
\funcdesc[x, y, ...]{all} inserts a logical |AND| in-between its arguments and evaluates the
resulting logical assertion (as with all functions, all arguments are
evaluated).
\begin{everbatim*}
\xinteval{all(1,1,1), all([1,0,1]), all([1,1,1])}
\end{everbatim*}
\funcdesc[x, y, ...]{any} inserts a logical |OR| in-between its arguments and evaluates the
resulting logical assertion,
\begin{everbatim*}
\xinteval{any(0,0,0), any([1,0,1]), any([0,0,0])}
\end{everbatim*}
\funcdesc[x, y, ...]{xor} inserts a logical |XOR| in-between its arguments and evaluates
the resulting logical assertion,
\begin{everbatim*}
\xinteval{xor(1,1,1), xor([1,0,1]), xor([1,1,1])}
\end{everbatim*}
\funcdesc[x, y, ...]{`+`} adds (left ticks mandatory):
\begin{everbatim*}
\xinttheexpr `+`(1,3,19), `+`(1**2,3**2,sqr(19)), `+`([1**2,3**2,sqr(19)])\relax
\end{everbatim*}
\funcdesc[x, y, ...]{`\lowast`} multiplies (left ticks mandatory):
\begin{everbatim*}
\xinttheexpr `*`(1,3,19), `*`(1^2,3^2,19^2), `*`([1^2,3^2,19^2])\relax
\end{everbatim*}
\funcdesc[x, y, ...]{max} maximum of the (arbitrarily many) arguments,
\begin{everbatim*}
\xinttheexpr max(1,3,19), min([1,3,19])\relax
\end{everbatim*}
\funcdesc[x, y, ...]{min} minimum of the (arbitrarily many) arguments,
\begin{everbatim*}
\xinttheexpr min(1,3,19), min([1,3,19])\relax
\end{everbatim*}
\funcdesc[x, y, ...]{gcd} computes the positive generator of the fractional
ideal of rational numbers $x\mathbb Z + y\mathbb Z + ... \subset \mathbb
Q$. Since |1.4d| the output is always in lowest terms.
This example shows how to reduce an n-uple to its primitive part:
\begin{everbatim*}
\xinteval{gcd(7/300, 11/150, 13/60)}\newline
$(7/300, 11/150, 13/60)\to
(\xinteval{subsn(seq(reduce(x/D), x = L), D=gcd(L); L=7/300, 11/150, 13/60)})$\newline
\xintexpr gcd([7/300, 11/150, 13/60])\relax\par
\end{everbatim*}
MEMO
Perhaps a future release will provide a |primpart()| function as built-in
functionality.
In case of strict integers, using a |\xintiiexpr...\relax| wrapper is
advantageous as the integer-only |gcd()| is more efficient.
%
% ceci semble encore à peu près exact à 1.4d :
% (about |6X|) than the one accepting general fractional inputs.
%
As \csbxint{iiexpr} accepts only strict integers, doing this may require
wrapping the argument in \func{num}.
\funcdesc[x, y, ...]{lcm} computes the positive generator of the
fractional ideal of rational numbers $x\mathbb Z \cap y\mathbb Z \cap ...
\subset \mathbb Q$.
\begin{everbatim*}
\xinttheexpr lcm([7/300, 11/150, 13/60])\relax
\end{everbatim*}
As for \func{gcd}, since |1.4d| the output is always in lowest terms.
% Memo 1.4d: This
% function got (I did not tests extensively) a |4X| speed gain for inputs being
% only integers
For strict integers it is slightly advantageous to use a sub
\csbxint{iiexpr}-ession.
%
% je disais à 1.4:
% (about |9X|) than the one accepting general fractional inputs.
% mais à 1.4d c'est seulement 2X : le lcm pour les fractions
% a quadruplé sa vitesse !
%
\funcdesc[x, y, ...]{first} first item of the list or nutple argument:
\begin{everbatim*}
\xintiiexpr first([last(-7..3), [58, 97..105]])\relax
\end{everbatim*}
\funcdesc[x, y, ...]{last} last item of the list or nutple argument:
\begin{everbatim*}
\xintiiexpr last([-7..3, 58, first(97..105)])\relax
\end{everbatim*}
\funcdesc[x, y, ...]{reversed} reverses the order of the comma separated list
or inside a nutple:
\begin{everbatim*}
\xintiieval{reversed(reversed(1..5), reversed([1..5]))}
\end{everbatim*}
The above is correct as \xintexprname functions may produce oples and this is
the case here.
\funcdesc[x, y, ...]{len} computes the number of items in a comma separated
list or inside a nutple (at first level only: it is not a counter of leaves).
\begin{everbatim*}
\xinttheiiexpr len(37.5), len(1..50, [101..150], 1001..1050), len([1..10])\relax
\end{everbatim*}
\funcdesc[\lowast nutples]{zip} behaves similarly to
the Python function of the same name: i.e. it produces \emph{an ople of nutples,
where the i-th nutple contains the i-th element from each of the argument
nutples. The ople ends when the shortest input nutple is exhausted.
With a single nutple argument, it returns an ople of 1-nutples.
With no arguments, it returns the empty ople.}
As there is no exact match in \xintexprname of the concept of \myenquote{iterator} object,%
%
\footnote{%
Speaking of iterators, I have some ideas about this: as \csbxint{expr} does not
have the global expression in its hands it is difficult to organize globally
expandably the idea of iterator, but locally via syntax like the one for
\func{seq} this is feasible. When one thinks about it, \func{seq} is closely related
to the iterator idea.}
%
there is a significant difference here that (for example) the |zip(x,x,x)|
Python idiom to cluster the iterator |x| into successive chunks of length 3
does not apply. Consider for this reason even the name of the function as
work-in-progress, susceptible to change.\unstable{}
\begin{everbatim*}
\xintiieval{zip([1..9], [0, 1, 2], [11..29], [111..139])}
\end{everbatim*}
See also \csbxint{thespaceseparated} for some possible usage in combination with \func{flat}.
\end{description}
\subsubsection{Functions requiring dummy variables}
\hypertarget{ssec:dummies}{}
The pseudo-functions \xintFor #1 in {subs, seq, subsm, subsn, iter, add, mul,
rseq, iterr, rrseq, iterr, ndseq, ndmap, ndfillraw} \do
{\func{#1}\xintifForLast{}{, }} use delimited macros for some tasks:
\begin{itemize}
\item for all of them, whenever a |=| chunk must be parsed into a
(non-assigned) variable name, then the equal sign must be visible,
\item and if the syntax is with |,=| the initial comma also must be
visible (spaces do not matter),
\item for all of them but \func{ndmap} and \func{ndfillraw} the final closing
parenthesis must be visible.
\end{itemize}
Although delimited macros involving commas are used to locate |,=| part
may also be created from the expansion which will generate the initial comma
separated values delimited by a semi-colon.
Prior to |1.4|, semi-colons needed to be braced or otherwise hidden when
located in an expression parsed by \csbxint{defvar} or
\csbxint{deffunc}, to not be confused with the expression
terminator.
\func{seq}, \func{rseq}, \func{iter}, \func{rrseq},
\func{iterr} and also \func{add}, \func{mul}, but not \func{subs} admit the
\keyword{omit}, \keyword{abort}, and \func{break} keywords. This is a
new feature at |1.4| for \func{add} and \func{mul}.
In the case
of a potentially infinite list generated by the |++| syntax, use of
\keyword{abort} or of \func{break} is mandatory, naturally.
All lowercase and uppercase Latin letters are pre-configured for usage as
dummy variables. In Unicode engines one can use \csbxint{newdummy} to turn any
letter into a usable dummy variable.
And since |1.4|, \csbxint{newdummy} works (in all engines) to
turn a multi-letter word into a dummy variable. In the descriptions,
|varname| stands for such a dummy variable, either single-letter or word.
\begin{description}
% [parsep=0pt,align=left,
% leftmargin=0pt, itemindent=0pt,
% labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt,
% listparindent=\leftmarginiii]
\funcdesc[expr, varname=comma separated values]{subs} for variable substitution.
\begin{everbatim*}
\xinttheexpr subs(subs(seq(x*z,x=1..10),z=y^2),y=10)\relax\newline
\end{everbatim*}%
Attention that |xz| generates an error, one must use explicitely |x*z|, else
the parser expects a variable with name |xz|.
\func{subs} is useful when defining macros for which some argument will be
used more than once but may itself be a complicated expression or macro, and
should be evaluated only once, for matters of efficiency. But \func{subs} is
helpless in function definitions: all places where a variable is substituted
will receive the complete recipe to compute the variable, rather than evaluate
only once.
One should rather define auxiliary functions to compute intermediate
results. Or one can use \func{seq}. See the documentation of
\csbxint{deffunc}.
\funcdesc[expr, varname=comma separated values]{add} addition
\begin{everbatim*}
\xintiiexpr add(x^3,x=1..20), add(x(x+1), x=1,3,19)\relax\newline
\xintiiexpr add(x^3, x = 1..[2]..20)\relax\newline % add only odd cubes
\xintiiexpr add((odd(x))?{x^3}{omit}, x = 1..20)\relax\par % add only odd cubes
\end{everbatim*}
At |1.4| (fixed at |1.4a|), the keywords \keyword{omit} (as in
example above), \keyword{abort} and \func{break} are allowed.
The meaning of \func{break} is specific: its argument serves as last
operand for the addition, not as ultimate value.
\begin{everbatim*}
\xintiiexpr add((x>10)?{break(1000)}{x}, x = 1..15)\relax
\end{everbatim*}
The |@| special variable holds the so-far accumulated value. Initially its
value is zero.
\begin{everbatim*}
\xintiiexpr add(1 + @, i=1..10)\relax % iterates x <- 2x+1
\end{everbatim*}
See \func{`+`} for syntax simply adding items of a
list without usage of a dummy variable.
\funcdesc[expr, varname=comma separated values]{mul} multiplication
\begin{everbatim*}
\xintiiexpr mul(x^2, x = 1, 3, 19, 37..50)\relax
\end{everbatim*}
The |@| special variable holds the so-far accumulated value. Initially its
value is one.
At |1.4| (fixed at |1.4a|), the keywords \keyword{omit},
\keyword{abort} and \func{break} are allowed. The meaning of \func{break} is
specific: its argument serves as last operand for the multiplication, not as
ultimate value.
\begin{everbatim*}
\xintiieval{mul((i==100)?{break(i^4)}{i}, i = 98, 99, 100)}
\end{everbatim*}
See \func{`\lowast`} for syntax without a dummy variable.
\funcdesc[expr, varname=comma separated valuesvalues]{seq} comma separated values generated according to a formula
\begin{everbatim*}
\xintiiexpr seq(x(x+1)(x+2)(x+3),x=1..10), `*`(seq(3x+2,x=1..10))\relax
\end{everbatim*}
\begin{everbatim*}
\smallskip
\leavevmode\vbox{\xintthealign\xintiiexpr [seq([seq(i^2+j^2, i=0..j)], j=0..10)]\relax}
\end{everbatim*}
\funcdesc[initial value; expr, varname=comma separated values]{rseq} recursive sequence, |@| for the previous value.
\begin{everbatim*}
\printnumber {\xintthefloatexpr subs(rseq (1; @/2+y/2@, i=1..10),y=1000)\relax }\newline
\end{everbatim*}%
Attention: in the example above |y/2@| is interpreted as
|y/(2*@)|.\IMPORTANT{} With versions |1.2c| or earlier it would have been
interpreted as |(y/2)*@|.
In case the initial stretch is a comma separated list, |@| refers at the first
iteration to the whole list. Use parentheses at each iteration to maintain
this ``nuple''. For example:
\begin{everbatim*}
\printnumber{\xintthefloatexpr rseq(1,10^6;
(sqrt(@[0]*@[1]),(@[0]+@[1])/2), i=1..7)\relax }
\end{everbatim*}
Prior to |1.4| the above example had to be written with |[@]|. This is still
possible (|@| stands for an ople with two items, bracketing then extracting is
like extracting directly), but it is leaner to drop the extra \myenquote{packing}.
\funcdesc[initial value; expr, varname=comma separated values]{iter} is exactly like |rseq|, except that it only prints
the last iteration.
\hypertarget{BrentSalamin}{}
|iter()| is convenient to handle compactly higher order iterations.
We can illustrate its use with an expandable (!)
implementation of the Brent-Salamin algorithm for the computation of $\pi$:
\begin{everbatim*}
\xintDigits:= 87\relax % we target 84 digits, and use 3 guard digits
\xintdeffloatfunc BS(a, b, t, p):= 0.5*(a+b), sqrt(a*b), t-p*sqr(a-b),
\xintiiexpr 2p\relax;
\xinteval
{trunc(% I feel truncation is better than rounding to display decimals of π
\xintfloatexpr
iter(1, sqrt(0.5), 1, 1; % initial values
% this 43 is 84/2 + 1
(@[0]-@[1]<2e-43)?% stopping criteria; takes into account that the
% exit computation (break() argument) doubles
% number of exact digits (roughly)
{break(sqr(@[0]+@[1])/@[2])} % ... do final computation,
{BS(@)}, % else do iteration
i=1++) % This generates infinite iteration. The i is not used.
\relax
% this 83 is 84 - 1 (there is a digit known to be 3 actually, before decimal mark)
, 83)% closing parenthesis of trunc()
}...% some dots following end of \xinteval argument
\xintDigits:=16\relax
\end{everbatim*}\newline
You can try with |\xintDigits:=1004\relax| and |2e-501| in place of
|\xintDigits:=87\relax| and |2e-43|, but be patient for some seconds
for the result. Of course don't truncate the final
result to only \dtt{83} fractional decimal digits but \dtt{1000}...\@
and better to wrap the whole thing in |\message| or
|\immediate\write128| or |\edef| because it will then run in the right margin.
Prior to |1.4| the above example had to use notation such as |[@][0]|; this
would still work but |@[0]| is leaner.
\funcdesc[initial values; expr, varname=comma separated values]{rrseq} recursive sequence with multiple initial terms. Say, there are
|K| of them. Then |@1|, ..., |@4| and then |@@(n)| up to |n=K| refer to the
last |K| values. Notice the difference with |rseq()| for which |@| refers to
a list of items in case the initial value is a list and not a single item.%
%
\footnote{Prior to |1.4|, one could use |@| in |rrseq()| and |iterr()| as an
alias to |@1|. This undocumented feature is dropped and |@| will break |rrseq()| and |iterr()|.}
%
Using |rrseq()| with |@1| etc...\@{} accessors may be perhaps a bit
more efficient than using |rseq()| with a list as staring value and
constructs such as |@[0]|, |@[1]| (or rather |@[-1]|, |@[-2]| to
mimick what |@1|, |@2|, |@3|, |@4| and |@@(integer)| do in |rrseq()|.
\begin{everbatim*}
\xinttheiiexpr rrseq(0,1; @1+@2, i=2..30)\relax
\end{everbatim*}
\begin{everbatim*}
\xinttheiiexpr rseq(1; 2@, i=1..10)\relax
\end{everbatim*}
\begin{everbatim*}
\xinttheiiexpr rseq(1; 2@+1, i=1..10)\relax
\end{everbatim*}
\begin{everbatim*}
\xinttheiiexpr rseq(2; @(@+1)/2, i=1..5)\relax
\end{everbatim*}
\begin{everbatim*}
\xinttheiiexpr rrseq(0,1,2,3,4,5; @1+@2+@3+@4+@@(5)+@@(6), i=1..20)\relax
\end{everbatim*}
I implemented an |Rseq| which at all times keeps the memory of \emph{all}
previous items, but decided to drop it as the package was becoming big.
\funcdesc[initial values; expr, varname=comma separated values]{iterr} same as |rrseq| but does not print any value until the last |K|.
\begin{everbatim*}
\xinttheiiexpr iterr(0,1; @1+@2, i=2..5, 6..10)\relax
% the iterated over list is allowed to have disjoint defining parts.
\end{everbatim*}
\funcdesc[expr, var1=value1; var2=value2; ....; varN=valueN{[;]}]{subsm}
Simultaneous
substitutions. The assigned values must not involve the
variables. An optional final
semi-colon is allowed.
\begin{everbatim*}
\xintiieval{subsm(x+2y+3z+4t, x=1; y=10; z=100; t=1000;)}
\end{everbatim*}
\funcdesc[expr, var1=value1; var2=value2; ....; varN=valueN{[;]}]{subsn}
Simultaneous
substitutions. The assigned values may involve all variables
located further to its right. An optional final
semi-colon is allowed.
\begin{everbatim*}
\xintiieval{subsn(x+y+z+t, x=20y; y=20z; z=20t; t=1)}
\end{everbatim*}
\funcdesc[function, values1; values2; ....; valuesN{[;]}]{ndmap}
%
Construction of a nested list (a priori having |N| dimensions) from function
values. The function must be an |N|-variable function (or a function accepting
arbitrarily many arguments), but it is not constrained to produce only scalar
values. Only in the latter case is the output really an |N|-dimensional
\myenquote{|ndlist|} type object. An optional final semi-colon in the input before the
closing parenthesis is
allowed.
\begin{everbatim*}
\xintdeffunc foo(a,b,c,d) = a+b+c+d;
\begin{multicols}{2}
\xintthealign\xintexpr ndmap(foo, 1000,2000,3000; 100,200,300; 10,20,30; 1,2,3)\relax
\end{multicols}
\end{everbatim*}
\funcdesc[expr, var1=values1; var2=values2; ....; varN = valuesN{[;]}]{ndseq}
%
Constructs a nested list (a priori having |N| dimensions) from
substitutions in an expression involving |N| (dummy) variables. The
expression is not constrained to produce only scalar values. Only in the
latter case is the output really an |N|-dimensional \myenquote{|ndlist|} type object.
An optional final semi-colon in the input before the closing parenthesis is
allowed.
\begin{everbatim*}
\begin{multicols}{2}
\xintthealign\xintexpr ndseq(a+b+c+d, a=1000,2000,3000; b=100,200,300;
c=10,20,30; d=1,2,3;)\relax
\end{multicols}% in case of page break, this makes amusing zigzag rendering
\end{everbatim*}
\end{description}
Recursions may be nested, with |@@@(n)| giving access to the values of the
outer recursion\dots and there is even |@@@@(n)| to access the outer outer
recursion but I never tried it!
The following keywords are recognized:
\begin{description}
\keyworddesc{abort} it is a pseudo-variable which indicates to stop here and now.
\keyworddesc{omit} it is a pseudo-variable which says to omit this value and
go to next one.
\funcdesc[stuff]{break} says to abort and insert |stuff| as last value.
\keyworddesc{++} serves to generate a potentially infinite list. In
conjunction with an \keyword{abort} or \func{break} this is often
more efficient than iterating over a pre-established list of values.
\begin{everbatim*}
\xinttheiiexpr iter(1;(@>10^40)?{break(@)}{2@},i=1++)\relax
\end{everbatim*}
is the smallest power of 2 with at least fourty one digits.
The |i=++| syntax (any letter is allowed in place of |i|) works only
in the form |=++|, something like |x=10,17,30++| is not
legal. The || must be a \TeX-allowable integer.
\begin{everbatim*}
First Fibonacci number at least |2^31| and its index
% we use iterr to refer via @1 and @2 to the previous and previous to previous.
\xinttheiiexpr iterr(0,1; (@1>=2^31)?{break(@1, i)}{@2+@1}, i=1++)\relax
\end{everbatim*}%
. If one also wants the previous Fibonacci number one only has to use |break(@2,
@1, i)| in the above example.
\end{description}
\subsection{Generators of arithmetic progressions}
\label{ssec:arithseq}
\begin{itemize}
\item |a..b| constructs the \textbf{small} integers from the ceil $\lceil
a\rceil$ to the floor
$\lfloor b\rfloor$ (possibly a decreasing sequence): one has to be careful
if using this for algorithms that |1..0| for example is not empty or |1|
but expands to |1, 0|. Again, |a..b| \emph{can not} be used with |a| and
|b| greater than $2^{31}-1$. Also, only about at most \dtt{5000} integers
can be generated (this depends upon some \TeX{} memory settings).
The |..| has lower precedence than the arithmetic operations.
\begin{everbatim*}
\xintexpr 1.5+0.4..2.3+1.1\relax; \xintexpr 1.9..3.4\relax; \xintexpr 2..3\relax
\end{everbatim*}
The step of replacing $a$ by its ceil and $b$ by its floor is a kind of
silly overhead, but $a$ and $b$ are allowed to be themselves the result
of computations and there is no notion of \myenquote{int} type in \csbxint{eval}.
The solution is, when $a$ and $b$ are given explicit integers to
temporarily switch to the \csbxint{iiexpr} parser:
\begin{everbatim*}
\xintexpr \xintiiexpr 1..10\relax\relax
\end{everbatim*}
On the other hand integers from |\xintexpr 1..10\relax| are already in
raw \xintfracname format for example |3/1[0]| which speeds up their usage
in the macros internally involved in computations...\@{} thus perhaps what one
gains on one side is lost on the other side.
\item |a..[d]..b| generates \myenquote{real} numbers along arithmetic progression
of reason |d|. It does
\emph{not} replace |a| by its ceil, nor |b| by its floor. The generated
list is empty if |b-a| and |d| are of opposite signs; if |d=0| or if |a=b|
the list expands to single element |a|.
\begin{everbatim*}
\xintexpr 1.5..[1.01]..11.23\relax
\end{everbatim*}
At |1.4|, this generator behaves in \csbxint{floatexpr} exactly as in
\csbxint{expr}, i.e.\@{} \emph{exactly}. This is breaking
change.
\begin{everbatim*}
\xintDigits:=6;
\xintexpr\xintfloatexpr 100..[1.23456]..110\relax\relax
\xintDigits:=16;
\end{everbatim*}
This demonstration embedded the float expression in the exact parser only
to avoid the rounding to the prevailing precision on output, thus we can
see that internally additions are done exactly and not with
\dtt{6} digits mantissas (in this example).
\end{itemize}
\subsection{Python slicing and indexing of one-di\-men\-sional sequences}
\label{ssec:lists}
We denote here by \emph{list} or \emph{sequence} a general \emph{ople}, either
given as a variable or explicitly. \emph{In the former case the parentheses are
optional}.%
%
\footnote{Even for an \myenquote{open list}, if it is given as a \emph{variable} then the indexing or slicing will not apply to its last item but to itself as an entity.}
\begin{itemize}
\item |(list)[n]| returns the |n+1|th item if |n>=0|. If |n<0| it enumerates
items from the tail. Items are numbered as in Python, the
first element corresponding to |n=0|.
\begin{everbatim*}
\xintexpr (0..10)[6], (0..10)[-1], (0..10)[23*18-22*19]\relax
\end{everbatim*}
This also works for singleton \emph{oples} which are in fact a \emph{number}:
\begin{everbatim*}
\xintexpr (7)[0], (7)[-1], 9, (7)[-2], 9\relax
\end{everbatim*}
In the example above the parentheses serve to disambiguate from the raw
\xintfracname format such as |7[-1]| which, although discouraged, is accepted
on input. And we used a trick to show that |(7)[-2]| returns |nil|.
The behaviour changes for singleton \emph{oples} which are not
\emph{numbers}. They are thus \emph{nutples}, or equivalently they are the
bracketing (bracing, packing) of another \emph{ople}. In this case, the meaning
of the syntax for item indexing is, as in Python, item
\emph{extraction}:
\begin{everbatim*}
\xintexpr [0,1,2,3,4,5][2], [0,1,2,3,4,5][-3]\relax\newline
\xintexpr [0,[1,2,3,4,5],6][1][-1]\relax
\end{everbatim*}
\item |(list)[:n]| produces the first |n| elements if |n>0|, or suppresses
the last \verb+|n|+ elements if |n<0|.
\begin{everbatim*}
\xintiiexpr (0..10)[:6]\relax\ and \xintiiexpr (0..10)[:-6]\relax
\end{everbatim*}
As above, the meaning change for \emph{nutples} and fits with expectations
from Python regarding its sequence types:
\begin{everbatim*}
\xintiiexpr [0..10][:6]\relax\ and \xintiiexpr [0..10][:-6]\relax
\end{everbatim*}
\item |(list)[n:]| suppresses the first |n| elements if |n>0|, or extracts
the last \verb+|n|+ elements if |n<0|.
\begin{everbatim*}
\xintiiexpr (0..10)[6:]\relax\ and \xintiiexpr (0..10)[-6:]\relax
\end{everbatim*}
As above, the meaning change for \emph{nutples} and fit with expectations
from Python with \emph{tuple} or \emph{list} types:
\begin{everbatim*}
\xintiiexpr [0..10][6:]\relax\ and \xintiiexpr [0..10][-6:]\relax
\end{everbatim*}
\item Finally, |(list)[a:b]| also works according to the Python ``slicing''
rules (inclusive of negative indices). Notice though that stepping is
currently not supported.
\begin{everbatim*}
\xinttheiiexpr (1..20)[6:13]\relax\ = \xinttheiiexpr (1..20)[6-20:13-20]\relax
\newline
\xinttheiiexpr [1..20][6:13]\relax\ = \xinttheiiexpr [1..20][6-20:13-20]\relax
\end{everbatim*}
\item It is naturally possible to execute such slicing operations one after
the other (the syntax is simplified compared to before |1.4|):
\begin{everbatim*}
\xintexpr (1..50)[13:37][10:-10]\relax\newline
\xintexpr (1..50)[13:37][10:-10][-1]\relax
\end{everbatim*}
\end{itemize}
\subsection{NumPy like nested slicing and indexing for arbitrary oples and nutples}
I will give one illustrative example and refer to the NumPy documentation for
more.
Notice though that our interpretation of the syntax is more general than
NumPy's concepts (of basic slicing/indexing):
\begin{itemize}
\item slicing and itemizing apply also to non-bracketed objects i.e.\@{} \emph{oples},
\item the leaves do not have to be all at the same depth,
\item there are never any out-of-range index errors: out-of-range indices
are silently ignored.
\end{itemize}
\begin{everbatim*}
\begin{multicols}{3}
\xintdefvar myArray = ndseq(a+b+c, a=100,200,300; b=40,50,60; c=7,8,9);
myArray = \xintthealign\xintexpr myArray\relax
\columnbreak
mySubArray = \xintthealign\xintexpr myArray[0:2,0:2,0:2]\relax
myExtractedSubArray = \xintthealign\xintexpr myArray[0:2,0:2,0:2][0]\relax
\columnbreak
myExtractedSubArray = \xintthealign\xintexpr myArray[0:2,0:2,0:2][0,1]\relax
\noindent
firstExtractedScalar = \xintexpr myArray[0:2,0:2,0:2][0,1,0]\relax\newline
secondExtractedScalar = \xintexpr myArray[0,1,0]\relax\par
\end{multicols}
\end{everbatim*}
As said before, \emph{stepping} is not yet implemented. Also the NumPy
extension to Python for item selection (i.e.\@{} via a |tuple| of comma separated
indices) is not yet implemented.
\subsection{Tacit multiplication}
\label{ssec:tacit multiplication}
Tacit multiplication (insertion of a |*|) applies when the parser is currently
either scanning the digits of a number (or its decimal part or scientific
part, or hexadecimal input), or is looking for an infix operator, and:
\begin{enumerate}[nosep, label=(\arabic*.)]
\item \relax\emph{encounters a count or dimen or skip register or variable or an
\eTeX{} expression,} or
\item \emph{encounters a sub-\csa{xintexpr}ession}, or
\item \emph{encounters an opening parenthesis}, or
\item \emph{encounters a
letter (which is interpreted as signaling the start of either a variable or
a function name)}, or
\item (of course, only when in state "looking for an operator") \emph{encounters a digit}.
\end{enumerate}
\begin{framed}
\centeredline{\textcolor{Red}{\textbf{!!!!ATTENTION!!!!}}}
Explicit digits prefixing a variable, or a function, whose name starts with
an |e| or |E| will trap the parser into trying to build a number in
scientific notation. So the |*| must be explicitly inserted.
\begin{everbatim}
\xintdefiivar e := (2a+4b+6d+N)/:7;%
\xintdefiivar f := (c+11d+22*e)//451;% 22e would raise errors
\end{everbatim}
I don't think I will fix this anytime soon...
\end{framed}
\begin{framed}
For example, if |x, y, z| are variables all three of |(x+y)z|, |x(y+z)|,
|(x+y)(x+z)| will create a tacit multiplication.
Furthermore starting with release
|1.2e|, %\MyMarginNote[\kern\dimexpr\FrameSep+\FrameRule\relax]{Changed}
whenever tacit multiplication is applied, in all cases it \emph{always}
``ties'' more\IMPORTANT{} than normal multiplication or division, but
still less than power. Thus |x/2y| is interpreted as |x/(2y)| and
similarly for |x/2max(3,5)| but |x^2y| is still interpreted as |(x^2)*y|
and |2n!| as |2*n!|.
\begin{everbatim*}
\xintdefvar x:=30;\xintdefvar y:=5;%
\xinttheexpr (x+y)x, x/2y, x^2y, x!, 2x!, x/2max(x,y)\relax
\end{everbatim*}
Since |1.2q| tacit multiplication is triggered also in cases such as
|(1+2)5| or |10!20!30!|.
\begin{everbatim*}
\xinttheexpr (10+7)5, 4!4!, add(i, i=1..10)10, max(x, y)100\relax
\end{everbatim*}
The ``tie more'' rule applies to all cases of tacit multiplication. It
impacts only situations with a division operator as the last seen
operator, as multiplication is mathematically associative.
\begin{everbatim*}
\xinttheexpr 1/(3)5, (1+2)/(3+4)(5+6), 2/x(10), 2/10x,
3/y\xintiiexpr 5+6\relax, 1/x(y)\relax\
differ from\newline\xinttheexpr 1/3*5, (1+2)/(3+4)*(5+6), 2/x*(10), 2/10*x,
3/y*\xintiiexpr 5+6\relax, 1/x*(y)\relax\par
\end{everbatim*}
\end{framed}
Note that |y|\csbxint{theiiexpr}| 5+6\relax| would have tried to use a variable
with name |y11| rather than doing |y*11|: tacit multiplication works only
in front of sub-\csbxint{expr}essions, not in front of
\csbxint{theexpr}essions which are unlocked into explicit digits.
Here is an expression whose meaning is
completely modified by the ``tie more'' property of tacit multiplication:
\begin{everbatim}
\xintdeffunc e(z):=1+z(1+z/2(1+z/3(1+z/4)));
\end{everbatim}
will be parsed as
\begin{everbatim}
\xintdeffunc e(z):=1+z*(1+z/(2*(1+z/(3*(1+z/4)))));
\end{everbatim}
which is not at all the presumably hoped for:
\begin{everbatim}
\xintdeffunc e(z):=1+z*(1+(z/2)*(1+(z/3)*(1+(z/4))));
\end{everbatim}
% This case can be handled this way:
% \begin{everbatim}
% \xintdeffunc e(z):=(((z/4+1)z/3+1)z/2+1)z+1;
% \end{everbatim}
\subsection{User defined variables}
\label{ssec:uservariables}
\label{xintdefvar}
\label{xintdefiivar}
\label{xintdeffloatvar}
Since release |1.1| it is possible to make an assignment to a variable name
and let it be known to the parsers of \xintexprname. Since |1.2p| simultaneous
assignments are possible. Since |1.4| simultaneous assignments are possible with
a right-hand-side being a \texttt{nutple} which will be automatically unpacked.
\begin{everbatim*}
\xintdefvar myPi:=3.141592653589793238462643;%
$myPi = \xinteval{myPi}$\newline % (there is already built-in Pi variable)
\xintdefvar x_1, x_2, x_3 := 10, 20, 30;%
$x_1 = \xinteval{x_1}, x_2 = \xinteval{x_2}, x_3 = \xinteval{x_3}$\newline
\xintdefvar x_1, x_2, x_3 := [100, 200, 300];%
$x_1 = \xinteval{x_1}, x_2 = \xinteval{x_2}, x_3 = \xinteval{x_3}$\par
\end{everbatim*}
Simultaneous assignments with more variables than values do not
raise an error but simply set the extra variables to the \dtt{nil} value.
\begin{everbatim*}
\xintdefiivar a, b, c := [1, 2];% will be automatically unpacked
The value of a is \xinteval{a}, the one of b is \xinteval{b} and
the one of c is \xinteval{c}.
\end{everbatim*}
\begin{everbatim*}
\xintdefiivar a, b, c := 314;%
The value of a is \xinteval{a}, the one of b is \xinteval{b} and
the one of c is \xinteval{c}.
\end{everbatim*}
Notice that \dtt{nil} variables must be used with caution as they break
arithmetic operations if used as operands to them. And they are not the same
as the \dtt{None} variables, which can also be input as |[]|.
Simultaneous assignments with less variables than values do not
raise an error but set the last variable to be the ople concatenating the
remaining values.
\begin{everbatim*}
\xintdefiivar seq := 1..10;%
\xintdefiivar a, seq := seq;%
\xintdefiivar b, seq := seq;%
\xintdefiivar c, d, seq := seq;%
The value of a is \xinteval{a}, the one of b is \xinteval{b}, the one of c is \xinteval{c},
the one of d is \xinteval{d}, the one of seq is \xinteval{seq}.
\end{everbatim*}
In the above we define a variable |seq| but there is a built-in
function \func{seq}. It is indeed allowed to use the same name for both a
variable and a function.%
%
\footnote{But until a bugfix added at release |1.4i|, some built-in function
names (those implementing syntax with dummy variables, and the so-called
\myenquote{pseudo}-functions) were fragile under such overloading.}
But for safety we will unassign |seq| now:
\begin{everbatim*}
\xintunassignvar{a}\xintunassignvar{b}\xintunassignvar{c}\xintunassignvar{d}%
\xintunassignvar{seq}%
\end{everbatim*}%
Single letter names |a..z| and |A..Z| are pre-declared by the package for use
as a special type of variables called ``dummy variables''. Unnassigning them
restores this initial meaning. See further \csbxint{unassignvar} and
\csbxint{newdummy}. Since |1.4| even assigned variables can be used in the
call signatures of function declarations.
Regarding the manipulation of an \myenquote{open list} as above, there is no way
to obtain with only one use of the variable both its last item and the
reduction of the variable to its truncated self. One can do rather:
\begin{everbatim*}
\xintdefiivar mylist := 1..10;%
\xintdefiivar z, mylist := last(mylist), mylist[:-1];%
The value of z is \xinteval{z} and mylist is now \xinteval{mylist}.\par
\end{everbatim*}
This uses twice |mylist| and is about the same as doing it in two steps:
\begin{everbatim*}
\xintdefiivar w := last(mylist);%
\xintdefiivar mylist := mylist[:-1];%
The value of w is \xinteval{w} and mylist is now \xinteval{mylist}.%
\xintunassignvar{z}\xintunassignvar{w}\xintunassignvar{mylist}\par
\end{everbatim*}
It is recommended generally speaking to work with \myenquote{closed (i.e. bracketed)
lists} because only them and numbers can be arguments to functions (but see
\csbxint{deffunc} and the notion of variadic last argument). For more on the
Python-like slicing used above see \autoref{ssec:lists} and
\autoref{sssec:opleslicing}. For more information relative to variables
versus arguments see \autoref{sssec:funcargs}.
\begin{itemize}[noitemsep]
\item For catcodes issues (particularly, for the semi-colon used to delimit
the fetched expression), see the discussion of \csbxint{exprSafeCatcodes} and some comments in the section documenting \csbxint{deffunc}.
\item
Both syntaxes |\xintdefvar foo := ;| and |\xintdefvar foo = ;|
are accepted.
\item
Spaces in the variable name or around the equal sign are removed and are
immaterial.
\item
The variable names are expanded in an |\edef| (and stripped of spaces).
Example:
\begin{everbatim}
\xintdefvar x\xintListWithSep{, x}{\xintSeq{0}{10}} := seq(2**i, i = 0..10);%
\end{everbatim}
This defines |x0|, |x1|, \dots, |x10| for future usage.
\end{itemize}
Legal variable names are composed of letters, digits, |_| and |@| and
characters. A variable name must start with a letter. Variable names starting
with a |@| or |_| are reserved for internal usage.%
%
\footnote{The process of variable declaration does not check that these rules
are met, and breakage will arise on use, if rules are not followed. For
example, prior to |1.4g|, using a variable (illegally)
declared with a name starting with a (normal, catcode 8) |_| triggered an
infinite loop.}
As |x_1x_2| or even |x_1x| are licit variable names, and as the parser does
not trace back its steps, input syntax must be |x_1*x_2| if the aim is to
multiply such variables.
Using \csa{xintdefvar}, \csa{xintdefiivar}, or \csa{xintdeffloatvar} means
that the variable value will be computed using respectively \csa{xintexpr},
\csa{xintiiexpr} or \csa{xintfloatexpr}. It can then be used in all three
parsers, as long as the parser understands the format. Currently this means
that variables using \csa{xintdefvar} or \csa{xintdeffloatvar} can be used
freely either with \csa{xintexpr} or \csa{xintfloatexpr} but not with
\csa{xintiiexpr}, and variables defined via \csa{xintdefiivar} can be used in
all parsers.
When defining a variable with \csa{xintdeffloatvar} it (or
generally speaking its numerical leaves) is rounded to \csbxint{theDigits}
precision. So the variable holds the same value as would be printed via
\csbxint{floateval} for the same computation.
Prior to |1.4e|, this was the case only if the variable definition actually
involved some computation.
However the \csbxint{floatexpr}|..\relax| wrapper by itself induces no rounding. If
it is encountered in the typesetting flow, the print-out will be rounded to
\csbxint{theDigits} precision, but this is an effet of behaving like
\csbxint{floateval} in this context.
\begin{everbatim*}
% Since 1.4e, \xintdeffloatvar always rounds (to \xinttheDigits)
\xintdeffloatvar e:=2.7182818284590452353602874713526624977572470936999595749669676;%
1) \xintexpr e\relax\newline % shows the recorded value: it is rounded
2) \xintfloatexpr % when used in typesetting flow, acts like \xintfloateval:
2.7182818284590452353602874713526624977572470936999595749669676
\relax\newline % the print-out is rounded.
3) \xintexpr
\xintfloatexpr
2.7182818284590452353602874713526624977572470936999595749669676
\relax
\relax\newline
%
% but we can see via the \xintexpr wrapper all the digits were there rounding
% can be forced using an extra 0+, the float() function, or the [D] option.
% tidbit: comparison operators do not pre-round, so 1.2345678 is not same as
% (1.2345678+0) in low precision.
%
\begingroup\xintDigits:=4;%
4) \xintifboolfloatexpr{1.2345 == 1.23456}
{\error}{Different! Comparisons do not pre-round to Digits precision.}\newline
5) \xintifboolfloatexpr{1.2345 == 1.2345 + 0}
{\error}{Different! Right hand side rounded from operation,
left hand side not rounded.}\par
\endgroup
\end{everbatim*}
% not so exciting example
% In the next examples we examine the effect of cumulated float operations on
% rounding errors:
% \begin{everbatim*}
% \xintdefvar e_1:=add(1/i!, i=0..10);% exact sum
% \xintdeffloatvar e_2:=add(1/i!, i=0..10);% float sum
% \xintthefloatexpr e_1, e_2\relax\newline
% \xintdefvar e_3:=e_1+add(1/i!, i=11..20);% exact sum
% \xintdeffloatvar e_4:=e_2+add(1/i!, i=11..20);% float sum
% \xintthefloatexpr e_3, e_4\relax\newline
% \xintdeffloatvar e:=2.7182818284590452353602874713526624977572470936999595749669676;%
% \xintDigits:=24\relax
% \xintthefloatexpr[16] e, e^1000, e^1000000\relax (e rounded to 24 digits first)\newline
% \xintDigits:=16\relax
% \xintthefloatexpr e, e^1000, e^1000000\relax (e rounded to 16 digits first)\par
% \end{everbatim*}
After issuing \csbxint{verbosetrue} the values of defined variables are
written out to the log (and terminal). As in this example:
\begin{everbatim}
Package xintexpr Info: (on line 1)
Variable myPi defined with value {3141592653589793238462643[-24]}.
Package xintexpr Info: (on line 2)
Variable x_1 defined with value {10}.
Package xintexpr Info: (on line 2)
Variable x_2 defined with value {20}.
Package xintexpr Info: (on line 2)
Variable x_3 defined with value {30}.
Package xintexpr Info: (on line 3)
Variable List defined with value {0}{1}{3}{6}{10}{15}{21}{28}{36}{45}{55}
.
Package xintexpr Info: (on line 4)
Variable Nuple defined with value {{0}{1}{9}{36}{100}{225}{441}{784}{1296
}{2025}{3025}}.
Package xintexpr Info: (on line 5)
Variable FourthPowers defined with value {{0}{1}{81}{1296}{10000}{50625}{
194481}{614656}{1679616}{4100625}{9150625}}.
\end{everbatim}
\subsubsection{\csh{xintunassignvar}}
\label{xintunassignvar}
\csa{xintunassignvar}\marg{variable} will make the \meta{variable} un-assigned.
For example in the previous section we used
\begin{everbatim}
\xintdeffloatvar e := ...some value...;
\end{everbatim}
To undo one either waits for the current scope (e.g.\@ a \LaTeX{}
environment) to expire or the impatient does:
\begin{everbatim*}
\xintunassignvar{e}
\end{everbatim*}
In this special case\IMPORTANT{} of using \csa{xintunassignvar} with a
single \meta{letter} the effect is actually to let
the \meta{letter} recover the meaning of a dummy variable (i.e.\@ it is
the same as using \csbxint{newdummy} documented in the next section):
\begin{everbatim*}
% overwriting a dummy letter
\xintdefvar i := 3;%
\xinteval{i^3} is as expected but |\xinteval{add(i,i=1..10)}| computes
\xinteval{add(i,i=1..10)} because "i" has the fixed value 3.\newline
\xintunassignvar{i}% back to normal
After |\xintunassignvar{i}|
|\xinteval{add(i,i=..10)}| is evluated with "i" acting as a dummy variable
and thus outputs \xinteval{add(i,i=1..10)}.\par
\end{everbatim*}
Under \csbxint{globaldefstrue} regime the effect of \csa{xintunassignvar} is
of global scope.
\subsubsection{\csh{xintnewdummy}}
\label{xintnewdummy}
Any catcode 11 character can serve as a dummy variable, via this declaration:
\begin{everbatim}
\xintnewdummy{}% the must be of catcode letter!
\end{everbatim}
For example with Lua\TeX\ or Xe\TeX\ the following works:
\begin{everbatim}
% Requires a Unicode engine
\xintnewdummy{ξ}
\xinteval{add(ξ, ξ=1..10)}
\end{everbatim}
Starting with |1.4|, it is allowed to use \csa{xintnewdummy} to define
``dummy variables'' having names with more than one letter. They can
then be used as expected:
\begin{everbatim}
% Requires a Unicode engine
\xintnewdummy{ατλν}
\xintdeffunc test(ατλν) = sqr(1 + ατλν);
\xinteval{seq(test(ατλν), ατλν = 0..10)}
\end{everbatim}
Remark regarding Op\TeX: it is a format using Lua\TeX, but non ascii
letters have catcode ``other''. So for the above example to compile
with |optex|, the catcodes need to be set to ``letter'' beforehand:
\begin{everbatim}
% Requires a Unicode engine
% next line is required if with OpTeX (only):
\xintFor* #1 in {ατλν}\do{\catcode`#1=11 }
\xintnewdummy{ατλν}
\xintdeffunc test(ατλν) = sqr(1 + ατλν);
\xinteval{seq(test(ατλν), ατλν = 0..10)}
\end{everbatim}
Under \csbxint{globaldefstrue} regime the effect of \csa{xintnewdummy} is
of global scope.
\subsubsection{\csh{xintensuredummy}, \csh{xintrestorevariable}}
\label{xintensuredummy}
\label{xintrestorevariable}
Use
\begin{everbatim}
\xintensuredummy{}
...
... code using the (catcode 11) character as a dummy variable
...
\xintrestorevariable{}
\end{everbatim}
if other parts need the letter as an assigned variable name. For example
\calxtrigname being written at high level needs a few genuine dummy variables,
and it uses \csbxint{ensuredummy} to be certain everything is ok.
\subsection{User defined functions}
\label{ssec:userfunctions}
\def\tocstylesubsubsectionHOOK#1#2#3{}
\etocsetnexttocdepth{subsubsection}
\localtableofcontents
\let\tocstylesubsubsectionHOOK\empty
\subsubsection{\csh{xintdeffunc}}
\label{xintdeffunc}
Here is an example:
\begin{everbatim*}
\xintdeffunc
Rump(x,y):=1335 y^6/4 + x^2 (11 x^2 y^2 - y^6 - 121 y^4 - 2) + 11 y^8/2 + x/2y;
\end{everbatim*}(notice the numerous tacit multiplications in this expression;
and that |x/2y| is interpreted as |x/(2y)|.)
\begin{framed}
\begin{itemize}
\item The ending semi-colon is allowed to be of active catcode, as
|\xintdeffunc| temporarily resets catcodes via
\csbxint{exprSafeCatcodes} before parsing the expression.
But this will fail if the whole thing is inside a macro
definition. Then the used semi-colon must be the standard one.
In the case of a \LaTeX{} document using Babel, and a language such
as French which makes the semi-colon active, it is still the
standard one inside the preamble, so there is no problem there.
For a macro definition done inside the document body, which, as I
understand, is sin, almost evil, either turn off locally the
activation (|\string;| will not work because \csbxint{deffunc} uses
delimited macros to fetch all the way to the semi-colon), or define
in the preamble |\MyDefFunc{#1}| to do |\xintdeffunc #1;| and use
that in the |\newcommand\foo| inside the document body.
\item Semi-colons used inside the expression need not be hidden inside
braces. (new with |1.4|)
\item The colon before the equal sign is optional and its (reasonable)
catcode does not matter.
\end{itemize}
\end{framed}
Here are a few important items (bookmark this for reading again later once you
have gained experience in using this interface...):
\begin{itemize}
\item The function names are composed of letters, digits, underscores or |@|
signs. A function name must start with a letter. It may be a single letter
(see \autoref{sssec:overload}).
\item The variable names used in the function signature may be multi-letter
words. It is also allowed for them to already be in use for previously
declared variables. Their meanings will get restored for usage after the
function declaration.
\item A function can be declared with at most nine arguments. It can be declared as a
function with no arguments.
\item If in the function declaration the last argument is
prefixed by |*|, it stands for a |nutple| which will gather all arguments of
the function call beyond the first positional ones. See \autoref{sssec:funcargs}
for additional explanations on such \myenquote{variadic} arguments.
\item Recursive definitions are possible; for them to not generate error or
fall in infinite loops, the use of the short-circuit conditionals |?| and
|??| is \emph{mandatory}.
\item If a function is used in another definition it will check if it is
applied to numerical arguments and if this is the case will expand
fully.
\item The previous item has an exception for functions with no arguments; they
never expand immediately in other function definitions (else they would be
almost like variables). This provides a way to define functions with
parameters: simply let their definition use some functions with no arguments.
\item A function declared via \csbxint{deffunc} remains \fbox{unknown} to
\csbxint{floatexpr} (or \csbxint{floateval}). See \csbxint{deffloatfunc},
\csbxint{defiifunc}. One can use the same formula in a new definition, but
if one wants the expansion to execute in a parser independent way, one can
transfer a function with scalar values like this:
\begin{everbatim}
\xintdeffloatfunc foo(x) := float_dgt(\xintexpr foo(x)\relax);
\end{everbatim}
The \func{float\string_dgt} wrapper (which was renamed at
|1.4e|) is in order for the float variant to produce an already-rounded
value, possibly speeding-up usage if used as input for other
functions. Using \func{float} here would work the same but the produced
function would incorporate a routine to check (at time of use, because at
time of definition it is impossible to tell what will be the case) if it is
applied to one or two arguments.
\item And in the reverse direction one can do:
\begin{everbatim}
\xintdeffunc bar(x) := \xintfloatexpr bar(float(x))\relax;
\end{everbatim}
With this the transplanted float-function will expand in \csbxint{expr} as
it would have in \csbxint{floatexpr}, i.e.\@{} using float operations; this is
different from declaring the function again with the same expression as used
for the original, as it would have then been parsed with a mapping of infix
operators to the macros doing the exact operations, not the floating point
ones.
The inner \func{float} above is not mandatory but recommended: the macro
associated to the user float function |bar(x)| may use many times its
argument |x| and does not worry about rounding it, because its expectation
is that it is already rounded; but in \csbxint{expr} that value could very
well be a fraction |19/13| and its float rounding will be done again by each
float macro receiving it as argument; with a \func{float} used as above this
will have already been done once and the ulterior roundings are faster: they
have nothing to do apart from realizing that they have nothing to do.... One
can also use \func{sfloat}, this would serve to nothing for the |19/13| case
but would possibly for a short integer input involved in multiplications.
Here it is not needed to use \func{float\string_dgt}, because it will be
identified at time of definition that \func{float} is used without optional
argument.
An external \func{float\string_dgt} could be added but is not a priori
necessary, except perhaps if the |bar()| function has been defined at a low
level using support macros producing output with garbage extra digits, which
usually would be rounded out in input to other float functions.
\end{itemize}
A function once declared is a first class citizen, its
expression is entirely parsed and converted into a big nested \fexpan dable
macro.
When used its action is via this defined macro. For example
\begin{everbatim*}
\xintdeffunc
e(z):=(((((((((z/10+1)z/9+1)z/8+1)z/7+1)z/6+1)z/5+1)z/4+1)z/3+1)z/2+1)z+1;
\end{everbatim*}
creates a macro whose meaning one can find in the log file, after
\csbxint{verbosetrue}. Here it is (it has at |1.4| an extra external brace pair
compared to what happened with earlier releases):
\begin{everbatim}
Function e for \xintexpr parser associated to \XINT_expr_userfunc_e with me
aning macro:#1->{\xintAdd {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\x
intDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\
xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {
\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {#1}{10}}{1}}{#1}}{9
}}{1}}{#1}}{8}}{1}}{#1}}{7}}{1}}{#1}}{6}}{1}}{#1}}{5}}{1}}{#1}}{4}}{1}}{#1}}{3}
}{1}}{#1}}{2}}{1}}{#1}}{1}}
\end{everbatim}
The above is not entirely true. At |1.4|, \csbxint{deffunc} is
more powerful and digests more of the syntax but it may have to store it in
such a way that usage will be done via a sub-expression: hence it is not the
case that the original expression has been \emph{entirely} parsed. See
\csbxint{NewFunction} for related discussion.
The main difficulty of \csbxint{deffunc} is with the pseudo-functions
\func{seq}, \func{iter}, etc..., which admit the keywords \keyword{omit},
\keyword{abort}, \func{break}. We have no alternative for them, if the
iterated over values are not entirely numerical than to postpone expansion,
but this means simply storing for later a possibly big sub-expression.
At |1.4| we did some obstinate work to make this working but:
\begin{itemize}
\item this means that the stored function body has not been entirely parsed,
parsing will happen on the fly at each execution for small or large bits,
\item there remains a main stumbling-block. If the variables used in the
function declaration are used only in the iterated over values or the
initial values, then the mechanism may work. If however they are used not
only in those values iterated over but directly in the expression which the
generators map to the iterated over values, then it will break
certainly. Indeed at this stage the variables are simply names, and it is
impossible to transfer the mechanism which converts these names into
numerical arguments for delayed usage by the declared function. Except if
one is ready to basically freeze the entire thing; which then is not any
different at all than using \csbxint{NewFunction}.
\end{itemize}
Conclusion: if some \csbxint{deffunc} break, check if it does not fit the
above criterion before reporting...\@{} and recall \csbxint{NewFunction} is your
friend. It has the big advantage of declaring a function for all parsers
simultaneously!
A special note on \func{subs}: it is and has always been hopeless in \csbxint{deffunc}
context. All it does (if it works at all) after being malaxed by
\csbxint{deffunc} is to copy over at the indicated places the \emph{recipe} to
compute something. Thus at every location where that something is needed it will be
evaluated from scratch again. Yes, this is disappointing. But...\@{} on the other
hand the more general \func{seq} does work, or pretends to work. Let me
illustrate to make thinks clear. We start with this:
\begin{everbatim*}
\xintverbosetrue
\xintdeffunc foo(x,y,z) = subs(S + S^2, S = x+y+z);
\xintdeffunc bar(x,y,z) = seq(S + S^2, S = x+y+z);
\xintexpr foo(100,10,1), bar(100,10,1)\relax
\xintverbosefalse
\end{everbatim*}
It produces in the log:
\begin{everbatim}
Package xintexpr Info: (on line 2)
Function foo for \xintexpr parser associated to \XINT_expr_userfunc_foo wit
h meaning macro:#1#2#3->{\xintAdd {\xintAdd {\xintAdd {#1}{#2}}{#3}}{\xintPow {
\xintAdd {\xintAdd {#1}{#2}}{#3}}{2}}}
Package xintexpr Info: (on line 3)
Function bar for \xintexpr parser associated to \XINT_expr_userfunc_bar wit
h meaning macro:#1#2#3->\expanded \bgroup \expanded {\unexpanded {\XINT_expr_se
q:_b {\xintbareeval S + S^2\relax !S}}{\xintAdd {\xintAdd {#1}{#2}}{#3}}^}
\end{everbatim}
Even without understanding all details one sees that in the first case the
|\xintAdd {\xintAdd {#1}{#2}}{#3}}| appears twice, and in the second case only
once. But in the second case we have a yet to evaluate expression. So the
second approach is not much different in its effect than using the more
simple-minded \csbxint{NewFunction}. Besides one gets a feeling why the
function arguments can not appear in the expression but only in the iterated
over values, because there is no way to understand what |x|, |y|, |z| are
supposed to mean without adding extra structure showing they map to |#1|,
|#2|, |#3|.
The above remarks apply to \func{subsm} and \func{subsn}. Even if they do work
in \csbxint{deffunc} context (warning, testing at |1.4| release has remained
minimal), they will not bring added efficiency if the substituted values are
to be used multiple times. They may still be useful to visually simplify the
input of a big expression by expressing it in terms of smaller constituents.
Another workaround if one wants genuine (not \myenquote{macro}-) functions for some
expression where the same thing is used multiple times is to define helper
functions computing the intermediate data. One can see illustrations of this
in the code source of \calxtrigname (or in the matrix multiplication example
at the end of this chapter).
\subsubsection{\csh{xintdefiifunc}}
\label{xintdefiifunc}
With \csbxint{deffunc} the created function is known by the \csbxint{expr}
parser only.
For usage in the \csbxint{iiexpr} parser, it is required to use
\csa{xintdefiifunc}.
\subsubsection{\csh{xintdeffloatfunc}}
\label{xintdeffloatfunc}
With \csbxint{deffunc} the created function is known by the \csbxint{expr}
parser only. For usage in the \csbxint{floatexpr} parser, it is required to use
\csa{xintdeffloatfunc}.
Note: the optional argument |[Q]| accepted by \csbxint{floatexpr} does not
work with \csbxint{deffloatfunc}. It is still possible to wrap the expression
in |float(expression,Q)|, if it evaluates to a scalar.
\subsubsection{\csh{xintdefufunc}, \csh{xintdefiiufunc}, \csh{xintdeffloatufunc}}
\label{xintdefufunc}
\label{xintdefiiufunc}
\label{xintdeffloatufunc}
This allows to define so-called \myenquote{Universal functions}. This is terminology
borrowed from |NumPy|.
Here is an example:
\begin{everbatim*}
\xintdefiivar Array = ndmap(lcm, 1..5; 1..10; 1..10);
Array = \xintthealign\xintiiexpr Array\relax
\xintdefiiufunc foo(x) = x^3;
\begin{figure}[htbp]
\caption{Output of a universal function acting on an array}\label{fig:ufunc}
\centeredline{$\vcenter{\xintthealign\xintiiexpr foo(Array)\relax}$}
\end{figure}
See \autopageref{fig:ufunc} for the output.
\end{everbatim*}
The function can be applied to any nested strucure:
\begin{everbatim*}
\xintiiexpr foo([1, [2, [3, [4, [5, 6, 7, 8, 9, 10]]]]])\relax
\end{everbatim*}
It must be defined as function acting on scalars, but its value type is not constrained.
\begin{everbatim*}
\xintdefiivar Array = [1..10];
\xintdefiiufunc foo(x) = [1..x];
\xintthealign\xintiiexpr foo(Array)\relax
\end{everbatim*}
It is even allowed to produce oples and act on oples:
\begin{everbatim*}
\xintdefiivar Ople = 1..10;
\xintdefiiufunc bar(x) = x, x^2, x^3;
\xintiiexpr bar(Ople)\relax
\end{everbatim*}
\subsubsection{Using the same name for both a variable and a function}
\label{sssec:overload}
It is licit to overload a variable name (all Latin letters are predefined as
dummy variables) with a function name and vice versa. The parsers will decide
from the context if the function or variable interpretation must be used
(dropping various cases of tacit multiplication as normally applied).
\begin{everbatim*}
\xintdefiifunc f(x):=x^3;
\xinttheiiexpr add(f(f),f=100..120)\relax\newline
\xintdeffunc f(x,y):=x^2+y^2;
\xinttheexpr mul(f(f(f,f),f(f,f)),f=1..10)\relax
\xintunassigniiexprfunc{f}\xintunassignexprfunc{f}%
\end{everbatim*}
\subsubsection{\csh{xintunassignexprfunc}, \csh{xintunassigniiexprfunc},
\csh{xintunassignfloatexprfunc}}
\label{xintunassignexprfunc}
\label{xintunassigniiexprfunc}
\label{xintunassignfloatexprfunc}
Function names can be unassigned via \csa{xintunassignexprfunc}\marg{name},
\csa{xintunassigniiexprfunc}\marg{name}, and
\csa{xintunassignfloatexprfunc}\marg{name}.
\begin{everbatim*}
\xintunassignexprfunc{e}
\xintunassignexprfunc{f}
\end{everbatim*}
Warning: no check is done to avoid undefining built-in functions...
\subsubsection{\csh{ifxintverbose} conditional}
\label{xintverbosetrue}
\label{xintverbosefalse}
\label{ifxintverbose}
With |\xintverbosetrue| the meanings of the
functions (or rather their associated macros) will be written to the log. For
example the |Rump| declaration above generates this in the log file:
\begin{everbatim}
Function Rump for \xintexpr parser associated to \XINT_expr_userfunc_Rump w
ith meaning macro:#1#2->{\xintAdd {\xintAdd {\xintAdd {\xintDiv {\xintMul {1335
}{\xintPow {#2}{6}}}{4}}{\xintMul {\xintPow {#1}{2}}{\xintSub {\xintSub {\xintS
ub {\xintMul {11}{\xintMul {\xintPow {#1}{2}}{\xintPow {#2}{2}}}}{\xintPow {#2}
{6}}}{\xintMul {121}{\xintPow {#2}{4}}}}{2}}}}{\xintDiv {\xintMul {11}{\xintPow
{#2}{8}}}{2}}}{\xintDiv {#1}{\xintMul {2}{#2}}}}
\end{everbatim}
\begin{framed}
The meanings written out to the log for more complicated functions may
sometimes use the same character at different locations but with different
catcodes.\IMPORTANTf
It may thus be impossible to retokenize it (even after having removed the
extra spaces from the added line breaks).
This is in contrast with variable values which are always output in the log
in the benign way, using digits, braces and some characters of catcode 12.
\end{framed}
\subsubsection{\csh{ifxintglobaldefs} conditional}
\label{xintglobaldefstrue}
\label{xintglobaldefsfalse}
\label{ifxintglobaldefs}
If true user defined variables (\csbxint{defvar}, ...) and functions
(\csbxint{deffunc}, ..., \csbxint{NewFunction}) for the expression parsers, as
well as macros obtained via \csbxint{NewExpr} et al.\@{} have global scope. If
false (default) they have local scope.
\subsubsection{\csh{xintNewFunction}}
\label{xintNewFunction}
This is syntactic sugar which allows to use notation of functions for what is
nothing more in disguise than a \TeX{} macro. Here is an example:
\begin{everbatim*}
\xintNewFunction {foo}[3]{add(mul(x+i, i=#1..#2),x=1..#3)}
\end{everbatim*}
We now have a genuine function |foo()| of three variables which can
be used in \emph{all three parsers}.
\begin{everbatim*}
\xintexpr seq(foo(0, 3, j), j= 1..10)\relax
\end{everbatim*}
Each time the created \myenquote{macro-function} |foo()| will be encountered the
corresponding replacement text will get inserted as a sub-expression (of the
same type as the surrounding one), the macro parameters having been replaced
with the (already evaluated) function arguments, and the parser \emph{will
then have to parse the expression.} It is very much like a macro
substitution, but with parentheses and comma separated arguments (which can be
arbitrary expressions themselves).
It differs fundamentally from \csbxint{deffunc} as it realizes no pre-parsing
whatsoever of the associated sub-expression; using it shortens the input but
not the parsing time (which however is most of the time negligible compared to
actual numerical computations). Use it for syntax which \csbxint{deffunc}
does not parse successfully.
\subsection{Examples of user defined functions}
\subsubsection{Example with vectors and matrices}
\label{sssec:csv}
Suppose we want to manipulate 3-dimensional vectors, which will be represented
as |nutples| of length 3. And let's add a bit of matrix algebra.
\begin{everbatim*}
\xintdeffunc dprod(V, W) := V[0]*W[0] + V[1]*W[1] + V[2]*W[2];
\xintdeffunc cprod(V, W) := [V[1]*W[2] - V[2]*W[1],
V[2]*W[0] - V[0]*W[2],
V[0]*W[1] - V[1]*W[0]];
\xintdeffunc Det3(U, V, W) := dprod(cprod(U, V), W);
\xintdeffunc DetMat(M) = Det3(*M);
\xintdeffunc RowMat(U, V, W) := [U, V, W];
\xintdeffunc ColMat(U, V, W) := [[U[0], V[0], W[0]],
[U[1], V[1], W[1]],
[U[2], V[2], W[2]]];
\xintdeffunc MatMul(A, B) :=
[[A[0,0]*B[0,0]+A[0,1]*B[1,0]+A[0,2]*B[2,0],
A[0,0]*B[0,1]+A[0,1]*B[1,1]+A[0,2]*B[2,1],
A[0,0]*B[0,2]+A[0,1]*B[1,2]+A[0,2]*B[2,2]],
[A[1,0]*B[0,0]+A[1,1]*B[1,0]+A[1,2]*B[2,0],
A[1,0]*B[0,1]+A[1,1]*B[1,1]+A[1,2]*B[2,1],
A[1,0]*B[0,2]+A[1,1]*B[1,2]+A[1,2]*B[2,2]],
[A[2,0]*B[0,0]+A[2,1]*B[1,0]+A[2,2]*B[2,0],
A[2,0]*B[0,1]+A[2,1]*B[1,1]+A[2,2]*B[2,1],
A[2,0]*B[0,2]+A[2,1]*B[1,2]+A[2,2]*B[2,2]]];
\xintdefvar vec1, vec2, vec3 := [1, 1, 1], [1, 1/2, 1/4], [1, 1/3, 1/9];
\xintdefvar mat1 = RowMat(vec1, vec2, vec3);
\xintdefvar mat2 = ColMat(vec1, vec2, vec3);
\xintdefvar mat12 = MatMul(mat1,mat2);
\xintdefvar mat21 = MatMul(mat2,mat1);
Some computations (|align| executes multiple times hence we pre-computed!):
\begin{align*}
M_1 &= \vcenter{\xintthealign \xintexpr mat1\relax}&&\qquad
M_2 . M_1 = \vcenter{\xintthealign \xintexpr mat21\relax}\\[3\jot]
M_2 &= \vcenter{\xintthealign \xintexpr mat2\relax}&&\qquad
M_1 . M_2 = \vcenter{\xintthealign \xintexpr mat12\relax}
\end{align*}
$$
\det(M_1) = \xinteval{DetMat(mat1)},\quad
\det(M_1.M_2) = \xinteval{reduce(DetMat(mat12))},\quad
\det(M_2.M_1) = \xinteval{reduce(DetMat(mat21))}
$$
\end{everbatim*}%
For some hair-raising experience check the \csbxint{verbosetrue} output in the
log...\@{} here is an alternative with two (three, counting |dprod()|) helper
functions:
\begin{everbatim*}
% annoying that Tr also starts Trace, but Spur is available
% well Sp also starts Spectrum. Big problems.
\xintdeffunc Tr(M) :=
[[M[0,0], M[1,0], M[2,0]],
[M[0,1], M[1,1], M[2,1]],
[M[0,2], M[1,2], M[2,2]]];
\xintdeffunc MatMul_a(r1, r2, r3, c1, c2, c3) :=
[[dprod(r1, c1), dprod(r1, c2), dprod(r1, c3)],
[dprod(r2, c1), dprod(r2, c2), dprod(r2, c3)],
[dprod(r3, c1), dprod(r3, c2), dprod(r3, c3)]];
\xintdeffunc MatMul(A, B) := MatMul_a(*A, *Tr(B));
\end{everbatim*}
And once we have the transpose and the scalar product of vectors, we can
simply use \func{ndmap} for a lean syntax (this would extend to arbitrary
dimension):
\begin{everbatim*}
\xintdeffunc MatMul(A, B) = ndmap(dprod, *A; *Tr(B));
\xintdefvar mat1212 = MatMul(mat12, mat12);
\begingroup
\def\xintexprPrintOne #1{\xintTeXFrac{#1}}%
\def\xintexpralignbegin {\begin{pmatrix}}%
\def\xintexpralignend {\end{pmatrix}}%
\def\xintexpralignlinesep {\noexpand\\[2\jot]}% counteract an internal \expanded
\def\xintexpraligninnersep {&}%
\let\xintexpralignleftbracket\empty \let\xintexpralignleftsep\empty
\let\xintexpralignrightbracket\empty \let\xintexpralignrightsep\empty
$$ \xintthealign \xintexpr mat1\relax \cdot \xintthealign \xintexpr mat2\relax \cdot
\xintthealign \xintexpr mat1\relax \cdot \xintthealign \xintexpr mat2\relax =
\xintthealign \xintexpr mat12\relax ^2 = \xintthealign \xintexpr mat1212\relax$$
$$ \det(M_1\cdot M_2 \cdot M_1 \cdot M_2) = \xinteval{reduce(DetMat(mat1212))}$$
\endgroup
\end{everbatim*}
\subsubsection{Example with the \textsc{Rump} test}
\label{sssec:Rump}
Let's try out our |Rump()| function:
\begin{everbatim*}
\xinttheexpr Rump(77617,33096)\relax.
\end{everbatim*}
Nothing problematic for an \emph{exact} evaluation, naturally!
Thus to test the \textsc{Rump} polynomial (it is not quite a polynomial with
its |x/2y| final term) with floats, we \emph{must} also
declare |Rump| as a function to be used there:
\begin{everbatim*}
\xintdeffloatfunc
Rump(x,y):=333.75 y^6 + x^2 (11 x^2 y^2 - y^6 - 121 y^4 - 2) + 5.5 y^8 + x/2y;
\end{everbatim*}
The numbers are scanned with the current precision, hence as here it is
\dtt{16}, they are scanned exactly in this case. We can then vary the
precision for the evaluation.
\begin{everbatim*}
\def\CR{\cr}
\halign
{\tabskip1ex
\hfil\bfseries#&\xintDigits:=\xintiloopindex\relax
\xintthefloatexpr Rump(77617,33096)#\cr
\xintiloop [8+1]
\xintiloopindex &\relax\CR
\ifnum\xintiloopindex<40 \repeat
}
\end{everbatim*}
\subsubsection{Examples of recursive definitions}
\label{sssec:recursive}
Recursive definitions \emph{require} using the short-circuit branching
operators.
\begin{everbatim*}
\xintdeffunc GCD(a,b):=(b)?{GCD(b,a/:b)}{a};
\end{everbatim*}
This of course is the Euclide algorithm: it will be here applied to variables
which may be fractions. For example:
\begin{everbatim*}
\xinttheexpr GCD(385/102, 605/238)\relax
\end{everbatim*}
There is already a built-in \func{gcd} (which
accepts arbitrarily many arguments):
\begin{everbatim*}
\xinttheexpr gcd(385/102, 605/238)\relax
\end{everbatim*}
Our second example is modular exponentiation:
\begin{everbatim*}
\xintdefiifunc powmod_a(x, m, n) :=
isone(m)?
% m=1, return x modulo n
{ x /: n }
% m > 1 test if odd or even and do recursive call
{ odd(m)? { x*sqr(powmod_a(x, m//2, n)) /: n }
{ sqr(powmod_a(x, m//2, n)) /: n }
}
;
\xintdefiifunc powmod(x, m, n) := (m)?{powmod_a(x, m, n)}{1};
\end{everbatim*}
I have made the definition here for the |\xintiiexpr| parser; we could do the
same for the |\xintexpr|-parser (but its usage with big powers would quickly
create big denominators, think |powmod(1/2, 1000, 1)| for example.)
\begin{everbatim*}
\xinttheiiexpr seq(powmod(x, 1000, 128), x=9, 11, 13, 15, 17, 19, 21)\relax\par
\end{everbatim*}
The function assumes the exponent is non-negative (the Python |pow| behaved
the same until |3.8| release), but zealous users will add the necessary code for negative
exponents, after having defined another function for modular inverse!
If function |A| needs function |B| which needs function |A| start by giving to
|B| some dummy definition, define |A|, then define |B| properly. TODO: add
some example here...
\subsection {Links to some (old) examples within this document}
\label{sec:awesome}
\begin{itemize}
\item The utilities provided by \xinttoolsname (\autoref{sec:tools}), some
completely expandable, others not, are of independent interest. Their use
is illustrated through various examples: among those, it is shown in
\autoref{ssec:quicksort} how to implement in a completely expandable way
the \hyperref[ssec:quicksort]{Quick Sort algorithm} and also how to illustrate
it graphically. Other examples include some dynamically constructed
alignments with automatically computed prime number cells: one using a
completely expandable prime test and \csbxint{ApplyUnbraced}
(\autoref{ssec:primesI}), another one with \csbxint{For*} (\autoref{ssec:primesIII}).
\item One has also a \hyperref[edefprimes]{computation of primes within an
\csa{edef}} (\autoref{xintiloop}), with the help of \csbxint{iloop}.
Also with \csbxint{iloop} an
\hyperref[ssec:factorizationtable]{automatically generated table of
factorizations} (\autoref{ssec:factorizationtable}).
\item The code for the title page fun with Fibonacci numbers is given in
\autoref{ssec:fibonacci} with \csbxint{For*} joining the game.
\item The computations of \hyperref[ssec:Machin]{ $\pi$ and $\log 2$}
(\autoref{ssec:Machin}) using \xintname and the computation of the
\hyperref[ssec:e-convergents]{convergents of $e$} with the further help of
the \xintcfracname package are among further examples.
\item Also included,
an \hyperlink{BrentSalamin}{expandable implementation of the Brent-Salamin
algorithm} for evaluating $\pi$.
\item The \autoref{ssec:PrimesIV} implements expandably the Miller-Rabin
pseudo-primality test.
\item The functionalities of \xintexprname are illustrated with various
other examples, in \autoref{xintdeffunc},
\hyperlink{ssec:dummies}{Functions with dummy variables},
\autoref{ssec:moredummies} or \hyperref[sssec:recursive]{Recursive definitions}.
\end{itemize}
% ça va sans dire
% Almost all of the computational results interspersed throughout the
% documentation are not hard-coded in the source file of this document but are
% obtained via the expansion of the package macros during the \TeX{}
% run.%
\subsection{Oples and nutples: the \texttt{1.4} terminology}
\label{oples}
\emph{Skip this on first reading, else you will never start using the
package.} \fbox{SKIP THIS!} (understood?)
In this section I will describe a mathematical terminology which models
how the parser handles the input syntax with numbers, commas, and brackets,
and how it maps internally to \TeX\ specific concept, particularly braces and
macro arguments.
\etocsetnexttocdepth{subsubsection}
\localtableofcontents
\subsubsection{Base terminology}
We start with a set $\mathcal{A}$ of \emph{atoms}, which represent numeric
data. In \TeX{} syntax such \emph{atoms} are always braced, more precisely,
currently they look like
%
\centeredline{\dtt{\{raw format within \TeX{} braces\}}}
%
The \TeX{} braces are not set-theoretical braces here, they are simply used
for \TeX nical reasons (one could imagine using rather some terminator token,
but ultimately support macros for built-in and user defined functions rely on
\TeX\ macros with undelimited parameters, at least so far).
Our category $\mathcal{C}$ of \myenquote{oples} is the smallest collection of
\emph{totally ordered finite sets} verifying these properties:
\begin{enumerate}
\item The empty set \dtt{$\emptyset$} is an \emph{ople}, i.e.\@{} it belongs to
$\mathcal{C}$.
\item Each singleton set \dtt{$\{O\}$} whose element \dtt{$O$} is either an
\emph{atom} $a\in\mathcal{A}$ or an \emph{ople} qualifies as an \emph{ople}.
\item $\mathcal{C}$ is stable by concatenation.
\end{enumerate}
Notes:
\begin{itemize}
\item
We refer to the empty set \dtt{$\emptyset$} via the variable \emph{nil}.%
%
\footnote{There is
actually a built-in variable with this name. At |1.4|, |\xintexpr\relax| is
legal and also generates the \emph{nil}.}
\item It is convenient to accept the empty set as being also an
\emph{atom}. If this is done, then we may refer to the original
\emph{atoms} (elements of $\mathcal{A}$) as \emph{non empty numerical data}.
\item
Concatenation is represented in the syntax by the
comma. Thus repeated commas are like only one and |nil| is a neutral element.
\item A singleton \emph{ople} \dtt{$\{a\}$} whose single element is a
(non-empty) \emph{atom} is called a \emph{number}.%
%
\footnote{This has to be taken in a general sense, for example with
\ctanpackage{polexpr}, polynomials are represented by such \myenquote{numbers}.}
%
\item
The operation of constructing \dtt{$\{O\}$} from the \emph{ople} \dtt{$O$} is
called \emph{bracing} (set theory, \TeX), or \emph{bracketing} (\xintexprname
input syntax, Python |lists|), or \emph{packing} (as a reverse to Python's
unpacking of sequence type objects). In the expression input syntax it
corresponds to enclosing \dtt{$O$} within square brackets: \dtt{$[O]$}.
\item A braced \emph{ople} is called a \emph{nutple}. Among them \dtt{\{nil\}}
(aka $\{\emptyset\}$) is a bit special. It is called the \emph{none-ple}.%
%
\footnote{Prior to version |1.4j| of this documentation it was called the
\emph{not-ple}.}
%
It is not \dtt{nil}.%
%
\footnote{There is (experimental) a pre-defined \myenquote{\dtt{None}} variable which
stands for the \emph{none-ple}. It can also be input as |[]|.}
\end{itemize}
Each \emph{ople} has a \emph{length} which is its cardinality as set. The
singleton |oples| are called \emph{one-ples}. There are thus two types of
\emph{one-ples}:
\begin{itemize}
\item \emph{numbers} \dtt{$\{a\}$}, $a \in \mathcal{A}$,
\item \emph{nutples} \dtt{$\{O\}$}, $O \in \mathcal{C}$.
\end{itemize}
If we consider the empty set |nil| on the same footing as |atoms|, the two
types have only one common object which is the \emph{none-ple}. As a rule
arithmetic operations will either break or silently convert the \emph{none-ple}
to the zero value:
\begin{everbatim*}
\xinteval{3+[], 5^[], 10*[]}
\end{everbatim*}.
But attention that \csbxint{iieval} in contrast to \csbxint{eval} is broken by
such inputs.
\subsubsection{Items (and sub-items) versus elements}
In order to illustrate these concepts, let us consider how one should
interpret notation such as |3,5,7,9| when it arises in an
\csbxint{expr}|ession|:
\begin{description}
\item[tempting vocabulary:] Each of |3|, |5|, |7|, and |9| is an \emph{item}, or
\emph{element} of the (comma separated) \emph{list}. In other terms we have
here a list with 4 items.
\item[rigorous vocabulary:] each one of |3|, |5|, |7|, |9| stands for an
\emph{ople} (of the \emph{one-ple} type) and |3,5,7,9| stands for their \emph{concatenation}.
\end{description}
It is important to understand that in an \csbxint{expr}|ession|, there is no
difference between |3,5,7| and |3,,,,5,,,,,,,,,7|. So the view of the comma
as separator is misleading. In other terms, the comma is NOT a separator but
the (associative) operator of concatenation of totally ordered sets, and the
number |3| for example represents a (singleton) set.
If we want to refer to |3| or |5| or |7| or |9| as \myenquote{the items of the
(open) list |3,5,7,9|} (and probably this documentation already has such
utterances, due to legacy reasons from the pre-|1.4| internal model), we
\emph{must} realize that this clashes with using the word \emph{item} as
synonymous to \emph{element} in the set-theoretical sense.
To repeat, any ople \dtt{$O$} is a finite totally ordered set: if not the empty
set, it has \emph{elements} \dtt{$a_1$}, \dots, \dtt{$a_k$}, and the above means that
its \emph{items} are the singleton oples (aka one-ples) \dtt{$I_1=\{a_1\}$},
\dots, \dtt{$I_k=\{a_k\}$}. Each \dtt{$a_j$} may be an |atom|, then
\dtt{$I_j$} is a |number|, or \dtt{$a_j$} is an |ople| (possibly the empty set), then
\dtt{$I_j$} is a |nutple| whose depth is one more than the one of the ople
\dtt{$a_j$}.
Thus we can refer to \myenquote{items} but must then understand they are not \myenquote{elements}:
\myenquote{items} are \myenquote{singleton sub-sets}. The cardinality (aka length) of an ople is
also the number of its
items. It would be tempting to use the terminology \myenquote{sub-item} to keep in mind they are \myenquote{sub-sets}
but this would again create confusion: a |nutple| has only one item which is
itself; and we need some terminology to refer to the individual numbers in the
|nutple| given in input as |[1,2,3]| for example. It is natural to refer to
|1|, |2|, |3| as \myenquote{sub-items} of |[1,2,3]| as the latter may be an \myenquote{item} (it
is in particular an \myenquote{item} of itself, the unique one at that).
We distinguish the |oples| of length zero (there is only one, the empty set)
or at least two as those which can never be an \myenquote{item}. Those of length one,
the |one-ples|, are exactly those which can be \myenquote{items}. Among them some may
have \myenquote{sub-items}, they are the |nutples| with the exception of the |none-ple|.
And the others do not have \myenquote{sub-items}, they are the |numbers| and the |none-ple| (whose input syntax is
either |[]| or the variable |None|).%
%
\footnote{%
A note on the \csbxint{verbosetrue} regime: for a variable defined to be
|3,5,7,9|, it will say that its value is |{3}{5}{7}{9}|, because it does not
keep the external set-theoretical braces. The braces here are only \TeX{}
braces, and |{3}| is an |atom|. The |number| would be |{{3}}| with the
external braces being set-theoretical and also used internally as \TeX{}
braces. From the four numbers |{{3}}|, ..., |{{9}}| concatenation gives
|{{3}{5}{7}{9}}|, which is the |ople| |3,5,7,9|. But the log view drops
deliberately the external braces. If the variable is defined to be the
|nutple| |[3,5,7,9]|, then the log view will be |{{3}{5}{7}{9}}| (up to
details on how exactly the numeric quantities are coded) and the actual
internal \TeX{} entity will be |{{{3}{5}{7}{9}}}|, where the two external
layers of braces are both set-theoretical and \TeX nical braces.}
\subsubsection{Oples as trees}
We say that the empty set |nil| and \emph{atoms} are \emph{leaves}.
We associate with any \emph{ople} a tree. The root is the ople. In the case of
the |nil| ople, there is nothing else than the root, which we then consider
also a \emph{leaf}. Else the children at top level are the successive
\emph{elements} (not \myenquote{items}!) of the ople.%
%
\footnote{\label{fn:alttree}%
We could also consider a tree for which the children of the root node would
be its items and recursively; in that case the leaves would be |numbers| and
possibly the |None|. The tree of the |nil| would be the empty tree, the tree
of |None| would have a single node and no edges. Such a tree would match
the input syntax (of course applying the rule that iterated commas are like
only one). The tree which is described in this section matches more
directly the internal syntax, hence is more useful to the author, who is
also the sole reader who extracts some benefit from reading this
documentation once in a while.}
%
Among the elements some are \emph{atoms} giving \emph{leaves} of the tree,
others are \emph{nutples} which in turn have children. In the special case of
the \emph{none-ple} we consider it has a child, which is the empty set and this
is why we consider the empty set |nil| to be also a potential \emph{leaf}. We
then proceed recursively. We thus obtain from the root \emph{ople} a tree
whose vertices are either \emph{oples} or \emph{leaves}. Only the empty set
|nil| is both a \emph{leaf} and an \emph{ople}.
Considering the empty set |nil| as an \emph{atom} fits with the \xintexprname
internal implementation based on \TeX: |nil| is an empty pair of braces |{}|,
whereas an \emph{atom} is a braced representation of a numeric value using
digits and other characters. We construct \emph{oples} by putting one after
the other such constituents and bracing them, and then repeating the process
recursively.
It has also an impact on the definition of the \emph{depth} (a.k.a as
\emph{maximal dimension}) of an \emph{ople}. For example the \emph{ople}
$\{\emptyset A_1A_2\}$ with three elements, among them the empty set and two
atoms is said to have depth $1$, or to have maximal dimension $1$. And
$\{\{\emptyset\}A_1A_2\}$ is of depth $2$ because it has a leaf (the empty
set) which is a child of a child of the \emph{ople}. NumPy \emph{ndarrays}
have a more restricted structure for example
$\{\{A_{00}A_{01}\}\{A_{10}A_{11}\}\}$ is a $2$-dimensional array, where all
leaves are at the same depth. When slicing empties the array from its atoms,
NumPy keeps the shape information but prints the array as $[]$. This will not
be the case with \xintexprname, which has no other way to indicate the shape
than display it.
\begin{everbatim*}
\xinteval{[[],[]]}
\end{everbatim*}
\begin{everbatim*}
\xinteval{[[0,1],[10,11]][:,2:]}
\end{everbatim*}
\subsubsection{Ople slicing and indexing}
\label{sssec:opleslicing}
\myenquote{Set-theoretical} slicing of an \emph{ople} means replacing it with one of its
subsets. This applies also if it is a \emph{number}. Then it can be sliced
only to itself or to the empty set (indeed it has only one element, which is
an atom). Similarly the \emph{none-ple} can only be sliced to give itself or
the empty set. And more generally a \emph{nutple} is a singleton so also can
only be set-sliced to either the empty set or itself.
\xintexprname extends \myenquote{Python-like} slicing to act on \emph{oples}:
\begin{itemize}[nosep]
\item if they are not \emph{nutples} set-theoretical slicing applies,
\item if they are \emph{nutples} (only case having a one-to-one
correspondence in Python) then the slicing happens \emph{within brackets}:
i.e.\@{} the \emph{nutple} is unpacked then the set-theoretical slicing is
applied, then the result is \emph{repacked} to produce a new \emph{nutple}.
\end{itemize}
With these conventions the \emph{none-ple} for example is invariant under
slicing: unpacking it gives the empty set, which has only the empty set as
subset and repacking gives back the \emph{none-ple}. Slicing a general
\emph{nutple} returns a \emph{nutple} but now of course in general distinct
from the first one.
The input syntax for Python slicing is to postfix a variable or a
parenthesized ople with |[a:b]|. See \autoref{ssec:lists} for more. There
are never any out-of-range errors when slicing or indexing. All operations
are licit and resolved by the |nil|, a.k.a. empty set.
\myenquote{Set-theoretical} item indexing of an \emph{ople} means reducing it to a
subset which is a singleton. It is thus a special case of set-theoretical
slicing (which is the general process of selecting a subset as replacement of
a set).
\xintexprname extends \myenquote{Python-like} indexing to act on \emph{oples}:
\begin{itemize}[nosep]
\item if they are not \emph{nutples} set-theoretical item indexing applies,
\item if they are \emph{nutples} (only case having a one-to-one
correspondence in Python) then the meaning becomes \emph{extracting}: i.e.\@
the \emph{nutple} is unpacked then the set-theoretical indexing is applied,
but the result is \emph{not repacked}.
\end{itemize}
For example when applied to the \emph{none-ple} we always obtain
the |nil|. Whereas as we saw slicing the \emph{none-ple} always gives back the
\emph{none-ple}. Indexing is denoted in the syntax by postfixing by |[N]|. Thus
for \emph{nutples} (which are analogous to Python objects), there is genuine
difference between the |[N]| extractor and the |[N:N+1]| slicer. But for
\emph{oples} which are either |nil|, a \emph{number}, or of length at least 2,
there is no difference.
\subsubsection{Nested slicing of oples}
Nested slicing is a concept from NumPy, which is extended by \xintexprname to
trees of varying depths. We have a chain of slicers and extractors. I will
describe only the case of slicers and letting them act on a |nutple|. The
first slicer gives back a new |nutple|. The second slicer will be applied to
each of one of its remaining elements. However some of them may be
\emph{atoms} or the empty set. In the NumPy context all leaves are at the
same depth thus this can happen only when we have reached beyond the last
dimension (axis). This is not permitted by NumPy and generates an error.
\xintexprname does not generate an error. But any attempt to slice an
\emph{atom} or the empty set (as element of its container) removes it. Recall
we call them \emph{leaves}. We can not slice leaves. We can only slice
non-leaf elements: such items are necessarily |nutples|. The procedure then
applies recursively.
If we handle an extractor rather than a slicer, the procedure is similar: we
can not extract out of an \emph{atom} or the empty set. They are thus
removed. Else we have a |nutple|. It is thus unpacked and replaced by the
selected element. This element may be an atom or the empty set and any further
slicer or extractor will remove them, or it is a |nutple| and the procedure
applies with the next slicer/extractor.
\xintexprname allows to apply such a |[a:b,c:d,N,e:f,...]| chain of
slicing/extracting also to an \emph{ople}, which is not a \emph{nutple}. We
simply apply the first step as has been described previously and successive
steps will only get applied to either \emph{nutples} or \emph{leaves}, the
latter getting silently removed by any attempted operation.
\subsubsection{Function arguments versus variables}
\label{sssec:funcargs}
In a function declaration with \csbxint{deffunc}, the call signature is parsed
as a comma separated list, so here it is not true that repeated commas are
like only one: repeated commas are not allowed and will break the function
declaration.
When \xintexprname parses a function call, it first constructs the ople which
is delimited by the opening and closing parentheses, then it applies the
function body, after having mapped the successive items (not the elements) of
the parsed ople to the variables appearing in the function call
signature. Hence the arguments in the call signature stand for |one-ples|
(i.e.\@{} either |numbers| or |nutples|).
Let me explain why we can not define a function |foo(A,B)| of two oples: the
function call will evaluate as an ople what is enclosed within the
parentheses. It is then impossible in general to split this uniquely into two
oples |A| and |B|, except if for example we know a priori the length of |A|.
We could imagine defining a declarative interface for a |foo(A,B)| with |A|
preset to have \dtt{37} items or at least a pre-defined number of items but
this is extraneous layer for a functionality no-one will use.
The alternative would be to consider that declaring |foo(A,B)| means |A| will
pick-up always the first item and |B| all the remaining ones, and thus will be
an ople; here, there are some \TeX nical implementation reasons which have
dissuaded the author to do this.
In its place, a special syntax |foo(A,*B)| for the declaration of the function
is available. It means that |B| stands for the |nutple| which
receives as items all arguments in the function call beyond the first one
already assigned to |A|.
More generally, the last positional argument in a function declaration can
have the form |*|\meta{argname}. This then means that \meta{argname}
represents a |nutple| which will receive as items all arguments in the
function call remaining after the earlier positional arguments have been
assigned. The declared function body is free to again use the syntax
|*|\meta{argname} which will unpack it and thus produce the ople concatenating
all such optional arguments.
With \csbxint{defvar} one can define a variable with value an |ople| of
arbitrary cardinality. Such a variable can be used in a function call, it
will then occupy the place of as many arguments as its cardinality (which is
its number of elements, hence of its associated items). For example if
function |foo| was declared as a function of 5 arguments |f(a,b,c,d,e)| it is
legitimate to use it as |f(A,B)| if |A| is an ople-valued variable of length
three and |B| of length two. The actual arguments |a,b,c,d,e| will be made to
match the three items of |A| and the two items of |B|.
\subsubsection{Final words on leaves}
In case things were too clear, let's try to add a bit of confusion with an
extra word on \emph{leaves}. When we discuss informally (particularly to
compare with NumPy) an input such as
\begin{everbatim}
[[1, 2], [3, 4]]
\end{everbatim}
we may well refer to |1|, |2|, |3|, and |4| as being \myenquote{the leaves of the 2d
array}. But obviously we have here numbers and previously we explained that a
number is not a \emph{leaf}, its \emph{atom} is. Well, the point here is that
we must make a difference between the input form as above and the actual
constructed \emph{ople} the parser will obtain out of it. In the input we do
have numbers. The comma is a \emph{concatenator}, it is not a separator for
enumeration! The \emph{ople} which corresponds to it has a \TeX{}
representation like this:
\begin{everbatim}
{{{1}{2}}{{3}{4}}}
\end{everbatim}
where we don't have the \emph{numbers} anymore (which would look like |{{1}}|,
|{{2}}|, ...) but numeric \emph{atoms} |{1}|, |{2}|, |{3}|, |{4}| where the
braces are \TeX{} braces and \textbf{not} set-theoretical braces (the other
braces are both). Hence we should see the above as the |ople|
$\{\{A_{00}A_{01}\}\{A_{10}A_{11}\}\}$ with atoms $A_{00}=\{1\}$, ..., being the
\emph{leaves} of the tree associated to (or which is) the \emph{ople}.
Numbers may be called the \emph{leaves} of the \textbf{input}, but once
parsed, the input becomes an \emph{ople} which is
(morally) a tree whose leaves are \emph{atoms} (and the empty set).
This discussion can also be revisited with footnote
%%\footref{fn:alttree}
\ref{fn:alttree} in mind.
\subsubsection{Farewell, thanks for your visit!}
I hope this is clear to everyone. If not, maybe time to say this section is
not needed to understand almost all of the manual, but I needed to
write it to be able to maintain in future my own software.
\subsection{Expansion (for geeks only)}
As mentioned already, the parsers are compatible with expansion-only
context.
Also, they expand the expression piece by piece: the normal mode of operation
of the parsers is to unveil the parsed material token by token. Unveiling is
a process combining space swallowing, brace removal (one level generally), and
\fexpan sion.
For example a closing parenthesis after some function arguments does not have
to be immediately visible, it and the arguments themselves may arise from
\fexpan sion (applied before grabbing each successive token). Even the ending
|\relax| may arise from expansion. Even though the \csbxint{eval} user
interface means that the package has at some point the entire expression in
its hands, it immediately re-inserts it into token stream with an additional
postfixed |\relax| and from this point on has lost any ways (a simple-minded
delimited macro won't do because the expression is allowed to contain
sub-\csbxint{expr}essions, even nested) to manipulate formally again the whole
thing; it can only re-discover it one token at a time.
This general behaviour (which allows much more freedom in assembling
expressions than is usually the case with familiar programming languages such
as Python, although admittedly that freedom will prove useful only to
power-\TeX users and possibly does not have that many significant use cases)
has significative exceptions. These exceptions are mostly related to
\myenquote{pseudo}-functions. A \myenquote{pseudo}-function will grab some of its arguments via
delimited macros. For example |subs(expr1,x=expr2)| needs to see the comma,
equal sign and closing parenthesis. But it has mechanisms to allow |expr1| and
|expr2| to possess their own commas and parentheses.
Inner semi-colons on the other hand currently always can originate from expansion.
Defining functions or variables requires a visible semi-colon acting as
delimiter of the expression, but inner semi-colons do not need to be
hidden within braces or macros.
The expansion stops only when the ending |\relax| has been found
(it is then removed from the token stream).
For catcode related matters see \csbxint{exprSafeCatcodes}.
A word of warning on the bracketed optional argument of respectively
\csbxint{floatexpr} and \csbxint{iexpr}. When defining macros which will hand
over some argument to one of these two parsers, the argument may potentially
start with a left square bracket |[| (e.g. argument could be |[1, 2, 3]|) and
this will break the parser. The fix is to use in the macro definition
|\xintfloatexpr\empty|. This extra |\empty| token will prevent the parser
from thinking there is an optional argument and it will then disappear during
expansion.
\begin{footnotesize}
If comparing to other languages able to handle floating point numbers or big
integers, such as Python, one should take into account that what the \xintname
packages manipulate are streams of ascii bytes, one per digit. At no time
(due to expandability) is it possible to store intermediate results in an
arithmetic CPU register; each elementary operation via |\the\numexpr| will
output digit tokens (hence as many bytes), not things such as handles to
memory locations where some numbers are stored as memory words. The process
can never put aside things but can only possibly permute them with upcoming
tokens, to use them later, or, via combinations of |\expanded| and
|\unexpanded| or some other more antiquated means grab some tokens and shift
the expansion to some distant locations to later come back. The process is a
never-ending one-dimensional one...\par
\end{footnotesize}
\subsection{Known bugs/features (last updated at \texttt{1.4n})}
\begin{description}
% probable wont-fix
\item[{\cs{xinteval}\char`\{\cs{xintLength}\char`\{\cs{par}\cs{par}\cs{par}\char`\}\char`\}} complains about a Runaway argument:]\mbox{}
|\xintLength{\par\par\par}| has no issue as
|\xintLength| is a |\long| macro but this is not the case of
|\xinteval|. Most macros of a non arithmetic nature in
\xintkernelname and \xinttoolsname are declared |\long| but
absolutely none in \xintexprname, and its dependencies \xintname, etc...
%
As a remark in passing, I could not use the \LaTeX{} |\item| directly:%
%
\footnote{For those who wonder my custom |\verb| employs a
|\scantokens| approach, so it can be used in the argument of a
macro, for example \verb+\footnote{\verb|\verb|}+.}
%
\begin{everbatim}
Runaway argument?
{|\xinteval {\xintLength {
! Paragraph ended before \@item was complete.
\par
l.4434 \item[{|\xinteval{\xintLength{\par
\par\par}| complains about a Runawa...
\end{everbatim}
This is the reason I guess why everything is a priori |\long| in the
\LaTeX3 interface except if asked for otherwise (as far as I know).
Although most macros are dealing with inputs which can only be with digits
and some other character tokens, it would still be quite some work to
chase all top-level ones. Besides, in pratice, it does help better locate
ill-formed input.
\item[|if(100>0,(100,125),(100,128))| breaks my code:]
%
This is a feature. This is a syntax error, as the comma serves to contatenate
"oples" (see \autoref{oples}), and parentheses do not create analogs of
"tuples", so this input is parsed the same as
\begin{everbatim}
if(100>0,100,125,100,128)
\end{everbatim}
which is an error as \func{if} requires exactly three arguments, not
five. Use:
\begin{everbatim}
if(100>0,[100,125],[100,128])
\end{everbatim}
which will expand to the "tuple" |[100,125]|.
\item[{\cs{xintdeffunc} |foo(x):= gcd((x>0)?{[x,125]}{[x,128]});|
creates a broken function:}]
%
Bug. Normally \func{gcd} (and other
multi-arguments functions) work both with open lists of arguments or
bracketed lists ("nutples") and the above syntax would work perfectly fine
in numerical context. But the presence of the \oper{?} breaks in
\csbxint{deffunc} context the flexibility of \func{gcd}.
Currently working alternatives:
\begin{everbatim}
\xintdeffunc foo(x) := gcd(if(x>0, [x,125], [x,128]));
\xintdeffunc foo(x) := if(x>0, gcd(x,125), gcd(x,128));
\xintdeffunc foo(x) := if(x>0, gcd([x,125]), gcd([x,128]));
\xintdeffunc foo(x) := gcd((x>0)?{x,125}{x,128});
\xintdeffunc foo(x) := (x>0)?{gcd(x,125)}{gcd(x,128)};
\xintdeffunc foo(x) := (x>0)?{gcd([x,125])}{gcd([x,128])};
\end{everbatim}
The same problem will arise with an \oper{??} nested inside \func{gcd} or
similar functions, in an \csbxint{deffunc}.
\item[{\cs{xinteval}|{0^-.5}| says "0 raised to power -1"}]
%
Feature. Half integer exponents are handled via a square-root extraction, so
here \xintexprname wanted to first raise \dtt{0} to power \dtt{-1}, as
reported.
\item[{Comparison operator |==| crashes with nutples}]
%
Not yet implemented...
\item[{I liked the ``broadcasting'' |[1..10]^10| syntax, but it
was removed at 1.4}]
%
Patience...\@{} |seq(x^10,x=1..10)| is alternative (add external |[..]| to get
a nutple).
\item[{|1e\numexpr5+2\relax| crashes}]
%
Not clear yet if bug or feature.
The syntax accepted in the scientific part is limited, and failure
is expected: hitting a |\numexpr|
when parsing a number triggers insertion of a tacit multiplication and then
|1e| is missing the scientific exponent. The same happens with |1e(2+3)|.
Use syntax such as |1e\the\numexpr5+2\relax|, or |1e\xinteval{5+2}|
(although here this relies on output format of |\xinteval| using integer
notation with no decoration in this case).
\item[{|seq(1e-i,i=1..5)| crashes}]
%
Not clear if bug or feature. Use |seq(1e\xinteval{-i},i=1..5)| or, as a
possibly faster way |seq(1e\xintiieval{-i},i=\xintiiexpr1..5\relax)|.
\item[{\keyword{omit}/\keyword{abort} if nested and not last in the sub-expression cause a crash}]
%
For example |seq(subs((i)?{i}{abort},t=i)+10, i=-2, -1, 0, 1)| crashes, due
to the presence of the |+10|. This is a longstanding limitation, applying
ever since |omit/abort| were added to the syntax at |1.1|. Even without
the |+10| the nested case was broken by a |1.4| regression and got fixed
only at |1.4h|. The non-nested case |seq((i)?{i}{abort}+10, i=-2, -1, 0,
1)| works and the \myenquote{must be last in expression if nested} limitation is
currently considered a feature.
\item[{|\xintdeffunc X(a,k)= add(n^k, n=1..a);| creates a broken function:}]
%
Bug. Sadly \csbxint{deffunc} has problems. When it does not work, use
\csbxint{NewFunction} to define the function. Examples:
\begin{everbatim*}
\xintNewFunction{myX}[2]{add(n^#2, n=1..#1)}\xinteval{myX(10,7)}\newline
\xintNewFunction{myY}[2]{mul(1 - j/#1, j=1..#2-1)}\xintfloateval{myY(10,10)}
\end{everbatim*}
\item[{|seq([i,i^2], i=1..10)| crashes with Ooops, looks like we are missing a
]. Aborting!}]
%
Bug. The cause is that the square brackets do not hide the comma from
|seq()| parsing. Contrarily to what happens with parentheses, there
is no balancing mechanism for square brackets. Work-arounds: either
use an extra pair of parentheses |seq(([i,i^2]), ...)| or hide the
inner comma within braces |seq([i{,}i^2], ...)|.
\item[{|subs([x,x^2],x=3);| crashes with Ooops, looks like we are missing a ]. Aborting!}]
%
Bug. Same cause as previous one. Workaround: use parentheses
|subs(([x,x^2]),x=3| or curly braces |subs({[x,x^2]},x=3|.
\begin{everbatim*}
\xinteval{subs({[x^10,x^20,x^30]}, x=17)}
\end{everbatim*}
\item[{|seq([x,2x,3x],x=3..5);| crashes with Ooops, looks like we are
missing a ]. Aborting!}]
%
Bug. Same cause as previous one. The
workaround is again to use braces to hide the inner commas.
\begin{everbatim*}
\xinteval{seq({[x^10,x^20,x^30]}, x=1, 2, 3)}
\end{everbatim*}
\item[{%
\settowidth{\dimen0}{we are missing a ]. Aborting!}%
\makebox[\the\dimen0][l]
{\parbox[b]{\linewidth}
{|iter([1,10^6];[sqrt(@[0]*@[1]),(@[0]+@[1])/2], i=1..7)|
also complains with Ooops, looks like we are missing a ]. Aborting!}%
}%
}]
%
Bug. Turns out that braces would not do the job here, but parentheses do work:
\begingroup\xintSetDigits{32}%
\begin{everbatim*}
% 32 digits and 8 iterations v------ parentheses added ------v
\xintfloateval{iter([1,10^6];([sqrt(@[0]*@[1]),(@[0]+@[1])/2]), i=1..8)}
\end{everbatim*}
\endgroup
\end{description}
More bugs are known to the author and many more no doubt exist.
\clearpage
\etocdepthtag.toc {part1B}
\let\xintexprnameUp\undefined
\csname xintexpr (old doc)nameUp\endcsname
\section{The macros of \xintexprname (ancient documentation, mostly)}%
\RaisedLabel{sec:oldxintexpr}
\localtableofcontents
\subsection{Introduction}
The \xintexprname package was first released with version |1.07|
(|2013/05/25|) of the \xintbundlename. It was substantially enhanced with
release |1.1| from |2014/10/28|.
The |1.4| release from |2020/01/31| maintains the same general architecture
but needed adapting all the code base for the switch from |\csname| to
|\expanded| techniques. On this occasion the mechanism for defining functions
was substantially strengthened. The parser core mechanisms were improved too.
The package loads automatically \xintfracname and \xinttoolsname.
This section should be trimmed to contain only information not
already covered in \autoref{sec:expr}.
\subsection{The \csh{xintexpr} expressions}
\label{xintexpr}
\label{xinttheexpr}
\label{xintthe}
An \xintexprname{}ession is a construct
\csbxint{expr}\meta{expandable\_expression}|\relax|\etype{x} where the
expandable expression is read and completely expanded from left to right.
An |\xintexpr...\relax| \emph{must} end in a |\relax| (which will be absorbed).
Contrarily to a |\numexpr| expression, it is printable as is without a prefix
|\the| or |\number| (don't use them with |\xintexpr| this will raise an
error).
But one can use |\xintthe| prefix if one does need the explicit digits and
other characters as in the final typesetted result.
As an alternative and equivalent syntax to
\begin{everbatim}
\xintexpr round(, D)\relax
\end{everbatim}
there is
\begin{everbatim}
\xintiexpr [D] \relax
\end{everbatim}
For |D>0| this produces a decimal number with |D| figures after the decimal
mark, which is the rounding of the expression. For |D=0| the rounding to an
integer is produced. For |D<0| (and this was changed at |1.4f|), the rounded
quotient of the expression by \verb=1e|D|= is produced.
\begin{itemize}
\item the expression may contain arbitrarily many levels of nested parenthesized
sub-expressions,
\item the expression may contain explicitely or from a macro expansion a
sub-expression |\xintexpr...\relax|, which itself may contain a
sub-expressions etc\dots
\item to let sub-contents evaluate as a sub-unit it should thus be either
\begin{enumerate}
\item parenthesized,
\item or a sub-expression |\xintexpr...\relax|.
\end{enumerate}
\item to use an expression as argument to macros from \xintfracname,
or more generally to macros which expand their arguments, one must use the
|\xinttheexpr...\relax| or |\xintthe\xintexpr...\relax| forms.
\item one should not use |\xintthe\xintexpr...\relax| as a sub-constituent of
another expression but only the
|\xintexpr...\relax| form which is more efficient in this context.
\item each \xintexprname{}ession, whether prefixed or not with |\xintthe|, is
completely expandable and obtains its result in two expansion steps.
\end{itemize}
The information now following is possibly in need of updates.
\begin{itemize}[parsep=0pt, labelwidth=\leftmarginii,
itemindent=0pt, listparindent=\leftmarginiii, leftmargin=\leftmarginii]
\item An expression is built the standard way with opening and closing
parentheses, infix operators, and (big) numbers, with possibly a fractional
part, and/or scientific notation (except for \csbxint{iiexpr} which only
admits big integers). All variants work with comma separated expressions. On
output each comma will be followed by a space. A decimal number must have
digits either before or after the decimal mark.
\item As everything gets expanded, the characters |.|, |+|, |-|, |*|, |/|, |^|,
|!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, |=|, |(|, |)|, |"|, |]|, |[|, |@|
and the comma |,| should not (if used in the expression) be active.
\begin{snugframed}
\begin{itemize}[nosep]
\item Babel-activated\NewWithf{1.4n} characters (for example |!|,
|?|, |;| and |:| with French) are not a problem.
\item If the character is active due to some other mechanism, prefix it with
|\string|.
\item A few syntax elements involving the comma, the equal sign and the
closing parenthesis are implemented using delimited macros. They are
not allowed to be catcode active (even via Babel) and |\string| will
not work. Use then \csbxint{exprSafeCatcodes}, see next.
\end{itemize}
\end{snugframed}
One can use \csbxint{exprSafeCatcodes} to reset all
characters potentially needed by \csbxint{expr} to their standard catcodes
and \csbxint{exprRestoreCatcodes} then restores the former status.
Note that this is what \csbxint{defvar} and \csbxint{deffunc} do automatically.
Expandable \csbxint{floateval} et al. can't do that.
\item Count registers and |\numexpr|-essions are accepted (LaTeX{}'s counters
can be inserted using |\value|) natively without |\the| or |\number| as
prefix. Also dimen registers and control sequences, skip registers and
control sequences (\LaTeX{}'s lengths), |\dimexpr|-essions,
|\glueexpr|-essions are automatically unpacked using |\number|, discarding
the stretch and shrink components and giving the dimension value in |sp|
units ($1/65536$th of a \TeX{} point). Furthermore, tacit multiplication is
implied, when the (count or dimen or glue) register or variable, or the
(|\numexpr| or |\dimexpr| or |\glueexpr|) expression is immediately prefixed
by a (decimal) number. See \autoref{ssec:tacit multiplication} for the complete rules
of tacit multiplication.\IMPORTANT
\item With a macro |\x| defined like this:
%
\leftedline{|\def\x {\xintexpr \a + \b \relax}| or |\edef\x {\xintexpr
\a+\b\relax}|}
%
one may then do |\xintthe\x|, either for printing the result on the page or
to use it in some other macros expanding their arguments. The |\edef| does
the computation immediately but keeps it in a protected form.
Naturally, the |\edef| is only possible if |\a| and |\b| are already
defined. With both approaches the |\x| can be inserted in other expressions,
as for example (assuming naturally as we use an |\edef| that in the
`yet-to-be computed' case the |\a| and |\b| now have some suitable meaning):
%
\leftedline {|\edef\y {\xintexpr \x^3\relax}|}
\item There is also \csbxint{boolexpr}| ... \relax| and
\csbxint{theboolexpr}| ... \relax|.
\item See also
\csbxint{ifboolexpr} (\autoref{xintifboolexpr}) and the
\func{bool} and \func{togl} functions
in \autoref{sec:expr}. Here is an example. Well in fact the
example ended up using only \csbxint{boolexpr} so it
was modified to use \csbxint{ifboolexpr}.
\catcode`| 12 %
\begin{everbatim*}
\xintdeffunc A(p,q,r) = p && (q || r) ;
\xintdeffunc B(p,q,r) = p || (q && r) ;
\xintdeffunc C(p,q,r) = xor(p, q, r) ;
\centeredline{\normalcolor
\begin{tabular}{ccrclcl}
\xintFor* #1 in {{False}{True}} \do {%
\xintFor* #2 in {{False}{True}} \do {%
\xintFor* #3 in {{False}{True}} \do {%
#1 &AND &(#2 &OR )&is&\textcolor[named]{OrangeRed}
{\xintifboolexpr{A(#1,#2,#3)}{true}{false}}\\
#1 &OR &(#2 &AND )&is&\textcolor[named]{OrangeRed}
{\xintifboolexpr{B(#1,#2,#3)}{yes}{no}}\\
#1 &XOR & #2 &XOR &is&\textcolor[named]{OrangeRed}
{\xintifboolexpr{C(#1,#2,#3)}{oui}{non}}\\
}}}
\end{tabular}%
}
\end{everbatim*}\catcode`| 13
\item See also \csbxint{ifsgnexpr}.
\item There is \csbxint{floatexpr}| ... \relax| where the algebra is done
in floating point approximation (also for each intermediate result). Use the
syntax |\xintDigits:=N\relax| to set the precision. Default: $16$ digits.
%
\leftedline{|\xintthefloatexpr 2^100000\relax:| \dtt{\xintthefloatexpr
2^100000\relax }}
%
The square-root operation can be used in |\xintexpr|, it is computed
as a float with the precision set by |\xintDigits| or by the optional
second argument:
%
\begin{everbatim*}
\xinttheexpr sqrt(2,60)\relax\newline
Here the [60] is to avoid truncation to |\xinttheDigits| of precision on output.
\newline
\printnumber{\xintthefloatexpr [60] sqrt(2,60)\relax}
\end{everbatim*}
Floats are quickly indispensable when using the power function, as exact
results will easily have hundreds, even thousands of digits.
%
\begin{everbatim*}
\xintDigits:=48\relax \xintthefloatexpr 2^100000\relax
\end{everbatim*}
Only integer and (in |\xintfloatexpr...\relax|) half-integer exponents are
allowed.
\item if one uses \emph{macros} within |\xintexpr..\relax| one should
obviously take into account that the parser will \emph{not} see the macro
arguments, hence one cannot use the syntax there, except if the arguments
are themselves wrapped as |\xinttheexpr...\relax| and assuming the macro
\fexpan ds these arguments.
\end{itemize}
\subsection{\texorpdfstring{\texttt{\protect\string\numexpr}}{\textbackslash
numexpr} or \texorpdfstring{\texttt{\protect\string\dimexpr}}{\textbackslash
dimexpr} expressions, count and dimension registers and variables}
\label{ssec:countinexpr}
Count registers, count control sequences, dimen registers, dimen control
sequences (like |\parindent|), skips and skip control sequences, |\numexpr|,
|\dimexpr|, |\glueexpr|, |\fontdimen| can be inserted directly, they will be
unpacked using |\number| which gives the internal value in terms of scaled
points for the dimensional variables: $1$\,|pt|${}=65536$\,|sp| (stretch and
shrink components are thus discarded).
Tacit multiplication (see \autoref{ssec:tacit multiplication}) is implied,
when a number or decimal number prefixes such a register or control sequence.
\LaTeX{} lengths are skip control sequences and \LaTeX{} counters should be
inserted using |\value|.
Release |1.2| of the |\xintexpr| parser also recognizes and prefixes with
|\number| the |\ht|, |\dp|, and |\wd| \TeX{} primitives as well as the
|\fontcharht|, |\fontcharwd|, |\fontchardp| and |\fontcharic| \eTeX{}
primitives.
In the case of numbered registers like |\count255| or |\dimen0| (or |\ht0|),
the resulting digits will be re-parsed, so for example |\count255 0| is like
|100| if |\the\count255| would give |10|. The same happens with inputs such
as |\fontdimen6\font|. And |\numexpr 35+52\relax| will be exactly as if |87|
as been encountered by the parser, thus more digits may follow: |\numexpr
35+52\relax 000| is like |87000|. If a new |\numexpr| follows, it is treated
as what would happen when |\xintexpr| scans a number and finds a non-digit: it
does a tacit multiplication.
\begin{everbatim*}
\xinttheexpr \numexpr 351+877\relax\numexpr 1000-125\relax\relax{} is the same
as \xinttheexpr 1228*875\relax.
\end{everbatim*}
Control sequences however (such as |\parindent|) are picked up as a whole by
|\xintexpr|, and the numbers they define cannot be extended extra digits, a
syntax error is raised if the parser finds digits rather than a legal
operation after such a control sequence.
A token list variable must be prefixed by |\the|, it will not be unpacked
automatically (the parser will actually try |\number|, and thus fail). Do not
use |\the| but only |\number| with a dimen or skip, as the |\xintexpr| parser
doesn't understand |pt| and its presence is a syntax error. To use a dimension
expressed in terms of points or other \TeX{} recognized units, incorporate it in
|\dimexpr...\relax|.
Regarding how dimensional expressions are converted by \TeX{} into scaled points
see also \autoref{sec:Dimensions}.
\subsection{Catcodes and spaces}
The main problems are caused by active characters, because \csbxint{expr} et
al.\@{} expand forward whatever comes from token stream; they apply |\string|
only in a second step. For example the catcode of |&| from |&&| Boolean
disjunction is not really important as long as it is not active, or comment,
or escape...\@{} or brace...\@{} or ignored...\@{} in brief, as long as it is reasonable,
and in particular whether |@| is of catcode letter or other does not matter.
It is always possible to insert manually the |\string| in the expression
before a problematic (but reasonable) character catcode, or even to use
|\detokenize| for a big chunk.
\subsubsection{\csh{xintexprSafeCatcodes}}
\label{xintexprSafeCatcodes}
Some problems with active characters can be resolved on the fly by prefixing
them by |\string| but some aspects of the parsing done by \csbxint{expr}
involves delimited macros which need the comma, equality sign and closing
parenthesis to have their standard catcodes.
So \csbxint{exprSafeCatcodes} is provided as a utility to set in one go
catcodes of many characters to \csbxint{expr}-safely compatible values. This
is a non-expandable step as it changes catcodes.
% This is used
% internally by \csbxint{NewExpr} (restoring the catcodes on exit), hence it
% does not have to be protected against active characters when used at
% top-level.
\csbxint{defvar}, \csbxint{deffunc}, et al., use it, and then they restore
catcodes to the prior state via \csbxint{exprRestoreCatcodes}.
% As \csbxint{NewExpr} and \csbxint{deffunc} and variants use internally some
% |\scantokens|, they will (reasonably) succeed in sanitizing catcodes in the
% expressions, even if all is from the replacement text of some macro whose
% definition was done under some special catcode regime.
% \csbxint{deffunc} is more lenient than \csbxint{defvar} regarding catcodes of
% characters in expression bodies as it does some |\scantokens| which will reset
% compatible catcodes.
% Even if used in a context where catcodes are already set, \csbxint{deffunc},
% \csbxint{defvar} and variants ignore completely the colon in |:=| so it can
% have any (reasonable) catcode. Moreover it is optional.
% The semi-colon in the syntax of \csbxint{Digits} is no real problem either
% (cf. \csbxint{Digits} documentation).
\subsubsection{\csh{xintexprRestoreCatcodes}}
\label{xintexprRestoreCatcodes}
Restores the catcodes to the state prevailing at the time of the last executed
\csbxint{exprSafeCatcodes} (if located at the same \LaTeX\ environment or
\TeX\ grouping level).
Prior to |1.4k|, in a situation like the following:
\begin{everbatim}
\xintexprSafeCatcodes
....stuff possibly changing catcodes
\xintexprSafeCatcodes
....stuff possibly changing catcodes
\xintexprSafeCatcodes
....stuff possibly changing catcodes
\xintexprRestoreCatcodes
\end{everbatim}
On exit, the catcodes recovered their status as prior to the \emph{first}
\csbxint{exprSafeCatcodes}. Since |1.4k|, they are set to what they were
prior to the \emph{last} \csbxint{exprSafeCatcodes}, i.e. the mechanism is now
similar to a ``last in, first out'' stack.
Note that no global assignments are made so the behaviour can be modified
by usage of \TeX\ groups or \LaTeX\ environments: e.g. if an
\csbxint{exprSafeCatcodes} is issued inside a \LaTeX\ environment it does not
have to be paired by \csbxint{exprRestoreCatcodes} explicitly, the catcode
scope is limited by the environment.
\bigskip
Spaces inside an |\xinttheexpr...\relax| should mostly be
innocuous (except inside macro arguments).
|\xintexpr| and |\xinttheexpr| are for the most part agnostic regarding
catcodes,
but the characters
% |+|, |-|, |*|, |/|, |^|, |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|,
%|=|, |(|, |)|, |"|, |[|, |]|, |;|,
in the expression should not be \myenquote{active} (except on purpose)
as everything is expanded along the way, and |\xintexpr| will choke on
typesetting related commands. One can (in almost all cases) use
|\string| to prefix a problematic character.
\begin{snugframed}
Babel-activated\NewWithf{1.4n} characters are not a problem.
\end{snugframed}
Digits, slash, square brackets, minus sign, in the output from an
|\xinttheexpr| are all of catcode 12. For |\xintthefloatexpr| the `e' in the
output has its standard catcode ``letter''.
\subsection{Expandability, \csh{xintexpro}}
As is the case with all other package macros |\xintexpr| \fexpan ds (in two
steps) to its final (somewhat protected) result; and |\xinttheexpr| \fexpan ds
(in two steps) to the chain of digits (and possibly minus sign |-|, decimal
mark |.|, fraction slash |/|, scientific |e|, square brackets |[|, |]|)
representing the result.
The once expanded |\xintexpr| is |\romannumeral0\xintexpro|. And there
are similarly |\xintiexpro| |\xintiiexpro| and |\xintfloatexpro|. For an
example see \autoref{ssec:fibonacci}.
An expression can only be legally terminated by a |\relax| token, which
will be absorbed. This token may arose from expansion, it does not have
to be immediately visible.
It is quite possible to nest expressions among themselves; for example, if one
needs inside an |\xintiiexpr...\relax| to do some computations with fractions,
rounding the final result to an integer, one just has to insert
|\xintiexpr...\relax|. The functioning of the infix operators will not be in
the least affected from the fact that the outer ``environment'' is the
|\xintiiexpr| one.
\subsection{\csh{xintDigits*}, \csh{xintSetDigits*}}
\label{xintDigits*}
\label{xintSetDigits*}
These starred variants of \csbxint{Digits} and \csbxint{SetDigits} are
only aliases\CHANGED{2.0a1} to the non-starred versions.
\subsection{\csh{xintiexpr}, \csh{xinttheiexpr}}
\label{xintiexpr}\label{xinttheiexpr}
Equivalent\etype{x} to doing |\xintexpr round(...)\relax| (more precisely,
|round| is applied to each leaf item of the |ople| independently of its
depth).
Intermediate calculations are exact, only the final output gets
rounded. Half integers are rounded towards $+\infty$ for positive
numbers and towards $-\infty$ for negative ones.
An optional parameter |D| within brackets, immediately after |\xintiexpr| is
allowed: it instructs (for |D>0|) the expression to do its final rounding to
the nearest value with that many digits after the decimal mark, i.e.\@
|\xintiexpr [D] \relax| is equivalent (in case of a single
expression) to |\xintexpr round(, D)\relax|.
|\xintiexpr [0] ...| is the same as |\xintiexpr ...| and rounds to an integer.
The case of negative |D| gives quantization to an integer multiple of
\dtt{1e-D}. This was modified at |1.4f| and the produced value
is now the rounded quotient by \dtt{1e-D} (i.e. no trailing zeros nor
scientific exponent in the output).
If truncation rather than rounding is needed on can use |\xintexpr
trunc(...)\relax| for truncation to an integer or |\xintexpr
trunc(...,D)\relax| for quantization to an integer multiple or \dtt{1eD} (if
|D>0|, for |D<0| the analog would be |trunc((...)/1e-D)|). But
this works only for a single scalar value.
\begin{framed}
When defining a macro doing something such as |\xintiexpr #1\relax|,
it is recommended to rather use |\xintiexpr\empty #1\relax|, as the
|#1| may start with a |[| which without the |\empty| would be
interpreted by |\xintiexpr| as the start of the optional |[D]|.
\end{framed}
\subsection{\csh{xintiiexpr}, \csh{xinttheiiexpr}}
\label{xintiiexpr}\label{xinttheiiexpr}
This variant\etype{x} does not know fractions. It deals almost only with long
integers. Comma separated lists of expressions are allowed.
\begin{framed}
It maps |/| to the \emph{rounded} quotient. The operator
|//| is, like in |\xintexpr...\relax|, mapped to \emph{truncated} division.
The Euclidean quotient (which for positive operands is like the truncated
quotient) was, prior to release |1.1|, associated to |/|. The function
|quo(a,b)| can still be employed.
\end{framed}
The \csbxint{iiexpr}-essions use the `ii' macros for addition, subtraction,
multiplication, power, square, sums, products, Euclidean quotient and
remainder.
The \func{floor} and \func{ceil} functions are available in this integer
only parser, with arguments allowed to be decimal numbers. But for
example |floor(5/3)| returns the perhaps counter intuitive value |2|,
because |/| does the rounded division to an integer. To force the
parser to allow fractions and not interpret |/| as integer-only
operator, uses \func{qfrac} as in the examples below.
Also \func{round} and \func{trunc} are allowed in
\csbxint{iiexpr}-essions: they are mapped to \csbxint{iRound} and
\csbxint{iTrunc} which explains how they behave with respect to their
optional second argument.
\begin{everbatim*}
\xinttheiiexpr 5/3, round(5/3,3), trunc(5/3,3),
\relax{} do the integer division
%
\xinttheiiexpr 5/3, round(qfrac(5/3),3), trunc(qfrac(5/3),3), floor(qfrac(5/3)),
ceil(qfrac(5/3))\relax{} work!
\end{everbatim*}
% trunc(\xintDiv {5}{3},3), % NOT ALLOWED WITH xint-calx 2.0
% trunc(\xintRaw {5/3},3)% NOT ALLOWED WITH xint-calx 2.0
\begin{framed}
Scientific notation is perfectly legitimate if it
defines an integer:\NewWithf{2.0}
\begin{everbatim*}
\xintiieval{1e20}
\xintiieval{100000000e-4}
\end{everbatim*}
No need to use |num()|.
On the other hand the \xintfracname "raw" format such as
|5/3[0]| \textbf{is no longer supported} for input in \csbxint{iieval},
even as first argument to |trunc()| or |round()|.
\end{framed}
The |reduce| function is not available and will raise an error. The |frac|
function also. The |sqrt| function is mapped to \csbxint{iiSqrt} which gives
a truncated square root. The |sqrtr| function is mapped to \csbxint{iiSqrtR}
which gives a rounded square root.
One can use the Float macros if one is careful to use |num|, or |round|
etc\dots on their output.
\begin{everbatim*}
\xinttheiiexpr \xintFloatSqrt [20]{2},
\xintFloatSqrt [20]{3}\relax % no operations
\end{everbatim*}
The above went through because no actual operations were carried out. But it
is dangerous because the ``printer'' for \csbxint{theiiexpr} could choke on
such values. By default however it does nothing.
In the next example there will be an addition. So we firt apply |round| to
get integers (the second argument of |round| and |trunc| tells how many digits
from after the decimal mark one should keep.)
\begin{everbatim*}
\xinttheiiexpr round(\xintFloatSqrt [20]{2},19) +
round(\xintFloatSqrt [20]{3},19)\relax
\end{everbatim*}
The whole point of \csbxint{iiexpr} is to gain some speed in
\emph{integer-only} algorithms, and the above explanations related to how to
nevertheless use fractions therein are a bit peripheral. We observed
(2013/12/18) of the order of $30$\% speed gain when dealing with numbers with
circa one hundred digits (1.2: this info may be obsolete).
\subsection{\csh{xintboolexpr}, \csh{xinttheboolexpr}}
\label{xintboolexpr}\label{xinttheboolexpr}
Equivalent\etype{x} to doing |\xintexpr ...\relax| and returning |true| if the
result does not vanish, and |false| if the result is zero. As |\xintexpr|, this
can be used on comma separated lists of expressions, and even bracketed lists.
It can be customized, one only needs to modify the following:
\begin{everbatim}
\def\xintboolexprPrintOne#1{\xintiiifNotZero{#1}{true}{talse}}%
\end{everbatim}
Not only are |true| and |false| usable in input, also |True| and |False| are
pre-declared variables.
There is quirk in case it is used as a sub-expression: the boolean
expression needs at least one logic operation else the value is not
standardized to |1| or |0|, for example we get from
\begin{everbatim*}
\xinttheexpr \xintboolexpr 1.23\relax\relax\newline
\end{everbatim*}which is to be compared with
\begin{everbatim*}
\xinttheboolexpr 1.23\relax
\end{everbatim*}
% A related issue existed with
% |\xinttheexpr \xintiexpr 1.23\relax\relax|, which was fixed with |1.1|
% release, and I decided back then not to add the needed overhead also to the
% |\xintboolexpr| context, as one only needs to use |?(1.23)| for example or
% involve the |1.23| in any logic operation like |1.23 'and' 3.45|, or involve
% the |\xintboolexpr ..\relax | itself with any logical operation, contrarily to
% the sub-|\xintiexpr| case where |\xinttheexpr 1+\xintiexpr 1.23\relax\relax|
% did behave contrarily to expectations until |1.1|.
\subsection{\csh{xintfloatexpr},
\csh{xintthefloatexpr}}
\label{xintfloatexpr}\label{xintthefloatexpr}
\csbxint{floatexpr}|...\relax|\etype{x} is a variant of
|\xintexpr...\relax| which does floating point operations.
The target precision for the computation is from the
current setting of |\xintDigits|. Comma separated lists of expressions are
allowed.
An optional parameter within brackets |[Q]| is allowed at the very start
of the expression:
\begin{itemize}
\item if positive it instructs the macro to round the result to that
many digits of precision. It thus makes sense to employ it only if
this parameter is less than the \csbxint{theDigits} precision.
\item if negative it means to trim off that many digits (of course, in
the sense of rounding the values to shorter mantissas). Don't use it
to trim all digits (or more than all)!
\end{itemize}
Since |1.2f| all float operations first round their arguments; a parsed number
is not rounded prior to its use as operand to such a float operation.
|\xintDigits:=36\relax|\xintDigits:=36\relax
%
\leftedline{|\xintthefloatexpr
(1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax|}
%
\leftedline{\dtt{\xintthefloatexpr
(1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax}}
% 0.00564487459334466559166166079096852897
%
\leftedline{|\xintthefloatexpr\xintexpr
(1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax\relax|}
%
\leftedline{\dtt{\xintthefloatexpr\xintexpr
(1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax\relax}}
\xintDigits := 16;
The latter is the rounding of the exact result. The former one has
its last three digits wrong due to the cumulative effect of rounding errors
in the intermediate computations, as compared to exact evaluations.
I recall here from \autoref{ssec:floatingpoint} that with release |1.2f| the
float macros for addition, subtraction, multiplication and division round
their arguments first to |P| significant places with |P| the asked-for
precision of the output; and similarly the power macros and the
square root macro. This does not modify anything for computations with
arguments having at most |P| significant places already.
\begin{framed}
When defining a macro doing something such as |\xintfloatexpr #1\relax|,
it is recommended to rather use |\xintfloatexpr\empty #1\relax|, as the
|#1| may start with a |[| which without the |\empty| would be
interpreted by |\xintfloatexpr| as the start of the optional |[Q]|.
\end{framed}
\subsection{\csh{xinteval}, \csh{xintieval}, \csh{xintiieval},
\csh{xintfloateval}}
\label{xinteval}\label{xintieval}\label{xintiieval}\label{xintfloateval}
\csbxint{eval}\etype{x} is an \fexpan dable macro which is basically
defined in such a way that |\xinteval|\marg{expression} behaves like
\csbxint{theexpr}\marg{expression}|\relax|. It expands completely in
two steps and delivers its output using digits, the dot |.| as decimal
separator, the letter |e| for scientific notation, the slash |/| for
fractions, as well as commas in case of multi-items expression and
square brackets |[| and |]| for nesting.
\csbxint{ieval}\etype{x} is similarly related to \csbxint{theiexpr}. It
admits an optional argument |[D]| which may be located in the expected
location from conventions of \LaTeX2e macros with optional argument, but
had been long constrained (until |1.4k|) to be inside the braces at the
start of the expression.
\begin{everbatim*}
\xintieval[7]{355/113} = \xintieval{[7]355/113}
\end{everbatim*}
\begin{framed}
When defining a macro doing something such as |\xintieval{#1}|,
it is recommended to rather use |\xintieval{\empty #1}|, as the
|#1| may start with a |[| which without the |\empty| would be
interpreted by |\xintieval| as the start of the optional |[D]|.
\end{framed}
\csbxint{iieval}\etype{x} is similarly related to \csbxint{theiiexpr}.
% \begin{everbatim*}
% \xintiieval{add(x^2, x = 100..110), add(x^3, x = 100..110)}
% \end{everbatim*}
\csbxint{floateval}\etype{x} is similarly related to
\csbxint{thefloatexpr}. It admits an optional argument |[Q]| which
may be located either outside (since |1.4k|) or inside the braces.
\begin{everbatim*}
\xintfloateval [7]{355/113} = \xintfloateval{[7] 355/113}
\end{everbatim*}
When negative, the optional argument tells how many digits to remove
from the prevailing precision:
\begin{everbatim*}
\xintfloateval[-2]{355/113}=
\xintfloateval{[-2]355/113} has \xinttheDigits\ minus 2 digits.
\end{everbatim*}
\begin{framed}
When defining a macro doing something such as |\xintfloateval{#1}|,
it is recommended to rather use |\xintfloateval{\empty #1}|, as the
|#1| may start with a |[| which without the |\empty| would be
interpreted by |\xintfloateval| as the start of the optional |[Q]|.
\end{framed}
\subsection{Using an expression parser within another one}
This was already illustrated before. In the following:
\begin{everbatim*}
\xintfloatexpr \xintexpr add(1/i, i=1234..1243)\relax ^100\relax
\end{everbatim*},
the inner sum is computed exactly. Then it will be rounded to |\xinttheDigits|
significant digits, and then its power will be evaluated as a float operation.
One should avoid the "|\xintthe|" parsers in inner positions as this induces
digit by digit parsing of the inner computation result by the outer parser.
Here is the same computation done with floats all the way:
\begin{everbatim*}
\xintfloatexpr add(1/i, i=1234..1243)^100\relax
\end{everbatim*}
Not surprisingly this differs from the previous one which was exact until
raising to the |100|th power.
The fact that the inner expression occurs inside a bigger one has nil
influence on its behaviour. There is the limitation though that the outputs
from \csbxint{expr} and \csbxint{floatexpr} can not be used directly in
\csbxint{theiiexpr} integer-only parser. But one can do:
\begin{everbatim*}
\xintiiexpr round(\xintfloatexpr 3.14^10\relax)\relax % or trunc
\end{everbatim*}
\subsection{The \csh{xintthecoords} macro}
\label{xintthecoords}
It converts (in two expansion steps) the expansion result of
\csbxint{floatexpr} (or \csbxint{expr} or \csbxint{iiexpr}) into the |(a, b)
(c, d) ...| format for list of coordinates as expected by the |TikZ|
|coordinates| syntax.
For use in the following way:
\centeredline{coordinates \{\csbxint{thecoords}\csbxint{floatexpr} ... \csa{relax}\}}
or rather perhaps (pay attention with the doubled \csa{relax})
\centeredline{coordinates \{\csbxint{thecoords}\csbxint{iexpr}[5]\csbxint{floatexpr} ... \csa{relax}\csa{relax}\}}
but attention, do NOT use it with \csbxint{thefloatexpr} only with \csbxint{floatexpr}.
The syntax with \csbxint{iexpr} and a rounding argument |[N]|
immediately following it is to make sure that TikZ's parser only gets some
decimal numbers with a |N| decimal places. Without it, i.e.\@ with only
\csbxint{floatexpr} (and possibly some float rounding optional argument |[P]|),
TikZ could receive numbers in scientific notation (but attow I don't recall
if that is a problem and I don't have time available to test).
TODO: donner un exemple plus joli.
\begin{everbatim*}
\begin{figure}[htbp]
\centering\begin{tikzpicture}[scale=10]\xintDigits:=8\relax
\clip (-1.1,-.25) rectangle (.3,.25);
\draw [blue] (-1.1,0)--(1,0);
\draw [blue] (0,-1)--(0,+1);
\draw [red] plot[smooth] coordinates {%
%%% \xintthecoords converts output of next expression into the
%%% (x1, y1) (x2, y2) ...
%%% format
\xintthecoords\xintfloatexpr
%%% This syntax -1+[0..4]/2 is currenty dropped at xint 1.4
%%% seq((x^2-1,mul(x-t,t=-1+[0..4]/2)),x=-1.2..[0.1]..+1.2)\relax
%%% Use this:
seq((x^2-1,mul(x-t,t=seq(-1+u/2, u=0..4))),x=-1.2..[0.1]..+1.2)
\relax
};
\end{tikzpicture}
\caption{Coordinates with \csbxint{thecoords}.}
\end{figure}
\end{everbatim*}
% Notice: if x goes not take exactly value 1 or -1, the origin appears slightly
% off the curve, not MY fault!!!
It is currently undecided how \csa{xintthecoords} should handle bracketed
data.\UNSTABLE{} Currently, it (or |TikZ|) will break it the input contains
nested structures. One can use it with \func{flat} which removes all nesting.
And in combination with \func{zip} it is easy to plot data given by some
mechanism in separate
lists of x- and y-coordinates (see an example in next section)
\subsection{The \csh{xintthespaceseparated} macro}
\label{xintthespaceseparated}
It converts (in two expansion steps) the expansion result of
\csbxint{floatexpr} (or \csbxint{expr} or \csbxint{iiexpr}) into the space
separated format suitable for usage with |PS-Tricks| |\listplot| macro.
Here is for example some syntax (the replacement text of |\foo|, which is used
here only to show that indeed complete expansion is attained in two steps)
which can be used as argument to |\listplot|. Using 4 fractional decimal
digits is sufficient when unit is the centimeter (it gives a fixed point
precision of one micron, amply enough for plots...).
\begin{everbatim*}
\oodef\foo{%
\xintthespaceseparated
\xintiexpr[4]\xintfloatexpr seq((i, log10(i)), i=1..[0.5]..10)\relax\relax
}\meaning\foo
\end{everbatim*}
Here we don't really need the inner |\xintfloatexpr...\relax| because the
\func{log10} function works the same in the exact parser |\xintexpr| but in
general this is recommended.
It is currently undecided how \csa{xintthespaceseparated} should handle
bracketed data.\UNSTABLE{} Currently, it (or |\listplot|) will break if the
input contains nested structures. One can use it with \func{flat} which
removes all nesting. And in combination with \func{zip} it is easy to plot
data given by some mechanism in separate lists of x- and y-coordinates.
\begin{everbatim*}
% let's imagine we have something like this
\def\Xcoordinates{1, 3, 5, 7, 9}
\def\Ycoordinates{1, 9, 25, 49, 81}
% then:
|\xintthespaceseparated\xintexpr flat(zip([\Xcoordinates], [\Ycoordinates]))\relax|
is suitable to use as argument to |\listplot|, as it expands to
\xintthespaceseparated\xintexpr flat(zip([\Xcoordinates], [\Ycoordinates]))\relax
\end{everbatim*}
\subsection{\csh{xintifboolexpr}, \csh{xintifboolfloatexpr}, \csh{xintifbooliiexpr}}
\label{xintifboolexpr}
\label{xintifboolfloatexpr}
\label{xintifbooliiexpr}
\csa{xintifboolexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does
\csbxint{theexpr}|\relax| and then executes the \meta{YES} or the
\meta{NO} branch depending on whether the outcome was non-zero or zero. Thus
one can read \emph{if bool expr} as meaning \emph{if not zero}:
\centeredline{if \meta{expr}-ession does not vanish do \meta{YES} else do
\meta{NO}}
The expression is not limited to using only comparison operators and Boolean
logic (|<|, |>|, |==|, |!=|, |&&|, \verb+||+, \func{all}, \func{any},
\func{xor}, \func{bool}, \func{togl}, ...), it can be the most general
computation.
\csa{xintifboolfloatexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does
\csbxint{thefloatexpr}\meta{expr}|\relax| and then executes the \meta{YES} or the
\meta{NO} branch depending on whether the outcome was non zero or zero.
\csa{xintifbooliiexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does
\csbxint{theiiexpr}\meta{expr}|\relax| and then executes the \meta{YES} or the
\meta{NO} branch depending on whether the outcome was non zero or zero.
The expression argument must be a single one, comma separated sub-expressions
will cause low-level errors.
\subsection{\csh{xintifsgnexpr}, \csh{xintifsgnfloatexpr}, \csh{xintifsgniiexpr}}
\label{xintifsgnexpr}
\label{xintifsgnfloatexpr}
\label{xintifsgniiexpr}
\csa{xintifsgnexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates
the \csbxint{expr}ession and chooses the branch corresponding to its sign.
\csa{xintifsgnfloatexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates
the \csbxint{floatexpr}ession and chooses the branch corresponding to its sign.
\csa{xintifsgniiexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates
the \csbxint{iiexpr}ession and chooses the branch corresponding to its sign.
The expression argument must be a single one, comma separated sub-expressions
will cause low-level errors.
\subsection{The \csh{xintNewExpr}, \csh{xintNewIIExpr},
\csh{xintNewFloatExpr}, \csh{xintNewIExpr}, and \csh{xintNewBoolExpr}
macros}
\label{xintNewExpr}
\label{xintNewIIExpr}
\label{xintNewFloatExpr}
\label{xintNewIExpr}
\label{xintNewBoolExpr}
\csbxint{NewExpr} macro is used as:
%
\leftedline{|\xintNewExpr{\myformula}[n]|\marg{stuff}, where}
\begin{itemize}
\item \meta{stuff} will be inserted inside |\xinttheexpr . . . \relax|,
\item |n| is an integer between zero and nine, inclusive, which is the number
of parameters of |\myformula|,
\item the placeholders |#1|, |#2|, ..., |#n| are used inside \meta{stuff} in
their usual r\^ole,%
%
\catcode`# 12
\footnote{if \csa{xintNewExpr} is used inside a macro,
the |#|'s must be doubled as usual.}
\footnote{the |#|'s will in pratice have their usual
catcode, but category code other |#|'s are accepted too.}
\catcode`# 6
%
\item the |[n]| is \emph{mandatory}, even for |n=0|.%
\footnote{there is some use for \csa{xintNewExpr}|[0]| compared to an
\csa{edef} as \csa{xintNewExpr} has some built-in catcode protection.}
\item the macro |\myformula| is defined without checking if it already exists,
\LaTeX{} users might prefer to do first |\newcommand*\myformula {}| to get a
reasonable error message in case |\myformula| already exists,
\item the protection against active characters is done automatically (as long
as the whole thing has not already been fetched as a macro argument and
the catcodes correspondingly already frozen).
\end{itemize}
It (if it succeeds) will be a completely expandable macro entirely built-up using |\xintAdd|,
|\xintSub|, |\xintMul|, |\xintDiv|, |\xintPow|, etc\dots as corresponds to the
expression written with the infix operators.
Macros created by |\xintNewExpr| can thus be nested.
\begin{everbatim*}
\xintNewFloatExpr \FA [2]{(#1+#2)^10}
\xintNewFloatExpr \FB [2]{sqrt(#1*#2)}
\begin{enumerate}[nosep]
\item \FA {5}{5}
\item \FB {30}{10}
\item \FA {\FB {30}{10}}{\FB {40}{20}}
\end{enumerate}
\end{everbatim*}
The documentation is much shortened here because \csbxint{NewExpr} and \csbxint{deffunc}
are very much related one with the other.
\begin{framed}
ATTENTION!
The original spirit of \csbxint{NewExpr} was to define a (possibly very big)
macro using only \xintfracname, and this means in particular that it must be
used only with arguments compatible with the \xintfracname input
format.\IMPORTANTf
Thus an |\xintexpr| declared variable has no chance to work, it must be
wrapped explicitly in |\xinteval{...}| to be fetched as argument to a macro
constructed by \csbxint{NewExpr}.
\end{framed}
They share essentially the same limitations.
Notice though that \csbxint{NewFloatExpr} accepts and recognizes the optional
argument |[Q]| of \csbxint{floatexpr}, contrarily to \csbxint{deffloatfunc}.
Use an |\empty| in case the contents are not known in advance.
Historical note: prior to |1.4|, \xintexprname used a |\csname..\endcsname|
encapsulation technique which impacted the string pool memory. The
\csbxint{NewExpr} was designed as a method to pre-parse the expression and
produce one single, gigantic, nested usage of the relevant \xintfracname
macros. This way, only those macros were expanded which had nil impact on the
\TeX{} string pool.
Later on it was found that this mechanism could be employed to define
functions. Basically underneath |98%| of \csbxint{NewExpr} and
\csbxint{deffunc} are using the same shared code.
\xintDigits:= 16\relax
\subsection{Analogies and differences of \csh{xintiiexpr} with \csh{numexpr}}
\csbxint{iiexpr}|..\relax| is a parser of expressions knowing only (big)
integers. There are, besides the enlarged range of allowable inputs, some
important differences of syntax between |\numexpr| and |\xintiiexpr| and
variants:
\begin{itemize}
\item Contrarily to |\numexpr|, the |\xintiiexpr| parser will stop expanding
only after having encountered (and swallowed) a \emph{mandatory} |\relax|
token.
\item In particular, spaces between digits (and not only around infix
operators or parentheses) do not stop |\xintiiexpr|, contrarily to the
situation with |numexpr|: |\the\numexpr 7 + 3 5\relax| expands (in one
step)%
%
\footnote {The |\numexpr| triggers continued expansion after the space
following the |3| to check if some operator like |+| is upstream. But
after having found the |5| it treats it as and end-marker.}
%
to \dtt{\detokenize\expandafter{\the\numexpr 7 + 3 5\relax}\unskip}, whereas
|\xintthe\xintiiexpr 7 + 3 5\relax| expands (in two steps) to
\dtt{\detokenize\expandafter\expandafter\expandafter {\xintthe\xintiiexpr 7
+ 3 5\relax}}.%
%
\footnote {Since |1.2l| one can also use the underscore |_| to separate digits
for readability of long numbers.}
\item Inside an |\edef|, an expression |\xintiiexpr...\relax| get fully
evaluated, whereas |\numexpr| without |\the| or |\number| prefix would not,
if not itself embedded in another |\the\numexpr| or similar context.
\item (ctd.) The private format to which |\xintiiexpr...\relax| (et al.)
evaluates may use |\xintthe| prefix to turn into explicit digits,
(for example in arguments to some macros which expand their arguments). The |\the| \TeX\ primitive prefix would
not work here.
\item (ctd.) One can embed a |\numexpr...\relax| (with its |\relax|!) inside an
|\xintiiexpr...\relax| without |\the| or |\number|, but the reverse situation
requires usage of |\xintthe| or \csbxint{eval} user interface,
\item |\the\numexpr -(1)\relax| is illegal. In contrast |\xinttheiiexpr -(1)\relax| is
perfectly legal and gives the expected result (what else ?).
\item |\the\numexpr 2+-(1+1)\relax| is illegal. In contrast
|\xinttheiiexpr 2+-(1+1)\relax| is legal.
\item |\the\numexpr 2\cnta\relax| is illegal (with |\cnta| a |\count| register.)
In contrast
|\xinttheiiexpr 2\cnta\relax| is perfectly legal and will do the tacit
multiplication.
\item |\the\numexpr| or |\number\numexpr| expands in one step, but
|\xintthe\xintiiexpr| or |\xinttheiiexpr| needs two steps.
\end{itemize}
\subsection{Chaining expressions for expandable algorithmics}
\label{ssec:fibonacci}
We will see in this section how to chain |\xintexpr|-essions with
|\expandafter|'s, like it is possible with |\numexpr|. For this it is
convenient to use |\romannumeral0\xintexpro| which is the once-expanded form of
|\xintexpr|, as we can then chain using only one |\expandafter| each time.
The background of page 2 of this document displays the 1250\textup{th}
Fibonacci number. For its computation the following |\FibonacciN| macro
(or rather a very close variant) was used, which takes as input a
positive integer |N| (we did not add an overhead for |N| negative or
zero). It depends on another macro, called |\FibonacciPair| which
outputs \dtt{$F_{N}$} and \dtt{$F_{N-1}$} one after the other both inside
braces.
A technicality is that the Fibonacci numbers are left in a private
format which needs |\xintthe| to resolve to digit tokens. But the
output of |\FibonacciN| can also be used directly in the typesetting
phase.
As per the algorithm it is based upon the quadratic relations which
allow to go from $(F_n,F_{n-1})$ to either $(F_{2n}, F_{2n-1})$
(operation of type A) or to $(F_{2n+1}, F_{2n})$ (operation of type B).
We first convert $n$ into binary base, and read the digits from most
significant to least significant applying each time either type A or
type B. Each one of type A or B will cost only 3 multiplications and a
bunch of additions, which of course are done using \csbxint{iiexpr}. In
total the algorithm costs (because $3\log_2 10\approx 10$) about $10L$
multiplications (doubling is not counted as a multiplication) where $L$
is the number of decimal digits of $N$ (of course the cost of each
multiplication increases with the length of operands).
\begin{everbatim*}
\makeatletter
\newcommand\FibonacciPair[1]{%
\expandafter\Fibo@start
\romannumeral0\xintdectobin{\the\numexpr#1\relax};%
}
% To chain \xintiiexpr's easily we use the once-expanded form which is
% \romannumeral0\xintiiexpro. We could also have used \expanded and \xintiieval
% calls, that would have been simpler but old habits die hard.
%
% Gobble the first digit which is 1 (this is where we could have tested for a
% negative or zero input). Prepare encapsulated 1 and 0. Then repeatedly
% dispatch according to binary digits (which are strategically located at end
% of input stream to optimize), or the semicolon which signals completion.
%
% We use \csname-governed branching (because it is cool). We could have
% used some \if test or even an \ifcase with an {-1} at end, or any other
% of the many possibilities opened up by TeX syntax.
\def\Fibo@start 1#1{%
\csname Fibo@#1\expandafter\endcsname
\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter;%
\romannumeral0\xintiiexpro 0\relax;%
}
\@namedef{Fibo@0}#1;#2;#3{%
\csname Fibo@#3\expandafter\endcsname
\romannumeral0\xintiiexpro (#1+2*#2)*#1\expandafter\relax\expandafter;%
\romannumeral0\xintiiexpro #1*#1+#2*#2\relax;%
}
\@namedef{Fibo@1}#1;#2;#3{%
\csname Fibo@#3\expandafter\endcsname
\romannumeral0\xintiiexpro 2*(#1+#2)*#1+#2*#2\expandafter\relax\expandafter;%
\romannumeral0\xintiiexpro (#1+2*#2)*#1\relax;%
}
% #1 is F_N (and #2 is F_{N-1}) and both are in need of unpacking.
% #1 is F_N (and #2 is F_{N-1}) and both in need of unpacking.
\@namedef{Fibo@;}#1;#2;{{#1}{#2}}
\newcommand\FibonacciN{\expandafter\@firstoftwo\romannumeral0\FibonacciPair}
\makeatother
\end{everbatim*}
\begingroup\footnotesize\sffamily\baselineskip 10pt
Here a code snippet which
checks the routine via a \string\message\ of the first $50$ Fibonacci
numbers (this is not an efficient way to generate a sequence of such
numbers, it is only for validating \csa{FibonacciN}).
%
\begin{everbatim}
\def\Fibo #1.{\xintthe\FibonacciN {#1}}%
\message{\xintiloop [1+1] \expandafter\Fibo\xintiloopindex.,
\ifnum\xintiloopindex<49 \repeat \xintthe\FibonacciN{50}.}
\end{everbatim}
\endgroup
The way we use |\expandafter|'s to chain successive |\xintiiexpro| evaluations
is exactly analogous to what is possible with |\numexpr|. The various
|\romannumeral0\xintiiexpro| could very well all have been |\xintiiexpr|'s but
then we would have needed |\expandafter\expandafter\expandafter| each
time.
\begin{framed}
There is a difference though: |\numexpr| does \emph{NOT} expand inside an
|\edef|, and to force its expansion we must prefix it with |\the| or
|\number| or |\romannumeral| or another |\numexpr| which is itself prefixed,
etc\dots.
But |\xintexpr|, |\xintiexpr|, ..., expand fully in an |\edef|, with the
completely expanded
result encapsulated in a private format.
Using |\xintthe| as prefix is necessary to print the result (like |\the| or
|\number| in the case of |\numexpr|), but it is not necessary to get the
computation done (contrarily to the situation with |\numexpr|).
\end{framed}
Our |\Fibonacci| expands completely under \fexpan sion, so we can use
\hyperref[fdef]{\ttfamily\char92fdef} rather than |\edef| in a situation such
as
%
\leftedline {|\fdef \X {\FibonacciN {100}}|\;,}
%
but it is usually about as efficient to employ |\edef|. And if we want
%
\leftedline{|\edef \Y {(\FibonacciN{100},\FibonacciN{200})}|\;,}
%
then |\edef| is necessary.
% slightly refactored pour 1.4p doc (use of @ rather than _, less braces, so
% less \expandafter's, only keeping one integer along)
Allright, so let's now give the code%
%
\footnote{Coding\NewWith{1.4p} for \cs{FibonacciPair} and \cs{FibonacciSeq} was improved at |1.4p| after ten years kept unchanged...}
%
to generate |{F(N)}{F(N+1)}{F(N+2)}...|,
using |\FibonacciPair| for the first two and then using the standard recursion
|F(N+2)=F(N+1)+F(N)|:
\begin{everbatim*}
\makeatletter
\newcommand\FibonacciSeq[2]{%#1=starting index, #2>#1=ending index
\expandafter\Fibonacci@Seq
\the\numexpr #1\expandafter.\the\numexpr #2.%
}%
% The #1+1 is because \FibonacciPair{N} expands to {F_{N}}{F_{N-1}},
% so here we will have {F_{A+1}}{F_{A}} as starting point.
% We want up to {F_B}. If B=A+1 there will be nothing to do.
\def\Fibonacci@Seq #1.#2.{%
\expandafter\Fibonacci@Seq@loop
\the\numexpr #2-#1-1\expandafter.\romannumeral0\FibonacciPair{#1+1}%
}%
% Now leave in stream one coefficient, test if we have reached B
% and until then apply standard Fibonacci recursion.
\def\Fibonacci@Seq@loop #1.#2#3{% standard Fibonacci recursion
{#3}\ifnum #1=\z@ \expandafter\Fibonacci@Seq@end\fi
\expandafter\Fibonacci@Seq@loop
\the\numexpr #1-1\expandafter.\expandafter
{\romannumeral0\xintiiexpro #2+#3\relax}{#2}%
}%
\def\Fibonacci@Seq@end#1\expandafter.\expandafter#2{}%
\makeatother
\end{everbatim*}
Again, let's repeat that here the braced values require |\xintthe| to expand
to digit tokens in an |\edef| (but not for typesetting).
%\typeout{\FibonacciSeq{1}{10}}
\ifnum\expanded{\noexpand\xintLength{\FibonacciSeq{1}{10}}}=10
\else\ERROR\fi
% MEMO: \xintLastItem removes braces. But actually \xintthe
% also. I hesitated to keep it but this could be used case.
% ATTENTION THAT \xintLastItem does NO expansion of its argument.
\ifnum\xintthe\expanded{\noexpand\xintLastItem{\FibonacciSeq{5}{11}}}=89
\else\ERROR\fi
This |\FibonacciSeq| macro is
completely expandable but it is not \fexpan dable.
This is not a problem in the next example which uses \csbxint{For*} as the
latter applies repeatedly full expansion to what comes next each time it
fetches an item from its list argument. Thus \csbxint{For*} still manages to
generate the list via iterated full expansion.
\begin{figure*}[ht!]
\phantomsection\label{fibonacci}
\newcounter{myindex}
\fdef\Fibxxx{\FibonacciN {30}}%
\setcounter{myindex}{30}%
\centeredline{\tabskip 1ex
\vbox{\halign{\bfseries#.\hfil\hfil &\hfil #\cr
\xintFor* #1 in {\FibonacciSeq {30}{59}}\do
{\themyindex &\xintthe#1 &
\xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}%
}\vrule
\vbox{\halign{\bfseries#.\hfil\hfil &\hfil #\cr
\xintFor* #1 in {\FibonacciSeq {60}{89}}\do
{\themyindex &\xintthe#1 &
\xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}%
}\vrule
\vbox{\halign{\bfseries#.\hfil\hfil &\hfil #\cr
\xintFor* #1 in {\FibonacciSeq {90}{119}}\do
{\themyindex &\xintthe#1 &
\xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}%
}}%
%
\centeredline{Some Fibonacci numbers together with their residues modulo
|F(30)|\dtt{=\xintthe\Fibxxx}}
\end{figure*}
\begingroup
\def\everbhook{\catcode`@ 14 }%
% à propos après donc de nombreuses années j'ai fait finalement
% un bug report https://github.com/latex3/latex2e/issues/823
\everb|@
\newcounter{myindex}% not "index", which would overwrite theindex environment!
% (many have probably been bitten by this trap)
\tabskip 1ex
\fdef\Fibxxx{\FibonacciN {30}}%
\setcounter{myindex}{30}%
\vbox{\halign{\bfseries#.\hfil\hfil &\hfil #\cr
\xintFor* #1 in {\FibonacciSeq {30}{59}}\do
{\themyindex &\xintthe#1 &
\xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}%
}\vrule
\vbox{\halign{\bfseries#.\hfil\hfil &\hfil #\cr
\xintFor* #1 in {\FibonacciSeq {60}{89}}\do
{\themyindex &\xintthe#1 &
\xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}%
}\vrule
\vbox{\halign{\bfseries#.\hfil\hfil &\hfil #\cr
\xintFor* #1 in {\FibonacciSeq {90}{119}}\do
{\themyindex &\xintthe#1 &
\xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}%
}%
|
\endgroup
This produces the Fibonacci numbers from |F(30)| to |F(119)|, and
computes also all the
congruence classes modulo |F(30)|. The output has
been put in a \hyperref[fibonacci]{float}, which appears
\vpageref[above]{fibonacci}. I leave to the mathematically inclined
readers the task to explain the visible patterns\dots |;-)|.
\subsection{When expandability is too much}
Let's use the macros of \autoref{ssec:fibonacci} related to Fibonacci numbers.
Notice that the $47$th Fibonacci number is \dtt{\xintthe\FibonacciN {47}} thus
already too big for \TeX{} and \eTeX{}.
The |\FibonacciN| macro found in \autoref{ssec:fibonacci} is completely
expandable, it is even \fexpan dable. We need a wrapper with |\xintthe|
prefix
\begin{everbatim*}
\def\theFibonacciN{\xintthe\FibonacciN}
\end{everbatim*}
to print in the document or to use within |\message| (or \LaTeX\ |typeout|) to
write to the log and terminal.
\begingroup
\def\A {1859} \def\B {1573}
\edef\X {\theFibonacciN\A} \edef\Y {\theFibonacciN\B}
\edef\GCDAB {\xintiiGCD\A\B}\edef\Z {\theFibonacciN\GCDAB}
\edef\GCDXY{\xintiiGCD\X\Y}
The |\xintthe| prefix also allows its use it as argument to the \xintname
macros: for example if we are interested in knowing how many digits
$F(1250)$ has, it suffices to issue |\xintLen {\theFibonacciN {1250}}|
(which expands to \dtt{\xintLen {\theFibonacciN {1250}}}). Or if we want to
check the formula $gcd(F(1859),F(1573))=F(gcd(1859,1573))=F(143)$, we only
need%
%
\footnote{The
\csa{xintiiGCD} macro is provided by both the \xintgcdname package (since
|1.0|) and by the \xintname package (since |1.3d|).}
%
\begin{everbatim}
$\xintiiGCD{\theFibonacciN{1859}}{\theFibonacciN{1573}}=%
\theFibonacciN{\xintiiGCD{1859}{1573}}$
\end{everbatim}
%
which produces:
%
\leftedline{$\dtt{\xintiiGCD{\X}{\Y}}=\dtt{\theFibonacciN{\GCDAB}}$}
The |\theFibonacciN| macro expanded its |\xintiiGCD{1859}{1573}| argument via the
services of |\numexpr|: this step allows only things obeying the \TeX{} bound,
naturally! (but \dtt{F(\xintiiPow2{31}}) would be rather big anyhow...).
This is very convenient but of course it repeats the complete evaluation each
time it is done. In practice, it is often useful to store the result of such
evaluations in macros. Any |\edef| will break expandability, but if the goal
is at some point to print something to the |dvi| or |pdf| output, and not only
to the |log| file, then expandability has to be broken one day or another!
Hence, in practice, if we want to print in the document some computation
results, we can proceed like this and avoid having to repeat identical
evaluations:
\begin{everbatim}
\begingroup
\def\A {1859} \def\B {1573}
\edef\X {\theFibonacciN\A} \edef\Y {\theFibonacciN\B}
\edef\GCDAB {\xintiiGCD\A\B}\edef\Z {\theFibonacciN\GCDAB}
\edef\GCDXY{\xintiiGCD\X\Y}
The identity $\gcd(F(\A),F(\B))=F(\gcd(\A,\B))$ can be checked via evaluation
of both sides: $\gcd(F(\A),F(\B))=\gcd(\printnumber\X,\printnumber\Y)=
\printnumber{\GCDXY} = F(\gcd(\A,\B)) = F(\GCDAB) =\printnumber\Z$.\par
% some further computations involving \A, \B, \X, \Y
\endgroup % closing the group removes assignments to \A, \B, ...
% or choose longer names less susceptible to overwrite something.
% Note: there is no LaTeX \newecommand which would be to \edef like
% \newcommand is to \def
\end{everbatim}
The identity $\gcd(F(\A),F(\B))=F(\gcd(\A,\B))$ can be checked via evaluation
of both sides: $\gcd(F(\A),F(\B))=\gcd(\printnumber\X,\printnumber\Y)=
\printnumber{\GCDXY} = F(\gcd(\A,\B)) = F(\GCDAB) =\printnumber\Z$.\par
\endgroup
One may legitimately ask the author: why expandability
to such extremes, for things such as big fractions or floating point numbers
(even continued fractions...) which anyhow can not be used directly within
\TeX's primitives such as |\ifnum|? Why insist on a concept
which is foreign to the vast majority of \TeX\ users and even programmers?
I have no answer: it made definitely sense at the start of \xintname (see
\autoref{ssec:origins}) and once started I could not stop.
\subsection{Acknowledgements (2013/05/25)}
I was greatly helped in my preparatory thinking, prior to producing such an
expandable parser, by the commented source of the
\href{https://ctan.org/pkg/l3kernel}{l3fp} package, specifically the
|l3fp-parse.dtx| file (in the version of April-May 2013; I think there was in
particular a text called ``roadmap'' which was helpful). Also the source of the
|calc| package was instructive, despite the fact that here for |\xintexpr| the
principles are necessarily different due to the aim of achieving expandability.
\clearpage
\expandafter\let\csname xintexpr (old doc)nameUp\endcsname\undefined
\csname calxtrignameUp\endcsname
\section{The \calxtrigname.tex library}
\RaisedLabel{sec:calxtrig}
\localtableofcontents
\subsection{Introduction}
This library (not to be loaded directly by user)
provides trigonometric functions for use within
\csbxint{floateval} (and \csbxint{eval}), up to a maximal accuracy of
\dtt{100} floating point digits\NewWith{2.0a1}.
This first version supporting trigonoometry was release |1.3e|
(|2019/04/05|) of \xintexprname. It was completely rewrittent at
|2.0a1|. It now supports precisions up to \dtt{100}, is faster and more
accurate. It defines no user level macro.
% At |1.4e| (|2021/05/05|) the accuracy of the trailing digits was significantly
% increased.%
% %
% \footnote{Prior to 2021, the high-level user interface was used to
% define the functions and intermediate operations were done without
% guard digits. As a result the last two digits were most of the time
% off, at least the last one.}
% Release |1.4p| adds the aliases \func{arcsin}, \func{arccos} and \func{arctg},
% and the reciprocal functions \func{acsc} and \func{asec} with aliases
% \func{arccsc} and \func{arcsec}.
At \csbxint{theDigits} set to \dtt{8} (or less), the computations are
targeting a slightly degraded accuracy (roughly at 8 digits, only about
95\% of values are correctly rounded, compared to 99.5\% for |P>8|. In
both cases the error is never more tha 1ulp. Actually the |2.0a1| implementation
appears to be excessively precise so the indicated percentage of correct rounding
is actually very conservative.
\textbf{Acknowledgements:} I finally decided to release some such functions
under friendly pressure of Jürgen \textsc{Gilg} and Thomas \textsc{Ossig}, let
them both be thanked here.
Jürgen passed away in 2022. I will miss our friendship which was born and grew
from numerous and regular exchanges on topics not limited to this package or
even the \TeX\ world. Let's now continue to \myenquote{take care and keep motivated}!
\subsection{\csh{xintreloadxinttrig}}\label{xintreloadxinttrig}
This macro does nothing. It is there only for bacward compatibility
with documents done with \xintexprname prior to |2.0|.
\subsection{Constants}
They are left free to use, or modified, or \csbxint{unassignvar}'d,
as this will have no impact whatsoever on the functions. They
are provided as backward compatible convenience.
\begin{description}
\vardesc{twoPi} what could that be?
\vardesc{threePiover2}
\vardesc{Pi}
\vardesc{Piover2}
\vardesc{oneRadian} this is one radian in degrees: $180/\pi$
\vardesc{oneDegree} this is one degree in radian: $\pi/180$
\end{description}
\subsection{Functions}
\subsubsection{Direct trigonometry}
With the variable in radians:
\begin{description}
\funcdesc{sin} sine
\funcdesc{cos} cosine
\funcdesc{tan} tangent
\funcdesc{tg} tangent
\funcdesc{cot} cotangent
\funcdesc{cotg} cotangent
\funcdesc{sec} secant
\funcdesc{csc} cosecant
\funcdesc{sinc} $\sinc(x) = \sin(x)/x$
\end{description}
Some have variants handling an input in degrees:
\begin{description}
\funcdesc{sind} sine
\funcdesc{cosd} cosine
\funcdesc{tand} tangent
\funcdesc{cotd} cotangent
\funcdesc{secd} secant
\funcdesc{cscd} cosecant
\end{description}
\subsubsection{Inverse trigonometry}
With the value in radians:
\begin{description}
\funcdesc{asin} arcsine
\funcdesc{arcsin} arcsine
\funcdesc{acsc} arccosecant
\funcdesc{arccsc} arccosecant
\funcdesc{acos} arccosine
\funcdesc{arccos} arccosine
\funcdesc{asec} arcsecant
\funcdesc{arcsec} arcsecant
\funcdesc{atan} arctangent
\funcdesc{arctg} arctangent
\funcdesc[x, y]{Arg} the main branch of the argument of the complex number
|x+iy|, from $-\pi$ (excluded) to $\pi$ (included). As the output is rounded
-\var{Pi} (its value) is a possible return value.
\funcdesc[x, y]{pArg} the branch of the argument of the complex number
|x+iy| with values going from $0$ (included) to $2\pi$ (excluded). Inherent
rounding makes \var{twoPi} (value) a possible return value.
\funcdesc[y, x]{atan2} is |Arg(x, y)|. Note the reversal of the arguments,
this seems to be the most frequently encountered convention across languages.
\end{description}
With the value in degrees:
\begin{description}
\funcdesc{asind} arcsine
\funcdesc{acosd} arccosine
\funcdesc{atand} arctangent
\funcdesc[x, y]{Argd} the main branch of the argument of the complex number
|x+iy|, from $-180$ (excluded) to $180$ (included). Inherent rounding of
output can cause |-180|
to be returned.
\funcdesc[x, y]{pArgd} the branch of the argument of the complex number
|x+iy| with values going from $0$ (included) to $360$ (excluded). Inherent rounding of
output can cause |360| to be returned.
\funcdesc[y, x]{atan2d} is |Argd(x, y)|. Note the reversal of the arguments,
this seems to be the most frequently encountered convention across languages.
\end{description}
\subsubsection{Conversion functions (optional definitions left to user
decision)}
Python provides functions |degrees()| and |radians()|. But as most of the
\calxname functions are already defined for the two units, I felt this was
not really needed. It is a oneliner to add them:
\begin{everbatim}
\xintdeffloatfunc radians(x) := x * oneDegree;
\xintdeffloatfunc degrees(x) := x * oneRadian;
\end{everbatim}
\subsection{Important implementation notes}
\label{ssec:trignotes}
\begin{itemize}
\item Floating point numbers with large exponents are integers and are
multiples of \dtt{1000}; hence modulo \dtt{360} all such ``angles''
are integer multiples of \dtt{280} degrees, i.e.\@ are modulo
\dtt{360} among the integer multiples of \dtt{40} degrees, which means
that there are \emph{only 10 such angles}. Needless to say,
considering usage of the |sind()| and |cosd()| functions with such
large floating point numbers is \textbf{meaningless}, or at least
\textbf{illusory} (contrarily to say compute a square, a square-root,
or a multiplication). This is the author's opinion, and you will have
a very hard time making me change my mind. A floating point number
represents a range of real numbers, and large floating point numbers
represent thus each a range encompassing multiple consecutive batches
of \dtt{360} degrees, there is no way you can seriously think that one
can give a meaning to the \func{sind} or \func{cosd} then apart from
their averabe value which is zero (same for \func{sin} and
\func{cos}).
% PROBABLY NOT TRUE AT 2.0 TO BE CHECKED
% \item Regarding |sin()| and |cos()|, \xinttrigname converts their argument to
% degrees by multiplication by (pre-rounded) $180/\pi$, then does range
% reduction modulo $360$ and finally goes back to radians in the appropriate
% octants to use usual Taylor series (roughly said). For large floats, the
% output value will thus be one of |sind(40n)|, |cosd(40n)|, |n=0..8|. If the
% unit in the last place of original variable was for example \dtt{1e9} the
% final result means nothing at all: the unit in the last place interval
% extends above possibly astronomical numbers of intervals of length $2\pi$.
% This intrinsic problem is not a by-product of conversion problems to and
% from degrees, it is an in-built inadequacy of the concept of floating point
% numbers to provide meaning to evaluating trigonometrical functions. The
% argument should be treated as a uniformly distributed random variable modulo
% $2\pi$, and the sine and cosine values should be random variables realizing
% the value distribution of these mathematical functions. Clearly this adds
% some (rather severe) implementation complications such as deciding how to
% make the transition to randomness. Too lazy for that.
% Opting for a random value also raises the question of how to deal with
% multiple such evaluations at the same argument in a single expression. I
% would argue again that as it is evil to consider meaningless quantities, it
% is not a problem if new compilations give different results, or even single
% compilation gives different results in various parts of the same formula,
% that's the whole point of randomness! As said already, I got too lazy to
% consider seriously implementing such a non-standard philosophy, despite its
% compelling soundness.
% \item Did I say the implementation was done at very high level (for the most
% part), hence has ample room for optimization? This is particularly the case
% for the handling of small inputs by functions such as sine or arcsine.
\end{itemize}
\subsection{Some example evaluations}
\noindent
\begin{everbatim*}
\xintDigits* := 48\relax
Digits at \xinttheDigits:\newline
$sind(17)\approx\xintfloateval{sind(17)}$\newline
$cosd(17)\approx\xintfloateval{cosd(17)}$\newline
$tand(17)\approx\xintfloateval{tand(17)}$\newline
$sind(43)\approx\xintfloateval{sind(43)}$\newline
$cosd(43)\approx\xintfloateval{cosd(43)}$\newline
$tand(43)\approx\xintfloateval{tand(43)}$\newline
$asind(0.3)\approx\xintfloateval{asind(0.3)}$\newline
$acosd(0.3)\approx\xintfloateval{acosd(0.3)}$\newline
$atand(3)\approx\xintfloateval{atand(3)}$\newline
$tan(atan(7))\approx\xintfloateval{tan(atan(7))}$\newline
$asind(sind(25))\approx\xintfloateval{asind(sind(25))}$\par\medskip
\noindent\xintDigits* := 24\relax
Digits at \xinttheDigits:\newline
$sind(17)\approx\xintfloateval{sind(17)}$\newline
$cosd(17)\approx\xintfloateval{cosd(17)}$\newline
$tand(17)\approx\xintfloateval{tand(17)}$\newline
$sind(43)\approx\xintfloateval{sind(43)}$\newline
$cosd(43)\approx\xintfloateval{cosd(43)}$\newline
$tand(43)\approx\xintfloateval{tand(43)}$\newline
$asind(0.3)\approx\xintfloateval{asind(0.3)}$\newline
$acosd(0.3)\approx\xintfloateval{acosd(0.3)}$\newline
$atand(3)\approx\xintfloateval{atand(3)}$\newline
$tan(atan(7))\approx\xintfloateval{tan(atan(7))}$\newline
$asind(sind(25))\approx\xintfloateval{asind(sind(25))}$\par
\xintDigits* := 16\relax
\end{everbatim*}
\clearpage
\let\calxtrignameUp\undefined
\csname calxlognameUp\endcsname
\def\n{|{N}|}
\def\m{|{M}|}
\def\x{|{x}|}
\section{The \calxlogname.tex library}
\RaisedLabel{sec:calxlog}
\localtableofcontents
\subsection{Introduction}
This package provides logarithms, exponentials and fractional powers for
use within \csbxint{floateval} (and \csbxint{eval}).
The first release of \xintexprname supporting logarithms and
exponentials was |1.3e| (|2019/04/05|). It is automatically loaded by
\xintexprname. Since |2.0a1| |2026/11/01| the maximal supported precision
is of \dtt{100} digits.
The \func{ln} alias, \func{expm1}, \func{log1p}, hyperbolic functions,
and their reciprocals were added at release |1.4p| (March 2026).
At \csbxint{theDigits} set to \dtt{8} (or less), the computations are
targeting a slighlty degraded accuracy (roughly at 8 digits, only about
95\% of values are correctly rounded, compared to 99.5\% for |P>8|. In
both cases the error is never more tha 1ulp.
% TODO: OBSOLETE FIX THAT
% \begin{TeXnote}
% For example, with \csbxint{Digits*} set to |8|, |log10(1.0011871)| is
% produced as |5.15245e-4| which stands for |0.000515245| having \dtt{9}
% correct decimal places in the \emph{fixed-point} sense, but only
% \dtt{6} correct digits in the \emph{floating point} sense. The
% situation is even worse with |log()| as it applies a conversion factor
% and does not remove the trailing junk digits (absent from the |log10()|
% output).
% For plotting though, such defects are usually not important, and
% there is some real speed benefits from using \csbxint{Digits*} set
% at |8| rather than its default of |16|.
% Nevertheless the author has some intention to revisit and improve the
% code in future, stop bootstrapping \xintlogname via
% \ctanpackage{poormanlog} and get computations with \csbxint{Digits*}
% set to |8| also achieve floating point accuracy, at an equivalent or
% even improved speed compared with the current code.
% \end{TeXnote}
\subsection{\csh{xintreloadxintlog}}\label{xintreloadxintlog}
This is a no-op, provided only for backward compatibility.
\subsection{Functions}
\begin{description}
\funcdesc{log10} logarithm in base 10
\funcdesc{pow10} fractional powers of 10
\funcdesc{log} natural logarithm
\funcdesc{ln} natural logarithm
\funcdesc{log1p} computes |log(1+x)|
\funcdesc{exp} exponential function
\funcdesc{expm1} computes |e^x-1|
\funcdesc[x, y]{pow} computes $x^y$ via the formula |pow(y*log(x))|.
The exponent |y| is not rounded to the target floating point precision
beforehand, but to this target precision plus 14. It does not have to
be, if integer, at most the \TeX{} bound for integers (which is
\dtt{\xintiieval{"7FFFFFFF}}). But the output must have a decimal
exponent obeying this bound (with some safety margin)
\begin{everbatim*}
\calxeval{3^3350214776, 2^5309964787}
\calxeval{3^3350214776/2^5309964787}
\end{everbatim*}
Inside the \csbxint{eval} evaluator, and if the exponent is integer, and
if it is anticipated that
the output will not exceed (or will only slightly exceed) \dtt{10000} digits
(separately for numerator and denominator), then the power is computed \emph{exactly}.
To compute exactly higher powers than |2^9999| or |9^9999| or |99^5000| or
|999^3333|, etc..., use \csbxint{iieval}. See \csbxint{iiPow} for related
comments if you don't want to melt your CPU.
\funcdesc{sinh} hyperbolic sine
\funcdesc{sh} hyperbolic sine
\funcdesc{cosh} hyperbolic cosine
\funcdesc{ch} hyperbolic cosine
\funcdesc{tanh} hyperbolic tangent
\funcdesc{th} hyperbolic tangent
\funcdesc{coth} hyperbolic cotangent
\funcdesc{sech} hyperbolic secant
\funcdesc{csch} hyperbolic cosecant
\funcdesc{asinh} reciprocal of hyperbolic sine
\funcdesc{argsh} reciprocal of hyperbolic sine
\funcdesc{acosh} reciprocal of hyperbolic cosine
\funcdesc{argch} reciprocal of hyperbolic cosine
\funcdesc{atanh} reciprocal of hyperbolic tangent
\funcdesc{argth} reciprocal of hyperbolic tangent
\funcdesc{acoth} reciprocal of hyperbolic cotangent
\funcdesc{argcoth} reciprocal of hyperbolic cotangent
\funcdesc{asech} reciprocal of hyperbolic secant
\funcdesc{argsech} reciprocal of hyperbolic secant
\funcdesc{acsch} reciprocal of hyperbolic cosecant
\funcdesc{argcsch} reciprocal of hyperbolic cosecant
\end{description}
\begin{everbatim*}
\xintDigits:=24\relax
\noindent\xintfloateval{ln(2), exp(1)}\newline
\xintfloateval{2^(1/3), 2^10000}\newline
\xintfloateval{sinh(1), cosh(1), tanh(1)}\newline
\xintfloateval{sh(1), ch(1), th(1)}
\end{everbatim*}
\xintDigits:=16;
\pdfstringdefDisableCommands{\let\cs\empty}
% TODO Check what is still true at 2.0 release
% \subsection{Some information on how powers are computed}
% For powers |a^b| or |a**b| in \csbxint{floateval} the following rules apply:
% \begin{enumerate}[noitemsep]
% \item a check is made if exponent is integer or half-integer,
% \item if this is the case legacy \csbxint{FloatPower} (combined with
% \csbxint{FloatSqrt} for half-integer case)
% are used to evaluate the power (and |a| can be negative if exponent is
% integer),
% \item else the power is computed as |pow10(b*log10(a))| (but keeping some
% extra digits in intermediate evaluations; in particular |b| is not
% float-rounded, but |a| is).
% \end{enumerate}
% The reason is that the log/exp approach loses accuracy for very big
% exponents (say for exponents of the order of \dtt{100000000} or more). Here is
% an example of a precise computation with a very large exponent (\dtt{\xintiieval{12^16}}):
% \begin{everbatim*}
% $\xintTeXFromSci{\xintfloateval{1.00000001^\xintiiexpr 12^16\relax}}$\newline
% \xintDigits:=48;%\xintreloadxintlog is not done as log10/pow10 will not be used
% $\xintTeXFromSci{\xintfloateval{1.00000001^12^16}}$\newline
% \xintDigits:=64;%\xintreloadxintlog is not done as log10/pow10 will not be used
% $\xintTeXFromSci{\xintfloateval{1.00000001^12^16}}$\newline
% \xintDigits:=80;%\xintreloadxintlog is not done as log10/pow10 will not be used
% $\xintTeXFromSci{\xintfloateval{1.00000001^12^16}}$
% \xintDigits:=16;%
% \end{everbatim*}
% Notes:
% \begin{itemize}[noitemsep]
% \item in the case with \dtt{16} digits precision, we ensured |12^16| got
% computed exactly with all its \dtt{18} digits and was not rounded to only
% \dtt{16} digits (and confirmation is that the result matches the second one
% at \dtt{48} digits),
% \item the |1.4g| right associativity
% of powers is taken into account to drop parentheses.
% \end{itemize}
% As the legacy \csbxint{FloatPower} and \csbxint{FloatSqrt} work in arbitrary
% precision, the result for integer or half-integer exponents is produced with a
% full-size mantissa, even if |Digits| is more than \dtt{62} (as is examplified
% above).
% In the |10^(b*log10(a))| branch the mantissa size is limited to the minimum of
% |Digits| and of \dtt{64}. Its last digits will start being wrong if |b|
% becomes about (in absolute value) \dtt{100000000}. If you really need to
% compute powers with exponents that large or larger, it is recommended to
% decompose the exponent as a sum of the nearest integer or half-integer and a
% fractional part and express the power as a product. This is not done
% automatically as it would add some overhead in general for some a priori very
% rare use cases.
% And recall that the decimal exponents of final and
% intermediate results should obey the \TeX\ bound for integers anyhow, i.e. be
% at most (in absolute value) \dtt{\number"7FFFFFFF}, add some safety margin...
% In \csbxint{eval}, this is as in \csbxint{floateval} but for one difference: integer
% exponents will trigger an exact evaluation, as long as:
% \begin{itemize}
% \item the exponent absolute value is at most \dtt{9999},
% \item it is evaluated a priori, based on the length of the input, that the
% output will have at most \dtt{10000} digits (or only a bit more), separately
% for numerator and denominator.
% \end{itemize}
% The check for integralness of exponent is not on its mathematical value
% but on its internal representation, for speed. So |6/3| is not recognized as
% being an integer exponent in \csbxint{eval}; but in \csbxint{floateval}, the
% |6/3| will have been computed and recognized as |2|. Also |2.00| or |200e-2|
% is recognized as an integer in both parsers. Similar remarks apply to
% half-integer case.
% OBSOLETE
% If |Digits| is at most \dtt{8}, logarithms are computed faster but
% with less accuracy; internally, using \dtt{9} \emph{fixed
% point fractional digits}. And powers |a^b| lose accuracy in
% last digits quickly as |b| rises. Here is what was observed
% with some random tests:
% \begin{itemize}[noitemsep]
% \item for |b| neither integer nor half-integer and |1|%
\dtt{\color{magenta}{}\expandafter\detokenize\expandafter
{\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}}+++}
\endgroup
\medskip
\noindent\csbxint{ZapLastSpaces}\marg{stuff}\etype{n} does not do \emph{any} expansion of
its argument, nor brace removal of any sort, nor does it alter \meta{stuff} in
anyway apart from stripping away all \emph{ending} spaces. The same remarks as
for \csbxint{ZapFirstSpaces} apply.
\begingroup
\def\x { \a { \X } { \b \Y } }
%
\leftedline{|\xintZapLastSpaces { \a { \X } { \b \Y } }->|%
\dtt{\color{magenta}{}\expandafter\detokenize\expandafter
{\romannumeral0\expandafter\xintzaplastspaces\expandafter{\x}}}+++}
\endgroup
\medskip
\noindent\csbxint{ZapSpaces}\marg{stuff}\etype{n} does not do \emph{any}
expansion of its
argument, nor brace removal of any sort, nor does it alter \meta{stuff} in
anyway apart from stripping away all \emph{leading} and all \emph{ending}
spaces. The same remarks as for \csbxint{ZapFirstSpaces} apply.
\begingroup
\def\x { \a { \X } { \b \Y } }
%
\leftedline{|\xintZapSpaces { \a { \X } { \b \Y } }->|%
\dtt{\color{magenta}{}\expandafter\detokenize\expandafter
{\romannumeral0\expandafter\xintzapspaces\expandafter{\x}}}+++}
\endgroup
\medskip
\noindent\csbxint{ZapSpacesB}\marg{stuff}\etype{n} does not do \emph{any}
expansion of
its argument, nor does it alter \meta{stuff} in anyway apart from stripping away
all leading and all ending spaces and possibly removing one level of braces if
\meta{stuff} had the shape |{braced}|. The same remarks as for
\csbxint{ZapFirstSpaces} apply.
\begingroup
\def\x { \a { \X } { \b \Y } }
%
\leftedline{|\xintZapSpacesB { \a { \X } { \b \Y } }->|%
\dtt{\color{magenta}{}\expandafter\detokenize\expandafter
{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++}
\def\x { { \a { \X } { \b \Y } } }
%
\leftedline{|\xintZapSpacesB { { \a { \X } { \b \Y } } }->|%
\dtt{\color{magenta}{}\expandafter\detokenize\expandafter
{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++}
\endgroup
The spaces here at the start and end of the output come from the braced
material, and are not removed (one would need a second application for that;
recall though that the \xintname zapping macros do not expand their argument).
\subsection{\csh{xintCSVtoList}}
\label{xintCSVtoList}
\label{xintCSVtoListNoExpand}
\csa{xintCSVtoList}|{a,b,c...,z}|\etype{f} returns |{a}{b}{c}...{z}|. A
\emph{list} is by
convention in this manual simply a succession of tokens, where each braced thing
will count as one item (``items'' are defined according to the rules of \TeX{}
for fetching undelimited parameters of a macro, which are exactly the same rules
as for \LaTeX{} and macro arguments [they are the same things]). The word
`list' in `comma separated list of items' has its usual linguistic meaning,
and then an ``item'' is what is delimited by commas.
So \csa{xintCSVtoList} takes on input a `comma separated list of items' and
converts it into a `\TeX{} list of braced items'. The argument to
|\xintCSVtoList| may be a macro: it will first be
\hyperref[ssec:expansions]{\fexpan ded}. Hence the item before the first comma,
if it is itself a macro, will be expanded which may or may not be a good thing.
A space inserted at the start of the first item serves to stop that expansion
(and disappears). The macro \csbxint{CSVtoListNoExpand}\etype{n} does the same
job without
the initial expansion of the list argument.
Apart from that no expansion of the items is done and the list items may thus be
completely arbitrary (and even contain perilous stuff such as unmatched |\if|
and |\fi| tokens).
Contiguous spaces and tab characters, are collapsed by \TeX{}
into single spaces. All such spaces around commas%
%
\footnote{and multiple space tokens are not a problem; but those at the
top level (not hidden inside braces) \emph{must} be of character code
|32|.}
%
\fbox{are removed}, as well as
the spaces at the start and the spaces at the end of the list.%
%
\footnote{let us recall that this is all done completely expandably...
There is absolutely no alteration of any sort of the item apart from
the stripping of initial and final space tokens (of character code
|32|) and brace removal if and only if the item apart from intial and
final spaces (or more generally multiple |char 32| space tokens) is
braced.}
%
The items may contain explicit |\par|'s or
empty lines (converted by the \TeX{} input parsing into |\par| tokens).
\begingroup
\edef\X{\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , { {x ,
y} } }}
%
\leftedline{|\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } ,
{ {x , y} } }|}
%
\leftedline{|->|%
{\makeatletter\dtt{\expandafter\strip@prefix\meaning\X}}}
One sees on this example how braces protect commas from
sub-lists to be perceived as delimiters of the top list. Braces around an entire
item are removed, even when surrounded by spaces before and/or after. Braces for
sub-parts of an item are not removed.
We observe also that there is a slight difference regarding the brace stripping
of an item: if the braces were not surrounded by spaces, also the initial and
final (but no other) spaces of the \emph{enclosed} material are removed. This is
the only situation where spaces protected by braces are nevertheless removed.
From the rules above: for an empty argument (only spaces, no braces, no comma)
the output is
\dtt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist { }}}
(a list with one empty item),
for ``|{}|'' the output is
\dtt{\expandafter\detokenize\expandafter
{\romannumeral0\xintcsvtolist { {} }}}
(again a list with one empty item, the braces were removed),
for ``|{ }|'' the output is
\dtt{\expandafter\detokenize\expandafter
{\romannumeral0\xintcsvtolist {{ }}}}
(again a list with one empty item, the braces were removed and then
the inner space was removed),
for ``| { }|'' the output is
\dtt{\expandafter\detokenize\expandafter
{\romannumeral0\xintcsvtolist { { }}}} (again a list with one empty item, the initial space served only to stop the expansion, so this was like ``|{ }|'' as input, the braces were removed and the inner space was stripped),
for ``\texttt{\ \{\ \ \}\ }'' the output is
\dtt{\expandafter\detokenize\expandafter
{\romannumeral0\xintcsvtolist { { } }}} (this time the ending space of the first
item meant that after brace removal the inner spaces were kept; recall though
that \TeX{} collapses on input consecutive blanks into one space token),
for ``|,|'' the output consists of two consecutive
empty items
\dtt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist
{,}}}. Recall that on output everything is braced, a |{}| is an ``empty''
item.
%
Most of the above is mainly irrelevant for every day use, apart perhaps from the
fact to be noted that an empty input does not give an empty output but a
one-empty-item list (it is as if an ending comma was always added at the end of
the input).
\def\y { \a,\b,\c,\d,\e}
\expandafter\def\expandafter\Y\expandafter{\romannumeral0\xintcsvtolist{\y}}
\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}
\expandafter\def\expandafter\T\expandafter{\romannumeral0\xintcsvtolist{\t}}
%
\leftedline{|\def\y{ \a,\b,\c,\d,\e} \xintCSVtoList\y->|%
{\makeatletter\dtt{\expandafter\strip@prefix\meaning\Y}}}
%
\leftedline{|\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|}
%
\leftedline
{|\xintCSVtoList\t->|\makeatletter\dtt{\expandafter\strip@prefix\meaning\T}}
%
The results above were automatically displayed using \TeX's primitive
\csa{meaning}, which adds a space after each control sequence name. These spaces
are not in the actual braced items of the produced lists. The first items |\a|
and |\if| were either preceded by a space or braced to prevent expansion. The
macro \csa{xintCSVtoListNoExpand} would have done the same job without the
initial expansion of the list argument, hence no need for such protection but if
|\y| is defined as |\def\y{\a,\b,\c,\d,\e}| we then must do:
%
\leftedline{|\expandafter\xintCSVtoListNoExpand\expandafter {\y}|} Else, we
may have direct use: %
%
\leftedline{|\xintCSVtoListNoExpand
{\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|}
%
\leftedline{|->|\dtt{\expandafter\detokenize\expandafter
{\romannumeral0\xintcsvtolistnoexpand
{\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}}}}
%
Again these spaces are an artefact from the use in the source of the document of
\csa{meaning} (or rather here, \csa{detokenize}) to display the result of using
\csa{xintCSVtoListNoExpand} (which is done for real in this document
source).
For the similar conversion from comma separated list to braced items list, but
without removal of spaces around the commas, there is
\csa{xintCSVtoListNonStripped}\etype{f} and
\csa{xintCSVtoListNonStrippedNoExpand}\etype{n}.
\endgroup
\subsection{\csh{xintNthElt}}\label{xintNthElt}
\def\macro #1{\the\numexpr 9-#1\relax}
\csa{xintNthElt\x}\marg{list}\etype{\numx f} gets (expandably) the |x|th
item of the \meta{list}. A braced item will lose one level of brace
pairs. The token list is first \fexpan ded.
Items are counted starting at one.
\leftedline{|\xintNthElt {3}{{agh}\u{zzz}\v{Z}}| is
\texttt{\xintNthElt {3}{{agh}\u{zzz}\v{Z}}}}
%
\leftedline{|\xintNthElt {3}{{agh}\u{{zzz}}\v{Z}}| is
\texttt{\expandafter\expandafter\expandafter
\detokenize\expandafter\expandafter\expandafter {\xintNthElt
{3}{{agh}\u{{zzz}}\v{Z}}}}}
%
\leftedline{|\xintNthElt {2}{{agh}\u{{zzz}}\v{Z}}| is
\texttt{\expandafter\expandafter\expandafter
\detokenize\expandafter\expandafter\expandafter {\xintNthElt
{2}{{agh}\u{{zzz}}\v{Z}}}}}
%
\leftedline{|\xintNthElt {37}{\xintiiFac {100}}|\dtt{=\xintNthElt
{37}{\xintiiFac {100}}} is the thirty-seventh digit of $100!$.}
%
\leftedline{|\xintNthElt {10}{\xintFtoCv
{566827/208524}}|\dtt{=\xintNthElt {10}{\xintFtoCv
{566827/208524}}}}
\leftedline{is the tenth convergent of $566827/208524$ (uses \xintcfracname
package).}
%
\leftedline{|\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|%
\dtt{=\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}}
%
\leftedline{|\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|%
\dtt{=\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}}
%
\leftedline{|\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|%
\dtt{=\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}}
If |x=0|,
the macro returns the \emph{length} of the expanded list: this is not equivalent
to \csbxint{Length} which does no pre-expansion. And it is different from
\csbxint{Len} which is to be used only on integers or fractions.
If |x<0|, the macro returns the \verb+|x|+th element from the end of the list.
Thus for example |x=-1| will fetch the last item of the list.
%
\leftedline {|\xintNthElt {-5}{{{agh}}\u{zzz}\v{Z}}| is
\texttt{\expandafter\expandafter\expandafter \detokenize
\expandafter\expandafter\expandafter{\xintNthElt {-5}{{{agh}}\u{zzz}\v{Z}}}}}
The macro \csa{xintNthEltNoExpand}\etype{\numx n} does the same job but without
first expanding the list argument: |\xintNthEltNoExpand {-4}{\u\v\w T\x\y\z}| is
\xintNthEltNoExpand {-4}{\a\b\c\u\v\w T\x\y\z}.
If |x| is strictly larger (in absolute value) than the length of the list
then |\xintNthElt| produces empty contents.
\subsection{\csh{xintNthOnePy}}
\label{xintNthOnePy}
\csa{xintNthOnePy\x}\marg{list}\etype{\numx f} gets (expandably) the |x|th
item of the \meta{list}, adding a brace pair if there wasn't one.
Attention, items are counted starting at zero. For negative index, behaves
as \csbxint{NthElt}.
If the index is out of range, the empty output is returned. If the input list
was empty (had no items) the empty output is returned.
\subsection{\csh{xintKeep}}\label{xintKeep}
\csa{xintKeep\x}\marg{list}\etype{\numx f} expands the token list argument |L|
and produces a new list, depending on the value of |x|:
\begin{itemize}[nosep]
\item if |x>0|, the new list contains the first |x| items from |L| (counting
starts at one.) \emph{Each
such item will be output within a brace pair.} Use \csbxint{KeepUnbraced} if
this is not desired. This means that if the list item was braced to start
with, there is no modification, but if it was a token without braces,
then it acquires them.
\item if |x>=length(L)|, the new list is the old one with all its items now
braced.
\item if |x=0| the empty list is returned.
\item if |x<0| the last \verb+|x|+ elements compose the output in the same
order as in the initial list; as the macro proceeds by removing head items
the kept items end up in output as they were in input: no added braces.
\item if |x<=-length(L)| the output is identical with the input.
\end{itemize}
\csa{xintKeepNoExpand} does the same without first \fexpan ding its list
argument.
%
\begin{everbatim*}
\fdef\test {\xintKeep {17}{\xintKeep {-69}{\xintSeq {1}{100}}}}\meaning\test\par
\noindent\fdef\test {\xintKeep {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par
\noindent\fdef\test {\xintKeep {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par
\noindent\fdef\test {\xintKeep {7}{123456789}}\meaning\test\par
\noindent\fdef\test {\xintKeep {-7}{123456789}}\meaning\test\par
\end{everbatim*}
\subsection{\csh{xintKeepUnbraced}}\label{xintKeepUnbraced}
Same as \csbxint{Keep} but no brace pairs are added around the kept items from
the head of the list in the case |x>0|: each such item will lose one level of
braces. Thus, to remove braces from all items of the list, one can use
\csbxint{KeepUnbraced} with its first argument larger than the length of the
list; the same is obtained from \csbxint{ListWithSep}|{}|\marg{list}. But the
new list will then have generally many more items than the original ones,
corresponding to the unbraced original items.
For |x<0| the macro is no different from \csbxint{Keep}. Hence the name is a
bit misleading because brace removal will happen only if |x>0|.
\csa{xintKeepUnbracedNoExpand} does the same without first \fexpan ding
its list argument.
%
\begin{everbatim*}
\fdef\test {\xintKeepUnbraced {10}{\xintSeq {1}{100}}}\meaning\test\par
\noindent\fdef\test {\xintKeepUnbraced {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}%
\meaning\test\par
\noindent\fdef\test {\xintKeepUnbraced {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}%
\meaning\test\par
\noindent\fdef\test {\xintKeepUnbraced {7}{123456789}}\meaning\test\par
\noindent\fdef\test {\xintKeepUnbraced {-7}{123456789}}\meaning\test\par
\end{everbatim*}
\subsection{\csh{xintTrim}}\label{xintTrim}
\csa{xintTrim\x}\marg{list}\etype{\numx f} expands the list argument and
gobbles its first |x| elements.
\begin{itemize}[nosep]
\item if |x>0|, the first |x| items from |L| are gobbled. The remaining items
are not modified.
\item if |x>=length(L)|, the returned list is empty.
\item if |x=0| the original list is returned (with no added braces.)
\item if |x<0| the last \verb+|x|+ items of the list are removed. \emph{The
head items end up braced in the output.} Use \csbxint{TrimUnbraced} if
this is not desired.
\item if |x<=-length(L)| the output is empty.
\end{itemize}
\csa{xintTrimNoExpand} does the same without first \fexpan ding its list
argument.
\begin{everbatim*}
\fdef\test {\xintTrim {17}{\xintTrim {-69}{\xintSeq {1}{100}}}}\meaning\test\par
\noindent\fdef\test {\xintTrim {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par
\noindent\fdef\test {\xintTrim {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par
\noindent\fdef\test {\xintTrim {7}{123456789}}\meaning\test\par
\noindent\fdef\test {\xintTrim {-7}{123456789}}\meaning\test\par
\end{everbatim*}
\subsection{\csh{xintTrimUnbraced}}\label{xintTrimUnbraced}
Same as \csbxint{Trim} but in case of a negative |x| (cutting items from
the tail), the kept items from the head are not enclosed in brace pairs. They
will lose one level of braces. The name is a bit misleading
because when |x>0| there is no brace-stripping done on the kept items, because
the macro works simply by gobbling the head ones.
\csa{xintTrimUnbracedNoExpand} does the same without first \fexpan ding its list
argument.
\begin{everbatim*}
\fdef\test {\xintTrimUnbraced {-90}{\xintSeq {1}{100}}}\meaning\test\par
\noindent\fdef\test {\xintTrimUnbraced {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}%
\meaning\test\par
\noindent\fdef\test {\xintTrimUnbraced {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}%
\meaning\test\par
\noindent\fdef\test {\xintTrimUnbraced {7}{123456789}}\meaning\test\par
\noindent\fdef\test {\xintTrimUnbraced {-7}{123456789}}\meaning\test\par
\end{everbatim*}
\subsection{\csh{xintListWithSep}}\label{xintListWithSep}
\def\macro #1{\the\numexpr 9-#1\relax}
\csa{xintListWithSep}\marg{sep}\marg{list}\etype{nf} inserts the separator
\meta{sep} in-between all items of the given list of braced items (or
individual tokens). The items are fetched as does \TeX\ with undelimited macro
arguments, thus they end up unbraced in output. If the \meta{list} is only one
(or multiple) space tokens, the output is empty.
The list argument \meta{list} gets \fexpan ded first (thus if it is a macro
whose contents are braced items, the first opening brace stops the expansion,
and it is as if the macro had been expanded once.) The separator \meta{sep} is
not pre-expanded, it ends up as is in the output (if the \meta{list} contained
at least two items.)
The variant \csa{xintListWithSepNoExpand}\etype{nn} does the same
job without the initial expansion of the \meta{list} argument.
\begin{everbatim*}
\edef\foo{\xintListWithSep{, }{123456789{10}{11}{12}}}\meaning\foo\newline
\edef\foo{\xintListWithSep{:}{\xintiiFac{20}}}\meaning\foo\newline
\oodef\FOO{\xintListWithSepNoExpand{\FOO}{\bat\baz\biz\buz}}\meaning\FOO\newline
% a braced item or a space stops the f-expansion:
\oodef\foo{\xintListWithSep{\FOO}{{\bat}\baz\biz\buz}}\meaning\foo\newline
\oodef\foo{\xintListWithSep{\FOO}{ \bat\baz\biz\buz}}\meaning\foo\par
\end{everbatim*}
\subsection{\csh{xintApply}}\label{xintApply}
\def\macro #1{\the\numexpr 9-#1\relax}
\csa{xintApply}|{\macro}|\marg{list}\etype{ff} expandably applies the one
parameter macro |\macro| to each item in the \meta{list} given as second
argument and returns a new list with these outputs: each item is given one after
the other as parameter to |\macro| which is expanded at that time (as usual,
\emph{i.e.\@} fully for what comes first), the results are braced and output
together as a succession of braced items (if |\macro| is defined to start with a
space, the space will be gobbled and the |\macro| will not be expanded; it is
allowed to have its own arguments, the list items serve as last arguments to
|\macro|). Hence |\xintApply{\macro}{{1}{2}{3}}| returns
|{\macro{1}}{\macro{2}}{\macro{3}}| where all instances of |\macro| have been
already \fexpan ded.
Trick: |{\macro}| is perfectly allowed to be |{\macro{17}}| if |\macro|
is actually a macro with \emph{two} arguments. It will thus be expanded
with the first one being always here |{17}|.
Being expandable, |\xintApply| is useful for example inside alignments where
implicit groups make standard loops constructs usually fail. In such situation
it is often not wished that the new list elements be braced, see
\csbxint{ApplyUnbraced}. The |\macro| does not have to be expandable:
|\xintApply| will try to expand it, the expansion may remain partial.
The \meta{list} may
itself be some macro expanding (in the previously described way) to the list of
tokens to which the macro |\macro| will be applied. For example, if the
\meta{list} expands to some positive number, then each digit will be replaced by
the result of applying |\macro| on it. %
%
\leftedline{|\def\macro #1{\the\numexpr
9-#1\relax}|} %
%
\leftedline{|\xintApply\macro{\xintiiFac
{20}}|\dtt{=\xintApply\macro{\xintiiFac {20}}}}
The macro \csa{xintApplyNoExpand}\etype{fn} does the same job without the first
initial expansion which gave the \meta{list} of braced tokens to which |\macro|
is applied.
\subsection{\csh{xintApplyUnbraced}}\label{xintApplyUnbraced}
\csa{xintApplyUnbraced}|{\macro}|\marg{list}\etype{ff} is like \csbxint{Apply}.
The difference is that after having expanded its list argument, and applied
|\macro| in turn to each item from the list, it reassembles the outputs without
enclosing them in braces. The net effect is the same as doing
%
\leftedline{|\xintListWithSep {}{\xintApply {\macro}|\marg{list}|}|} This is
useful for preparing a macro which will itself define some other macros or make
assignments, as the scope will not be limited by brace pairs.
%
\begin{everbatim*}
\def\macro #1{\expandafter\def\csname myself#1\endcsname {#1}}
\xintApplyUnbraced\macro{{elta}{eltb}{eltc}}
\begin{enumerate}[nosep,label=(\arabic{*})]
\item \meaning\myselfelta
\item \meaning\myselfeltb
\item \meaning\myselfeltc
\end{enumerate}
\end{everbatim*}
%
The macro \csa{xintApplyUnbracedNoExpand}\etype{fn} does the same job without
the first initial expansion which gave the \meta{list} of braced tokens to which
|\macro| is applied.
\subsection{\csh{xintSeq}}\label{xintSeq}
\csa{xintSeq}|[d]{x}{y}|\etype{{{\upshape[\numx]}}\numx\numx} generates
expandably |{x}{x+d}...| up to and possibly including |{y}| if |d>0| or down
to and including |{y}| if |d<0|. Naturally |{y}| is omitted if |y-x| is not a
multiple of |d|. If |d=0| the macro returns |{x}|. If |y-x| and |d| have
opposite signs, the macro returns nothing. If the optional argument |d| is
omitted it is taken to be the sign of |y-x|. Hence |\xintSeq {1}{0}| is not
empty but |{1}{0}|. But |\xintSeq [1]{1}{0}| is empty.
The arguments |x| and |y| are expanded inside a |\numexpr| so they may be
count registers or a \LaTeX{} |\value{countername}|, or arithmetic with such
things.
%
\begin{everbatim*}
\xintListWithSep{,\hskip2pt plus 1pt minus 1pt }{\xintSeq {12}{-25}}
\end{everbatim*}
%
\begin{everbatim*}
\xintiiSum{\xintSeq [3]{1}{1000}}
\end{everbatim*}
When the macro is used without the optional argument |d|, it can only generate
up to about $5000$ numbers\IMPORTANT, the precise value depends upon some
\TeX{} memory parameter (input save stack).
With the optional argument |d| the macro proceeds differently (but less
efficiently) and does not stress the input save stack.
\subsection{\csh{xintloop}, \csh{xintbreakloop}, \csh{xintbreakloopanddo}, \csh{xintloopskiptonext}}
\label{xintloop}
\label{xintbreakloop}
\label{xintbreakloopanddo}
\label{xintloopskiptonext}
|\xintloop|\meta{stuff}|\if...\repeat|\xtype{} is an expandable loop
compatible with nesting. However to break out of the loop one almost always need
some un-expandable step. The cousin \csbxint{iloop} is \csbxint{loop} with an
embedded expandable mechanism allowing to exit from the loop. The iterated
macros may contain |\par| tokens or empty lines.
If a sub-loop is to be used all the material from the start of the main loop and
up to the end of the entire subloop should be braced; these braces will be
removed and do not create a group. The simplest to allow the nesting of one or
more sub-loops is to brace everything between \csa{xintloop} and \csa{repeat},
being careful not to leave a space between the closing brace and |\repeat|.
As this loop and \csbxint{iloop} will primarily be of interest to experienced
\TeX{} macro programmers, my description will assume that the user is
knowledgeable enough. Some examples in this document will be perhaps more
illustrative than my attemps at explanation of use.
One can abort the loop with \csbxint{breakloop}; this should not be used inside
the final test, and one should expand the |\fi| from the corresponding test
before. One has also \csbxint{breakloopanddo} whose first argument will be
inserted in the token stream after the loop; one may need a macro such as
|\xint_afterfi| to move the whole thing after the |\fi|, as a simple
|\expandafter| will not be enough.
One will usually employ some count registers to manage the exit test from the
loop; this breaks expandability, see \csbxint{iloop} for an expandable integer
indexed loop. Use in alignments will be complicated by the fact that cells
create groups, and also from the fact that any encountered unexpandable material
will cause the \TeX{} input scanner to insert |\endtemplate| on each encountered
|&| or |\cr|; thus |\xintbreakloop| may not work as expected, but the situation
can be resolved via |\xint_firstofone{&}| or use of |\TAB| with |\def\TAB{&}|.
It is thus simpler for alignments to use rather than \csbxint{loop} either the
expandable \csbxint{ApplyUnbraced} or the non-expandable but alignment
compatible \csbxint{ApplyInline}, \csbxint{For} or \csbxint{For*}.
As an example, let us suppose we have two macros |\A|\marg{i}\marg{j} and
|\B|\marg{i}\marg{j} behaving like (small) integer valued matrix entries, and we
want to define a macro |\C|\marg{i}\marg{j} giving the matrix product (|i| and
|j| may be count registers). We will assume that |\A[I]| expands to the number
of rows, |\A[J]| to the number of columns and want the produced |\C| to act in
the same manner. The code is very dispendious in use of |\count| registers, not
optimized in any way, not made very robust (the defined macro can not have the
same name as the first two matrices for example), we just wanted to quickly
illustrate use of the nesting capabilities of |\xintloop|.%
%
\footnote{for a more sophisticated implementation of matrix
multiplication, inclusive of determinants, inverses, and display
utilities, with entries big integers or decimal numbers or even
fractions see some code online posted
from
November 11, 2013.}
%
\begin{everbatim*}
\newcount\rowmax \newcount\colmax \newcount\summax
\newcount\rowindex \newcount\colindex \newcount\sumindex
\newcount\tmpcount
\makeatletter
\def\MatrixMultiplication #1#2#3{%
\rowmax #1[I]\relax
\colmax #2[J]\relax
\summax #1[J]\relax
\rowindex 1
\xintloop % loop over row index i
{\colindex 1
\xintloop % loop over col index k
{\tmpcount 0
\sumindex 1
\xintloop % loop over intermediate index j
\advance\tmpcount \numexpr #1\rowindex\sumindex*#2\sumindex\colindex\relax
\ifnum\sumindex<\summax
\advance\sumindex 1
\repeat }%
\expandafter\edef\csname\string#3{\the\rowindex.\the\colindex}\endcsname
{\the\tmpcount}%
\ifnum\colindex<\colmax
\advance\colindex 1
\repeat }%
\ifnum\rowindex<\rowmax
\advance\rowindex 1
\repeat
\expandafter\edef\csname\string#3{I}\endcsname{\the\rowmax}%
\expandafter\edef\csname\string#3{J}\endcsname{\the\colmax}%
\def #3##1{\ifx[##1\expandafter\Matrix@helper@size
\else\expandafter\Matrix@helper@entry\fi #3{##1}}%
}%
\def\Matrix@helper@size #1#2#3]{\csname\string#1{#3}\endcsname }%
\def\Matrix@helper@entry #1#2#3%
{\csname\string#1{\the\numexpr#2.\the\numexpr#3}\endcsname }%
\def\A #1{\ifx[#1\expandafter\A@size
\else\expandafter\A@entry\fi {#1}}%
\def\A@size #1#2]{\ifx I#23\else4\fi}% 3rows, 4columns
\def\A@entry #1#2{\the\numexpr #1+#2-1\relax}% not pre-computed...
\def\B #1{\ifx[#1\expandafter\B@size
\else\expandafter\B@entry\fi {#1}}%
\def\B@size #1#2]{\ifx I#24\else3\fi}% 4rows, 3columns
\def\B@entry #1#2{\the\numexpr #1-#2\relax}% not pre-computed...
\makeatother
\MatrixMultiplication\A\B\C \MatrixMultiplication\C\C\D
\MatrixMultiplication\C\D\E \MatrixMultiplication\C\E\F
\begin{multicols}2
\[\begin{pmatrix}
\A11&\A12&\A13&\A14\\
\A21&\A22&\A23&\A24\\
\A31&\A32&\A33&\A34
\end{pmatrix}
\times
\begin{pmatrix}
\B11&\B12&\B13\\
\B21&\B22&\B23\\
\B31&\B32&\B33\\
\B41&\B42&\B43
\end{pmatrix}
=
\begin{pmatrix}
\C11&\C12&\C13\\
\C21&\C22&\C23\\
\C31&\C32&\C33
\end{pmatrix}\]
\[\begin{pmatrix}
\C11&\C12&\C13\\
\C21&\C22&\C23\\
\C31&\C32&\C33
\end{pmatrix}^2 = \begin{pmatrix}
\D11&\D12&\D13\\
\D21&\D22&\D23\\
\D31&\D32&\D33
\end{pmatrix}\]
\[\begin{pmatrix}
\C11&\C12&\C13\\
\C21&\C22&\C23\\
\C31&\C32&\C33
\end{pmatrix}^3 = \begin{pmatrix}
\E11&\E12&\E13\\
\E21&\E22&\E23\\
\E31&\E32&\E33
\end{pmatrix}\]
\[\begin{pmatrix}
\C11&\C12&\C13\\
\C21&\C22&\C23\\
\C31&\C32&\C33
\end{pmatrix}^4 = \begin{pmatrix}
\F11&\F12&\F13\\
\F21&\F22&\F23\\
\F31&\F32&\F33
\end{pmatrix}\]
\end{multicols}
\end{everbatim*}
\subsection{\csh{xintiloop}, \csh{xintiloopindex}, \csh{xintouteriloopindex},
\csh{xintbreakiloop}, \csh{xintbreakiloopanddo}, \csh{xintiloopskiptonext},
\csh{xintiloopskipandredo}}
\label{xintiloop}
\label{xintbreakiloop}
\label{xintbreakiloopanddo}
\label{xintiloopskiptonext}
\label{xintiloopskipandredo}
\label{xintiloopindex}
\label{xintouteriloopindex}
\csa{xintiloop}|[start+delta]|\meta{stuff}|\if ... \repeat|\xtype{} is a
completely expandable nestable loop. complete expandability depends naturally on
the actual iterated contents, and complete expansion will not be achievable
under a sole \fexpan sion, as is indicated by the hollow star in the margin;
thus the loop can be used inside an |\edef| but not inside arguments to the
package macros. It can be used inside an |\xintexpr..\relax|. The
|[start+delta]| is mandatory, not optional.
This loop benefits via \csbxint{iloopindex} to (a limited access to) the integer
index of the iteration. The starting value |start| (which may be a |\count|) and
increment |delta| (\emph{id.}) are mandatory arguments. A space after the
closing square bracket is not significant, it will be ignored. Spaces inside the
square brackets will also be ignored as the two arguments are first given to a
|\numexpr...\relax|. Empty lines and explicit |\par| tokens are accepted.
As with \csbxint{loop}, this tool will mostly be of interest to advanced users.
For nesting, one puts inside braces all the
material from the start (immediately after |[start+delta]|) and up to and
inclusive of the inner loop, these braces will be removed and do not create a
loop. In case of nesting, \csbxint{outeriloopindex} gives access to the index of
the outer loop. If needed one could write on its model a macro giving access to
the index of the outer outer loop (or even to the |nth| outer loop).
The \csa{xintiloopindex} and \csa{xintouteriloopindex} can not be used inside
braces, and generally speaking this means they should be expanded first when
given as argument to a macro, and that this macro receives them as delimited
arguments, not braced ones. Or, but naturally this will break expandability, one
can assign the value of \csa{xintiloopindex} to some |\count|. Both
\csa{xintiloopindex} and \csa{xintouteriloopindex} extend to the litteral
representation of the index, thus in |\ifnum| tests, if it comes last one has to
correctly end the macro with a |\space|, or encapsulate it in a
|\numexpr..\relax|.
When the repeat-test of the loop is, for example, |\ifnum\xintiloopindex<10
\repeat|, this means that the last iteration will be with |\xintiloopindex=10|
(assuming |delta=1|). There is also |\ifnum\xintiloopindex=10 \else\repeat| to
get the last iteration to be the one with |\xintiloopindex=10|.
One has \csbxint{breakiloop} and \csbxint{breakiloopanddo} to abort the loop.
The syntax of |\xintbreakiloopanddo| is a bit surprising, the sequence of tokens
to be executed after breaking the loop is not within braces but is delimited by
a dot as in:
%
\leftedline{|\xintbreakiloopanddo .etc.. etc... \repeat|}
%
The reason is that one may wish to use the then current value of
|\xintiloopindex| in || but it can't be within braces at the time it
is evaluated. However, it is not that easy as |\xintiloopindex| must be expanded
before, so one ends up with code like this:
%
\leftedline
{|\expandafter\xintbreakiloopanddo\expandafter\macro\xintiloopindex.%|}
%
\leftedline{|etc.. etc.. \repeat|}
%
As moreover the |\fi| from the test leading to the decision of breaking out of
the loop must be cleared out of the way, the above should be
a branch of an expandable conditional test, else one needs something such
as:
%
\leftedline
{|\xint_afterfi{\expandafter\xintbreakiloopanddo\expandafter\macro\xintiloopindex.}%|}
%
\leftedline{|\fi etc..etc.. \repeat|}
There is \csbxint{iloopskiptonext} to abort the current iteration and skip to
the next, \hyperref[xintiloopskipandredo]{\ttfamily\hyphenchar\font45 \char92
xintiloopskip\-and\-redo} to skip to the end of the current iteration and redo
it with the same value of the index (something else will have to change for this
not to become an eternal loop\dots ).
Inside alignments, if the looped-over text contains a |&| or a |\cr|, any
un-expandable material before a \csbxint{iloopindex} will make it fail because
of |\endtemplate|; in such cases one can always either replace |&| by a macro
expanding to it or replace it by a suitable |\firstofone{&}|, and similarly for
|\cr|.
\phantomsection\label{edefprimes}
As an example, let us construct an |\edef\z{...}| which will define |\z| to be a
list of prime numbers:
\begin{everbatim*}
\begingroup
\edef\z
{\xintiloop [10001+2]
{\xintiloop [3+2]
\ifnum\xintouteriloopindex<\numexpr\xintiloopindex*\xintiloopindex\relax
\xintouteriloopindex,
\expandafter\xintbreakiloop
\fi
\ifnum\xintouteriloopindex=\numexpr
(\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax
\else
\repeat
}% no space here
\ifnum \xintiloopindex < 10999 \repeat }%
\meaning\z\endgroup
\end{everbatim*}and we should have taken
some steps to not have a trailing comma, but
the point was to show that one can do that in an |\edef|\,! See also
\autoref{ssec:primesII} which extracts from this code its way of testing
primality.
Let us create an alignment where each row will contain all divisors of its
first entry.
Here is the output, thus obtained without any count register:
\begin{everbatim*}
\begin{multicols}2
\tabskip1ex \normalcolor
\halign{&\hfil#\hfil\cr
\xintiloop [1+1]
{\expandafter\bfseries\xintiloopindex &
\xintiloop [1+1]
\ifnum\xintouteriloopindex=\numexpr
(\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax
\xintiloopindex&\fi
\ifnum\xintiloopindex<\xintouteriloopindex\space % CRUCIAL \space HERE
\repeat \cr }%
\ifnum\xintiloopindex<30
\repeat
}
\end{multicols}
\end{everbatim*}
We wanted this first entry in bold face, but |\bfseries| leads to
unexpandable tokens, so the |\expandafter| was necessary for |\xintiloopindex|
and |\xintouteriloopindex| not to be confronted with a hard to digest
|\endtemplate|. An alternative way of coding:
%
\begin{everbatim}
\tabskip1ex
\def\firstofone #1{#1}%
\halign{&\hfil#\hfil\cr
\xintiloop [1+1]
{\bfseries\xintiloopindex\firstofone{&}%
\xintiloop [1+1] \ifnum\xintouteriloopindex=\numexpr
(\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax
\xintiloopindex\firstofone{&}\fi
\ifnum\xintiloopindex<\xintouteriloopindex\space % \space is CRUCIAL
\repeat \firstofone{\cr}}%
\ifnum\xintiloopindex<30 \repeat }
\end{everbatim}
\begin{framed}
The next utilities are not compatible with expansion-only context.
\end{framed}
\subsection{\csh{xintApplyInline}}\label{xintApplyInline}
\csa{xintApplyInline}|{\macro}|\marg{list}\ntype{o{\lowast f}} works non
expandably. It applies the one-parameter |\macro| to the first element of the
expanded list (|\macro| may have itself some arguments, the list item will be
appended as last argument), and is then re-inserted in the input stream after
the tokens resulting from this first expansion of |\macro|. The next item is
then handled.
This is to be used in situations where one needs to do some repetitive
things. It is not expandable and can not be completely expanded inside a
macro definition, to prepare material for later execution, contrarily to what
\csbxint{Apply} or \csbxint{ApplyUnbraced} achieve.
\begin{everbatim*}
\def\Macro #1{\advance\cnta #1 , \the\cnta}
\cnta 0
0\xintApplyInline\Macro {3141592653}.
\end{everbatim*}
The first argument |\macro| does not have to be an expandable macro.
\csa{xintApplyInline} submits its second, token list parameter to an
\hyperref[ssec:expansions]{\fexpan
sion}. Then, each \emph{unbraced} item will also be \fexpan ded. This provides
an easy way to insert one list inside another. \emph{Braced} items are not
expanded. Spaces in-between items are gobbled (as well as those at the start
or the end of the list), but not the spaces \emph{inside} the braced items.
\csa{xintApplyInline}, despite being non-expandable, does survive to
contexts where the executed |\macro| closes groups, as happens inside
alignments with the tabulation character |&|.
This tabular provides an example:\par
\begin{everbatim*}
\centerline{\normalcolor\begin{tabular}{ccc}
$N$ & $N^2$ & $N^3$ \\ \hline
\def\Row #1{ #1 & \xintiiSqr {#1} & \xintiiPow {#1}{3} \\ \hline }%
\xintApplyInline \Row {\xintCSVtoList{17,28,39,50,61}}
\end{tabular}}\medskip
\end{everbatim*}
We see that despite the fact that the first encountered tabulation character in
the first row close a group and thus erases |\Row| from \TeX's memory,
|\xintApplyInline| knows how to deal with this.
Using \csbxint{ApplyUnbraced} is an alternative: the difference is that
this would have prepared all rows first and only put them back into the
token stream once they are all assembled, whereas with |\xintApplyInline|
each row is constructed and immediately fed back into the token stream: when
one does things with numbers having hundreds of digits, one learns that
keeping on hold and shuffling around hundreds of tokens has an impact on
\TeX{}'s speed (make this ``thousands of tokens'' for the impact to be
noticeable).
One may nest various |\xintApplyInline|'s. For example (see the
\hyperref[float]{table} \vpageref{float}):\par
\begin{everbatim*}
\begin{figure*}[ht!]
\centering\phantomsection\label{float}
\def\Row #1{#1:\xintApplyInline {\Item {#1}}{0123456789}\\ }%
\def\Item #1#2{&\xintiiPow {#1}{#2}}%
\centeredline {\begin{tabular}{ccccccccccc} &0&1&2&3&4&5&6&7&8&9\\ \hline
\xintApplyInline \Row {0123456789}
\end{tabular}}
\end{figure*}
\end{everbatim*}
One could not move the definition of |\Item| inside the tabular,
as it would get lost after the first |&|. But this
works:
\everb|@
\begin{tabular}{ccccccccccc}
&0&1&2&3&4&5&6&7&8&9\\ \hline
\def\Row #1{#1:\xintApplyInline {&\xintiiPow {#1}}{0123456789}\\ }%
\xintApplyInline \Row {0123456789}
\end{tabular}
|
A limitation is that, contrarily to what one may have expected, the
|\macro| for an |\xintApplyInline| can not be used to define
the |\macro| for a nested sub-|\xintApplyInline|. For example,
this does not work:\par
\everb|@
\def\Row #1{#1:\def\Item ##1{&\xintiiPow {#1}{##1}}%
\xintApplyInline \Item {0123456789}\\ }%
\xintApplyInline \Row {0123456789} % does not work
|
\noindent But see \csbxint{For}.
\subsection{\csh{xintFor}, \csh{xintFor*}}\label{xintFor}\label{xintFor*}
\csbxint{For}\ntype{on} is a new kind of for loop.\footnote{first introduced
with \xintname |1.09c| of |2013/10/09|.} Rather than using macros
for encapsulating list items, its behaviour is like a macro with parameters:
|#1|, |#2|, \dots, |#9| are used to represent the items for up to nine levels of
nested loops. Here is an example:
%
\everb|@
\xintFor #9 in {1,2,3} \do {%
\xintFor #1 in {4,5,6} \do {%
\xintFor #3 in {7,8,9} \do {%
\xintFor #2 in {10,11,12} \do {%
$$#9\times#1\times#3\times#2=\xintiiPrd{{#1}{#2}{#3}{#9}}$$}}}}
|
\noindent This example illustrates that one does not have to use |#1| as the
first one:
the order is arbitrary. But each level of nesting should have its specific macro
parameter. Nine levels of nesting is presumably overkill, but I did not know
where it was reasonable to stop. |\par| tokens are accepted in both the comma
separated list and the replacement text.
\begin{framed}
\TeX nical notes:
\begin{itemize}
\item The |#1| is replaced in the iterated-over text exactly as in general
\TeX\ macros or \LaTeX\ commands. This spares the user quite a few
|\expandafter|'s or other tricks needed with loops which have the
values encapsulated in macros, like \LaTeX's |\@for| and |\@tfor|.
\item \csa{xintFor} (and \csa{xintFor*}) isn't purely expandable: one can
not use it inside an |\edef|. But it may be used, as will be shown in
examples, in some contexts such as \LaTeX's |tabular| which are usually
hostile to non-expandable loops.
\item \csa{xintFor} (and \csa{xintFor*}) does some assignments prior to
executing each iteration of the replacement text, but it acts purely
expandably after the last iteration, hence if for example the replacement
text ends with a |\\|, the loop can be used insided a tabular and be
followed by a |\hline| without creating the dreaded ``|Misplaced
\noalign|'' error.
\item As stated in previous item the first iteration follows some
non-expandable internal dealings. This means for example that in \LaTeX{},
one can not inject a |\multicolumn| in the first iteration. Sometimes one
way work around this by injecting father |&\multicolumn| or |\\
\multicolumn|.
\item It does not create groups.
\item It makes no global assignments.
\item The iterated replacement text may close a group which was opened even
before the start of the loop (typical example being with |&| in
alignments).
\begin{everbatim*}
\begin{tabular}{rccccc}
\hline
\xintFor #1 in {A, B, C} \do {%
#1:\xintFor #2 in {a, b, c, d, e} \do {&($ #2 \to #1 $)}\\ }%
\hline
\end{tabular}
\end{everbatim*}
\item There is no facility provided which would give access to a count of
the number of iterations as it is technically not easy to do so it in a
way working with nested loops while maintaining the ``expandable after
done'' property; something in the spirit of \csbxint{iloopindex} is
possible but this approach would bring its own limitations and
complications. Hence the user is invited to update her own count or
\LaTeX{} counter or macro at each iteration, if needed.
\item A |\macro| whose definition uses internally an \csbxint{For} loop
may be used inside another \csbxint{For} loop even if the two loops both
use the same macro parameter. The loop definition inside |\macro|
must use |##| as is the general rule for definitions done inside macros.
\item \csbxint{For} is for comma separated values and \csbxint{For*} for
lists of braced items; their respective expansion policies differ. They
are described later.
\end{itemize}
\unskip
\end{framed}
\noindent Regarding \csbxint{For}:
\begin{itemize}[nosep, listparindent=\leftmarginiii]
\item the spaces between the various declarative elements are all optional,
\item in the list of comma separated values, spaces around the commas or at
the start and end are ignored,
\item if an item must contain itself its own commas, then it should
be braced, and the braces will be removed before feeding the iterated-over
text,
\item the list may be a macro, it is expanded only once,
\item items are not pre-expanded. The first item should be braced or start
with a space if the list is explicit and the item should not be
pre-expanded,
\item empty items give empty |#1|'s in the replacement text, they are not
skipped,
\item an empty list executes once the replacement text with an empty parameter
value,
\item the list, if not a macro, \fbox{must be braced.}
\end{itemize}
\noindent Regarding \csbxint{For*}:\ntype{{\lowast f}n}
\begin{itemize}[nosep, listparindent=\leftmarginiii]
\item it handles lists of braced items (or naked tokens),
\item it \hyperref[ssec:expansions]{\fexpan ds} the list,
\item and more generally it \hyperref[ssec:expansions]{\fexpan ds} each naked
token encountered
before assigning the |#1| values (gobbling spaces in the process);
this
makes it easy to simulate concatenation of multiple lists|\x|, |\y|:
if |\x| expands to |{1}{2}{3}| and |\y| expands to |{4}{5}{6}| then |{\x\y}|
as argument to |\xintFor*| has the same effect as |{{1}{2}{3}{4}{5}{6}}|.
For a further illustration see the use of |\xintFor*| at the end of
\autoref{ssec:fibonacci}.
\item spaces at the start, end, or in-between items are gobbled (but naturally
not the spaces inside \emph{braced} items),
\item except if the list argument is a macro (with no parameters), \fbox{it
must be braced.},
\item an empty list leads to an empty result.
\end{itemize}
The macro \csbxint{Seq} which generates arithmetic sequences is to be used
with \csbxint{For*} as its output consists of successive braced numbers (given
as digit tokens).
\begin{everbatim*}
\xintFor* #1 in {\xintSeq [+2]{-7}{+2}}\do {stuff
with #1\xintifForLast{\par}{\newline}}
\end{everbatim*}
When nesting \csa{xintFor*} loops, using \csa{xintSeq} in the inner loops is
inefficient, as the arithmetic sequence will be re-created each time. A more
efficient style is:
%
\begin{everbatim}
\edef\innersequence {\xintSeq[+2]{-50}{50}}%
\xintFor* #1 in {\xintSeq {13}{27}} \do
{\xintFor* #2 in \innersequence \do {stuff with #1 and #2}%
.. some other macros .. }
\end{everbatim}
This is a general remark applying for any nesting of loops, one should avoid
recreating the inner lists of arguments at each iteration of the outer loop.
When the loop is defined inside a macro for later execution the |#| characters
must be doubled.%
%
\footnote{sometimes what seems to be a macro argument isn't really; in
\csa{raisebox\{1cm\}\{}\csa{xintFor \#1 in \{a,b,c\} }\csa{do
\{\#1\}\}} no doubling should be done.}
%
For example:
%
\begin{everbatim*}
\def\T{\def\z {}%
\xintFor* ##1 in {{u}{v}{w}} \do {%
\xintFor ##2 in {x,y,z} \do {%
\expandafter\def\expandafter\z\expandafter {\z\sep (##1,##2)} }%
}%
}%
\T\def\sep {\def\sep{, }}\z
\end{everbatim*}
Similarly when the replacement text
of |\xintFor| defines a macro with parameters, the macro character |#| must be
doubled.
The iterated macros as well as the list items are allowed to contain explicit
|\par| tokens.
\subsection{\csh{xintifForFirst}, \csh{xintifForLast}}
\label{xintifForFirst}\label{xintifForLast}
\csbxint{ifForFirst}\,\texttt{\{YES branch\}\{NO branch\}}\etype{nn}
and \csbxint{ifForLast}\,\texttt{\{YES
branch\}\hskip 0pt plus 0.2em \{NO branch\}}\etype{nn} execute the |YES| or
|NO| branch
if the
\csbxint{For}
or \csbxint{For*} loop is currently in its first, respectively last, iteration.
Designed to work as expected under nesting (but see frame next.) Don't forget
an empty brace pair |{}| if a branch is to do nothing. May be used multiple
times in the replacement text of the loop.
\begin{framed}
\noindent Pay attention to these implementation features:
\begin{itemize}[nosep, listparindent=\leftmarginiii]
\item \emph{if an inner \csbxint{For} loop is positioned before the
\csb{xintifForFirst} or \csb{xintifForLast} of the outer loop it will
contaminate their settings. This applies also naturally if the inner loop
arises from the expansion of some macro located before the outer
conditionals.}
One fix is to make sure that the outer conditionals are expanded before the
inner loop is executed, e.g. this will be the case if the inner loop is
located inside one of the branches of the conditional.
Another approach is to enclose, if feasible, the inner loop in a group of
its own.
\item \emph{if the replacement text closes a group (e.g. from a |&| inside an
alignment), the conditionals will lose their ascribed meanings and end up
possibly undefined, depending whether there is some outer loop whose
execution started before the opening of the group.}
The fix is to arrange things so that the conditionals are expanded
before \TeX\ encounters the closing-group token.
\end{itemize}
\end{framed}
\subsection{ \csh{xintBreakFor}, \csh{xintBreakForAndDo}}
\label{xintBreakFor}\label{xintBreakForAndDo}
One may immediately terminate an \csbxint{For} or \csbxint{For*} loop with
\csbxint{BreakFor}.
\begin{framed}
As it acts by clearing up all the rest of the replacement text when
encountered, it will not work from inside some |\if...\fi| without
suitable |\expandafter| or swapping technique.
Also it can't be used from inside braces as from there it can't see the end
of the replacement text.
\end{framed}
There is also \csbxint{BreakForAndDo}. Both are illustrated by various examples
in the next section which is devoted to ``forever'' loops.
\subsection{\csh{xintintegers}, \csh{xintdimensions}, \csh{xintrationals}}
\label{xintegers}\label{xintintegers}
\label{xintdimensions}\label{xintrationals}
If the list argument to \csbxint{For} (or \csbxint{For*}, both are equivalent in
this context) is \csbxint{integers} (equivalently \csbxint{egers}) or more
generally \csbxint{integers}|[||start|\allowbreak|+|\allowbreak|delta||]|
(\emph{the whole within braces}!)%
%
\footnote{the |start+delta| optional specification may have extra spaces
around the plus sign of near the square brackets, such spaces are
removed. The same applies with \csa{xintdimensions} and
\csa{xintrationals}.},
%
then \csbxint{For} does an infinite iteration where
|#1| (or |#2|, \dots, |#9|) will run through the arithmetic sequence of (short)
integers with initial value |start| and increment |delta| (default values:
|start=1|, |delta=1|; if the optional argument is present it must contains both
of them, and they may be explicit integers, or macros or count registers). The
|#1| (or |#2|, \dots, |#9|) will stand for |\numexpr \relax|,
and the litteral representation as a string of digits can thus be obtained as
\fbox{\csa{the\#1}} or |\number#1|. Such a |#1| can be used in an |\ifnum| test
with no need to be postfixed with a space or a |\relax| and one should
\emph{not} add them.
If the list argument is \csbxint{dimensions} or more generally
\csbxint{dimensions}|[||start|\allowbreak|+|\allowbreak|delta||]| (\emph{within
braces}!), then
\csbxint{For} does an infinite iteration where |#1| (or |#2|, \dots, |#9|) will
run through the arithmetic sequence of dimensions with initial value
|start| and increment |delta|. Default values: |start=0pt|, |delta=1pt|; if
the optional argument is present it must contain both of them, and they may
be explicit specifications, or macros, or dimen registers, or length macros
in \LaTeX{} (the stretch and shrink components will be discarded). The |#1|
will be |\dimexpr sp\relax|, from which one can get the
litteral (approximate) representation in points via |\the#1|. So |#1| can be
used anywhere \TeX{} expects a dimension (and there is no need in conditionals
to insert a |\relax|, and one should \emph{not} do it), and to print its value
one uses \fbox{\csa{the\#1}}. The chosen representation guarantees exact
incrementation with no rounding errors accumulating from converting into
points at each step.
If the list argument to \csbxint{For} (or \csbxint{For*}) is \csbxint{rationals}
or more generally
\csbxint{rationals}|[||start|\allowbreak|+|\allowbreak|delta||]| (\emph{within
braces}!), then \csbxint{For} does an infinite iteration where |#1| (or |#2|,
\dots, |#9|) will run through the arithmetic sequence of \xintfracname fractions
with initial value |start| and increment |delta| (default values: |start=1/1|,
|delta=1/1|). This loop works \emph{only with \xintfracname loaded}. if the
optional argument is present it must contain both of them, and they may be given
in any of the formats recognized by \xintfracname (fractions, decimal
numbers, numbers in scientific notations, numerators and denominators in
scientific notation, etc...) , or as macros or count registers (if they are
short integers). The |#1| (or |#2|, \dots, |#9|) will be an |a/b| fraction
(without a |[n]| part), where
the denominator |b| is the product of the denominators of
|start| and |delta| (for reasons of speed |#1| is not reduced to irreducible
form, and for another reason explained later |start| and |delta| are not put
either into irreducible form; the input may use explicitely \csa{xintIrr} to
achieve that).
\begin{everbatim*}
\begingroup\small
\noindent\parbox{\dimexpr\linewidth-3em}{\color[named]{OrangeRed}%
\xintFor #1 in {\xintrationals [10/21+1/21]} \do
{#1=\xintifInt {#1}
{\textcolor{blue}{\xintTrunc{10}{#1}}}
{\xintTrunc{10}{#1}}% display in blue if an integer
\xintifGt {#1}{1.123}{\xintBreakFor}{, }%
}}
\endgroup\smallskip
\end{everbatim*}
\smallskip The example above confirms that computations are done exactly, and
illustrates that the two initial (reduced) denominators are not multiplied when
they are found to be equal. It is thus recommended to input |start| and |delta|
with a common smallest possible denominator, or as fixed point numbers with the
same numbers of digits after the decimal mark; and this is also the reason why
|start| and |delta| are not by default made irreducible. As internally the
computations are done with numerators and denominators completely expanded, one
should be careful not to input numbers in scientific notation with exponents in
the hundreds, as they will get converted into as many zeroes.
\begin{everbatim*}
\noindent\parbox{\dimexpr.7\linewidth}{\raggedright
\xintFor #1 in {\xintrationals [0.000+0.125]} \do
{\edef\tmp{\xintTrunc{3}{#1}}%
\xintifInt {#1}
{\textcolor{blue}{\tmp}}
{\tmp}%
\xintifGt {#1}{2}{\xintBreakFor}{, }%
}}\smallskip
\end{everbatim*}
We see here that \csbxint{Trunc} outputs (deliberately) zero as $0$, not (here)
$0.000$, the idea being not to lose the information that the truncated thing was
truly zero. Perhaps this behaviour should be changed? or made optional? Anyhow
printing of fixed points numbers should be dealt with via dedicated packages
such as |numprint| or |siunitx|.\par
\subsection{\csh{xintForpair}, \csh{xintForthree}, \csh{xintForfour}}\label{xintForpair}\label{xintForthree}\label{xintForfour}
The syntax\ntype{on} is illustrated in this
example. The notation is the usual one for |n|-uples, with parentheses and
commas. Spaces around commas and parentheses are ignored.
%
\begin{everbatim*}
{\centering\begin{tabular}{cccc}
\xintForpair #1#2 in { ( A , a ) , ( B , b ) , ( C , c ) } \do {%
\xintForpair #3#4 in { ( X , x ) , ( Y , y ) , ( Z , z ) } \do {%
$\Biggl($\begin{tabular}{cc}
-#1- & -#3-\\
-#4- & -#2-\\
\end{tabular}$\Biggr)$&}\\\noalign{\vskip1\jot}}%
\end{tabular}\\}
\end{everbatim*}
\csbxint{Forpair} must be followed by either |#1#2|, |#2#3|, |#3#4|, \dots, or
|#8#9| with |#1| usable as an alias for |#1#2|, |#2| as alias for |#2#3|,
etc \dots\ and similarly for \csbxint{Forthree} (using |#1#2#3| or simply
|#1|, |#2#3#4| or simply |#2|, \dots) and \csbxint{Forfour} (with |#1#2#3#4|
etc\dots).
Nesting works as long as the macro parameters are distinct among |#1|, |#2|,
..., |#9|. A macro which expands to an \csa{xintFor} or a
\csa{xintFor(pair,three,four)} can be used in another one with no constraint
about using distinct macro parameters.
|\par| tokens are accepted in both the comma separated list and the
replacement text.
\subsection{\csh{xintAssign}}\label{xintAssign}
\csa{xintAssign}\meta{braced things}\csa{to}%
\meta{as many cs as they are things} %\ntype{{(f$\to$\lowast [x)}{\lowast N}}
%
defines (without checking if something gets overwritten) the control sequences
on the right of \csa{to} to expand to the successive tokens or braced items
located to the left of \csa{to}. \csa{xintAssign} is not an expandable macro.
\fexpan sion is first applied to the material in front of \csa{xintAssign}
which is fetched as one argument if it is braced. Then the expansion of this
argument is examined and successive items are assigned to the macros following
|\to|. There must be exactly as many macros as items. No check is done. The
macro assignments are done with removal of one level of brace pairs from each
item.
After the initial \fexpan sion, each assigned (brace-stripped) item will be
expanded according to the setting of the optional parameter.
For example |\xintAssign [e]...| means that all assignments are done using
|\edef|. With |[f]| the assignments will be made using
\hyperref[fdef]{\ttfamily\char92fdef}. The default is simply to make the
definitions with |\def|, corresponding to an empty optional paramter |[]|.
Possibilities for the optional parameter are: |[], [g], [e], [x], [o], [go],
[oo], [goo], [f], [gf]|. For example |[oo]| means a double expansion.
\begin{everbatim*}
\xintAssign \xintiiDivision{1000000000000}{133333333}\to\Q\R
\meaning\Q\newline
\meaning\R\newline
\xintAssign {{\xintiiDivision{1000000000000}{133333333}}}\to\X
\meaning\X\newline
\xintAssign [oo]{{\xintiiDivision{1000000000000}{133333333}}}\to\X
\meaning\X\newline
\xintAssign \xintiiPow{7}{13}\to\SevenToThePowerThirteen
\meaning\SevenToThePowerThirteen\par
\end{everbatim*}
Two special cases:
\begin{itemize}[nosep]
\item if after this initial expansion no brace is found immediately after
\csa{xintAssign}, it is assumed that there is only one control sequence
following |\to|, and this control sequence is then defined via |\def| (or
what is set-up by the optional parameter) to expand to the material between
\csa{xintAssign} and \csa{to}.
\item if the material between \csa{xintAssign} and |\to| is enclosed in two
brace pairs, the first brace pair is removed, then the \fexpan sion is
immediately stopped by the inner brace pair, hence \csa{xintAssign} now
finds a unique item and thus defines only a single macro to be this item,
which is now stripped of the second pair of braces.
\end{itemize}
\emph{Note:} prior to release |1.09j|, |\xintAssign| did an |\edef| by default
for each item assignment but it now does |\def| corresponding to no or empty
optional parameter.
It is allowed for the successive braced items to be separated by spaces. They
are removed during the assignments. But if a single macro is defined (which
happens if the argument after \fexpan sion does not start with a brace),
naturally the scooped up material has all intervening spaces, as it is
considered a
single item. But an upfront initial space will have been absorbed by \fexpan
sion.
\begin{everbatim*}
\def\X{ {a} {b} {c} {d} }\def\Y { u {a} {b} {c} {d} }
\xintAssign\X\to\A\B\C\D
\xintAssign\Y\to\Z
\meaning\A, \meaning\B, \meaning\C, \meaning\D+++\newline
\meaning\Z+++\par
\end{everbatim*}
As usual successive space characters in input make for a single \TeX\ space token.
\subsection{\csh{xintAssignArray}}\label{xintAssignArray}
\xintAssignArray \xintBezout {1000}{113}\to\Bez
\csa{xintAssignArray}\meta{braced things}\csa{to}\csa{myArray}
%
%\ntype{{(f$\to$\lowast x)}N}
%
first expands fully what comes immediately after |\xintAssignArray| and
expects to find a list of braced things |{A}{B}...| (or tokens). It then
defines \csa{myArray} as a macro with one parameter, such that \csa{myArray\x}
expands to give the |x|th braced thing of this original
list (the argument \texttt{\x} itself is fed to a |\numexpr| by |\myArray|,
and |\myArray| expands in two steps to its output). With |0| as parameter,
\csa{myArray}|{0}| returns the number |M| of elements of the array so that the
successive elements are \csa{myArray}|{1}|, \dots, \csa{myArray}|{M}|.
%
\leftedline{|\xintAssignArray \xintBezout {1000}{113}\to\Bez|} will set
|\Bez{0}| to \dtt{\Bez0}, |\Bez{1}| to \dtt{\Bez1}, |\Bez{2}| to
\dtt{\Bez2}, and |\Bez{3}| to \dtt{\Bez3}:
\dtt{$\Bez1\times1000+\Bez2\times113=\Bez3$.}
This macro is incompatible with expansion-only contexts.
\csa{xintAssignArray} admits an optional parameter, for example
|\xintAssignArray [e]| means that the definitions of the macros will be made
with |\edef|. The empty optional parameter (default) means that definitions
are done with |\def|. Other possibilities: |[], [o], [oo], [f]|. Contrarily to
\csbxint{Assign} one can not use the |g| here to make the definitions global.
For this, one should rather do |\xintAssignArray| within a group starting with
|\globaldefs 1|.
\subsection{\csh{xintDigitsOf}}\label{xintDigitsOf}
This is a synonym for \csbxint{AssignArray},\ntype{fN} to be used to define
an array giving all the digits of a given (positive, else the minus sign will
be treated as first item) number.
\begingroup\xintDigitsOf\xintiiPow {7}{500}\to\digits
%
\leftedline{|\xintDigitsOf\xintiiPow {7}{500}\to\digits|}
\noindent $7^{500}$ has |\digits{0}=|\digits{0} digits, and the 123rd among them
(starting from the most significant) is
|\digits{123}=|\digits{123}.
\endgroup
\subsection{\csh{xintRelaxArray}}\label{xintRelaxArray}
\csa{xintRelaxArray}\csa{myArray} %\ntype{N}
%
(globally) sets to \csa{relax} all macros which were defined by the previous
\csa{xintAssignArray} with \csa{myArray} as array macro.
\clearpage
\let\xinttoolsnameUp\undefined
\def\n{|{N}|}
\def\m{|{M}|}
\def\x{|{x}|}
\csname ExamplesnameUp\endcsname
\section {Additional (old) examples with \xinttoolsname or \xintexprname or both}
\RaisedLabel{sec:examples}
\localtableofcontents
\subsection{Introduction}
Note: \xintexprname.sty automatically loads \xinttoolsname.sty.
The examples given here start to feel dated and are currently in need of some
rewrite to better illustrate newer features of the package.
\subsection{More examples with dummy variables}
\label{ssec:moredummies}
These examples were first added to this manual at the time of the |1.1|
release (|2014/10/29|).
\begin{everbatim*}
Prime numbers are always cool
\xinttheiiexpr seq((seq((subs((x/:m)?{(m*m>x)?{1}{0}}{-1},m=2n+1))
??{break(0)}{omit}{break(1)},n=1++))?{x}{omit},
x=10001..[2]..10200)\relax
\end{everbatim*}
The syntax in this last example may look a bit involved (...\@{} and it is so I
admit). First |x/:m| computes |x modulo m| (this is the modulo with respect to
floored division). The |(x)?{yes}{no}| construct checks if |x| (which
\emph{must} be within parentheses) is true or false, i.e.\@{} non zero or zero. It
then executes either the |yes| or the |no| branch, the non chosen branch is
\emph{not} evaluated. Thus if |m| divides |x| we are in the second (``false'')
branch. This gives a |-1|. This |-1| is the argument to a |??| branch which is
of the type |(y)??{y<0}{y=0}{y>0}|, thus here the |y<0|, i.e.\@, |break(0)| is
chosen. This |0| is thus given to another |?| which consequently chooses
|omit|, hence the number is not kept in the list. The numbers which survive
are the prime numbers.
\begin{everbatim*}
The first Fibonacci number beyond |2^64|, |2^64|, and the index are respectively
\xinttheiiexpr subs(iterr(0,1;(@1>N)?{break(@1,N,i)}{@1+@2},i=1++),N=2^64)\relax.
\end{everbatim*}
% A006877 In the `3x+1' problem, these values for the starting value set new
% records for number of steps to reach 1. (Formerly M0748) 14 1, 2, 3, 6, 7,
% 9, 18, 25, 27, 54, 73, 97, 129, 171, 231, 313, 327, 649, 703, 871, 1161,
% 2223, 2463, 2919, 3711, 6171, 10971, 13255, 17647, 23529, 26623, 34239,
% 35655, 52527, 77031, 106239, 142587, 156159, 216367, 230631, 410011, 511935,
% 626331, 837799
One more recursion:
\begin{everbatim*}
\def\syr #1{\xinttheiiexpr
rseq(#1; (@<=1)?{break(i)}{odd(@)?{3@+1}{@//2}},i=0++)\relax}
The 3x+1 problem: \syr{231}\par
\end{everbatim*}
OK, a final one:%
\begin{everbatim*}
\def\syrMax #1{\xintiiexpr iterr(#1,#1;even(i)?
{(@2<=1)?{break(@1,i//2)}
{odd(@2)?{3@2+1}{@2//2}}}
{(@1>@2)?{@1}{@2}},i=0++)\relax }
With initial value 1161, the maximal intermediate value and the number of steps
needed to reach 1 are respectively \syrMax{1161}.\par
\end{everbatim*}
Look at the
\hyperlink{BrentSalamin}{Brent-Salamin algorithm implementation} for a more
interesting recursion.
% \begin{everbatim*}
% \newcommand\Factors [1]{\xinttheiiexpr
% subs(seq((i/:3=1)?{omit}{[L][i]},i=0..len(L)-1),
% L=rseq(#1;(p^2>[@][0])?{([@][0]>1)?{break(1,[@][0],1)}{abort}}
% {(([@][0])/:p)?{omit}
% {iter(([@][0])//p; (@/:p)?{break(@,p,e)}{@//p},e=1++)}},p=2++))\relax }
% \Factors {41^4*59^2*29^3*13^5*17^8*29^2*59^4*37^6}
% \end{everbatim*}
% This might look a bit scary, I admit.%
% %
% \footnote{Look at the
% \hyperlink{BrentSalamin}{Brent-Salamin algorithm implementation} for a much
% saner example.}
% %
% \xintexprname has minimal tools and
% is obstinate about doing everything expandably! We are hampered by absence of a
% notion of ``nuple''. The algorithm divides |N| by |2| until no more possible,
% then by |3|, then by |4| (which is silly), then by |5|, then by |6| (silly
% again), \dots.
% The variable |L=rseq(#1;...)| expands, if one follows the steps, to a comma
% separated list starting with the initial (evaluated) |N=#1| and then
% pseudo-triplets where the first item is |N| trimmed of small primes, the
% second item is the last prime divisor found, and the third item is its
% exponent in original |N|.
% The algorithm needs to keep handy the last computed quotient by prime powers,
% hence all of them, but at the very end it will be cleaner to get rid of them
% (this corresponds to the first line in the code above). This is achieved in a
% cumbersome inefficient way; indeed each item extraction |[L][i]| is costly: it
% is not like accessing an array stored in memory, due to expandability, nothing
% can be stored in memory! Nevertheless, this step could be done here in a far
% less inefficient manner if there was a variant of |seq| which, in the spirit
% of \csbxint{iloopindex}, would know how many steps it had been through so far.
% This is a feature to be added to |\xintexpr|! (as well as a |++| construct
% allowing a non unit step).
% Notice that in |iter(([@][0])//p;| the |@| refers to the previous triplet (or
% in the first step to |N|), but the latter |@| showing up in |(@/:p)?| refers
% to the previous value computed by |iter|.
% \begin{snugframed}
% Parentheses are essential in |..([y][0])| else the parser will see |..[| and
% end up in ultimate confusion, and also in |([@][0])/:p| else the parser will
% see the itemwise operator |]/| on lists and again be very confused (I could
% implement a |]/:| on lists, but in this situation this would also be very
% confusing to the parser.)
% \end{snugframed}
% See \autoref{ssec:factorize} for a routine |\Factorize| written directly with
% \xintname macros. Last time I checked |\Factors| was about seven times slower
% than |\Factorize| in test cases such as
% |16246355912554185673266068721806243461403654781833| and others. Among the
% various things explaining the speed difference, there is fact that the
% |\Factorize| algorithm step by increments of two, not one, and also it divides
% only once, obtaining quotient and remainder in one go. These two things
% already make for a speed-up factor of about four. Thus, |\Factors| is not
% completely inefficient in comparison, and was quite easier to come up with
% than |\Factorize|.
\subsection{Completely expandable prime test}
\label{ssec:primesI}
Let us now construct a completely expandable macro which returns $1$ if its
given input is prime and $0$ if not:
\everb|@
\def\remainder #1#2{\the\numexpr #1-(#1/#2)*#2\relax }
\def\IsPrime #1%
{\xintANDof {\xintApply {\remainder {#1}}{\xintSeq {2}{\xintiiSqrt{#1}}}}}
|
This uses \csbxint{iiSqrt} and assumes its input is at least $5$. Rather than
\xintname's own \csbxint{iiRem} we used a quicker |\numexpr| expression as we
are dealing with short integers. Also we used \csbxint{ANDof} which will
return $1$ only if all the items are non-zero. The macro is a bit
silly with an even input, ok, let's enhance it to detect an even input:
\everb|@
\def\IsPrime #1%
{\xintiiifOdd {#1}
{\xintANDof % odd case
{\xintApply {\remainder {#1}}
{\xintSeq [2]{3}{\xintiiSqrt{#1}}}%
}%
}
{\xintifEq {#1}{2}{1}{0}}%
}
|
We used the \xintname expandable tests (on big integers or fractions)
in order for |\IsPrime| to be \fexpan dable.
Our integers are short, but without |\expandafter|'s with
|\@firstoftwo|, % @ n'est plus actif dans le dtx 1.1 !
or some other related techniques,
direct use of |\ifnum..\fi| tests is dangerous. So to make the macro more
efficient we are going to use the expandable tests provided by the package
\href{http://ctan.org/pkg/etoolbox}{etoolbox}%
%
\footnote{\url{http://ctan.org/pkg/etoolbox}}.
%
The macro becomes:
%
\everb|@
\def\IsPrime #1%
{\ifnumodd {#1}
{\xintANDof % odd case
{\xintApply {\remainder {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}}
{\ifnumequal {#1}{2}{1}{0}}}
|
In the odd case however we have to assume the integer is at least $7$, as
|\xintSeq| generates an empty list if |#1=3| or |5|, and |\xintANDof| returns
$1$ when supplied an empty list. Let us ease up a bit |\xintANDof|'s work by
letting it work on only $0$'s and $1$'s. We could use:
%
\everb|@
\def\IsNotDivisibleBy #1#2%
{\ifnum\numexpr #1-(#1/#2)*#2=0 \expandafter 0\else \expandafter1\fi}
|
\noindent
where the |\expandafter|'s are crucial for this macro to be \fexpan dable and
hence work within the applied \csbxint{ANDof}. Anyhow, now that we have loaded
\href{http://ctan.org/pkg/etoolbox}{etoolbox}, we might as well use:
%
\everb|@
\newcommand{\IsNotDivisibleBy}[2]{\ifnumequal{#1-(#1/#2)*#2}{0}{0}{1}}
|
\noindent
Let us enhance our prime macro to work also on the small primes:
\everb|@
\newcommand{\IsPrime}[1] % returns 1 if #1 is prime, and 0 if not
{\ifnumodd {#1}
{\ifnumless {#1}{8}
{\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes
{\xintANDof
{\xintApply
{ \IsNotDivisibleBy {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}%
}}% END OF THE ODD BRANCH
{\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH
}
|
The input is still assumed positive. There is a deliberate blank before
\csa{IsNotDivisibleBy} to use this feature of \csbxint{Apply}: a space stops the
expansion of the applied macro (and disappears). This expansion will be done by
\csbxint{ANDof}, which has been designed to skip everything as soon as it finds
a false (i.e.\@{} zero) input. This way, the efficiency is considerably improved.
We did generate via the \csbxint{Seq} too many potential divisors though. Later
sections give two variants: one with \csbxint{iloop} (\autoref{ssec:primesII})
which is still expandable and another one (\autoref{ssec:primesIII}) which is a
close variant of the |\IsPrime| code above but with the \csbxint{For} loop, thus
breaking expandability. The \hyperref[ssec:primesII]{xintiloop variant} does not
first evaluate the integer square root, the \hyperref[ssec:primesIII]{xintFor
variant} still does. I did not compare their efficiencies.
Let us construct with this expandable primality test a table of the prime
numbers up to $1000$. We need to count how many we have in order to know how
many tab stops one shoud add in the last row.%
%
\footnote{although a tabular row may have less tabs than in the
preamble, there is a problem with the \char`\|\space\space vertical
rule, if one does that.}
%
There is some subtlety for this
last row. Turns out to be better to insert a |\\| only when we know for sure we
are starting a new row; this is how we have designed the |\OneCell| macro. And
for the last row, there are many ways, we use again |\xintApplyUnbraced| but
with a macro which gobbles its argument and replaces it with a tabulation
character. The \csbxint{For*} macro would be more elegant here.
%
\everb?@
\newcounter{primecount}
\newcounter{cellcount}
\newcommand{\NbOfColumns}{13}
\newcommand{\OneCell}[1]{%
\ifnumequal{\IsPrime{#1}}{1}
{\stepcounter{primecount}
\ifnumequal{\value{cellcount}}{\NbOfColumns}
{\\\setcounter{cellcount}{1}#1}
{&\stepcounter{cellcount}#1}%
} % was prime
{}% not a prime, nothing to do
}
\newcommand{\OneTab}[1]{&}
\begin{tabular}{|*{\NbOfColumns}{r}|}
\hline
2 \setcounter{cellcount}{1}\setcounter{primecount}{1}%
\xintApplyUnbraced \OneCell {\xintSeq [2]{3}{999}}%
\xintApplyUnbraced \OneTab
{\xintSeq [1]{1}{\the\numexpr\NbOfColumns-\value{cellcount}\relax}}%
\\
\hline
\end{tabular}
There are \arabic{primecount} prime numbers up to 1000.
?
The table has been put in \hyperref[primesupto1000]{float} which appears
\vpageref{primesupto1000}.
We had to be careful to use in the last row \csbxint{Seq} with its optional
argument |[1]| so as to not generate a decreasing sequence from |1| to |0|, but
really an empty sequence in case the row turns out to already have all its
cells (which doesn't happen here but would with a number of columns dividing
$168$).
%
\newcommand{\IsNotDivisibleBy}[2]{\ifnumequal{#1-(#1/#2)*#2}{0}{0}{1}}
\newcommand{\IsPrime}[1]
{\ifnumodd {#1}
{\ifnumless {#1}{8}
{\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes
{\xintANDof
{\xintApply
{ \IsNotDivisibleBy {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}%
}}% END OF THE ODD BRANCH
{\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH
}
\newcounter{primecount}
\newcounter{cellcount}
\newcommand{\NbOfColumns}{13}
\newcommand{\OneCell}[1]
{\ifnumequal{\IsPrime{#1}}{1}
{\stepcounter{primecount}
\ifnumequal{\value{cellcount}}{\NbOfColumns}
{\\\setcounter{cellcount}{1}#1}
{&\stepcounter{cellcount}#1}%
} % was prime
{}% not a prime nothing to do
}
\newcommand{\OneTab}[1]{&}
\begin{figure*}[ht!]
\centering
\phantomsection\label{primesupto1000}
\begin{tabular}{|*{\NbOfColumns}{r}|}
\hline
2\setcounter{cellcount}{1}\setcounter{primecount}{1}%
\xintApplyUnbraced \OneCell {\xintSeq [2]{3}{999}}%
\xintApplyUnbraced \OneTab
{\xintSeq [1]{1}{\the\numexpr\NbOfColumns-\value{cellcount}\relax}}%
\\
\hline
\end{tabular}
\smallskip
\centeredline{There are \arabic{primecount} prime numbers up to 1000.}
\end{figure*}
\subsection{Another completely expandable prime test}
\label{ssec:primesII}
The |\IsPrime| macro from \autoref{ssec:primesI} checked expandably if a (short)
integer was prime, here is a partial rewrite using \csbxint{iloop}. We use the
|etoolbox| expandable conditionals for convenience, but not everywhere as
|\xintiloopindex| can not be evaluated while being braced. This is also the
reason why |\xintbreakiloopanddo| is delimited, and the next macro
|\SmallestFactor| which returns the smallest prime factor examplifies that. One
could write more efficient completely expandable routines, the aim here was only
to illustrate use of the general purpose \csbxint{iloop}. A little table giving
the first values of |\SmallestFactor| follows, its coding uses \csbxint{For},
which is described later; none of this uses count registers.
%
\begin{everbatim*}
% clean up possible left-over mess from previous examples
\let\IsPrime\undefined \let\SmallestFactor\undefined
\newcommand{\IsPrime}[1] % returns 1 if #1 is prime, and 0 if not
{\ifnumodd {#1}
{\ifnumless {#1}{8}
{\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes
{\if
\xintiloop [3+2]
\ifnum#1<\numexpr\xintiloopindex*\xintiloopindex\relax
\expandafter\xintbreakiloopanddo\expandafter1\expandafter.%
\fi
\ifnum#1=\numexpr (#1/\xintiloopindex)*\xintiloopindex\relax
\else
\repeat 00\expandafter0\else\expandafter1\fi
}%
}% END OF THE ODD BRANCH
{\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH
}%
\catcode`_ 11
\newcommand{\SmallestFactor}[1] % returns the smallest prime factor of #1>1
{\ifnumodd {#1}
{\ifnumless {#1}{8}
{#1}% 3,5,7 are primes
{\xintiloop [3+2]
\ifnum#1<\numexpr\xintiloopindex*\xintiloopindex\relax
\xint_afterfi{\xintbreakiloopanddo#1.}%
\fi
\ifnum#1=\numexpr (#1/\xintiloopindex)*\xintiloopindex\relax
\xint_afterfi{\expandafter\xintbreakiloopanddo\xintiloopindex.}%
\fi
\iftrue\repeat
}%
}% END OF THE ODD BRANCH
{2}% EVEN BRANCH
}%
\catcode`_ 8
{\centering
\begin{tabular}{|c|*{10}c|}
\hline
\xintFor #1 in {0,1,2,3,4,5,6,7,8,9}\do {&\bfseries #1}\\
\hline
\bfseries 0&--&--&2&3&2&5&2&7&2&3\\
\xintFor #1 in {1,2,3,4,5,6,7,8,9}\do
{\bfseries #1%
\xintFor #2 in {0,1,2,3,4,5,6,7,8,9}\do
{&\SmallestFactor{#1#2}}\\}%
\hline
\end{tabular}\par
}
\end{everbatim*}
\subsection{Miller-Rabin Pseudo-Primality expandably}
\label{ssec:PrimesIV}
% At the time of writing, the code at the link above is still the version from
% April 2016 and it needed some hacks to get recursive (pseudo)-functions
% defined. Since |1.2h| of |2016/11/20| there is \csbxint{NewFunction} which
% allows us here to avoid such internal hacking.
% And since |1.3| of |2018/03/01|, it is possible to use \csbxint{defiifunc}
% also for recursive definitions, so we use it here, but we can benefit from it
% only for modular exponentiation as the rest of the code uses |iter| or |break|
% statements which are not yet compatible with \csbxint{defiifunc}.
The |isPseudoPrime(n)| is usable in \csbxint{iiexpr}-essions and establishes
if its (positive) argument is a Miller-Rabin PseudoPrime to the bases $2, 3,
5, 7, 11, 13, 17$. If this is true and $n<341550071728321$ (which has 15
digits) then $n$ really is a prime number.
Similarly $n=3825123056546413051$ (19 digits) is the smallest composite number
which is a strong pseudo prime for bases $2, 3, 5, 7, 11, 13, 17, 19$ and
$23$. It is easy to extend the code below to include these additional tests
(we could make the list of tested bases an argument too, now that I think
about it.)
For more information see
\centeredline{\url{https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test#Deterministic_variants_of_the_test}}
and
\centeredline{\url{http://primes.utm.edu/prove/prove2_3.html}}
In particular, according to \textsc{Jaeschke} \emph{On strong pseudoprimes to
several bases,} Math. Comp., 61 (1993) 915-926, if $n < 4,759,123,141$ it is
enough to establish Rabin-Miller pseudo-primality to bases $a = 2, 7, 61$ to
prove that $n$ is prime. This range is enough for \TeX\ numbers and we could
then write a very fast expandable primality test for such numbers using only
|\numexpr|. Left as an exercise\dots
\begin{everbatim*}
% I -------------------------------- Modular Exponentiation
% Computes x^m modulo n (with m non negative).
% We will always use it with 1 < x < n
%
% With xint 1.4 we should use ? and ?? (although in the case at hand ifsgn()
% and if() would be ok but I should not say that).
%
\xintdefiifunc powmod_a(x, m, n) :=
isone(m)?
% m=1, return x modulo n
{ x /: n }
% m > 1 test if odd or even and do recursive call
{ odd(m)? { x*sqr(powmod_a(x, m//2, n)) /: n }
{ sqr(powmod_a(x, m//2, n)) /: n }
}
;
\xintdefiifunc powmod(x, m, n) := (m)?{powmod_a(x, m, n)}{1};
%% Syntax used before xint 1.4:
% \xintdefiifunc powmod_a(x, m, n) :=
% ifone(m,
% % m=1, return x modulo n
% x /: n,
% % m > 1 test if odd or even and do recursive call
% if(odd(m), (x*sqr(powmod_a(x, m//2, n))) /: n,
% sqr(powmod_a(x, m//2, n)) /: n
% )
% );
% \xintdefiifunc powmod(x, m, n) := if(m, powmod_a(x, m, n), 1);
% II ------------------------------ Miller-Rabin compositeness witness
% n=2^k m + 1 with m odd and k at least 1
% Choose 1 if at some point n-1 mod n found, we can't say anything and break out
% -> if however we never find n-1 mod n before reaching
% z=y^{2^{k-1}} with j=k
% we then have z^2=x^{n-1}.
% Suppose z is not -1 mod n. If z^2 is 1 mod n, then n can be prime only if
% z is 1 mod n, and we can go back up, until initial y, and we have already
% excluded y=1. Thus if z is not -1 mod n and z^2 is 1 then n is not prime.
% But if z^2 is not 1, then n is not prime by Fermat. Hence (z not -1 mod n)
% implies (n is composite). (Miller test)
% let's use again xintexpr indecipherable (except to author) syntax. Of course
% doing it with macros only would be faster.
% Here \xintdefiifunc is not usable because not compatible with iter, break, ...
% but \xintNewFunction comes to the rescue.
\xintNewFunction{isCompositeWitness}[4]{% x=#1, n=#2, m=#3, k=#4
subs((y==1)?{0}
{iter(y;(j==#4)?{break(!(@==#2-1))}
{(@==#2-1)?{break(0)}{sqr(@)/:#2}},j=1++)}
,y=powmod(#1,#3,#2))}
% added note (2018/03/07) it is possible in the above that m=#3 is never
% zero, so we should rather call powmod_a for a small gain, but I don't
% have time to re-read the code comments and settle this.
% III ------------------------------------- Strong Pseudo Primes
% cf
% http://oeis.org/A014233
%
%
% check if positive integer <49 si a prime.
% 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47
\def\IsVerySmallPrime #1%
{\ifnum#1=1 \xintdothis0\fi
\ifnum#1=2 \xintdothis1\fi
\ifnum#1=3 \xintdothis1\fi
\ifnum#1=5 \xintdothis1\fi
\ifnum#1=\numexpr (#1/2)*2\relax\xintdothis0\fi
\ifnum#1=\numexpr (#1/3)*3\relax\xintdothis0\fi
\ifnum#1=\numexpr (#1/5)*5\relax\xintdothis0\fi
\xintorthat 1}
\xintNewFunction{isPseudoPrime}[1]{% n = #1
(#1<49)?% use ? syntax to evaluate only what is needed
% prior to 1.4 we had \xintthe#1 here but the actual tokens represented
% by this #1 when isPseudoPrime() function expands have changed and
% the correct way is now \xintiieval{#1} to hand over explicit digits to
% the \IsVerySmallPrime macro.
{\IsVerySmallPrime{\xintiieval{#1}}}
{(even(#1))?
{0}
{subs(%
% L expands to two values m, k hence isCompositeWitness does get
% its four variables x, n, m, k
isCompositeWitness(2, #1, L)?
{0}%
{isCompositeWitness(3, #1, L)?
{0}%
{isCompositeWitness(5, #1, L)?
{0}%
{isCompositeWitness(7, #1, L)?
{0}%
% above enough for N<3215031751 hence all TeX numbers
{isCompositeWitness(11, #1, L)?
{0}%
% above enough for N<2152302898747, hence all 12-digits numbers
{isCompositeWitness(13, #1, L)?
{0}%
% above enough for N<3474749660383
{isCompositeWitness(17, #1, L)?
{0}%
% above enough for N<341550071728321
{1}%
}% not needed to comment-out end of lines spaces inside
}% \xintexpr but this is too much of a habit for me with TeX!
}% I left some after the ? characters.
}%
}%
}% this computes (m, k) such that n = 2^k m + 1, m odd, k>=1
, L=iter(#1//2;(even(@))?{@//2}{break(@,k)},k=1++))%
}%
}%
}
% if needed:
%\def\IsPseudoPrime #1{\xinttheiiexpr isPseudoPrime(#1)\relax}
\noindent The smallest prime number at least equal to 3141592653589 is
\xintiiexpr
seq(isPseudoPrime(3141592653589+n)?
{break(3141592653589+n)}{omit}, n=0++)\relax.
% we could not use 3141592653589++ syntax because it works only with TeX numbers
\par
\end{everbatim*}
\subsection{A table of factorizations}
\label{ssec:factorizationtable}
As one more example with \csbxint{iloop} let us use an alignment to display the
factorization of some numbers. The loop will actually only play a minor r\^ole
here, just handling the row index, the row contents being almost entirely
produced via a macro |\factorize|. The factorizing macro does not use
|\xintiloop| as it didn't appear to be the convenient tool. As |\factorize| will
have to be used on |\xintiloopindex|, it has been defined as a delimited macro.
To spare some fractions of a second in the compilation time of this document
(which has many many other things to do), \number"7FFFFFED{} and
\number"7FFFFFFF, which turn out to be prime numbers, are not given to
|factorize| but just typeset directly; this illustrates use of
\csbxint{iloopskiptonext}.
The code next generates a \hyperref[floatfactorize]{table} which has
been made into a float appearing \vpageref{floatfactorize}. Here is now
the code for factorization; the conditionals use the package provided
|\xint_firstoftwo| and |\xint_secondoftwo|, one could have employed
rather \LaTeX{}'s own |\@firstoftwo| and |\@secondoftwo|, or, simpler
still in \LaTeX{} context, the |\ifnumequal|, |\ifnumless| \dots,
utilities from the package |etoolbox| which do exactly that under the
hood. Only \TeX{} acceptable numbers are treated here, but it would be
easy to make a translation and use the \xintname macros, thus extending
the scope to big numbers; naturally up to a cost in speed.
The reason for some strange looking expressions is to avoid arithmetic overflow.
\begin{everbatim*}
\catcode`_ 11
\def\abortfactorize #1\xint_secondoftwo\fi #2#3{\fi}
\def\factorize #1.{\ifnum#1=1 \abortfactorize\fi
\ifnum\numexpr #1-2=\numexpr ((#1/2)-1)*2\relax
\expandafter\xint_firstoftwo
\else\expandafter\xint_secondoftwo
\fi
{2&\expandafter\factorize\the\numexpr#1/2.}%
{\factorize_b #1.3.}}%
\def\factorize_b #1.#2.{\ifnum#1=1 \abortfactorize\fi
\ifnum\numexpr #1-(#2-1)*#2<#2
#1\abortfactorize
\fi
\ifnum \numexpr #1-#2=\numexpr ((#1/#2)-1)*#2\relax
\expandafter\xint_firstoftwo
\else\expandafter\xint_secondoftwo
\fi
{#2&\expandafter\factorize_b\the\numexpr#1/#2.#2.}%
{\expandafter\factorize_b\the\numexpr #1\expandafter.%
\the\numexpr #2+2.}}%
\catcode`_ 8
\begin{figure*}[ht!]
\centering\phantomsection\label{floatfactorize}\normalcolor
\tabskip1ex
\centeredline{\vbox{\halign {\hfil\strut#\hfil&&\hfil#\hfil\cr\noalign{\hrule}
\xintiloop ["7FFFFFE0+1]
\expandafter\bfseries\xintiloopindex &
\ifnum\xintiloopindex="7FFFFFED
\number"7FFFFFED\cr\noalign{\hrule}
\expandafter\xintiloopskiptonext
\fi
\expandafter\factorize\xintiloopindex.\cr\noalign{\hrule}
\ifnum\xintiloopindex<"7FFFFFFE
\repeat
\bfseries \number"7FFFFFFF&\number "7FFFFFFF\cr\noalign{\hrule}
}}}
\centeredline{A table of factorizations}
\end{figure*}
\end{everbatim*}
\subsection{Another table of primes}
\label{ssec:primesIII}
As a further example, let us dynamically generate a tabular with the first $50$
prime numbers after $12345$. First we need a macro to test if a (short) number
is prime. Such a completely expandable macro was given in \autoref{ssec:primesI},
here we consider a variant which will be slightly more efficient. This new
|\IsPrime| has two parameters. The first one is a macro which it redefines to
expand to the result of the primality test applied to the second argument. For
convenience we use the \href{http://ctan.org/pkg/etoolbox}{etoolbox} wrappers to
various |\ifnum| tests, although here there isn't anymore the constraint of
complete expandability (but using explicit |\if..\fi| in tabulars has its
quirks); equivalent tests are provided by \xintname, but they have some overhead
as they are able to deal with arbitrarily big integers.
\def\IsPrime #1#2%
{\edef\TheNumber {\the\numexpr #2}% positive integer
\ifnumodd {\TheNumber}
{\ifnumgreater {\TheNumber}{1}
{\edef\ItsSquareRoot{\xintiiSqrt \TheNumber}%
\xintFor ##1 in {\xintintegers [3+2]}\do
{\ifnumgreater {##1}{\ItsSquareRoot}
{\def#1{1}\xintBreakFor}
{}%
\ifnumequal {\TheNumber}{(\TheNumber/##1)*##1}
{\def#1{0}\xintBreakFor }
{}%
}}
{\def#1{0}}}% 1 is not prime
{\ifnumequal {\TheNumber}{2}{\def#1{1}}{\def#1{0}}}%
}%
\everb|@
\def\IsPrime #1#2% """color[named]{PineGreen}#1=\Result, #2=tested number (assumed >0).;!
{\edef\TheNumber {\the\numexpr #2}%"""color[named]{PineGreen} hence #2 may be a count or \numexpr.;!
\ifnumodd {\TheNumber}
{\ifnumgreater {\TheNumber}{1}
{\edef\ItsSquareRoot{\xintiiSqrt \TheNumber}%
\xintFor """color{red}##1;! in {"""color{red}\xintintegers;! [3+2]}\do
{\ifnumgreater {"""color{red}##1;!}{\ItsSquareRoot} """color[named]{PineGreen}% "textcolor{red}{##1} is a \numexpr.;!
{\def#1{1}\xintBreakFor}
{}%
\ifnumequal {\TheNumber}{(\TheNumber/##1)*##1}
{\def#1{0}\xintBreakFor }
{}%
}}
{\def#1{0}}}% 1 is not prime
{\ifnumequal {\TheNumber}{2}{\def#1{1}}{\def#1{0}}}%
}
|
As we used \csbxint{For} inside a macro we had to double the |#| in its |#1|
parameter. Here is now the code which creates the prime table (the table has
been put in a \hyperref[primes]{float}, which should be found on page
\pageref{primes}):
\everb?@
\newcounter{primecount}
\newcounter{cellcount}
\begin{figure*}[ht!]
\centering
\begin{tabular}{|*{7}c|}
\hline
\setcounter{primecount}{0}\setcounter{cellcount}{0}%
\xintFor """color{red}#1;! in {"""color{red}\xintintegers;! [12345+2]} \do
"""color[named]{PineGreen}% "textcolor{red}{#1} is a \numexpr.;!
{\IsPrime\Result{#1}%
\ifnumgreater{\Result}{0}
{\stepcounter{primecount}%
\stepcounter{cellcount}%
\ifnumequal {\value{cellcount}}{7}
{"""color{red}\the#1;! \\\setcounter{cellcount}{0}}
{"""color{red}\the#1;! &}}
{}%
\ifnumequal {\value{primecount}}{50}
{\xintBreakForAndDo
{\multicolumn {6}{l|}{These are the first 50 primes after 12345.}\\}}
{}%
}\hline
\end{tabular}
\end{figure*}
?
\begin{figure*}[ht!]
\centering\phantomsection\label{primes}
\begin{tabular}{|*{7}c|}
\hline
\setcounter{primecount}{0}\setcounter{cellcount}{0}%
\xintFor #1 in {\xintintegers [12345+2]} \do
{\IsPrime\Result{#1}%
\ifnumgreater{\Result}{0}
{\stepcounter{primecount}%
\stepcounter{cellcount}%
\ifnumequal {\value{cellcount}}{7}
{\the#1 \\\setcounter{cellcount}{0}}
{\the#1 &}}
{}%
\ifnumequal {\value{primecount}}{50}
{\xintBreakForAndDo
{\multicolumn {6}{l|}{These are the first 50 primes after 12345.}\\}}
{}%
}\hline
\end{tabular}
\end{figure*}
\subsection{Factorizing again}
\label{ssec:factorize}
Here is an \fexpan dable macro which computes the factors of an integer. It
uses the \xintname macros only.
\begin{everbatim*}
\catcode`\@ 11
\let\factorize\relax
\newcommand\Factorize [1]
{\romannumeral0\expandafter\factorize\expandafter{\romannumeral-`0#1}}%
\newcommand\factorize [1]{\xintiiifOne{#1}{ 1}{\factors@a #1.{#1};}}%
\def\factors@a #1.{\xintiiifOdd{#1}
{\factors@c 3.#1.}%
{\expandafter\factors@b \expandafter1\expandafter.\romannumeral0\xinthalf{#1}.}}%
\def\factors@b #1.#2.{\xintiiifOne{#2}
{\factors@end {2, #1}}%
{\xintiiifOdd{#2}{\factors@c 3.#2.{2, #1}}%
{\expandafter\factors@b \the\numexpr #1+\@ne\expandafter.%
\romannumeral0\xinthalf{#2}.}}%
}%
\def\factors@c #1.#2.{%
\expandafter\factors@d\romannumeral0\xintiidivision {#2}{#1}{#1}{#2}%
}%
\def\factors@d #1#2#3#4{\xintiiifNotZero{#2}
{\xintiiifGt{#3}{#1}
{\factors@end {#4, 1}}% ultimate quotient is a prime with power 1
{\expandafter\factors@c\the\numexpr #3+\tw@.#4.}}%
{\factors@e 1.#3.#1.}%
}%
\def\factors@e #1.#2.#3.{\xintiiifOne{#3}
{\factors@end {#2, #1}}%
{\expandafter\factors@f\romannumeral0\xintiidivision {#3}{#2}{#1}{#2}{#3}}%
}%
\def\factors@f #1#2#3#4#5{\xintiiifNotZero{#2}
{\expandafter\factors@c\the\numexpr #4+\tw@.#5.{#4, #3}}%
{\expandafter\factors@e\the\numexpr #3+\@ne.#4.#1.}%
}%
\def\factors@end #1;{\xintlistwithsep{, }{\xintRevWithBraces {#1}}}%
\catcode`@ 12
\end{everbatim*}
The macro will be acceptably efficient only with numbers having somewhat small
prime factors.
\begin{everbatim}
\Factorize{16246355912554185673266068721806243461403654781833}
\end{everbatim}
\begingroup\fdef\Z
{\Factorize{16246355912554185673266068721806243461403654781833}}
\noindent{\small\dtt{\Z}}
It puts a little stress on the input save stack in order
not be bothered with previously gathered things.\footnote{2015/11/18 I have
not revisited this code for a long time, and perhaps I could improve it now
with some new techniques.}
Its output is a comma separated list with the number first, then its prime
factors with multiplicity. Let's produce something prettier:
\begin{everbatim*}
\catcode`_ 11
\def\ShowFactors #1{\expandafter
\ShowFactors_a\romannumeral-`0\Factorize{#1},\relax,\relax,}
\def\ShowFactors_a #1,{#1=\ShowFactors_b}
\def\ShowFactors_b #1,#2,{\if\relax#1\else#1^{#2}\expandafter\ShowFactors_b\fi}
\catcode`_ 8
\end{everbatim*}
\begin{everbatim}
$$\ShowFactors{16246355912554185673266068721806243461403654781833}$$
\end{everbatim}
$$\csname ShowFactors_a\expandafter\endcsname\Z,\relax,\relax,$$
\endgroup
If we only considered small integers, we could write pure |\numexpr| methods
which would be very much faster (especially if we had a table of small primes
prepared first) but still ridiculously slow compared to any non expandable
implementation, not to mention use of programming languages directly accessing
the CPU registers\dots
\subsection{The Quick Sort algorithm illustrated}\label{ssec:quicksort}
First a completely expandable macro which sorts a comma separated list of
numbers.%
%
\footnote{The code in earlier versions of this manual handled inputs composed
of braced items. I have switched to comma separated inputs on the occasion
of (link removed)
The version here is like
|code 3| on
(link removed) (which is about |3x| faster
than the earlier code it replaced in this manual) with a modification to
make it more efficient if the data has many repeated values.
A faster routine (for sorting hundreds of values) is provided as |code 6| at
the link mentioned in the footnote, it is based on Merge Sort, but limited
to inputs which one can handle as \TeX{} dimensions.%
This |code 6| could be extended to handle more general numbers, as
acceptable by \xintfracname. I have also written a non expandable version,
which is even faster, but this matters really only when handling hundreds or
rather thousands of values.}
%
The |\QSx| macro expands its list argument, which may thus be a macro; its
comma separated items must expand to integers or decimal numbers or fractions
or scientific notation as acceptable to \xintfracname, but if an item is
itself some (expandable) macro, this macro will be expanded each time the item
is considered in a comparison test! This is actually good if the macro expands
in one step to the digits, and there are many many digits, but bad if the macro
needs to do many computations. Thus |\QSx| should be used with either explicit
numbers or with items being macros expanding in one step to the numbers
(particularly if these numbers are very big).
If the interest is only in \TeX{} integers, then one should replace the
|\xintifCmp| macro with a suitable conditional, possibly helped by tools such as
|\ifnumgreater|, |\ifnumequal| and |\ifnumless| from
\href{http://ctan.org/pkg/etoolbox}{etoolbox} (\LaTeX{} only; I didn't see a
direct equivalent to |\xintifCmp|.) Or, if we are dealing with decimal numbers
with at most four+four digits, then one should use suitable |\ifdim| tests.
Naturally this will boost consequently the speed, from having skipped all the
overhead in parsing fractions and scientific numbers as are acceptable by
\xintfracname macros, and subsequent treatment.
\begin{everbatim*}
% THE QUICK SORT ALGORITHM EXPANDABLY
% \usepackage{xintfrac} in the preamble (latex)
\makeatletter
% use extra safe delimiters
\catcode`! 3 \catcode`? 3
\def\QSx {\romannumeral0\qsx }%
% first we check if empty list (else \qsx@finish will not find a comma)
\def\qsx #1{\expandafter\qsx@a\romannumeral-`0#1,!,?}%
\def\qsx@a #1{\ifx,#1\expandafter\qsx@abort\else
\expandafter\qsx@start\fi #1}%
\def\qsx@abort #1?{ }%
\def\qsx@start {\expandafter\qsx@finish\romannumeral0\qsx@b,}%
\def\qsx@finish ,#1{ #1}%
%
% we check if empty of single and if not pick up the first as Pivot:
\def\qsx@b ,#1#2,#3{\ifx?#3\xintdothis\qsx@empty\fi
\ifx!#3\xintdothis\qsx@single\fi
\xintorthat\qsx@separate {#1#2}{}{}{#1#2}#3}%
\def\qsx@empty #1#2#3#4#5{ }%
\def\qsx@single #1#2#3#4#5?{, #4}%
\def\qsx@separate #1#2#3#4#5#6,%
{%
\ifx!#5\expandafter\qsx@separate@done\fi
\xintifCmp {#5#6}{#4}%
\qsx@separate@appendtosmaller
\qsx@separate@appendtoequal
\qsx@separate@appendtogreater {#5#6}{#1}{#2}{#3}{#4}%
}%
%
\def\qsx@separate@appendtoequal #1#2{\qsx@separate {#2,#1}}%
\def\qsx@separate@appendtogreater #1#2#3{\qsx@separate {#2}{#3,#1}}%
\def\qsx@separate@appendtosmaller #1#2#3#4{\qsx@separate {#2}{#3}{#4,#1}}%
%
\def\qsx@separate@done\xintifCmp #1%
\qsx@separate@appendtosmaller
\qsx@separate@appendtoequal
\qsx@separate@appendtogreater #2#3#4#5#6#7?%
{%
\expandafter\qsx@f\expandafter {\romannumeral0\qsx@b #4,!,?}{\qsx@b #5,!,?}{#3}%
}%
%
\def\qsx@f #1#2#3{#2, #3#1}%
%
\catcode`! 12 \catcode`? 12
\makeatother
% EXAMPLE
\begingroup
\edef\z {\QSx {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4,
1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9}}
\meaning\z
\def\a {3.123456789123456789}\def\b {3.123456789123456788}
\def\c {3.123456789123456790}\def\d {3.123456789123456787}
\oodef\z {\QSx { \a, \b, \c, \d}}%
% The space before \a to let it not be expanded during the conversion from CSV
% values to List. The \oodef expands exactly twice (via a bunch of \expandafter's)
\meaning\z
\endgroup
\end{everbatim*} (the spaces after \string\d, etc...\@{} come from the use of the
|\meaning| primitive.)
The choice of pivot as first element is bad if the list is already almost
sorted. Let's add a variant which will pick up the pivot index randomly. The
previous routine worked also internally with comma separated lists, but for a
change this one will use internally lists of braced items (the initial
conversion via \csbxint{CSVtoList} handles all potential spurious space
problems).
\begin{everbatim*}
% QuickSort expandably on comma separated values with random choice of pivots
% \usepackage{xintfrac, xinttools} in preamble
\makeatletter
\def\QSx {\romannumeral0\qsx }% This is a f-expandable macro.
% This converts from comma separated values on input and back on output.
% **** NOTE: these steps (and the other ones too, actually) are costly if input
% has thousands of items.
\def\qsx #1{\xintlistwithsep{, }%
{\expandafter\qsx@sort@a\expandafter{\romannumeral0\xintcsvtolist{#1}}}}%
%
% we check if empty or single or double and if not pick up the first as Pivot:
\def\qsx@sort@a #1%
{\expandafter\qsx@sort@b\expandafter{\romannumeral0\xintlength{#1}}{#1}}%
\def\qsx@sort@b #1{\ifcase #1
\expandafter\qsx@sort@empty
\or\expandafter\qsx@sort@single
\or\expandafter\qsx@sort@double
\else\expandafter\qsx@sort@c\fi {#1}}%
\def\qsx@sort@empty #1#2{ }%
\def\qsx@sort@single #1#2{#2}%
\catcode`_ 11
\def\qsx@sort@double #1#2{\xintifGt #2{\xint_exchangetwo_keepbraces}{}#2}%
\catcode`_ 8
\def\qsx@sort@c #1#2{%
\expandafter\qsx@sort@sep@a\expandafter
{\romannumeral0\xintnthelt{\xintUniformDeviate #1+\@ne}{#2}}#2?}%
\def\qsx@sort@sep@a #1{\qsx@sort@sep@loop {}{}{}{#1}}%
\def\qsx@sort@sep@loop #1#2#3#4#5%
{%
\ifx?#5\expandafter\qsx@sort@sep@done\fi
\xintifCmp {#5}{#4}%
\qsx@sort@sep@appendtosmaller
\qsx@sort@sep@appendtoequal
\qsx@sort@sep@appendtogreater {#5}{#1}{#2}{#3}{#4}%
}%
%
\def\qsx@sort@sep@appendtoequal #1#2{\qsx@sort@sep@loop {#2{#1}}}%
\def\qsx@sort@sep@appendtogreater #1#2#3{\qsx@sort@sep@loop {#2}{#3{#1}}}%
\def\qsx@sort@sep@appendtosmaller #1#2#3#4{\qsx@sort@sep@loop {#2}{#3}{#4{#1}}}%
%
\def\qsx@sort@sep@done\xintifCmp #1%
\qsx@sort@sep@appendtosmaller
\qsx@sort@sep@appendtoequal
\qsx@sort@sep@appendtogreater #2#3#4#5#6%
{%
\expandafter\qsx@sort@recurse\expandafter
{\romannumeral0\qsx@sort@a {#4}}{\qsx@sort@a {#5}}{#3}%
}%
%
\def\qsx@sort@recurse #1#2#3{#2#3#1}%
%
\makeatother
% EXAMPLES
\begingroup
\edef\z {\QSx {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4,
1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9}}
\meaning\z
\def\a {3.123456789123456789}\def\b {3.123456789123456788}
\def\c {3.123456789123456790}\def\d {3.123456789123456787}
\oodef\z {\QSx { \a, \b, \c, \d}}%
% The space before \a to let it not be expanded during the conversion from CSV
% values to List. The \oodef expands exactly twice (via a bunch of \expandafter's)
\meaning\z
\def\somenumbers{%
3997.6421, 8809.9358, 1805.4976, 5673.6478, 3179.1328, 1425.4503, 4417.7691,
2166.9040, 9279.7159, 3797.6992, 8057.1926, 2971.9166, 9372.2699, 9128.4052,
1228.0931, 3859.5459, 8561.7670, 2949.6929, 3512.1873, 1698.3952, 5282.9359,
1055.2154, 8760.8428, 7543.6015, 4934.4302, 7526.2729, 6246.0052, 9512.4667,
7423.1124, 5601.8436, 4433.5361, 9970.4849, 1519.3302, 7944.4953, 4910.7662,
3679.1515, 8167.6824, 2644.4325, 8239.4799, 4595.1908, 1560.2458, 6098.9677,
3116.3850, 9130.5298, 3236.2895, 3177.6830, 5373.1193, 5118.4922, 2743.8513,
8008.5975, 4189.2614, 1883.2764, 9090.9641, 2625.5400, 2899.3257, 9157.1094,
8048.4216, 3875.6233, 5684.3375, 8399.4277, 4528.5308, 6926.7729, 6941.6278,
9745.4137, 1875.1205, 2755.0443, 9161.1524, 9491.1593, 8857.3519, 4290.0451,
2382.4218, 3678.2963, 5647.0379, 1528.7301, 2627.8957, 9007.9860, 1988.5417,
2405.1911, 5065.8063, 5856.2141, 8989.8105, 9349.7840, 9970.3013, 8105.4062,
3041.7779, 5058.0480, 8165.0721, 9637.7196, 1795.0894, 7275.3838, 5997.0429,
7562.6481, 8084.0163, 3481.6319, 8078.8512, 2983.7624, 3925.4026, 4931.5812,
1323.1517, 6253.0945}%
\oodef\z {\QSx \somenumbers}% produced as a comma+space separated list
% black magic as workaround to the shrinkability of spaces in last line...
\hsize 87\fontcharwd\font`0
\lccode`~=32
\lowercase{\def~}{\discretionary{}{}{\kern\fontcharwd\font`0}}\catcode32 13
\noindent\phantom{00}\scantokens\expandafter{\meaning\z}\par
\endgroup
\end{everbatim*}
All the previous examples were with numbers which could have been handled via
|\ifdim| tests rather than the \csbxint{ifCmp} macro from \xintfracname; using
|\ifdim| tests would naturally be faster. Even faster routine is |code 6| at
(link removed) which uses |\pdfescapestring| and a
Merge Sort algorithm.
We then turn to a graphical illustration of the algorithm.%
%
\footnote{I have rewritten (2015/11/21) the routine to do only once (and not thrice) the
needed calls to \csa{xintifCmp}, up to the price of one additional |\edef|,
although due to the context execution time on our side is not an issue and
moreover is anyhow overwhelmed by the TikZ's activities. Simultaneously I
have updated the code.
The
variant with the choice of pivot on the right has more overhead: the reason
is simply that we do not convert the data into an array, but maintain a list
of tokens with self-reorganizing delimiters.}
%
For simplicity the pivot is always chosen as the first list item. Then we also
give a variant which picks up the last item as pivot.
\begin{everbatim*}
% in LaTeX preamble:
% \usepackage{xintfrac, xinttools}
% \usepackage{color}
% or, when using Plain TeX:
% \input xintfrac.sty \input xinttools.sty
% \input color.tex
%
% Color definitions
\definecolor{LEFT}{RGB}{216,195,88}
\definecolor{RIGHT}{RGB}{208,231,153}
\definecolor{INERT}{RGB}{199,200,194}
\definecolor{INERTpiv}{RGB}{237,237,237}
\definecolor{PIVOT}{RGB}{109,8,57}
% Start of macro defintions
\makeatletter
% \catcode`? 3 % a bit too paranoid. Normal ? will do.
%
% argument will never be empty
\def\QS@cmp@a #1{\QS@cmp@b #1??}%
\def\QS@cmp@b #1{\noexpand\QS@sep@A\@ne{#1}\QS@cmp@d {#1}}%
\def\QS@cmp@d #1#2{\ifx ?#2\expandafter\QS@cmp@done\fi
\xintifCmp {#1}{#2}\tw@\@ne\z@{#2}\QS@cmp@d {#1}}%
\def\QS@cmp@done #1?{?}%
%
\def\QS@sep@A #1?{\QSLr\QS@sep@L #1\thr@@?#1\thr@@?#1\thr@@?}%
\def\QS@sep@L #1#2{\ifcase #1{#2}\or\or\else
\expandafter\QS@sep@I@start\fi \QS@sep@L}%
\def\QS@sep@I@start\QS@sep@L {\noexpand\empty?\QSIr\QS@sep@I}%
\def\QS@sep@I #1#2{\ifcase#1\or{#2}\or\else\expandafter\QS@sep@R@start\fi\QS@sep@I}%
\def\QS@sep@R@start\QS@sep@I {\noexpand\empty?\QSRr\QS@sep@R}%
\def\QS@sep@R #1#2{\ifcase#1\or\or{#2}\else\expandafter\QS@sep@done\fi\QS@sep@R}%
\def\QS@sep@done\QS@sep@R {\noexpand\empty?}%
%
\def\QS@loop {%
\xintloop
% pivot phase
\def\QS@pivotcount{0}%
\let\QSLr\DecoLEFTwithPivot \let\QSIr \DecoINERT
\let\QSRr\DecoRIGHTwithPivot \let\QSIrr\DecoINERT
\centerline{\QS@list}%
% sorting phase
\ifnum\QS@pivotcount>\z@
\def\QSLr {\QS@cmp@a}\def\QSRr {\QS@cmp@a}%
\def\QSIr {\QSIrr}\let\QSIrr\relax
\edef\QS@list{\QS@list}% compare
\let\QSLr\relax\let\QSRr\relax\let\QSIr\relax
\edef\QS@list{\QS@list}% separate
\def\QSLr ##1##2?{\ifx\empty##1\else\noexpand \QSLr {{##1}##2}\fi}%
\def\QSIr ##1##2?{\ifx\empty##1\else\noexpand \QSIr {{##1}##2}\fi}%
\def\QSRr ##1##2?{\ifx\empty##1\else\noexpand \QSRr {{##1}##2}\fi}%
\edef\QS@list{\QS@list}% gather
\let\QSLr\DecoLEFT \let\QSRr\DecoRIGHT
\let\QSIr\DecoINERTwithPivot \let\QSIrr\DecoINERT
\centerline{\QS@list}%
\repeat }%
%
% \xintFor* loops handle gracefully empty lists.
\def\DecoLEFT #1{\xintFor* ##1 in {#1} \do {\colorbox{LEFT}{##1}}}%
\def\DecoINERT #1{\xintFor* ##1 in {#1} \do {\colorbox{INERT}{##1}}}%
\def\DecoRIGHT #1{\xintFor* ##1 in {#1} \do {\colorbox{RIGHT}{##1}}}%
\def\DecoPivot #1{\begingroup
\color{PIVOT}\advance\fboxsep-\fboxrule\fbox{#1}\endgroup}%
%
\def\DecoLEFTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}%
\xintFor* ##1 in {#1} \do
{\xintifForFirst {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}}%
\def\DecoINERTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}%
\xintFor* ##1 in {#1} \do
{\xintifForFirst {\colorbox{INERTpiv}{##1}}{\colorbox{INERT}{##1}}}}%
\def\DecoRIGHTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}%
\xintFor* ##1 in {#1} \do
{\xintifForFirst {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}}%
%
\def\QuickSort #1{% warning: not compatible with empty #1.
% initialize, doing conversion from comma separated values
% to a list of braced items
\edef\QS@list{\noexpand\QSRr{\xintCSVtoList{#1}}}%
% may \edef's are to follow anyhow
% earlier I did a first drawing of the list, here with the color of RIGHT elements,
% but the color should have been for example white, anyway I drop this first line
%\let\QSRr\DecoRIGHT
%\par\centerline{\QS@list}%
%
% loop as many times as needed
\QS@loop }%
%
% \catcode`? 12 % in case we had used a funny ? as delimiter.
\makeatother
%% End of macro definitions.
%% Start of Example
\begingroup\offinterlineskip
\small
% \QuickSort {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4,
% 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9}
% \medskip
% with repeated values
\QuickSort {1.0, 0.5, 0.3, 0.8, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4,
1.3, 1.1, 0.7, 0.3, 1.6, 0.6, 0.3, 0.8, 0.2, 0.8, 0.7, 1.2}
\endgroup
\end{everbatim*}
Here is the variant which always picks the pivot as the rightmost element.
\begin{everbatim*}
\makeatletter
%
\def\QS@cmp@a #1{\noexpand\QS@sep@A\expandafter\QS@cmp@d\expandafter
{\romannumeral0\xintnthelt{-1}{#1}}#1??}%
%
\def\DecoLEFTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}%
\xintFor* ##1 in {#1} \do
{\xintifForLast {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}}
\def\DecoINERTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}%
\xintFor* ##1 in {#1} \do
{\xintifForLast {\colorbox{INERTpiv}{##1}}{\colorbox{INERT}{##1}}}}
\def\DecoRIGHTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}%
\xintFor* ##1 in {#1} \do
{\xintifForLast {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}}
\def\QuickSort #1{%
% initialize, doing conversion from comma separated values
% to a list of braced items
\edef\QS@list{\noexpand\QSLr {\xintCSVtoList{#1}}}%
% many \edef's are to follow anyhow
%
% loop as many times as needed
\QS@loop }%
\makeatother
\begingroup\offinterlineskip
\small
% \QuickSort {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4,
% 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9}
% \medskip
% with repeated values
\QuickSort {1.0, 0.5, 0.3, 0.8, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4,
1.3, 1.1, 0.7, 0.3, 1.6, 0.6, 0.3, 0.8, 0.2, 0.8, 0.7, 1.2}
\endgroup
\end{everbatim*}
The choice of the first or last item as pivot is not a good one as nearly
ordered lists will take quadratic time. But for explaining the algorithm via a
graphical interpretation, it is not that bad. If one wanted to pick up the
pivot randomly, the routine would have to be substantially rewritten: in
particular the |\Deco..withPivot| macros need to know where the pivot is, and
currently this is implemented by using either |\xintifForFirst| or
|\xintifForLast|.
\clearpage
\expandafter\let\csname ExamplesnameUp\endcsname\undefined
\csname xintbundlenameUp\endcsname
\def\xintRunningHeader{{\inheadertrue\catcode`,12\relax
\DOCxintfrontpage,
\xintbundlename,
\xintkernelname,
\xintcorename,
\xintname,
\xintfracname,
\xintbinhexname,
\xintgcdname,
\xintseriesname,
\xintcfracname}}
\markboth{\makebox[0pt]{\xintRunningHeader}}{\makebox[0pt]{\xintRunningHeader}}
\etocdepthtag.toc {macros}
\addtocontents{toc}{\gdef\string\tocstylesectionbracedcolor{{tocstylebundlesectioncolor}}}
\part{The macro layer for expandable computations: \xintcorename, \xintname,
\xintfracname, and some extras}
\RaisedLabel[15]{sec:bundle}
\begin{framed}
WARNING !
The documentation is getting old, and is in need of rewrites for many
sections, particularly for examples.
We do try to keep updated the description of macros
provided by the packages.
\end{framed}
\etocsetnexttocdepth{section}
\localtableofcontents
\section{Introduction: the \xintbundlename}
\localtableofcontents
\subsection{Characteristics}
\begin{framed}
The main characteristics are:
\begin{enumerate}
\item exact algebra on ``big numbers'', integers as well as
fractions,
\item floating point variants with user-chosen precision,
\item the computational macros are compatible with expansion-only context,
\item the bundle comes with parsers (integer-only, or handling fractions, or
doing floating point computations) of infix operations implementing
beyond infix operations extra features such as dummy variables.
\end{enumerate}
Since |1.2| ``big numbers'' must have less than about \dtt{19950} digits:
the maximal number of digits for addition is at \dtt{19968} digits, and it
is \dtt{19959} for multiplication. The reasonable range of use of the
package is with numbers of up to a few hundred digits.\footnotemark
\TeX\ does not know off-hand how to print on the page such very long
numbers, see \autoref{ssec:printnumber}.
\end{framed}
\footnotetext{For example multiplication of integers having from \dtt{50} to
\dtt{100} digits takes roughly of the order of the millisecond on a 2012
desktop computer. I compared this to using Python3: using timeit module on a
wrapper defined as |return w*z| with random integers of \dtt{100} digits, I
observe on the same computer a computation time of roughly $4.10^{-7}$s per
call. And with |return str(w*z)| then this becomes more like $16.10^{-7}$s
per call. And with |return str(int(W)*int(Z))| where |W| and |Z| are
strings, this becomes about $26.10^{-7}$s (I am deliberately ignoring
Python's Decimal module here...) Anyway, my sentence from earlier version of
this documentation: \emph{this is, I guess, at least about 1000 times slower
than what can be expected with any reasonable programming language,} is
about right. I then added: \emph{nevertheless as compilation of a typical
\LaTeX\ document already takes of the order of seconds and even dozens of
seconds for long ones, this leaves room for reasonably many computations
via \xintexprname or via direct use of the macros of
\xintname/\xintfracname.}}
Integers with only $10$ digits and starting with a $3$ already exceed the
\TeX{} bound; and \TeX{} does not have a native processing of floating point
numbers (multiplication by a decimal number of a dimension register is allowed
--- this is used for example by the
\href{http://mirrors.ctan.org/graphics/pgf/base}{pgf} basic math engine.)
\TeX{} elementary operations on numbers are done via the non-expandable
\emph{\char92advance, \char92multiply, \emph{and} \char92divide} assignments.
This was changed with \eTeX{}'s |\numexpr| which does expandable computations
using standard infix notations with \TeX{} integers. But \eTeX{} did not
modify the \TeX{} bound on acceptable integers, and did not add floating point
support.
The \ctanpackage{bigintcalc} package by
\textsc{Heiko Oberdiek} provided expandable macros (using some of |\numexpr|
possibilities, when available) on arbitrarily big integers, beyond the \TeX{}
bound. It does not provide an expression parser.%
%
\footnote{One can currently use package
\ctanpackage{bnumexpr} to associate the |bigintcalc|
macros with an expression parser. This may be unavailable in future if
|bnumexpr| becomes more tightly associated with future evolutions or
variants of \xintcorename. EDIT: still possible as of \ctanpackage{bnumexpr}
|1.6| |2025/09/01|.}
%
\xintname did it again using more of |\numexpr| for higher speed, and in a
later evolution added handling of exact fractions, of scientific numbers, and
an expression parser. Arbitrary precision floating points operations were
added as a derivative, and not part of the initial design goal.
The concept of signed infinities, signed zeroes, |NaN|'s, error
traps\dots,\footnote{The latter exist as work-in-progress for some time in the
source code.} have not been implemented, only the notion of `scientific
notation with a given number of significant figures'.%
%
\footnote{Multiplication of two floats with |P=\xinttheDigits| digits is
first done exactly then rounded to |P| digits, rather than using a
specially tailored multiplication for floating point numbers which
would be more efficient (it is a waste to evaluate fully the
multiplication result with |2P| or |2P-1| digits.)}
The \LaTeX3 project has implemented expandably floating-point computations with
\dtt{16} significant figures
(\href{https://ctan.org/pkg/l3kernel}{l3fp}), including
functions such as exp, log, sine and cosine.\footnote{at the time of writing (2014/10/28) the
\href{https://ctan.org/pkg/l3kernel}{l3fp} (exactly represented) floating
point numbers have their exponents limited to $\pm$\dtt{9999}.}
%
More directly related to the \xintbundlename there is the \liiibigint{}
package, also devoted to big integers and in development a.t.t.o.w (2015/10/09,
no division yet). It is part of the experimental trunk of the
\href{http://latex-project.org}{\LaTeX3 Project} and provides an expression
parser for expandable arithmetic with big integers. Its author Bruno
\textsc{Le Floch} succeeded brilliantly into implementing expandably the
Karatsuba multiplication algorithm and he achieves \emph{sub-quadratic growth
for the computation time}. This shows up very clearly with numbers having
thousands of digits, up to the maximum which a.t.t.o.w is at $8192$ digits.
The \liiibigint{} multiplication from late |2015| is observed to be roughly
|3x--4x| faster than the one from \csbxint{iiexpr} in the range of \dtt{4000}
to \dtt{5000} digits integers, and isn't far from being |9x| faster at
\dtt{8000} digits. On the other hand \csbxint{iiexpr}'s multiplication is
found to be on average roughly |2.5x| faster than \liiibigint's for numbers up
to \dtt{100} digits and the two packages achieve about the same speed at
\dtt{900} digits: but each such multiplication of numbers of \dtt{900} digits
costs about one or two tenths of a second on a 2012 desktop computer, whereas
the order of magnitude is rather the |ms| for numbers with \dtt{50--100}
digits.\footnote{I have tested this again on |2016/12/19|, but the macros have
not changed on the \liiibigint{} side and barely on the \xintcorename side,
hence I got again the same results\dots}
Even with the superior \liiibigint{} Karatsuba multiplication it takes about
|3.5s| on this 2012 desktop computer for a single multiplication of two
\dtt{5000}-digits numbers. Hence it is not possible to do routinely such
computations in a document. I have long been thinking that without the
expandability constraint much higher speeds could be achieved, but perhaps I
have not given enough thought to sustain that optimistic stance.\footnote{The
\ctanpackage{apnum} package implements
(non-expandably) arbitrary precision fixed point algebra and (v1.6)
functions exp, log, sqrt, the trigonometrical direct and inverse functions.}
I remain of the opinion that if one really wants to do computations with
\emph{thousands} of digits, one should drop the expandability requirement.
Indeed, as clearly demonstrated long ago by the
\href{https://ctan.org/pkg/pi}{pi computing file} by \textsc{D. Roegel} one
can program \TeX{} to compute with many digits at a much higher speed than
what \xintname achieves: but, direct access to memory storage in one form or
another seems a necessity for this kind of speed and one has to renounce at
the complete expandability.%
%
\footnote{The Lua\TeX{} project possibly makes endeavours such as \xintname
appear even more insane that they are, in truth: \xintname is able to handle
fast enough computations involving numbers with less than one hundred digits
and brings this to all engines.}
\subsection{Floating point evaluations}
\label{ssec:floatingpoint}
\begin{framed}
WARNING: THIS PART OF THE DOCUMENTATION IS IN DIRE NEED OF BEING
REVISED AND MAY BE EVEN MORE BADLY OBSOLETE THAN THE REST OF THIS DOCUMENTATION.
\end{framed}
Floating point macros are provided by package \xintfracname to work with a
given arbitrary precision |P|. The default value is $P=16$ meaning that the
significands of the produced (non-zero) numbers have \dtt{16} decimal digits.
The syntax to set the precision to |P| is
%
\centeredline{|\xintDigits:=P\relax|}
%
The value is local to the group or environment (if using \LaTeX). To query the
current value use \csbxint{theDigits}.
Most floating point macros accept an optional first argument |[P]| which then
sets the target precision and replaces the |\xintDigits| assigned value (the
|[P]| must be repeated if the arguments are themselves \xintfracname macros
with arguments of their own.) In this section |P| refers to the prevailing
|\xinttheDigits| float precision or to the target precision set in this way as
an optional argument.
\csbxint{floatexpr}|[Q]...\relax| also admits an optional argument |[Q]| but
it has an altogether different meaning: the computations are always done with
the prevailing |\xinttheDigits| precision and the optional argument |Q| is
used for the final rounding. This makes sense only if |Q<\xinttheDigits| and
is intended to clean up the result from dubious last digits (when |Q<0| it
indicates rather by how many digits one should reduce the mantissa lengths via a
final rounding).
\begin{framed}
The |IEEE 754|\footnotemark\ requirement of \emph{correct rounding} for
addition, subtraction, multiplication, division and square root is achieved
(in arbitrary precision) by the macros of \xintfracname hence also by the
infix operators |+|, |-|, |*|, |/|.
This means that for operands given with at most |P| significant digits
(and arbitrary exponents) the output coincides exactly with the rounding
of the exact theoretical result (barring overflow or underflow).
{\footnotesize Due to a typographical oversight, this documentation
(up to |1.2j|) adjoined |^| and |**| to the above list of
infix operators. But as
is explained in \autoref{xintFloatPower}, what is guaranteed regarding
integer powers is an error of at most |0.52ulp|, not the correct rounding.
Half-integer powers are computed as square roots of integer powers.\par }%
The rounding mode is ``round to nearest, ties away from zero''.
It is not customizable.
Currently \xintfracname has no notion of |NaN|s or signed infinities or signed
zeroes, but this is intended for the future.
\end{framed}
%
\footnotetext{The |IEEE 754-1985| standard was for hardware implementations of
binary floating-point arithmetic with a specific value for the precision
($24$ bits for single precision, $53$ bits for double precision). The newer
{\texttt{IEEE 754-2008}}
(\url{https://en.wikipedia.org/wiki/IEEE_floating_point}) normalizes five
basic formats, three binaries and two decimals ($16$ and $34$ decimal
digits) and discusses extended formats with higher precision. These
standards are only indirectly relevant to libraries like \xintname dealing
with arbitrary precision.%
}
Since release
|1.2f|, square root extraction achieves correct rounding in arbitrary
precision.
The maximal floating point decimal exponent is currently
\dtt{\number"7FFFFFFF} which is the maximal number handled by \TeX. The
minimal exponent is its opposite. But this means that overflow or underflow
are detected only via low-level |\numexpr| arithmetic overflows which are
basically un-recoverable. Besides there are some border effects as the
routines need to add or subtract lengths of numbers from exponents, possibly
triggering the low-level overflows. In the future not only the Precision but
also the maximal and minimal exponents |Emin| and |Emax| will be specifiable
by the user.
Since |1.2f|, the float macros round their inputs to the target precision |P|
before further processing. Formerly, the initial rounding was done to |P+2|
digits (and at least |P+3| for the power operation.)
The more ambitious model would be for the computing macros to obey the
intrinsic precision of their inputs, i.e.\@{} to compute the correct rounding to
|P| digits of the exact mathematical result corresponding to inputs allowed to
have their own higher precision.%
%
\footnote{The |MPFR| library
\url{http://www.mpfr.org/} implements this but it does not know fractions!}
%
This would be feasible by \xintfracname which after all knows how to compute
exactly, but I have for the time being decided that for reasons of efficiency,
the chosen model is the one of rounding inputs to the target precision first.
The float macros of \xintfracname have to handle inputs which
not only may have much more digits than the target float precision, but may
even be fractions: in a way this means infinite precision.
From releases |1.08a| to |1.2j| a fraction input $AeM/BeN$ had its numerator
and denominator $A$ and $B$ truncated to |Q+2| digits of precision, then the
substituted fraction was correctly rounded to |Q| digits of precision (usually
with |Q| set to |P+2|) and then the operation was implemented on such rounded
inputs. But this meant that two fractions representing the same rational
number could end up being rounded differently (with a difference of one unit
in the last place), if it had numerators and denominators with at least |Q+3|
digits.
Starting with release |1.2k| a fractional input $AeM/BeN$ is handled
intrinsically: the fraction, independently of its representation $AeM/BeN$, is
\emph{correctly rounded} to |P| digits during the input parsing. Hence the
output depends only on its arguments as mathematical fractions and not on
their representatives as quotients.
Notice that in float expressions, the |/| is treated as operator, and is
applied to arguments which are generally already |P|-floats, hence the above
discussion becomes relevant in this context only for the special input form
|qfloat(A/B)| or when using a sub-expression |\xintexpr A/B\relax| embedded in
the float expression with |A| or |B| having more digits than the prevailing
float precision |P|.
\subsection{Expansion matters}
\subsubsection{Full expansion of the first token}
\label{ssec:expansions}
The whole business of \xintname is to build upon |\numexpr| and handle
arbitrarily large numbers. Each basic operation is thus done via a macro:
\csbxint{iiAdd}, \csbxint{iiSub}, \csbxint{iiMul}, \csbxint{iiDivision}. In
order to handle more complex operations, it must be possible to nest these
macros.
%
An expandable macro can not execute a |\def| or an |\edef|. But the macro must
expand its arguments to find the digits it is supposed to manipulate. \TeX{}
provides a tool to do the job of (expandable !) repeated expansion of the
first token found until hitting something non expandable, such as a digit, a
|\def| token, a brace, a |\count| token, etc...\@{} is found. A space token also
will stop the expansion (and be swallowed, contrarily to the non-expandable
tokens).
By convention in this manual \fexpan sion (``full expansion'' or ``full first
expansion'') will be this \TeX{} process of expanding repeatedly the first
token seen. For those familiar with \LaTeX3 (which is not used by \xintname)
this is what is called in its documentation full expansion, whereas expansion
inside |\edef| would be described I think as ``exhaustive'' expansion
and will be referred too in this manual as \xexpan sion.
Most of the package macros, and all those dealing with computations%
%
\footnote{except \csbxint{XTrunc}.},
%
are expandable in the strong sense that they expand to their final result via
this \fexpan sion. This will be signaled in their descriptions via a
\etype{}star in the margin.
These macros not only have this property of \fexpan dability, they all begin
by first applying \fexpan sion to their arguments. Again from \LaTeX3's
conventions this will be signaled by a%
%
\ntype{{\setbox0 \hbox{\Ff}\hbox to \wd0 {\hss f\hss}}}
%
margin annotation next to the description of the arguments.
\subsubsection{Summary of important expandability aspects}
\begin{enumerate}
\item the macros \fexpan d their arguments, this means that they expand the
first token seen (for each argument), then expand, etc..., until something
un-expandable such as a\strut{} digit or a brace is hit against. This
example
%
\leftedline{|\def\x{98765}\def\y{43210}| |\xintiiAdd {\x}{\x\y}|}
%
is \emph{not} a legal construct, as the |\y| will remain untouched by
expansion and not get converted into the digits which are expected by the
sub-routines of |\xintiiAdd|. It is a |\numexpr| which will expand it and an
arithmetic overflow will arise as |9876543210| exceeds the \TeX{} bounds.
The same would hold for |\xintAdd|.
\begingroup\slshape
To the contrary \csbxint{theiiexpr} and others have no issues with
things such as |\xinttheiiexpr \x+\x\y\relax|.\hfill
\endgroup
\item\label{fn:expansions} using |\if...\fi| constructs \emph{inside} the
package macro arguments requires suitably mastering \TeX niques
(|\expandafter|'s and/or swapping techniques) to ensure that the \fexpan sion
will indeed absorb the \csa{else} or closing \csa{fi}, else some error will
arise in further processing. Therefore it is highly recommended to use the
package provided conditionals such as \csbxint{ifEq}, \csbxint{ifGt},
\csbxint{ifSgn},\dots\ or, for \LaTeX{} users and when dealing
with short integers the
\ctanpackage{etoolbox}%
%
\footnote{\url{https://ctan.org/pkg/etoolbox}}
expandable conditionals (for small integers only) such as \texttt{\char92
ifnumequal}, \texttt{\char92 ifnumgreater}, \dots . Use of
\emph{non-expandable} things such as \csa{ifthenelse} is impossible inside the
arguments of \xintname macros.
\begingroup\slshape
One can use naive |\if..\fi| things inside an \csbxint{theexpr}-ession
and cousins, as long as the test is
expandable, for example\upshape
%
\leftedline{|\xinttheiexpr\ifnum3>2 143\else 33\fi
0^2\relax|$\to$\dtt{\xinttheiexpr \ifnum3>2 143\else 33\fi 0^2\relax
=1430\char`\^2}}
%
\endgroup
\item after the definition |\def\x {12}|, one can not use
{\color{blue}|-\x|} as input to one of the package macros: the \fexpan sion
will act only on the minus sign, hence do nothing. The only way is to use the
\csbxint{Opp} macro (or \csbxint{iiOpp} which is integer only)
which obtains the opposite of a given number.
\begingroup\slshape
Again, this is otherwise inside an \csbxint{theexpr}-ession or
\csbxint{thefloatexpr}-ession. There, the
minus sign may prefix macros which will expand to numbers (or parentheses
etc...)
\endgroup
\def\x {12}%
\def\AplusBC #1#2#3{\xintAdd {#1}{\xintMul {#2}{#3}}}%
\item \label{item:xpxp} With the definition
%
\leftedline{|\def\AplusBC #1#2#3{\xintAdd {#1}{\xintMul {#2}{#3}}}|}
%
one obtains an
expandable macro producing the expected result, not in two, but rather in
three steps: a first expansion is consumed by the macro expanding to its
definition. As the package macros expand their arguments until no more is
possible (regarding what comes first), this |\AplusBC| may be used inside
them: {|\xintAdd {\AplusBC {1}{2}{3}}{4}|} does work and returns
\dtt{\xintAdd {\AplusBC {1}{2}{3}}{4}}.
If, for some reason, it is important to create a macro expanding in two steps
to its final value, one may either do:
%
\smallskip
%
\leftedline {|\def\AplusBC #1#2#3{\romannumeral-`0\xintAdd {#1}{\xintMul
{#2}{#3}}}|}
%
or use the \emph{lowercase} form of \csa{xintAdd}:
%
\smallskip
%
\leftedline {|\def\AplusBC #1#2#3{\romannumeral0\xintadd {#1}{\xintMul
{#2}{#3}}}|}
and then \csa{AplusBC} will share the same properties as do the
other \xintname `primitive' macros.
\item
The |\romannumeral0| and |\romannumeral-`0| things above look like an invitation
to hacker's territory; if it is not important that the macro expands in two
steps only, there is no reason to follow these guidelines. Just chain
arbitrarily the package macros, and the new ones will be completely expandable
and usable one within the other.
Since release |1.07| the \csbxint{NewExpr} macro automatizes the creation of
such expandable macros:
%
\leftedline{|\xintNewExpr\AplusBC[3]{#1+#2*#3}|}
%
creates the |\AplusBC| macro doing the above and expanding in two expansion
steps.
\item In the expression parsers of \xintexprname such as
\csbxint{expr}|..\relax|, \csbxint{floatexpr}|..\relax| the contents are
expanded completely from left to right until the ending |\relax| is found
and swallowed, and spaces and even (to some extent) catcodes do not matter.
\item For all variants, prefixing with \csbxint{the} allows to print the
result or use it in other contexts. Shortcuts \csbxint{theexpr},
\csbxint{thefloatexpr}, \csbxint{theiiexpr}, \dots\ are available.
\end{enumerate}
\subsection {Input formats for macros}\label{ssec:inputs}
Macros can have different types of arguments (we do not consider here the
\csbxint{expr}-parsers but only the macros of
\xintcorename/\xintname/\xintfracname). In a macro description, a
margin annotation signals what is the argument type.
\begin{enumerate}
\item \TeX\ integers\ntype{\numx} are handled inside a |\numexpr..\relax|
hence may be count registers or variables. Beware that |-(1+1)| is not legal
and raises an error, but |0-(1+1)| is. Also |2\cnta| with |\cnta| a |\count|
isn't legal. Integers must be kept less than \dtt{\number "7FFFFFFF} in
absolute value, although the \emph{scaling} operation |(a*b)/c| computes the
intermediate product with twice as many bits.
The slash |/| does a \fbox{rounded} division which is a fact of life of
|\numexpr| which I have found very annoying in at least nine cases out of
ten, not to say ninety-nine cases out of one hundred. Besides, it is at odds
with \TeX's |\divide| which does a truncated division (non-expandably).
But to follow-suit |/| also does rounded integer division in
\csbxint{iiexpr}|..\relax|, and the operator |//| does there the truncated
division.
\item the strict format\ntype{f} applies to macros handling big integers but
only \fexpan ding their arguments. After this \fexpan sion the input should
be a string of digits, optionally preceded by a unique minus sign. The first
digit can be zero only if it is the only digit. A plus sign is not accepted.
|-0| is not legal in the strict format. Macros of \xintname with a double
|ii| require this `strict' format for the inputs.
\item the extended integer format\ntype{\Numf} applies when the macro parses
its arguments via \csbxint{Num}. The input may then have arbitrarily many
leading minus and plus signs, followed by leading zeroes, and further
digits. With \xintfracname loaded, \csbxint{Num} is extended to
accept fractions and its action is to truncate them to integers.
\item the fraction input format\ntype{\Ff} applies to the arguments of
\xintfracname macros handling genuine fractions. It allows two types
of inputs: general and restricted. The restricted type is parsed faster,
but...\@{} is restricted.
\begin{description}
\item[general:] inputs of the shape |A.BeC/D.EeF|. Example:
\begin{everbatim*}
\noindent\xintRaw{+--0367.8920280e17/-++278.289287e-15}\newline
\xintRaw{+--+1253.2782e++--3/---0087.123e---5}\par
\end{everbatim*}
The input parser does not reduce fractions to smallest terms.
Here are the rules of this general fraction format:
\begin{itemize}
\item everything is optional, absent numbers are treated as zero, here are
some extreme cases:
\begin{everbatim*}
\xintRaw{}, \xintRaw{.}, \xintRaw{./1.e}, \xintRaw{-.e}, \xintRaw{e/-1}
\end{everbatim*}
\item |AB| and |DE| may start with pluses and minuses, then leading
zeroes, then digits.
\item |C| and |F| will be given to |\numexpr| and can be anything
recognized as such and not provoking arithmetic overflow (the lengths of
|B| and |E| will also intervene to build the final exponent naturally
which must obey the \TeX{} bound).
\item the |/|, |.| (numerator and/or denominator) and |e|
(numerator and/or denominator) are all optional components.
\item each of |A|, |B|, |C|, |D|, |E| and |F| may arise from \fexpan sion
of a macro.
\item the whole thing may arise from \fexpan sion, however the |/|, |.|,
and |e| should all come from this initial expansion. The |e| of
scientific notation is mandatorily lowercased.
\end{itemize}
\item[restricted:] inputs either of the shape |A[N]| or |A/B[N]|, which
represents the fraction |A/B| times |10^N|. The whole thing or
each of |A|, |B|, |N| (but then not |/| or |[|) may arise from \fexpan
sion, |A| (after expansion) \emph{must} have a unique optional minus sign
and no leading zeroes, |B| (after expansion) if present \emph{must} be a
positive integer with no signs and no leading zeroes, |[N]| if present
will be given to |\numexpr|. Any deviation from the rules above will
result in errors.
\end{description}
Notice that |*|, |+| and |-| contrarily to the |/| (which is treated simply
as a kind of delimiter) are not acceptable within arguments of this
type\ntype{\Ff} (see \autoref{sec:useofcount}
for some exceptions to this.)
\end{enumerate}
Generally speaking, there should be no spaces among the digits in the inputs
(in arguments to the package macros). Although most would be harmless in most
macros, there are some cases where spaces could break havoc.%
\footnote{The \csbxint{Num} macro does not remove spaces between digits beyond
the first non zero ones; however this should not really alter the subsequent
functioning of the arithmetic macros, and besides, since \xintcorename 1.2
there is an initial parsing of the entire number, during which spaces will
be gobbled. However I have not done a complete review of the legacy code to
be certain of all possibilities after |1.2| release. One thing to be aware
of is that \csa{numexpr} stops on spaces between digits (although it
provokes an expansion to see if an infix operator follows); the exponent for
\csbxint{iiPow} or the argument of the factorial \csbxint{iiFac} are only
subjected to such a \csa{numexpr} (there are a few other macros with such
input types in \xintname). If the input is given as, say |1 2\x| where
\csa{x} is a macro, the macro \csa{x} will not be expanded by the
\csa{numexpr}, and this will surely cause problems afterwards. Perhaps a
later \xintname will force \csa{numexpr} to expand beyond spaces, but I
decided that was not really worth the effort. Another immediate cause of
problems is an input of the type |\xintiiAdd{\x}{\y}|, because the
space will stop the initial expansion; this will most certainly cause an
arithmetic overflow later when the \csa{x} will be expanded in a
\csa{numexpr}. Thus in conclusion, damages due to spaces are unlikely if
only explicit digits are involved in the inputs, or arguments are single
macros with no preceding space.}
So the best is to avoid them entirely.
This is entirely otherwise inside an |\xintexpr|-ession, where spaces are
ignored (except when they occur inside arguments to some macros, thus
escaping the |\xintexpr| parser). See the \autoref{sec:expr}.
There are also some slighly more obscure expansion types: in particular, the
\csbxint{ApplyInline} and \csbxint{For*} macros from \xinttoolsname apply a
special iterated \fexpan sion, which gobbles spaces, to the non-braced items
(braced items are submitted to no expansion because the opening brace stops
it) coming from their list argument; this is denoted by a special
symbol\ntype{{\lowast f}} in the margin. Some other macros such as
\csbxint{Sum} from \xintfracname first do an \fexpan sion, then treat each
found (braced or not) item (skipping spaces between such items) via the
general fraction input parsing, this is signaled as
here\ntype{f{$\to$}{\lowast\Ff}} in the margin where the signification of the
\lowast{} is thus a bit different from the previous case.
A few macros from \xinttoolsname do not expand, or expand only once their
argument\ntype{n{{\color{black}\upshape, resp.}} o}. This is also
signaled in the margin with notations \`a la \LaTeX3.
\subsection{Output formats of macros}
\label{ssec:outputs}
We do not consider here the \csbxint{expr}-parsers but only the macros from \xintcorename, \xintname and \xintfracname. Macros of other
components of the bundle may have their own output formats, for example for
continuous fractions with \xintcfracname.
There are mainly three types of outputs:%
\begin{itemize}[nosep,listparindent=\leftmarginiii]
\item arithmetic macros from \xintcorename/\xintname deliver integers
in the strict format as described in the previous section.
\item arithmetic macros from \xintfracname produce on output the strict
fraction format |A/B[N]|, which stands for |(A/B)|$\times$|10^N|, where |A|
and |B| are integers, |B| is positive, and |N| is a ``short'' integer. The
output is not reduced to smallest terms. The |A| and |B| may end with zeroes
(\emph{i.e}, |N| does not represent all powers of ten). The denominator |B| is
always strictly positive. There is no |+| sign. The |-| is always first if
present (i.e.\@{} the denominator on output is always positive.) The output will
be expressed as such a fraction even if the inputs are both integers and the
mathematical result is an integer. The |B=1| is not removed.%
%
\footnote{refer to the documentation of \csbxint{PRaw} for an alternative.}
\item macros from \xintfracname having |Float| in their names deliver a number
in the scientific notation as described in the documentation of
\csbxint{Float}.
The exception is \csbxint{PFloat} which does some customizable pretty
printing of the result.
\end{itemize}
\subsection{Count registers and variables}\label{sec:useofcount}
Inside |\xintexpr..\relax| and its variants, a count register or count control
sequence is automatically unpacked using |\number|, with tacit multiplication:
|1.23\counta| is like |1.23*\number\counta|. There
is a subtle difference between count \emph{registers} and count
\emph{variables}. In |1.23*\counta| the unpacked |\counta| variable defines a
complete operand thus |1.23*\counta 7| is a syntax error. But |1.23*\count0|
just replaces |\count0| by |\number\count0| hence |1.23*\count0 7| is like
|1.23*57| if |\count0| contains the integer value |5|.
Regarding now the package macros, there is first the case of arguments having to
be short integers: this means that they are fed to a |\numexpr...\relax|, hence
submitted to a \emph{complete expansion} which must deliver an integer, and
count registers and even algebraic expressions with them like
|\mycountA+\mycountB*17-\mycountC/12+\mycountD| are admissible arguments (the
slash stands here for the rounded integer division done by |\numexpr|). This
applies in particular to the number of digits to truncate or round with, to the
indices of a series partial sum, \dots
The macros allowing the extended format for long numbers or dealing with
fractions will \emph{to some extent} allow the direct use of count
registers and even infix algebra inside their arguments: a count
register |\mycountA| or |\count 255| is admissible as numerator or also as
denominator, with no need to be prefixed by |\the| or |\number|. It is possible
to have as argument an algebraic expression as would be acceptable by a
|\numexpr...\relax|, under this condition: \emph{each of the numerator and
denominator is expressed with at most \emph{nine}
tokens}.%
%
\footnote{The |1.2k| and earlier versions manual claimed up to 8
tokens, but low-level TeX error arose if the |\numexpr...\relax| occupied
exactly 8 tokens \emph{and} evaluated to zero. With |1.2l| and later, up to
9 tokens are always safe and one may even drop the ending |\relax|. But
well, all these explanations are somewhat silly because prefixing by |\the|
or |\number| is always working with arbitrarily many tokens.}
%
%
\footnote{Attention! in the \LaTeX{} context a
\csa{value}\texttt{\{countername\}} will behave ok only if it is first in
the input, if not it will not get expanded, and braces around the name will
be removed and chaos\IMPORTANT{} will ensue inside a \csa{numexpr}. One
should enclose the whole input in \csa{the}\csa{numexpr}|...|\csa{relax} in
such cases.}
%
Important: a slash for rounded division in a |\numexpr| should be written with
braces |{/}| to not be confused with the \xintfracname delimiter between
numerator and denominator (braces will be removed internally and the slash
will count for one token). Example:
|\mycountA+\mycountB{/}17/1+\mycountA*\mycountB|, or |\count 0+\count
2{/}17/1+\count 0*\count 2|.
%
\leftedline{|\cnta 10 \cntb 35 \xintRaw
{\cnta+\cntb{/}17/1+\cnta*\cntb}|\dtt{->\cnta 10 \cntb 35 \xintRaw
{\cnta+\cntb{/}17/1+\cnta*\cntb}}}
%
For longer algebraic expressions using
count registers, there are two possibilities:
\begin{enumerate}[nosep]
\item let the numerator and the denominator be presented as |\the\numexpr...\relax|,
\item or as |\numexpr {...}\relax| (the braces are removed during processing;
they are not legal for |\numexpr...\relax| syntax.)
\end{enumerate}
\everb|@
\cnta 100 \cntb 10 \cntc 1
\xintPRaw {\numexpr {\cnta*\cnta+\cntb*\cntb+\cntc*\cntc+
2*\cnta*\cntb+2*\cnta*\cntc+2*\cntb*\cntc}\relax/%
\numexpr {\cnta*\cnta+\cntb*\cntb+\cntc*\cntc}\relax }
|
\cnta 100 \cntb 10 \cntc 1
%
\leftedline{\dtt{\xintPRaw {\numexpr
{\cnta*\cnta+\cntb*\cntb+\cntc*\cntc+
2*\cnta*\cntb+2*\cnta*\cntc+2*\cntb*\cntc}\relax/%
\numexpr {\cnta*\cnta+\cntb*\cntb+\cntc*\cntc}\relax }}}
\subsection{Dimension registers and variables}
\label{sec:Dimensions}
\meta{dimen} variables can be converted into (short) integers suitable for the
\xintname macros by prefixing them with |\number|. This transforms a dimension
into an explicit short integer which is its value in terms of the |sp| unit
($1/65536$\,|pt|).
When |\number| is applied to a \meta{glue} variable, the stretch and shrink
components are lost.
For \LaTeX{} users: a length is a \meta{glue} variable, prefixing a
length macro defined by \csa{newlength} with \csa{number} will thus discard
the |plus| and |minus| glue components and return the dimension component as
described above, and usable in the \xintbundlename macros.
This conversion is done automatically inside an
|\xintexpr|-essions, with tacit multiplication implied if prefixed by some
(integral or decimal) number.
One may thus compute areas or volumes with no limitations, in units of |sp^2|
respectively |sp^3|, do arithmetic with them, compare them, etc..., and possibly
express some final result back in another unit, with the suitable conversion
factor and a rounding to a given number of decimal places.
A \hyperref[tableofdimensions]{table of dimensions} illustrates that the
internal values used by \TeX{} do not correspond always to the closest
rounding. For example a millimeter exact value in terms of |sp| units is
\dtt{72.27/10/2.54*65536=\xinttheexpr trunc(72.27/10/2.54*65536,3)\relax ...}
and \TeX{} uses internally \dtt{\number\dimexpr 1mm\relax}|sp| (\TeX{}
truncates to get an integral multiple of the |sp| unit; see at the end of this
section the exact rules applied internally by \TeX).
\begin{figure*}[ht!]
\phantomsection\label{tableofdimensions}
\begingroup\let\ignorespaces\empty
\let\unskip\empty
\def\T{\expandafter\TT\number\dimexpr}
\def\TT#1!{\gdef\tempT{#1}}
\def\E{\expandafter\expandafter\expandafter
\EE\xintexpr reduce(}
\def\EE#1!{\gdef\tempE{#1}}
\centeredline{\begin{tabular}{%
>{\bfseries\strut}c%
c%
>{\E}c<{)\relax!}@{}%
>{\xintthe\tempE}r@{${}={}$}%
>{\xinttheexpr trunc(\tempE,3)\relax...}l%
>{\T}c<{!}@{}%
>{\tempT}r%
>{\xinttheexpr round(100*(\tempT-\tempE)/\tempE,4)\relax\%}c}
\hline
Unit&%
definition&%
\omit &%
\multicolumn{2}{c}{Exact value in \texttt{sp} units\strut}&%
\omit &%
\omit\parbox{2cm}{\centering\strut\TeX's value in \texttt{sp} units\strut}&%
\omit\parbox{2cm}{\centering\strut Relative error\strut}\\\hline
cm&0.01 m&72.27/2.54*65536&&&1cm&&\\
mm&0.001 m&72.27/10/2.54*65536&&&1mm&&\\
in&2.54 cm&72.27*65536&&&1in&&\\
pc&12 pt&12*65536&&&1pc&&\\
pt&1/72.27 in&65536&&&1pt&&\\
bp&1/72 in&72.27*65536/72&&&1bp&&\\
\omit\hfil\llap{3}bp\strut\hfil&1/24 in&72.27*65536/24&&&3bp&&\\
\omit\hfil\llap{12}bp\strut\hfil&1/6 in&72.27*65536/6&&&12bp&&\\
\omit\hfil\llap{72}bp\strut\hfil&1 in&72.27*65536&&&72bp&&\\
dd&1238/1157 pt&1238/1157*65536&&&1dd&&\\
\omit\hfil\llap{11}dd\strut\hfil&11*1238/1157 pt&11*1238/1157*65536&&&11dd&&\\
\omit\hfil\llap{12}dd\strut\hfil&12*1238/1157 pt&12*1238/1157*65536&&&12dd&&\\
sp&1/65536 pt&1&&&1sp&&\\\hline
\multicolumn{8}{c}{\bfseries\large\TeX{} \strut dimensions}\\\hline
\end{tabular}}
\endgroup
\end{figure*}
There is something quite amusing with the Didot point. According to the \TeX
Book, $1157$\,|dd|=$1238$\,|pt|. The actual internal value of $1$\,|dd| in \TeX{} is $70124$\,|sp|. We can use \xintcfracname to display the list of
centered convergents of the fraction $70124/65536$:
%
\leftedline{|\xintListWithSep{, }{\xintFtoCCv{70124/65536}}|}
%
\xintFor* #1 in {\xintFtoCCv{70124/65536}}\do {$\printnumber{#1}$, }%
and we don't find
$1238/1157$ therein, but another approximant $1452/1357$!
And indeed multiplying $70124/65536$ by $1157$, and respectively $1357$, we find
the approximations (wait for more, later):
%
\leftedline{``$1157$\,|dd|''\dtt{=\xinttheexpr trunc(1157\dimexpr
1dd\relax/\dimexpr 1pt\relax,12)\relax}\dots|pt|}
%
\leftedline{``$1357$\,|dd|''\dtt{=\xinttheexpr trunc(1357\dimexpr
1dd\relax/\dimexpr 1pt\relax,12)\relax}\dots|pt|}
%
and we seemingly discover that $1357$\,|dd|=$1452$\,|pt| is \emph{far more
accurate} than
the \TeX Book formula $1157$\,|dd|=$1238$\,|pt|~!
The formula to compute $N$\,|dd| was
%
\leftedline{|\xinttheexpr trunc(N\dimexpr 1dd\relax/\dimexpr
1pt\relax,12)\relax}|}
%
What's the catch? The catch is that \TeX{} \emph{does not} compute $1157$\,|dd|
like we just did:%
%
\leftedline{$1157$\,|dd|=|\number\dimexpr 1157dd\relax/65536|%
\dtt{=\xintTrunc{12}{\number\dimexpr 1157dd\relax/65536}}\dots|pt|}
%
\leftedline{$1357$\,|dd|=|\number\dimexpr 1357dd\relax/65536|%
\dtt{=\xintTrunc{12}{\number\dimexpr 1357dd\relax/65536}}\dots|pt|}
%
We thus discover that \TeX{} (or rather here, e-\TeX{}, but one can check that
this works the same in \TeX82), uses $1238/1157$ as a conversion
factor (and necessarily intermediate computations simulate higher precision
than a priori available with integers less than $2^{31}$ or rather $2^{30}$ for
dimensions). Hence the $1452/1357$ ratio is irrelevant, an artefact
of the rounding (or rather, as we see, truncating) for one |dd| to be
expressed as an integral number of |sp|'s.
Let us now
use |\xintexpr| to compute the value of the Didot point in millimeters, if
the above rule is exactly verified:
%
\leftedline{|\xinttheexpr
trunc(1238/1157*25.4/72.27,12)\relax|%
\dtt{=\xinttheexpr trunc(1238/1157*25.4/72.27,12)\relax}|...mm|}
%
This fits very well with the possible values of the Didot point as listed in
the
\href{http://en.wikipedia.org/wiki/Point_%28typography%29#Didot}{Wikipedia Article}.
%
The value $0.376065$\,|mm| is said to be \emph{the traditional value in
European printers' offices}. So the $1157$\,|dd|=$1238$\,|pt| rule refers to
this Didot point, or more precisely to the \emph{conversion factor} to be used
between this Didot and \TeX{} points.
The actual value in millimeters of exactly one Didot point as implemented in
\TeX{} is
%
\leftedline {|\xinttheexpr trunc(\dimexpr
1dd\relax/65536/72.27*25.4,12)\relax|}
%
\leftedline{\dtt{=\xinttheexpr trunc(\dimexpr
1dd\relax/65536/72.27*25.4,12)\relax}|...mm|}
%
The difference of circa $5$\AA\ is arguably tiny!
% 543564351/508000000
By the way the \emph{European printers' offices \emph{(dixit Wikipedia)}
Didot} is thus exactly
%
\leftedline{|\xinttheexpr reduce(.376065/(25.4/72.27))\relax|%
\dtt{=\xinttheexpr reduce(.376065/(25.4/72.27))\relax}\,|pt|}
%
and the centered convergents of this fraction are \xintFor* #1 in
{\xintFtoCCv{543564351/508000000}}\do {\dtt{\printnumber{#1}}\xintifForLast{.}{, }} We do
recover the $1238/1157$ therein!
\begin{framed}
Here is how \TeX\ converts |abc.xyz...|. First the decimal is
\emph{rounded} to the nearest integral multiple of |1/65536|, say |X/65536|.
The || is associated to a ratio |N/D|, which represents |/pt|.
For the Didot point the ratio is indeed |1238/1157|. \TeX\ \emph{truncates}
the fraction |XN/D| to an integer |M|. The dimension is represented by |M
sp|.
\end{framed}
\subsection{\csh{ifcase}, \csh{ifnum}, \texorpdfstring{...\@}{...} constructs}\label{sec:ifcase}
When using things such as |\ifcase \xintSgn{\A}| one has to make sure to leave
a space after the closing brace for \TeX{} to
stop its scanning for a number: once \TeX{} has finished expanding
|\xintSgn{\A}| and has so far obtained either |1|, |0|, or |-1|, a
space (or something `unexpandable') must stop it looking for more
digits. Using |\ifcase\xintSgn\A| without the braces is very dangerous,
because the blanks (including the end of line) following |\A| will be
skipped and not serve to stop the number which |\ifcase| is looking for.
%
\begin{everbatim*}
\begin{enumerate}[nosep]\def\A{1}
\item \ifcase \xintSgn\A 0\or OK\else ERROR\fi
\item \ifcase \xintSgn\A\space 0\or OK\else ERROR\fi
\item \ifcase \xintSgn{\A} 0\or OK\else ERROR\fi
\end{enumerate}
\end{everbatim*}
In order to use successfully |\if...\fi| constructions either as arguments to
the \xintbundlename expandable macros, or when building up a completely
expandable macro of one's own, one needs some \TeX nical expertise (see also
\autoref{fn:expansions} on page~\pageref{fn:expansions}).
It is thus much to be recommended to use the expandable branching macros,
provided by \xintfracname succh as \csbxint{ifSgn}, \csbxint{ifZero},
\csbxint{ifOne}, \csbxint{ifNotZero}, \csbxint{ifTrueAelseB}, \csbxint{ifCmp},
\csbxint{ifGt}, \csbxint{ifLt}, \csbxint{ifEq},
\csbxint{ifInt}... See their respective documentations. All these conditionals
always have either two or three branches, and empty brace pairs |{}| for
unused branches should not be forgotten.
If these tests are to be applied to standard \TeX{} short integers, it is more
efficient to use (under \LaTeX{}) the equivalent conditional tests from the
\ctanpackage{etoolbox}%
%
\footnote{\url{https://ctan.org/pkg/etoolbox}}
package.
\subsection{No variable declarations are needed}
There is no notion of a \emph{declaration of a variable}.
To do a computation and assign its result to some macro |\z|, the user will employ the |\def|, |\edef|, or |\newcommand| (in \LaTeX)
as usual, keeping in mind that two expansion steps are needed, thus |\edef|
is initially the main tool:
%
\begin{everbatim*}
\def\x{1729728} \def\y{352827927} \edef\z{\xintiiMul {\x}{\y}}
\meaning\z
\end{everbatim*}
As an alternative to |\edef| the package provides |\oodef| which expands
exactly twice the replacement text, and |\fdef| which applies \fexpan sion to
the replacement text during the definition.
\begin{everbatim*}
\def\x{1729728}\def\y{352827927}
\oodef\w {\xintiiMul\x\y} \fdef\z{\xintiiMul {\x}{\y}}
\meaning\w, \meaning\z
\end{everbatim*}
In practice |\oodef| is slower than |\edef|, except for computations ending in
very big final replacement texts (thousands of digits). On the other hand
|\fdef|\IMPORTANT{} appears to be slightly faster than |\edef| already in the
case of expansions leading to only a few dozen digits.
\xintexprname does provide an interface to declare and assign values to
identifiers which can then be used in expressions: \autoref{xintdefvar}.
\subsection{Possible syntax errors to avoid}
\edef\x{\xintMul {3}{5}/\xintMul{7}{9}}
Here is a list of imaginable input errors. Some will cause compilation errors,
others are more annoying as they may pass through unsignaled.
\begin{itemize}
\item using |-| to prefix some macro: |-\xintiiSqr{35}/271|.%
%
\footnote{to the
contrary, this \emph{is}
allowed inside an |\xintexpr|-ession.}
\item using one pair of braces too many |\xintIrr{{\xintiiPow {3}{13}}/243}| (the
computation goes through with no error signaled, but the result is completely
wrong).
\item things like |\xintiiAdd { \x}{\y}| as the space will cause \csa{x} to be
expanded later, most probably within a |\numexpr| thus provoking possibly an
arithmetic overflow.
\item using |[]| and decimal points at the same time |1.5/3.5[2]|, or with a
sign in the denominator |3/-5[7]|. The scientific notation has no such
restriction, the two inputs |1.5/-3.5e-2| and |-1.5e2/3.5| are equivalent:
|\xintRaw{1.5/-3.5e-2}|\dtt{=\xintRaw{1.5/-3.5e-2}},
|\xintRaw{-1.5e2/3.5}|\dtt{=\xintRaw{-1.5e2/3.5}}.
\item generally speaking, using in a context expecting an integer (possibly
restricted to the \TeX{} bound) a macro or expression which returns a
fraction: |\xinttheexpr 4/2\relax| outputs \dtt{\xinttheexpr 4/2\relax},
not $2$. Use |\xintNum {\xinttheexpr 4/2\relax}| or |\xinttheiexpr 4/2\relax|
(which rounds the result to the nearest integer, here, the result is already
an integer) or |\xinttheiiexpr 4/2\relax|. Or, divide in your head |4| by
|2| and insert the result directly in the \TeX{} source.
\end{itemize}
\subsection{Error messages}
In situations such as division by zero, the \TeX{} run will be interrupted
with some error message. It conveys some short information on
the cause of the problem,%
%
\footnote{The wording of these messages has been last modified at |1.4m|.\CHANGED{1.4m}}
%
then an optimistic statement about a possible
recovery if the user (in interactive mode) simply hits the || key.
%
In non-interactive (|nonstopmode|) the \TeX{} run goes on uninterrupted and
the error data will be found in the compilation log. Often, \xintname will
fall-back to using a zero value. This is still an experimental feature.%
%
\footnote{Customizable handlers, error traps, error flags are implemented
in embryonic form but without user interface since |1.2l| release. This is
not ready yet.}
%
\footnote{The |1.4g| new formatting implementation benefited from a May 2021
thread at the \LaTeX3 site where expandable error messages were discussed,
with in particular contributions of |@blefloch| and |@Skillmon|.}
The encouragements will be slightly better formatted if the run is with
\LaTeX\ compared to Plain \eTeX: Plain by default does not set the
|\newlinechar| which allows to issue linebreaks in messages at chosen
locations. In the examples here, \ctanpackage{xintsession} is used, and it
loads \xintname in a way activating the nicer |\newlinechar| formatted
messages, even though it runs (a priori, but not necessarily) under Plain
\eTeX.
\begin{everbatim}
>>> 1/0;
Runaway argument?
! xint error: Division by zero: 1/0.
! Paragraph ended before \xint<...> is done, but will resume:
hit at the ? prompt to try fixing the error above
which has been encountered before expansion was complete.
\par
...
l.602 \xintsession
\endinput%^^M
?
@_1 0
>>> (-1)^3.2;
Runaway argument?
! xint error: Fractional power 32/1[-1] of negative -1[0].
! Paragraph ended before \xint<...> is done, but will resume:
hit at the ? prompt to try fixing the error above
which has been encountered before expansion was complete.
\par
...
l.602 \xintsession
\endinput%^^M
?
@_2 0
>>> cos 1);
Runaway argument?
! xint error: `cos1' unknown, say `Isome_var' or I use 0.
! Paragraph ended before \xint<...> is done, but will resume:
hit at the ? prompt to try fixing the error above
which has been encountered before expansion was complete.
\par
...
l.602 \xintsession
\endinput%^^M
?
Runaway argument?
! xint error: Extra ) removed. Hit , fingers crossed.
! Paragraph ended before \xint<...> is done, but will resume:
hit at the ? prompt to try fixing the error above
which has been encountered before expansion was complete.
\par
...
l.602 \xintsession
\endinput%^^M
?
@_3 0
>>> 3=4;
Runaway argument?
! xint error: Expected an operator but got `='. Ignoring.
! Paragraph ended before \xint<...> is done, but will resume:
hit at the ? prompt to try fixing the error above
which has been encountered before expansion was complete.
\par
...
l.602 \xintsession
\endinput%^^M
?
@_4 12
>>> &bye
\end{everbatim}
In the last example, tacit multiplication was applied as \xintexprname was
looking for an operator, got some invalid input and then a number.
Some constructs in \xintexprname-essions use delimited macros and there is
thus possibility in case of an ill-formed expression to end up beyond the
|\relax| end-marker. Such a situation can also occur from |\relax| being
swallowed by a non-terminated
|\numexpr|:
\begin{everbatim}
\xintexpr 3 + \numexpr 5+4\relax followed by some LaTeX code...
\end{everbatim}
The correct input is
\begin{everbatim}
\xintexpr 3 + \numexpr 5+4\relax\relax
\end{everbatim}
But people in their right mind will have done
\begin{everbatim}
\xintexpr 3 + 5 + 4\relax
\end{everbatim}
A few will have done the computation in their heads.
In such cases low-level errors will arise and may
lead to very cryptic messages; but nothing unusual or especially traumatizing
for the daring experienced \TeX/\LaTeX\ user, whose has seen zillions of
un-helpful error messages already in her daily practice of
\TeX/\LaTeX.
\subsection{Package namespace, catcodes}
This section reviews (probably with some omissions) important
miscellany regarding control sequence names and catcode matters and is
basically in its entirety a
\begin{TeXnote}
\begin{itemize}
\item The bundle packages
force the |\space| and |\empty|
control sequences into having their default meanings as in Plain \TeX{} or
\LaTeX2e formats.
\item Private macros (or internally used |\count| registers, and one private
|\toks|) have names starting with |\xint_| or |\XINT_|. Some, for legacy or
technical reasons, have |\xint| or |\XINT| prefix with no underscore.
\item All public macros have their names starting with |\xint| except for:
the \xintkernelname provided \hyperref[odef]{|\odef|},
\hyperref[oodef]{|\oodef|}, \hyperref[fdef]{|\fdef|}. If macros with
these names already exist \xinttoolsname will not overwrite them. Their
meanings are also available under the names \csbxint{odef}, \csbxint{oodef},
etc...
\item For the \xintfracname macros to be able to parse their inputs, standard
catcodes in the argument are assumed for the digits (of course), the plus
and minus signs, the dot, the letter |e|, the forward slash, the square
brackets. Spaces should be avoided although they may go unnoticed
sometimes.
\item For the \xintexprname expressions there is more leeway: the digit
tokens must have their standard catcodes, the letters must have their
standard catcodes for variable and function names to be recognized,
but other characters may mostly have unusual (but not extreme like
catcode zero or one) catcodes. Active characters will be
expanded and should usually be prefixed with |\string|. But,
if activated via Babel\NewWith{1.4n} this is not needed.
A few syntax elements are implemented via delimited macros. So the
comma, the equal sign and the closing parenthesis must have their
normal catcodes for these syntax elements to work. |\string| won't do.
Spaces are gobbled. The |e| of scientific notation may be |E| on
input, \xintfracname macros on the other hand will not recognize the
|E|.
\item
\csbxint{defvar} and \csbxint{deffunc} as they use automatically
\csbxint{exprSafeCatcodes} and \csbxint{exprRestoreCatcodes} to temporarily
set catcodes to safe values.
\item \csbxint{exprSafeCatcodes} and \csbxint{exprRestoreCatcodes} can be
employed at user level too.
\item
At loading time the
catcode configuration may be arbitrary as long as it satisfies the following
requirements:
\begin{itemize}[nosep]
\item \dtt{\%} has its normal category code,
\item \dtt{\char92} has its normal category code,
\item Latin letters have their normal category code "letter",
\item Digits have their normal category code "other".
\end{itemize}
Nothing more is assumed, for example |{| and |}| may have unusual catcodes
at package loading time. This will be admittedly unusual especially in
\LaTeX\ as |\usepackage{xintexpr}| would then have had to be replaced by
something such as |\usepackage|...
\item Loading the packages causes no insertion of space tokens.
\item The previous two items also apply to usage of \csbxint{reloadxintlog}
and of \csbxint{reloadxinttrig}.
\end{itemize}
\end{TeXnote}
\subsection{Origins of the package}
\label{ssec:origins}
|2013/03/28.| Package |bigintcalc| by \textsc{Heiko Oberdiek} already
provides expandable arithmetic operations on \myenquote{big integers}, i.e. integers
beyond the \TeX\ bound $2^{31}-1$, so why another%
%
\footnote{this section was written before the \xintfracname package; the
author is not aware of another package allowing expandable
computations with arbitrarily big fractions.}
%
one?
I got started on this in early March 2013, via a thread on the
|c.t.tex| usenet group, where \textsc{Ulrich D\,i\,e\,z} used the
previously cited package together with a macro (|\ReverseOrder|)
which I had contributed to another thread.%
%
\footnote{the \csa{ReverseOrder} could be avoided in that circumstance,
but it does play a crucial r\^ole here.}
%
What I had learned in this
other thread thanks to interaction with \textsc{Ulrich D\,i\,e\,z} and
\textsc{GL} on expandable manipulations of tokens motivated me to
try my hands at addition and multiplication.
I wrote macros \csa{bigMul} and \csa{bigAdd} which I posted to the
newsgroup; they appeared to work comparatively fast. These first
versions did not use the \eTeX{} \csa{numexpr} primitive, they worked
one digit at a time, having previously stored carry-arithmetic in
1200 macros.
I noticed that the |bigintcalc| package used \csa{numexpr}
if available, but (as far as I could tell) not
to do computations many digits at a time. Using \csa{numexpr} for
one digit at a time for \csa{bigAdd} and \csa{bigMul} slowed them
a tiny bit but avoided cluttering \TeX{} memory with the 1200
macros storing pre-computed digit arithmetic. I wondered if some speed
could be gained by using \csa{numexpr} to do four digits at a time
for elementary multiplications (as the maximal admissible number
for \csa{numexpr} has ten digits).
|2013/04/14|.\@{} This initial \xintname was followed by \xintfracname which
handled exactly fractions and decimal numbers.
|2013/05/25|.\@{} Later came \xintexprname and at the same time \xintfracname got
extended to handle floating point numbers.
|2013/11/22|.\@{} Later, \xinttoolsname was detached.
|2014/10/28|.\@{} Release |1.1| significantly extended the \xintexprname parsers.
|2015/10/10|.\@{} Release |1.2| rewrote the core integer routines which had
remained essentially unmodified, apart from a slight improvement of division
early 2014.
This |1.2| release also got its impulse from a fast
``reversing'' macro, which I wrote after my interest got awakened again as a
result of correspondence with Bruno \textsc{Le Floch} during September 2015:
this new reverse uses a \TeX nique which \emph{requires} the tokens to be
digits. I wrote a routine which works (expandably) in quasi-linear time, but a
less fancy |O(N^2)| variant which I developed concurrently proved to be faster
all the way up to perhaps $7000$ digits, thus I dropped the quasi-linear one.
The less fancy variant has the advantage that \xintname can handle numbers
with more than $19900$ digits (but not much more than $19950$). This is with
the current common values of the input save stack and maximal expansion depth:
$5000$ and $10000$ respectively.
\clearpage
\let\xintbundlenameUp\undefined
\csname xintkernelnameUp\endcsname
\section{Macros of the \xintkernelname package}
\RaisedLabel{sec:kernel}
\localtableofcontents
\subsection{Introduction}
The \xintkernelname package contains mainly the common code base for handling
the load-order of the bundle packages, the management of catcodes at loading
time, definition of common constants and macro utilities which are used
throughout the code etc ...\@{} it is automatically loaded by all packages of the
bundle.
It provides a few macros possibly useful in other contexts.
\subsection{\csh{odef}, \csh{oodef}, \csh{fdef}}
\label{odef}
\label{oodef}
\label{fdef}
\label{xintodef}
\label{xintoodef}
\label{xintfdef}
\csa{oodef}|\controlsequence {}| does
\everb|@
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\controlsequence
\expandafter\expandafter\expandafter{}
|
This works only for a single
|\controlsequence|, with no parameter text, even without parameters. An
alternative would be:
\everb|@
\def\oodef #1#{\def\oodefparametertext{#1}%
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\oodefparametertext
\expandafter\expandafter\expandafter }
|
\noindent
but it does not allow |\global| as prefix, and, besides, would have anyhow its
use (almost) limited to parameter texts without macro parameter tokens
(except if the expanded thing does not see them, or is designed to deal with
them).
There is a similar macro |\odef| with only one expansion of the replacement text
||, and |\fdef| which expands fully || using |\romannumeral-`0|.
They can be prefixed with |\global|. It appears than |\fdef| is generally a bit
faster than |\edef| when expanding macros from the \xintbundlename, when the
result has a few dozens of digits. |\oodef| needs thousands of digits it seems
to become competitive.
\xintkernelname will not define these macros if the control sequence names
already exist. It provides them always under the names |\xintodef|,
|\xintoodef| and |\xintfdef| respectively.
\subsection{\csh{xintReverseOrder}}\label{xintReverseOrder}
\csa{xintReverseOrder}\marg{list}\etype{n} does not do any expansion of its
argument and just reverses the order of the tokens in the \meta{list}. Braces
are removed once and the enclosed material, now unbraced, does not get
reversed. Unprotected spaces (of any character code) are gobbled.
%
\leftedline{|\xintReverseOrder{\xintDigitsOf\xintiiPow {2}{100}\to\Stuff}|}
%
\leftedline{gives:
\ttfamily{\string\Stuff\string\to1002\string\xintiiPow\string\xintDigitsOf}}
\xinttoolsname provides a variant \csbxint{RevWithBraces} which keeps brace
pairs in the output, and \fexpan ds its input first.
For inputs consisting only digit tokens, see \csbxint{ReverseDigits} from
\xintname.
\subsection{\csh{xintLength}}
\label{xintLength}
\csa{xintLength}\marg{list}\etype{n} counts how many tokens (or braced items)
there are (possibly none). It does no expansion of its argument, so to use it
to count things in the replacement text of a macro |\x| one should do
|\expandafter\xintLength\expandafter{\x}|. Blanks between items are not
counted. See also \csbxint{NthElt}|{0}| (from \xinttoolsname)
which first \fexpan ds its argument and then applies the same code.
%
\leftedline{|\xintLength {\xintiiPow {2}{100}}|\dtt{=\xintLength
{\xintiiPow{2}{100}}}}
%
\leftedline{${}\neq{}$|\xintLen {\xintiiPow {2}{100}}|\dtt{=\xintLen
{\xintiiPow{2}{100}}}}
The maximal input size is limited by \TeX{} main memory (it seems to be
about half of the \TeX Live |main_memory| setting from file |texmf.cnf|.
Because \TeX{} main memory is also where the used format is stored, as
well as all additional defined macros, it will for example be
higher if compiling with |etex| (PDF\TeX{} in dvi mode) than with
|pdftex|. Testing expansion inside an |\edef| with |etex| the author
obtained with \TeX Live 2025 a limit of \dtt{2492667} tokens with |1.4n|.
\subsection{\csh{xintFirstItem}}
\label{xintFirstItem}
\csa{xintFirstItem}\marg{list}\etype{n} returns the first item of its
argument, one pair of braces removed. If the list has no items the output is
empty.
It does no expansion. For this and the next similar ones, see
|xintsource.pdf| for comments on limitations.
\subsection{\csh{xintLastItem}}
\label{xintLastItem}
Added at |1.2i|.
\csa{xintLastItem}\marg{list}\etype{n} returns the last item
of its argument, one pair of braces removed. If the list has no items the
output is empty.
It does no expansion, which should be obtained via suitable |\expandafter|'s.
See also \csbxint{NthElt}|{-1}| from \xinttoolsname which obtains the same
result (but with another code) after having however \fexpan ded its
argument first.
\subsection{\csh{xintFirstOne}}
\label{xintFirstOne}
\csa{xintFirstOne}\marg{list}\etype{n} returns the first item as a braced
item. i.e.\@{} if it was braced the braces are kept, else the braces are added.
It looks like using \csbxint{FirstItem} within braces, but the difference is
when the input was empty. Then the output is empty.
It does no expansion, which should be obtained via suitable |\expandafter|'s.
\subsection{\csh{xintLastOne}}
\label{xintLastOne}
\csa{xintLastOne}\marg{list}\etype{n} returns the last item as a braced
item. i.e.\@{} if it was braced the braces are kept, else the braces are added.
It looks like using \csbxint{LastItem} within braces, but the
difference is when the input was empty. Then the output is empty.
It does no expansion, which should be obtained via suitable |\expandafter|'s.
\subsection{\csh{xintReplicate}, \csh{xintreplicate}}
\label{xintreplicate}
\label{xintReplicate}
\csa{romannumeral}\csa{xintreplicate}|{x}|\marg{stuff}\etype{\numx n} is simply
copied over from \LaTeX3's |\prg_replicate:nn| with some minor changes.%
%
\footnote{I started with the code from Joseph \textsc{Wright}
available on an online site.}
And \csa{xintReplicate}|{x}| integrates the
\csa{romannumeral} prefix.
It
does not do any expansion of its second argument but inserts it in the upcoming
token stream precisely |x| times. Using it with a negative |x| raises no error
and does nothing.%
%
\footnote{This behaviour may change in future.}
\subsection{\csh{xintGobble}, \csh{xintgobble}}
\label{xintgobble}
\label{xintGobble}
\csa{romannumeral}\csa{xintgobble}|{x}|\etype{\numx} is a Gobbling macro
written in the spirit of \LaTeX3's |\prg_replicate:nn| (which I cloned as
\csbxint{replicate}.) It gobbles |x| tokens upstream, with |x| allowed to be
as large as \dtt{531440}. Don't use it with |x<0|.
And \csa{xintGobble}|{x}| integrates the \csa{romannumeral}.
\csbxint{gobble} looks as if it must be related to \csbxint{Trim} from
\xinttoolsname, but the latter uses different code (using directly
\csbxint{gobble} is not possible because one must make sure not to gobble more
than the number of available items; and counting available items first is an
overhead which \csbxint{Trim} avoids.) It is rather\csbxint{Keep} with a
negative first argument which hands over to \csbxint{gobble} (because in that
case it is needed to count anyhow beforehand the number of items, hence
\csbxint{gobble} can then be used safely.)
I wrote an \csa{xintcount} in the same spirit as \csa{xintreplicate} and
\csa{xintgobble}. But it needs to be counting hundreds of tokens to be worth
its salt compared to \csbxint{Length}.
\subsection{(WIP) \csh{xintUniformDeviate}}
\label{xintUniformDeviate}
\csa{xintUniformDeviate}|{x}|\etype{\numx} is based upon the engine
primitive, which is |\pdfuniformdeviate| with \PDFTeX{}, and
|\uniformdeviate| with \LuaTeX{} and \XeTeX{}. A common name for that
primitive is |\xinttexuniformdeviate|. But \csbxint{UniformDeviate} is,
was will be explained designed to work around some features/limitations.
The argument is expanded in |\numexpr| and the macro itself needs two
expansion steps. It produces like the engine primitive an integer (digit
tokens) with minimal value \dtt{0} and maximal one \dtt{x-1} if |x| is
positive, or minimal value \dtt{x+1} and maximal value \dtt{0} if |x| is
negative. For the discussion next, |x| is supposed positive as this
avoids having to insert absolute values in formulas.
The underlying engine primitive (thus, |\xinttexuniformdeviate|)
accesses a random number generator (RNG) originally embedded into
MetaPost and described in \emph{The Art of Computer Programming,
Vol. 2}. During discussions with Bruno Le Floch in May 2018, when he
was adding to \LaTeX3 interface for randomness, the author became aware
of some limitations, some of them surprising, in the randomness of the
numbers produced by this RNG. For example, the values produced by
|\pdfuniformdeviate 201326592| and reduction modulo three are in the
proportion |1:1:2|, not |1:1:1|.
Let's count how many 0's, 1's, and 2's we get from reducing modulo 3 the
output of |\xinttexuniformdeviate 201326592|.
\begin{everbatim*}
\xintsetrandomseed 87654321
\def\A{0}\def\B{0}\def\C{0}
\xintReplicate{504}{\ifcase\xinteval{(\xinttexuniformdeviate 201326592)/:3}
\edef\A{\the\numexpr\A+1}\or
\edef\B{\the\numexpr\B+1}\or
\edef\C{\the\numexpr\C+1}\fi
}
We found \A{} 0's, \B{} 1's and \C{} 2's among 504 trials.
\end{everbatim*}
In contrast, here is what happens if using \csbxint{UniformDeviate}:
\begin{everbatim*}
\xintsetrandomseed 87654321
\def\A{0}\def\B{0}\def\C{0}
\xintReplicate{504}{\ifcase\xinteval{\xintUniformDeviate{201326592}/:3}
\edef\A{\the\numexpr\A+1}\or
\edef\B{\the\numexpr\B+1}\or
\edef\C{\the\numexpr\C+1}\fi
}
We found \A{} 0's, \B{} 1's and \C{} 2's among 504 trials.
\end{everbatim*}
\begin{TeXnote}
The RNG works with 28-bits integers. To output a supposedly uniform
random integer in a given range \dtt{0..x-1}, it first produces a
supposedly uniform integer in the range \dtt{0..$2^{28}-1$} (where
\dtt{$2^{28}=268435456$}) then rescales (with rounding) to the target
range.
%
Note that with \dtt{$x=2^{29}$} this means in particular that all produced
``random numbers'' in the \dtt{0..x-1} range will be even...
But even with \dtt{$x=2^{28}$} there are some more serious defects of
the RNG: two seeds sharing the same low |k| bits generate sequences of
28-bits integers which are identical one-to-one modulo |2^k|! In
particular after setting the seed, there are only 2 distinct sequences
for the parity bits for the integers generated by |\pdfuniformdeviate
268435456| (or rather with |\xinttexuniformdeviate| if with another
engine than |pdftex|).
Let's define the non-uniformity of |\pdfuniformdeviate x| to be the
maximum, taken over all |y|'s from \dtt{0} to |x-1|, of $\string|x\times
\mathrm{Prob}($|\pdfuniformdeviate x|${}=y) - 1\string|$. For a general
|x|, the engine primitive guarantees only a \dtt{$x/2^{28}$} relative
non-uniformity for the outputs of |\pdfuniformdeviate x|.
\csbxint{UniformDeviate} improves this by a factor of
\dtt{|2^{28}=|\number"10000000}: \emph{the relative non-uniformity now
is guaranteed to be bounded above by \fbox{\dtt{$x/2^{56}$}}}. With
such a small non-uniformity, modulo phenomena as mentioned earlier are
not observable in reasonable computing time.
%
% These estimates assume that the engine RNG underlying stream of
% 28-bits integers can be considered uniform; it is known that the
% parity bits of these 28-bits integers have a period of |55(2^{55}-1)| and
% that after that many draws the count of 1s has only an excess of 55 compared
% to the count of 0s, so the scale seems to be an intrinsic non-uniformity of
% |2^{-55}| but it is not obvious if it applies to much shorter ranges. At any
% rate we assumed that the non-uniformity for |x| a power of two less than
% |2^{28}| is negligible in comparison to |2^{-28}|. Bigger powers of 2
% produce only even integers because the output is rescaled by
% factor |x/2^{28}|!
%
The implementation of \csbxint{UniformDeviate} consumes exactly 5
calls to the engine primitive at each execution; the improved |x/2^{56}|
non-uniformity could be obtained with only 2 calls, but paranoïa about the
phenonemon of seeds with common bits has led me to accept the overhead of
using the 7 high bits of 4 random 28-bits integers, rather than one single
28-bits integer, or two, or three.
Timings indicate that one \csbxint{UniformDeviate} has a time cost about 13
times the one for one call to the engine primitive (and not only 5, as the
extra arithmetic expressions add overhead which is more costly than the
primitive itself). Except if the code using the pseudo-random number is very
short, this time penalty will prove in practice much less severe (and this is
one important reason why we opted for obtaining 28bits via the 7 high bits of
4 successive pseudo random numbers from the engine primitive).
For example
let's raise 100 times a random integer in the \dtt{0..99999999} range to the tenth power:%
%
\InputIfFileExists{JFBUORDI}{}{}%
\ifdefined\JFBUORDI
\footnote{%
\if0\xintstrcmp{IMAC}{\JFBUORDI}Timings done during dvi build on a
computer with a |2.8GHz| %
%quadri-core
cpu, old but still kicking, and with a locally compiled |latex| binary.\else
\if0\xintstrcmp{MBA}{\JFBUORDI}Timings done during dvi build on a
computer with a |2GHz| %
%dual-core
cpu, old but still kicking, and with a locally compiled |latex| binary.\else
\if0\xintstrcmp{MBA-M4}{\JFBUORDI}Timings done during dvi build on an Apple laptop with M4 architecture.\else
\if0\xintstrcmp{MINI}{\JFBUORDI}Timings done during dvi build on an Apple desktop with M4 Pro architecture.\else
DOCUMENTATION SEEMINGLY BUILT NOT ON AN AUTHOR-OWNED SYSTEM, BUT \string\JFBUORDI\space IS DEFINED, WEIRD!\fi\fi\fi\fi
}
\else
\footnote{These timings are done during a build on a computer not belonging to the author.}
\fi
%
\begin{everbatim*}
\xintsetrandomseed 12345678
\xintresettimer
\xintReplicate{100}{\edef\foo{\xintiiPow{\xintUniformDeviate{100000000}}{10}}}%
\xinttheseconds s (if using \string\xintUniformDeviate)\newline
\xintsetrandomseed 12345678
\xintresettimer
\xintReplicate{100}{\edef\foo{\xintiiPow{\xinttexuniformdeviate 100000000}{10}}}%
\xinttheseconds s (if using \string\xinttexuniformdeviate)\par
\end{everbatim*}
The macros \csbxint{RandomDigits} or \csbxint{iiRandRange}, and their
variants, as well as the supporting macros for \func{random} generate random
decimal digits eight by eight as if using
\csbxint{UniformDeviate}|{100000000}|, but via a direct optimized call made
possibly by the range being a power of 10.
\end{TeXnote}
\clearpage
\let\xintkernelnameUp\undefined
\csname xintcorenameUp\endcsname
\def\n{|{N}|}
\def\m{|{M}|}
\def\x{|{x}|}
\section{Macros of the \xintcorename package}
\RaisedLabel{sec:core}
\localtableofcontents
\subsection{Introduction}
Package \xintcorename is automatically loaded by \xintname.
\xintcorename provides for big integers the four basic arithmetic operations
(addition, subtraction, multiplication, division), as well as powers and
factorials.
In the descriptions of the macros \texttt{\n} and \texttt{\m} stand
for (big) integers or macros \hyperref[ssec:expansions]{\fexpan ding} to
such big integers in strict format as described in \autoref{ssec:inputs}.
All macros require strict integer format on input and produce
strict integer format on output, except:\IMPORTANT
\begin{itemize}[nosep]
\item \csbxint{iNum} which converts to strict integer format an input in
\emph{extended} integer format, i.e.\@{} admitting multiple leading plus or
minus signs, then possibly leading zeroes, then digits,
\item and \csbxint{Num} which is an alias for the former, which gets redefined by
\xintfracname to accept more generally also decimal numbers or fractions as
input and which truncates them to integers.
\end{itemize}
The |ii| in the names of the macros such as \csbxint{iiAdd} serves to stress
that they accept only strict integers as input (this is signaled by the margin
annotation \textcolor[named]{PineGreen}{\emph{f}}), or macros \fexpan ding to
such strict format (big) integers and that they produce strict integers as
output.
Other macros, such as \csbxint{Double}, lack the |ii|, but this is only a
legacy of the history of the package and they have the same requirements for
input and format of output as the |ii|-macros.
The letter \texttt{x} (with margin annotation
\smash{\textcolor[named]{PineGreen}{\numx}}) stands for an argument which will
be handled embedded in |\numexpr..\relax|. It will thus be completely expanded
and must give an integer obeying the \TeX{} bounds. See also
\autoref{sec:useofcount}. This is the case for the argument of \csbxint{iiFac}
or the exponent argument of \csbxint{iiPow}.
The {\color[named]{PineGreen}$\star$}'s in the margin are there to remind of
the complete expandability, even \fexpan dability of the macros, as discussed
in \autoref{ssec:expansions}.
\autoref{tab:maxsizes} summarizes the maximal allowed sizes for the four
operations. The first column is the tested macro (it is expanded in an
\csa{edef}; if deeper nested, the maximal admissible input sizes may
actually prove lower than stated). The second column gives
the maximal |N| such that the macro does not raise an error on both
inputs having |N| digits (for division,
the used test divisors had |N/4|, |N/2| and |3N/4| digits).
These maximal |N|'s depend on the values of \TeX\ parameters such as
input stack size and expansion depth. The last column gives the \TeX\
parameter cited in the error message when trying with |N+1| digits.
The table was last updated in July 2025, using |1.4m 2022/06/10| and
TeXLive 2025 default settings which are: input stack size at
\dtt{10000}, expansion depth at \dtt{10000}, parameter stack size at
\dtt{20000}.
\begin{table}[htbp]
\capstart
\centering
\def\E#1#2!{\edef\F{\the\numexpr(#1-\xintLength{#2})/2}%
\relax\romannumeral\xintreplicate{\F}{ }#2%
\romannumeral\xintreplicate{#1-\F-\xintLength{#2}}{ }\relax}%
% non satisfactory because depends on #1 oddness, but well. Temporary destined
% to stay...
\begin{tabular}{r>{\E{19}}c<{!}r}
\hline
&Max\ length\ of\ inputs&Limiting factor\\
\csbxint{iiAdd}&26648&expansion depth=10000\\
\csbxint{iiSub}&26632&expansion depth=10000\\
\csbxint{iiMul}&13320&expansion depth=10000\\
\csbxint{iiDivision}&26609&expansion depth=10000\\
\hline
\end{tabular}
\caption{Maximal sizes of inputs (using TeXLive 2025) for core arithmetic}\label{tab:maxsizes}
\end{table}
\subsection{\csh{xintiNum}}\label{xintiNum}
|\xintiNum|\n\etype{f} removes chains of plus or minus signs, followed by
zeroes.
\begin{everbatim*}
\xintiNum{+---++----+--000000000367941789479}
\end{everbatim*}
\subsection{\csh{xintDouble}}\label{xintDouble}
|\xintDouble|\n\etype{f} computes |2N|.
\subsection{\csh{xintHalf}}\label{xintHalf}
|\xintHalf|\n\etype{f} computes |N/2|
truncated towards zero.
\subsection{\csh{xintInc}}\label{xintInc}
|\xintInc|\n\etype{f} evaluates |N+1|.
\subsection{\csh{xintDec}}\label{xintDec}
|\xintDec|\n\etype{f} evaluates |N-1|.
\subsection{\csh{xintDSL}}\label{xintDSL}
|\xintDSL|\n\etype{f} is decimal shift left, \emph{i.e.\@} multiplication by
ten.
\subsection{\csh{xintDSR}}\label{xintDSR}
|\xintDSR|\n\etype{f} is truncated decimal shift right, \emph{i.e.\@} it is the
truncation of |N/10| towards zero.
\subsection{\csh{xintDSRr}}\label{xintDSRr}
|\xintDSRr|\n\etype{f} is rounded decimal shift right, \emph{i.e.\@} it is the
rounding of |N/10| away from zero. It is needed in \xintcorename for use by
\csbxint{iiDivRound}.
\subsection{\csh{xintFDg}}\label{xintFDg}
|\xintFDg|\n\etype{f} outputs the first digit (most significant) of the
number.
\subsection{\csh{xintLDg}}\label{xintLDg}
|\xintLDg|\n\etype{f} outputs the least significant digit. When the number
is positive, this is the same as the remainder in the Euclidean division by
ten.
\subsection{\csh{xintiiSgn}}\label{xintiiSgn}
|\xintiiSgn|\n\etype{f} returns 1 if the number is positive, 0 if it is zero
and -1 if it is negative.
\subsection{\csh{xintiiOpp}}\label{xintiiOpp}
|\xintiiOpp|\n\etype{f} outputs the opposite |-N| of the number |N|.
Important note: an input such as |-\foo| is not legal, generally speaking, as
argument to the macros of the \xintbundlename (except, naturally in
\csbxint{expr}-essions). The reason is that the minus sign stops the \fexpan
sion done during parsing of the inputs. One must use the syntax
|\xintiiOpp{\foo}| if one wants to pass |-\foo| as
argument to other macros.
\subsection{\csh{xintiiAbs}}\label{xintiiAbs}
|\xintiiAbs|\n\etype{f} outputs the absolute value of the number.
\subsection{\csh{xintiiAdd}}\label{xintiiAdd}
|\xintiiAdd|\n\m\etype{ff} computes the sum of the two (big) integers.
\subsection{\csh{xintiiCmp}}\label{xintiiCmp}
|\xintiiCmp|\n\m\etype{ff} produces \dtt{1} if |N>M|, \dtt{0} if |N=M|,
and \dtt{-1} if |N1+ and |x<0|, an error is raised. There will also
be an error if |x| exceeds the maximal \eTeX{} number \dtt{\number"7FFFFFFF},
but the real limit for exponents comes from either the computation time or the
settings of some \TeX\ memory parameters.
Generally speaking the computation will end in an error if the output goes
beyond what addition could accept on input, i.e.\@ (with \TeX Live 2025 default
settings) has more than about \dtt{26600} digits.
For example the maximal power of $2$ which \csbxint{iiPow} is able to compute
(with \TeX Live 2025 default memory parameters) is $2^{88470}$ which has
\dtt{26633} digits. I.e.\@ |\edef\z{\xintiiPow{2}{88470}}| succeeds (if you
are patient enough to wait) but |\edef\z{\xintiiPow{2}{88471}}| fails.
\subsection{\csh{xintiiFac}}\label{xintiiFac}
|\xintiiFac|\x\etype{\numx} computes the factorial.
The (theoretically) allowable range is $0\leqslant x\leqslant10000$.
However the maximal possible computation depends on the values of some memory
parameters of the \eTeX{} executable:
with \xintcorename at |1.4m| and using \TeX Live 2025, the maximal
(within an |\edef|) computable one is \dtt{7712!}\@ which has
\dtt{26631} decimal digits.
With the input stack size set at 10000, the limiting factor here is the
expansion depth at 10000.
The \func{factorial} function, or equivalently \func{!} as post-fix operator is
available in the three parsers:
\begin{everbatim*}
\xinttheiiexpr factorial(30)\relax\par
\printnumber{\xinteval{200!}}\par
\end{everbatim*}
Within \csbxint{floateval}, the macro \csbxint{FloatFac} from package \xintfracname is used.
\begin{everbatim*}
\xintfloateval{200!}\par
\end{everbatim*}
\begin{everbatim*}
\xintfloateval{2000!}\par
\end{everbatim*}
See its documentation for more.
\subsection{\csh{xintiiDivision}}\label{xintiiDivision}
|\xintiiDivision|\m\n\etype{ff} produces |{quotient}{remainder}|, in the sense
of (mathematical) Euclidean division: |M = QN + R|,
|0|${}\leq{}$\verb+R < |N|+. So the remainder is always non-negative and the
formula |M = QN + R| always holds independently of the signs of |N| or |M|.
Division by zero is an error (even if |M| vanishes) and returns |{0}{0}|.
\subsection{\csh{xintiiQuo}}\label{xintiiQuo}
|\xintiiQuo|\m\n\etype{ff} computes the quotient from the Euclidean division.
\subsection{\csh{xintiiRem}}\label{xintiiRem}
|\xintiiRem|\m\n\etype{ff} computes the remainder from the Euclidean
division.
\subsection{\csh{xintiiDivRound}}\label{xintiiDivRound}
|\xintiiDivRound|\m\n\etype{ff} returns the rounded value of the algebraic
quotient $M/N$ of two big integers. The rounding is ``away from zero.''
\begin{everbatim*}
\xintiiDivRound {100}{3}, \xintiiDivRound {101}{3}
\end{everbatim*}
\subsection{\csh{xintiiDivTrunc}}\label{xintiiDivTrunc}
|\xintiiDivTrunc|\m\n\etype{ff} computes $trunc(M/N)$. For positive arguments
$M,N>0$ it is the same as the Euclidean quotient \csbxint{iiQuo}.
\begin{everbatim*}
\xintiiQuo{1000}{57} (Euclidean), \xintiiDivTrunc{1000}{57} (truncated),
\xintiiDivRound{1000}{57} (rounded)\newline
\xintiiQuo{-1000}{57}, \xintiiDivTrunc{-1000}{57} (t), \xintiiDivRound{-1000}{57} (r)
\newline
\xintiiQuo{1000}{-57}, \xintiiDivTrunc{1000}{-57} (t), \xintiiDivRound{1000}{-57} (r)
\newline
\xintiiQuo{-1000}{-57}, \xintiiDivTrunc{-1000}{-57} (t), \xintiiDivRound{-1000}{-57} (r)
\par
\end{everbatim*}
\subsection{\csh{xintiiDivFloor}}\label{xintiiDivFloor}
|\xintiiDivFloor|\m\n\etype{ff} computes $floor(M/N)$. For positive divisor
$N>0$ and arbitrary dividend $M$ it is the same as the Euclidean quotient
\csbxint{iiQuo}.
\begin{everbatim*}
\xintiiQuo{1000}{57} (Euclidean), \xintiiDivFloor{1000}{57} (floored)\newline
\xintiiQuo{-1000}{57}, \xintiiDivFloor{-1000}{57}\newline
\xintiiQuo{1000}{-57}, \xintiiDivFloor{1000}{-57}\newline
\xintiiQuo{-1000}{-57}, \xintiiDivFloor{-1000}{-57}\par
\end{everbatim*}
\subsection{\csh{xintiiMod}}\label{xintiiMod}
|\xintiiMod|\m\n\etype{ff} computes $M - N*floor(M/N)$. For positive divisor
$N>0$ and arbitrary dividend $M$ it is the same as the Euclidean remainder
\csbxint{iiRem}.
Formerly, this macro computed $M - N*trunc(M/N)$. The former meaning is
retained as \csa{xintiiModTrunc}.
\begin{everbatim*}
\xintiiRem {1000}{57} (Euclidean), \xintiiMod {1000}{57} (floored),
\xintiiModTrunc {1000}{57} (truncated)\newline
\xintiiRem {-1000}{57}, \xintiiMod {-1000}{57}, \xintiiModTrunc {-1000}{57}\newline
\xintiiRem {1000}{-57}, \xintiiMod {1000}{-57}, \xintiiModTrunc {1000}{-57}\newline
\xintiiRem {-1000}{-57}, \xintiiMod {-1000}{-57}, \xintiiModTrunc {-1000}{-57}\par
\end{everbatim*}
\subsection{\csh{xintNum}}\label{xintNum}
|\xintNum|\etype{f} is originally an alias for \csbxint{iNum}. But with
\xintfracname loaded its meaning is \hyperref[xintNumFrac]{modified} to accept
more general inputs. It then becomes an alias to \csbxint{TTrunc} which
truncates the general input to an integer in strict format.
\clearpage
\let\xintcorenameUp\undefined
\csname xintnameUp\endcsname
\def\n{|{N}|}
\def\m{|{M}|}
\def\x{|{x}|}
\section{Macros of the \xintname package}
\RaisedLabel{sec:xint}
\etocsetnexttocdepth{subsubsection}
\localtableofcontents
\subsection{Introduction}
This package loads automatically \xintcorename (and \xintkernelname) hence
all macros described in \autoref{sec:core} are still available.
This is \texttt{\xintbndlversion} of
\texttt{\xintbndldate}.
Version |1.0| was released |2013/03/28|.
Since |1.1 2014/10/28| the core arithmetic macros have been moved to a separate
package \xintcorename, which is automatically loaded by \xintname.
Only the \csbxint{iiSum}, \csbxint{iiPrd}, \csbxint{iiSquareRoot},
\csbxint{iiSqrt}, \csbxint{iiSqrtR},
\csbxint{iiPFactorial}, \csbxint{iiBinomial} genuinely add to the arithmetic
macros from \xintcorename. (\csbxint{iiFac} which computes factorials is
already in \xintcorename.)
With the exception of \csbxint{Len}, of the \myenquote{Boolean logic macros} (see
next paragraphs) all macros require inputs being integers in strict format, see \autoref{ssec:inputs}.%
%
\footnote{of
course for conditionals such as \csbxint{iiifCmp} this constraint applies only
to the first two arguments.}
%
The |ii| in the macro names is here as a reminder of that fact. The output is
an integer in strict format, or a pair of two braced such integers for
\csbxint{iiSquareRoot}, with the exception of \csbxint{iiE} which may produce
strings of zero's if its first argument is zero.
Macros \csbxint{DecSplit} and \csbxint{ReverseDigits} are non-arithmetic and
have their own specific rules.
For all macros described here for which it makes sense, package \xintfracname
defines a similar one without |ii| in its name. This will handle more general
inputs: decimal, scientific numbers, fractions. The |ii| macros provided here
by \xintname can be nested inside macros of \xintfracname but the opposite
does not apply, because the output format of the \xintfracname macros, even
for representing integers, is not understood by the |ii| macros. The \myenquote{Boolean
macros} \csbxint{AND} etc...\@{} are exceptions though, they work fine if served
as inputs some \xintfracname output, despite doing only \fexpan
sion. Prior to |1.2o|, these macros did apply the \csbxint{Num}
or the more general \xintfracname general parsing, but this overhead was
deemed superfluous as it serves only to handle hand-written input and is not
needed if the input is obtained as a nested chain of \xintfracname macros for
example.
Prior to release |1.2o|, \xintname defined additional macros which applied
\csbxint{Num} to their input arguments. All these macros were deprecated at
|1.2o| and have been removed at |1.3|.
At |1.3d| macros \csbxint{iiGCD} and \csbxint{iiLCM} from package \xintgcdname
are also available from loading \xintname only. They are support macros for
the (multi-arguments) functions \func{gcd} and \func{lcm} in \csbxint{iiexpr}.
See \autoref{ssec:expansions} for the significance of the
\textcolor[named]{PineGreen}{\Numf}, \textcolor[named]{PineGreen}{\emph{f}},
\textcolor[named]{PineGreen}{\numx} and \textcolor[named]{PineGreen}{$\star$}
margin annotations.
\subsection{\csh{xintiLen}}\label{xintiLen}
|\xintiLen|\n\etype{\Numf} returns the length of the number, after its parsing
via \csbxint{iNum}. The count does not include the sign.
\begin{everbatim*}
\xintiLen{-12345678901234567890123456789}
\end{everbatim*}
Prior to |1.2o|, the package defined only \csbxint{Len}, which is extended by
\xintfracname to fractions or decimal numbers, hence acquires a bit more
overhead then.
\subsection{\csh{xintReverseDigits}} \label{xintReverseDigits}
\the\dp\strutbox, \the\ht\strutbox, \the\baselineskip
|\xintReverseDigits|\n\etype{f} will reverse the order of the digits of the
number. \csa{xintRev} is the former denomination and is kept as an alias.
Leading zeroes resulting from the operation are not removed. Contrarily to
\csbxint{ReverseOrder} this macro \fexpan ds its argument; it is only usable
with digit tokens. It does \emph{not} apply \csbxint{Num} to its argument (so
this must be done explicitely if the argument is an integer produced from some
\xintfracname macros). It does accept a leading minus sign which will be left
upfront in the output.
\begingroup
\begin{everbatim*}
\oodef\x{\xintReverseDigits
{98765432109876543210987654321098765432109876543210}}\meaning\x\par
\noindent\oodef\x{\xintReverseDigits {\xintReverseDigits
{98765432109876543210987654321098765432109876543210}}}\meaning\x\par
\end{everbatim*}
\endgroup
\subsection{\csh{xintDecSplit}}
\label{xintDecSplit}
|\xintDecSplit|\x\n\etype{\numx f} cuts the |N| (a list of digits) into two
pieces |L| and |R|: it outputs |{L}{R}| where the original |N|
is the concatenation |LR|. These two pieces are decided according to |x|:
\begin{itemize}[nosep]
\item for |x>0|, |R| coincides with the |x| least significant digits. If |x|
equals or exceeds the length of |N| the first piece |L| will thus be
\emph{empty},
\item for |x=0|, |R| is empty, and |L| is all of |N|,
\item for |x<0|, the first piece |L| consists of the \verb+|x|+ most
significant digits and the second piece |R| gets the remaining ones. If |x|
equals or exceeds the length of |N| the second piece |R| will thus be
\emph{empty}.
\end{itemize}
This macro provides public interface to some functionality which is primarily
of internal interest. It operates only (after \fexpan sion) on ``strings'' of
digits tokens: leading zeroes are allowed but a leading sign (even a minus
sign) will provoke an error.
Breaking change with |1.2i|: formerly |N<0| was replaced by its
absolute value. Now, a sign (positive or negative) will create an error.
\subsection{\csh{xintDecSplitL}, \csh{xintDecSplitR}}
\label{xintDecSplitL}
\label{xintDecSplitR}
|\xintDecSplitL|\x\n\etype{\numx f} returns the first piece (unbraced) from
the \csa{xintDecSplit} output.
\noindent|\xintDecSplitR|\x\n\etype{\numx f} returns the second piece
(unbraced) from the \csa{xintDecSplit} output.
\subsection{\csh{xintiiE}}\label{xintiiE}
|\xintiiE|\n\x\etype{f\numx } serves to extend |N| with |x| zeroes. The
parameter |x| must be non-negative. The same output would be obtained via
\csbxint{DSH}|{-x}{N}|, except for |N=0|, as |\xintDSH{-x}{N}| multiplies |N|
by |10^x| hence produces |0| if |N=0| whereas
|\xintiiE{0}{x}| produces |x+1| zeros.
\begin{everbatim*}
\xintiiE {0}{91}\par
\end{everbatim*}
\subsection{\csh{xintDSH}}\label{xintDSH}
|\xintDSH|\x\n\etype{\numx f} is parametrized decimal shift. When |x| is
negative, it is like iterating \csbxint{DSL} \verb+|x|+ times (\emph{i.e.\@}
multiplication by $10^{-x}$). When |x| positive, it is like iterating
\csbxint{DSR} |x| times (and is more efficient), and for a non-negative |N|
this is thus the same as the quotient from the Euclidean division by |10^x|.
\subsection{\csh{xintDSHr}, \csh{xintDSx}}\label{xintDSHr}\label{xintDSx}
|\xintDSHr|\x\n\etype{\numx f} expects |x| to be zero or positive and it
returns then a value |R| which is correlated to the value |Q| returned by
\csbxint{DSH}\x\n{} in the following manner:
\begin{itemize}
\item if |N| is
positive or zero, |Q| and |R| are the quotient and remainder in
the Euclidean division by |10^x| (obtained in a more efficient
manner than using \csa{xintiiDivision}),
\item if |N| is negative let
|Q1| and |R1| be the quotient and remainder in the Euclidean
division by |10^x| of the absolute value of |N|. If |Q1|
does not vanish, then |Q=-Q1| and |R=R1|. If |Q1| vanishes, then
|Q=0| and |R=-R1|.
\item for |x=0|, |Q=N| and |R=0|.
\end{itemize}
So one has |N = 10^x Q + R| if |Q| turns out to be zero or
positive, and |N = 10^x Q - R| if |Q| turns out to be negative,
which is exactly the case when |N| is at most |-10^x|.
|\xintDSx|\x\n\etype{\numx f} for |x| negative is exactly as
|\xintDSH|\x\n, \emph{i.e.\@} multiplication by $10^{-\text{|x|}}$. For |x| zero or
positive it returns the two numbers |{Q}{R}| described above, each one within
braces. So |Q| is |\xintDSH|\x\n, and |R| is |\xintDSHr|\x\n, but computed
simultaneously.
\subsection{\csh{xintiiEq}}\label{xintiiEq}
|\xintiiEq|\n\m\etype{ff} returns 1 if |N=M|, 0 otherwise.
\subsection{\csh{xintiiNotEq}}\label{xintiiNotEq}
|\xintiiNotEq|\n\m\etype{ff} returns 0 if |N=M|, 1 otherwise.
\subsection{\csh{xintiiGeq}}\label{xintiiGeq}
|\xintiiGeq|\n\m\etype{ff} returns 1 if the \emph{absolute value}
of the first number is at least equal to the absolute value of the second
number. If \verb+|N|<|M|+ it returns 0.
Important: the macro compares \emph{absolute values}.
\subsection{\csh{xintiiGt}}\label{xintiiGt}
|\xintiiGt|\n\m\etype{ff} returns 1 if |N|$>$|M|, 0 otherwise.
\subsection{\csh{xintiiLt}}\label{xintiiLt}
|\xintiiLt|\n\m\etype{ff} returns 1 if |N|$<$|M|, 0 otherwise.
\subsection{\csh{xintiiGtorEq}}\label{xintiiGtorEq}
|\xintiiGtorEq|\n\m\etype{ff} returns 1 if |N|$\geqslant$|M|, 0 otherwise.
Extended by \xintfracname to fractions.
\subsection{\csh{xintiiLtorEq}}\label{xintiiLtorEq}
|\xintiiLtorEq|\n\m\etype{ff} returns 1 if |N|$\leqslant$|M|, 0 otherwise.
\subsection{\csh{xintiiIsZero}}\label{xintiiIsZero}
|\xintiiIsZero|\n\etype{f} returns 1 if |N=0|, 0 otherwise.
\subsection{\csh{xintiiIsNotZero}}\label{xintiiIsNotZero}
|\xintiiIsNotZero|\n\etype{f} returns 1 if |N!=0|, 0 otherwise.
\subsection{\csh{xintiiIsOne}}\label{xintiiIsOne}
|\xintiiIsOne|\n\etype{f} returns 1 if |N=1|, 0 otherwise.
\subsection{\csh{xintiiOdd}}\label{xintiiOdd}
|\xintiiOdd|\n\etype{f} is 1 if the number is odd and 0 otherwise.
\subsection{\csh{xintiiEven}}\label{xintiiEven}
|\xintiiEven|\n\etype{f} is 1 if the number is even and 0 otherwise.
\subsection{\csh{xintiiMON}}\label{xintiiMON}
|\xintiiMON|\n\etype{f} computes |(-1)^N|.
\begin{everbatim*}
\xintiiMON {-280914019374101929}
\end{everbatim*}
\subsection{\csh{xintiiMMON}}\label{xintiiMMON}
|\xintiiMMON|\n\etype{f} computes |(-1)^{N-1}|.
\begin{everbatim*}
\xintiiMMON {280914019374101929}
\end{everbatim*}
\subsection{\csh{xintiiifSgn}}\label{xintiiifSgn}
\csh{xintiiifSgn}\marg{N}\marg{A}\marg{B}\marg{C}\etype{fnnn} executes either
the \meta{A}, \meta{B} or \meta{C} code, depending on its first argument being
respectively negative, zero, or positive.
\subsection{\csh{xintiiifZero}}\label{xintiiifZero}
\csa{xintiiifZero}\marg{N}\marg{IsZero}\marg{IsNotZero}\etype{fnn} expandably
checks if the first mandatory argument |N| (a number, possibly a fraction if
\xintfracname is loaded, or a macro expanding to one such) is zero or not. It
then either executes the first or the second branch.
Beware that both branches must be present.
\subsection{\csh{xintiiifNotZero}}\label{xintiiifNotZero}
\csa{xintiiifNotZero}\marg{N}\marg{IsNotZero}\marg{IsZero}\etype{fnn}
expandably checks if the first mandatory argument |N| is not
zero or is zero. It then either executes the first or the second branch.
Beware that both branches must be present.
\subsection{\csh{xintiiifOne}}\label{xintiiifOne}
\csa{xintiiifOne}\marg{N}\marg{IsOne}\marg{IsNotOne}\etype{fnn} expandably
checks if the first mandatory argument |N| is one or not one. It
then either executes the first or the second branch. Beware that both branches
must be present.
\subsection{\csh{xintiiifCmp}}\label{xintiiifCmp}
\csa{xintiiifCmp}\marg{A}\marg{B}\marg{AB}\etype{ffnnn}
compares its first two arguments and chooses accordingly the correct branch.
\subsection{\csh{xintiiifEq}}\label{xintiiifEq}
\csa{xintiiifEq}\marg{A}\marg{B}\marg{A=B}\marg{not(A=B)}\etype{ffnn} checks
equality of its two first arguments and executes the corresponding branch.
\subsection{\csh{xintiiifGt}}\label{xintiiifGt}
\csa{xintiiifGt}\marg{A}\marg{B}\marg{A>B}\marg{not(A>B)}\etype{ffnn}
checks if $A>B$ and executes the corresponding branch.
\subsection{\csh{xintiiifLt}}\label{xintiiifLt}
\csa{xintiiifLt}\marg{A}\marg{B}\marg{A0| and |M^2-d=N| with
|M| the smallest (hence if |N=k^2| is a perfect square then |M=k+1|, |d=2k+1|).
\begin{everbatim*}
\xintAssign\xintiiSquareRoot {17000000000000000000000000}\to\A\B
\xintiiSub{\xintiiSqr\A}\B=\A\string^2-\B
\end{everbatim*}
A rational approximation to $\sqrt{\text{|N|}}$ is
$\text{|M|}-\frac{\text{|d|}}{\text{|2M|}}$ which is a majorant and the error
is at most |1/2M| (if |N| is a perfect square |k^2| this gives |k+1/(2k+2)|,
not |k|.)
Package \xintfracname has \csbxint{FloatSqrt} for square roots of floating
point numbers.
\subsection{\csh{xintiiSqrt}, \csh{xintiiSqrtR}}
\label{xintiiSqrt}\label{xintiiSqrtR}
\noindent|\xintiiSqrt|\n\ computes the largest integer whose square
is at most equal to |N|.\etype{f} |\xintiiSqrtR|
produces the rounded, not truncated, square root.\etype{f}
\begin{everbatim*}
\begin{itemize}[nosep]
\item \xintiiSqrt {3000000000000000000000000000000000000}
\item \xintiiSqrtR {3000000000000000000000000000000000000}
\item \xintiiSqrt {\xintiiE {3}{100}}
\end{itemize}
\end{everbatim*}
\subsection{\csh{xintiiBinomial}}\label{xintiiBinomial}
|\xintiiBinomial{x}{y}|\etype{\numx\numx} computes binomial coefficients.
If |x<0| an out-of-range error is raised. Else, if |y<0| or if |x99999999$, or even
$x\geqslant 2^{31}$, but $y$ is not too large, one may use an ad hoc function
definition such as:
\begin{everbatim*}
\xintdeffunc mybigbinomial(x,y):=`*`(x-y+1..[1]..x)//y!;%
% without [1], x would have been limited to < 2^31
\printnumber{\xinttheexpr mybigbinomial(98765432109876543210,10)\relax}
\end{everbatim*}
To get this functionality in macro form, one can do:
\begin{everbatim*}
\xintNewIIExpr\MyBigBinomial [2]{`*`(#1-#2+1..[1]..#1)//#2!}
\printnumber{\MyBigBinomial {98765432109876543210}{10}}
\end{everbatim*}
As we used \csa{xintNewIIExpr}, this macro will only accept strict integers.
Had we used \csa{xintNewExpr} the |\MyBigBinomial| would have accepted general
fractions or decimal numbers, and computed the product at the numerator
without truncating them to integers; but the factorial at the denominator
would truncate its argument.
\subsection{\csh{xintiiPFactorial}}\label{xintiiPFactorial}
|\xintiiPFactorial{a}{b}|\etype{\numx\numx} computes the partial factorial
|(a+1)(a+2)...b|. For |a=b| the product is considered empty hence returns |1|.
%\begin{framed}
The allowed range
%
%
%
is $-100000000\leqslant a, b\leqslant99999999$.
The
rule is to interpret the formula as the product of the
$j$'s such that $ab$ or negative arguments, the definitive rules have not yet
been fixed.
\begin{everbatim*}
\xintiiPFactorial {100}{130}
\end{everbatim*}
%\end{framed}
This theoretical range allows computations whose result values would have more
than the roughly 19950 digits that the arithmetics of \xintname can handle. In
such cases, the computation will end up in a low-level \TeX{} error after a
long time.
The |pfactorial| function is available in the \xintexprname parsers.
\begin{everbatim*}
\xinttheiiexpr pfactorial(100,130)\relax
\end{everbatim*}
See \csbxint{FloatPFactorial} from package \xintfracname for the float
variant, used in \csbxint{floatexpr}.
In case values are needed with $b>99999999$, or even $b\geqslant 2^{31}$, but
$b-a$ is not too large, one may use an ad hoc function definition such as:
\begin{everbatim*}
\xintdeffunc mybigpfac(a,b):=`*`(a+1..[1]..b);%
% without [1], b would have been limited to < 2^31
\printnumber{\xinttheexpr mybigpfac(98765432100,98765432120)\relax}
\end{everbatim*}
\subsection{\csh{xintiiMax}}\label{xintiiMax}
|\xintiiMax|\n\m\etype{ff} returns the largest of the two in the sense
of the order structure on the relative integers (\emph{i.e.\@} the right-most
number if they are put on a line with positive numbers on the right):
|\xintiiMax {-5}{-6}|\dtt{=\xintiiMax{-5}{-6}}.
\subsection{\csh{xintiiMin}}\label{xintiiMin}
|\xintiiMin|\n\m\etype{ff} returns the smallest of the two in the sense of the
order structure on the relative integers (\emph{i.e.\@} the left-most number if
they are put on a line with positive numbers on the right): |\xintiiMin
{-5}{-6}|\dtt{=\xintiiMin{-5}{-6}}.
\subsection{\csh{xintiiMaxof}}\label{xintiiMaxof}
\csa{xintiiMaxof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns the
maximum. The list argument may be a macro, it is \fexpan ded first.
\subsection{\csh{xintiiMinof}}\label{xintiiMinof}
\csa{xintiiMinof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns the
minimum. The list argument may be a macro, it is \fexpan ded first.
\subsection{\csh{xintifTrueAelseB}}
\label{xintifTrueAelseB}
\csa{xintifTrueAelseB}\marg{f}\marg{true branch}\marg{false branch}\etype{fnn}
is a synonym for \csbxint{iiifNotZero}.
{\small
\noindent |\xintiiifnotzero| is lowercase companion macro.\par }
Note 1: as it does only \fexpan sion on its argument it fails with inputs such
as |--0|. But with \xintfracname loaded, it does work fine if nested with
other \xintfracname macros, because the output format of such macros is fine
as input to \csbxint{iiifNotZero}. This remark applies to all other \myenquote{Boolean
logic} macros next.
Note 2: prior to |1.2o| this macro was using \csbxint{ifNotZero} which applies
\csbxint{Num} to its argument (or gets redefined by \xintfracname to handle
general decimal numbers or fractions). Hence it would have
worked with input such as |--0|. But it was decided at |1.2o| that the
overhead was not worth it. The same remark applies to the other \myenquote{Boolean
logic} type macros next.
\subsection{\csh{xintifFalseAelseB}}
\label{xintifFalseAelseB}
\csa{xintifFalseAelseB}\marg{f}\marg{false branch}\marg{true
branch}\etype{fnn} is a synonym for \csbxint{iiifZero}.
{\small
\noindent |\xintiiifzero| is lowercase companion macro.\par }
\subsection{\csh{xintNOT}}\label{xintNOT}
\csa{xintNOT}\etype{f} is a synonym for \csa{xintiiIsZero}.
{\small |\xintiiiszero| serves as lowercase companion macro.\par}
\subsection{\csh{xintAND}}\label{xintAND}
|\xintAND{f}{g}|\etype{ff} returns \dtt{1} if |f!=0| and |g!=0| and \dtt{0}
otherwise.
\subsection{\csh{xintOR}}\label{xintOR}
|\xintOR{f}{g}|\etype{ff} returns \dtt{1} if |f!=0| or |g!=0| and \dtt{0}
otherwise.
\subsection{\csh{xintXOR}}\label{xintXOR}
|\xintXOR{f}{g}|\etype{ff} returns \dtt{1} if exactly one of |f| or |g|
is true (i.e.\@{} non-zero), else \dtt{0}.
\subsection{\csh{xintANDof}}\label{xintANDof}
\csa{xintANDof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns \dtt{1} if
all are true (i.e.\@{} non zero) and \dtt{0} otherwise. The list argument may be a
macro, it (or rather its first token) is \fexpan ded first to deliver its
items.
\subsection{\csh{xintORof}}\label{xintORof}
\csa{xintORof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns \dtt{1} if at
least one is true (i.e.\@{} does not vanish), else it produces \dtt{0}. The list
argument may be a macro, it is \fexpan ded first.
\subsection{\csh{xintXORof}}\label{xintXORof}
\csa{xintXORof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns \dtt{1} if an
odd number of them are true (i.e.\@{} do not vanish), else it produces \dtt{0}.
The list argument may be a macro, it is \fexpan ded first.
\subsection{\csh{xintiiGCD}}
\label{xintiiGCD}
|\xintiiGCD|\n\m\etype{ff} computes the greatest common divisor. It is
positive, except when both |N| and |M| vanish, in which case the macro returns
zero.
%
\leftedline{\csa{xintiiGCD}|{10000}{1113}|\dtt{=\xintiiGCD{10000}{1113}}}
%
\leftedline{|\xintiiGCD{123456789012345}{9876543210321}=|\dtt
{\xintiiGCD{123456789012345}{9876543210321}}}
At |1.3d|, this macro (which is used by the \func{gcd} function in
\csbxint{iiexpr}) was copied over to \xintname, thus removing a partial
dependency of \xintexprname on \xintgcdname.
At |1.4| \xintgcdname requires \xintname and the latter is thus the one
providing the macro.
\subsection{\csh{xintiiLCM}}
\label{xintiiLCM}
|\xintiiLCM|\n\m\etype{ff} computes the least common multiple. It is positive,
except if one of |N| or |M| vanish, in which case the macro returns zero.
%
\leftedline{\csa{xintiiLCM}|{10000}{1113}|\dtt{=\xintiiLCM{10000}{1113}}}
%
\leftedline{|\xintiiLCM{123456789012345}{9876543210321}=|\dtt
{\xintiiLCM{123456789012345}{9876543210321}}}
At |1.3d|, this macro (which is used by the \func{lcm} function in
\csbxint{iiexpr}) was copied over to \xintname, thus removing a partial
dependency of \xintexprname on \xintgcdname.
At |1.4| \xintgcdname requires \xintname and the latter is thus the one
providing the macro.
\subsection{\csh{xintiiGCDof}}\label{xintiiGCDof}
\csa{xintiiGCDof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast f}} computes the
greatest common divisor of the integers |a|, |b|, \dots{}. It is a support
macro for the |gcd()| function of the \csbxint{iiexpr} parser.
It replaces the \csbxint{GCDof} which was formerly provided by \xintgcdname
and is now available via \xintfracname in a version handling also
fractions.
\subsection{\csh{xintiiLCMof}}\label{xintiiLCMof}
\csa{xintiiLCMof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast f}} computes the
least common multiple of the integers |a|, |b|, \dots{}. It is a support
macro for the |lcm()| function of the \csbxint{iiexpr} parser.
It replaces the \csbxint{LCMof} which was formerly provided by \xintgcdname
and is now available via \xintfracname in a version handling also
fractions.
\subsection{\csh{xintLen}}\label{xintLen}
|\xintLen|\etype{\Numf} is originally an alias for \csbxint{iLen}. But with
\xintfracname loaded its meaning is \hyperref[xintLenFrac]{modified} to accept
more general inputs.
\subsection{(WIP) \csh{xintRandomDigits}}\label{xintRandomDigits}
\begin{framed}
All randomness related macros are Work-In-Progress: implementation and user
interface may change. They work only if the \TeX\ engine provides the
\csa{uniformdeviate} or \csa{pdfuniformdeviate} primitive. See
\csbxint{UniformDeviate} for additional information.
\end{framed}
|\xintRandomDigits{N}|\etype{\numx} expands in two steps to |N| random decimal
digits. The argument must be non-negative and is limited by \TeX\ memory
parameters.
On \TeX Live 2018 with input save stack size at \dtt{5000} the
maximal allowed |N| is at most \dtt{19984} (tested within a |\write| to an
auxiliary file, the macro context may cause a reduced maximum).
\begin{everbatim*}
\xintsetrandomseed 271828182
\xintRandomDigits{92}
\end{everbatim*}
\begin{TeXnote}
the digits are produced eight by eight by the same method which would result
from \csbxint{UniformDeviate}|{100000000}| but with less overhead.
\end{TeXnote}
% \subsection{\csh{\xintOneRandomDigit}}\label{xintOneRandomDigit}
\subsection{(WIP) \csh{xintXRandomDigits}}\label{xintXRandomDigits}
|\xintXRandomDigits{N}|\xtype{\numx} expands under exhaustive expansion
(|\edef|, |\write|, |\csname| ...) to |N| random decimal
digits. The argument must be non-negative.
For example:
\begin{everbatim}
\newwrite\out
\immediate\openout\out=\jobname-out.txt
\immediate\write\out{\xintXRandomDigits{4500000}}
\immediate\closeout\out
\end{everbatim}
creates a \dtt{4500001} bytes file (it ends with a line feed character).
Trying with \dtt{5000000} raises this error:
\begin{everbatim}
Runaway text?
588875947168511582764514135070217555354479805240439407753451354223283\ETC.
! TeX capacity exceeded, sorry [main memory size=5000000].
666515098
l.15 ...ate\write\out{\xintXRandomDigits{5000000}}
No pages of output.
Transcript written on temp.log.
\end{everbatim}
This can be lifted by increasing the \TeX\ memory settings (installation
dependent).
\begin{TeXnote}
the digits are produced eight by eight by the same method which would result
from \csbxint{UniformDeviate}|{100000000}| but with less overhead.
\end{TeXnote}
\subsection{(WIP) \csh{xintiiRandRange}}\label{xintiiRandRange}
|\xintiiRandRange{A}|\etype{f} expands to a random (big) integer |N|
such that |0<=N8|, if we proceed
immediately after having set the seed. If we add some entropy in any way, then
it is slightly more credible; but I think that for each seed the period is
something like |2^{27}(2^{55}-1)55|,%
%
\footnote{Compare the result of exercise 3.2.2-30 in TAOCP, vol II.}
%
so we expect at most about |2^{110}55|
``points in time'', and this is already small compared to the |10^40|
from example above. Thus already we are very far from being intrinsically
able to generate all numbers with forty digits as random numbers, and this
makes the previous section about usage of \csbxint{XRandomDigits} to generate
millions of digits a bit comical...
\begin{TeXnote}
the digits are produced eight by eight by the same method which would result
from \csbxint{UniformDeviate}|{100000000}| but with less overhead.
\end{TeXnote}
\subsection{(WIP) \csh{xintiiRandRangeAtoB}}\label{xintiiRandRangeAtoB}
|\xintiiRandRangeAtoB{A}{B}|\etype{ff} expands to a random (big) integer |N|
such that |A<=N| part, if actually present, into
|\cdot 10^{exponent}|. A fractional part |/B| if found in the expansion
of the input must be last and will be tranformed into |\cdot B^{-1}| if
there was a scientific part, else the output will be using |\frac{A}{B}|
(or the \TeX\ equivalent in place of |\frac|) with |A| the numerator.
\begin{TeXnote}
\begin{itemize}
\item I am hesitating whether the |\frac{A}{B}| branch choice should
require |A| to be an integer, or will also, as currently, be done
with |A| being a number in decimal notation. Please advise.
\item The package does:
\begin{everbatim}
\ifdefined\frac
\protected\def\xintTeXFromScifracmacro#1#2{\frac{#2}{#1}}%
\else
\protected\def\xintTeXFromScifracmacro#1#2{{#2\over#1}}%
\fi
\end{everbatim}
Customize as desired. Notice the interversion of arguments.
\end{itemize}
\end{TeXnote}
Example:
\begin{everbatim*}
$\xintTeXFromSci{\xintfloateval{1.1^10000/5}}$,
$\xintTeXFromSci{\xinteval{1.1^10000/5}}$\par
\end{everbatim*}
The above examples are in the case of a single numerical value. To
handle more complex outputs from \csbxint{eval} or \csbxint{floateval}
one will need to proceed via a redefinition of
\csbxint{floatexprPrintOne} and/or \csbxint{exprPrintOne} like this:
\begin{everbatim*}
\[\def\xintfloatexprPrintOne[#1]#2{\xintTeXFromSci{\xintPFloat[#1]{#2}}}
\xintfloateval[10]{2^100, 3^100, 13^100}\]
\end{everbatim*}
\par\vskip-\belowdisplayskip
\begin{everbatim*}
\[\def\xintexprPrintOne#1{\xintTeXFromSci{\xintFracToSci{#1}}}
\xinteval{sqrt(2^101,60), 355/113, 6.02e23/1000}\]
\end{everbatim*}% attention à l'espace TeX est en mode horizontal après display
This will however make then impossible, due to the added \TeX\ mark-up in the
output, the nesting of \csbxint{floateval}/\csbxint{eval} inside one another.
The core \csbxint{expr}|...\relax| syntax remains usable and is anyhow the
recommended way for such nesting as it is more efficient.
Some similar effect is also possible without \csbxint{TeXFromSci},
simply by a customization of \csbxint{PFloatE} like this:
\begin{everbatim*}
\begingroup
\def\xintPFloatE#1.{\cdot10^{#1}.}%
$\xintfloateval{1.1^10000/5}$, $\xinteval{1.1^10000/5}$
\endgroup\newline
\end{everbatim*}%
This method is simpler-minded but will leave the trailing |/B|'s \myenquote{as
is}, even if the numerator has no scientific exponent part. The
presence of extra \TeX\ mark-up in the output has the consequences
on nesting which were mentioned above.
\subsection{\csh{xintTeXFrac}}\label{xintTeXFrac}
This is a typesetting \LaTeX{} only macro\etype{\Ff}, math mode only as it
expands to |\frac{A}{B}10^n| for an input which ends up parsed into raw
format |A/B[n]|.
If the denominator |B| is \dtt{1}, the output is |A\cdot 10^n|. If the
exponent |n| is \dtt{0}, the |[\cdot]10^n| part is omitted.
\begin{everbatim*}
$\xintTeXFrac {178.000/25600000}$, $\xintTeXFrac {178.000/1}$,
$\xintTeXFrac {3.5/5.7}$\newline
\end{everbatim*}%
The input, if in a fraction form, is not simplified in any way, except for
transforming numerator and denominator into integers, separating a power of
ten part. Macros such as \csbxint{Irr}, \csbxint{PIrr}, \csbxint{REZ} can be
inserted to wrap the input and help simplify it. The minus sign ends up in
the numerator.
It is the new name since |1.4g| of |\xintFrac|. The old name now raises
a \TeX{} error.\CHANGED{1.4m}
\subsection{\csh{xintTeXsignedFrac}}\label{xintTeXsignedFrac}
This is as \csbxint{TeXFrac}\etype{\Ff} except that a negative fraction has the
sign ending up in front, not in the numerator.
\begin{everbatim*}
$\xintTeXFrac {-355/113}=\xintTeXsignedFrac {-355/113}$\newline
\end{everbatim*}%
It is the new name since |1.4g| of |\xintSignedFrac|. The old name now raises
a \TeX{} error.\CHANGED{1.4m}
\subsection{\csh{xintTeXOver}}\label{xintTeXOver}
This does the same as \csa{xintTeXFrac}\etype{\Ff} except that the \csa{over}
primitive is used for the fraction (in case the denominator is not one; and a
pair of braces contains the |A\over B| part).
\begin{everbatim*}
$\xintTeXOver {178.000/25600000}$, $\xintTeXOver {178.000/1}$,
$\xintTeXOver {3.5/5.7}$\newline
\end{everbatim*}%
It is the new name since |1.4g| of |\xintFwOver|. The old name now raises
a \TeX{} error.\CHANGED{1.4m}
\subsection{\csh{xintTeXsignedOver}}\label{xintTeXsignedOver}
This is as \csbxint{TeXOver}\etype{\Ff} except that a negative fraction has the
sign put in front, not in the numerator.
\begin{everbatim*}
$\xintTeXOver{-355/113}=\xintTeXsignedOver{-355/113}$\newline
\end{everbatim*}%
It is the new name since |1.4g| of |\xintSignedFwOver|. The old name now raises
a \TeX{} error.\CHANGED{1.4m}
\subsection{\csh{xintLen}}\label{xintLenFrac}
The \csbxint{Len} macro\etype{\Ff} from \xintname is extended to accept a fraction
on input: the length of |A/B[n]| is the length of |A| plus the length of |B|
plus the absolute value of |n| and minus one (an integer input as |N| is
internally represented in a form equivalent to |N/1[0]| so the minus one means
that the extended \csa{xintLen} behaves the same as the original for
integers).
\begin{everbatim*}
\xintLen{201710/298219}=\xintLen{201710}+\xintLen{298219}-1\newline
\xintLen{1234/1}=\xintLen{1234}=\xintLen{1234[0]}=\xintiLen{1234}\newline
\xintLen{-1e3/5.425} (\xintRaw {-1e3/5.425})\par
\end{everbatim*}
The length is computed on the |A/B[n]| which would have been returned by
\csbxint{Raw}, as illustrated by the last example above.
|\xintLen| is only for use with such (scientific) numbers or fractions. See
also \csbxint{NthElt} from \xinttoolsname. See also \csbxint{Length} (which
however does not expand its argument) from \xintkernelname for counting more
general tokens (or rather braced items).
\subsection{\csh{xintNum}}\label{xintNumFrac}
The \csbxint{Num} \etype{\Ff} from \xintname is transformed into a synonym to
\csbxint{TTrunc}.
Attention that for example |\xintNum{1e100000}| expands to the needed
\dtt{100001} digits...
The original \hyperref[xintiNum]{\string\xintNum} from \xintcorename which
does not understand the fraction slash or the scientific notation is still
available under the name \csbxint{iNum}.
\subsection{\csh{xintRaw}}\label{xintRaw}
This macro `prints' the\etype{\Ff}
fraction |f| as it is received by the package after its parsing and
expansion, in a form |A/B[N]| equivalent to the internal
representation: the denominator |B| is always strictly positive and is
printed even if it has value |1|.
\begin{everbatim*}
\xintRaw{\the\numexpr 571*987\relax.123e-10/\the\numexpr-201+59\relax e-7}
\end{everbatim*}
No simplification is done, not even of common zeroes between numerator and
denominator:
\begin{everbatim*}
\xintRaw {178000/25600000}
\end{everbatim*}
\subsection{\csh{xintRawBraced}}\label{xintRawBraced}
This macro expands and parses its input\etype{\Ff} |f| as all
\xintfracname macros and produces as output |{N}{A}{B}| (with \TeX\
braces) where \csbxint{Raw} would have returned |A/B[N]|.
\subsection{\csh{xintNumerator}}\label{xintNumerator}
The input data\etype{\Ff} is parsed as if by \csbxint{Raw} into |A/B[N]|
and then |A| is returned if |N<=0|, or |A| extended by |N| zeroes if |N>0|.
\begin{everbatim*}
\xintNumerator {178000/25600000[17]}\newline
\xintNumerator {312.289001/20198.27}\newline
\xintNumerator {178000e-3/256e5}\newline
\xintNumerator {178.000/25600000}
\end{everbatim*}
\subsection{\csh{xintDenominator}}\label{xintDenominator}
The input data\etype{\Ff} is parsed as if by \csbxint{Raw} into |A/B[N]|
and then |B| is returned if |N>0|, or |B| extended by \verb+|N|+ zeroes if |N<=0|.
\begin{everbatim*}
\xintDenominator {178000/25600000[17]}\newline
\xintDenominator {312.289001/20198.27}\newline
\xintDenominator {178000e-3/256e5}\newline
\xintDenominator {178.000/25600000}
\end{everbatim*}
\subsection{\csh{xintRawWithZeros}}\label{xintRawWithZeros}
This macro parses the input\etype{\Ff} and outputs |A'/B'|, with |A'|
as would be returned by \csa{xintNumerator}|{f}| and |B'| as would be returned by
\csa{xintDenominator}|{f}|.
\begin{everbatim*}
\xintRawWithZeros{178000/25600000[17]}\newline
\xintRawWithZeros{312.289001/20198.27}\newline
\xintRawWithZeros{178000e-3/256e5}\newline
\xintRawWithZeros{178.000/25600000}\newline
\xintRawWithZeros{\the\numexpr 571*987\relax.123e-10/\the\numexpr-201+59\relax e-7}
\end{everbatim*}
\subsection{\csh{xintREZ}}\label{xintREZ}
The input\etype{\Ff} is first parsed into |A/B[N]| as by \csbxint{Raw}, then
trailing zeroes of |A| and |B| are suppressed and |N| is accordingly adjusted.
\begin{everbatim*}
\xintREZ {178000/25600000[17]}
\end{everbatim*}
\subsection{\csh{xintIrr}}\label{xintIrr}
This puts the fraction\etype{\Ff} into its unique irreducible form:
\begin{everbatim*}
\xintIrr {178.256/256.1780}, \xintIrr {178000/25600000[17]}
\end{everbatim*}
The current implementation does not cleverly first factor powers of
2 and 5, and |\xintIrr {2/3[100]}| will execute the
Euclidean division of |2|\raisebox{.5ex}{|.|}|10^{100}| by |3|, which is a bit
stupid as it could have known that the \dtt{100} trailing zeros can not bring
any divisibility by \dtt{3}.
Starting with release |1.08|, \csa{xintIrr} does not remove the trailing |/1|
when the output is an integer. This was deemed better for various (questionable?)
reasons, anyway the output format is since \emph{always} |A/B| with |B>0|, even
in cases where it turns out that |B=1|.
Use \csbxint{PRaw} on top of \csa{xintIrr} if it is needed to get rid of such a
trailing |/1|.
\subsection{\csh{xintPIrr}}\label{xintPIrr}
This puts the fraction\etype{\Ff} into irreducible form,
\emph{keeping as is the
decimal part} |[N]| from raw internal |A/B[N]| format.
(|P| stands here for \emph{Partial})
\begin{everbatim*}
\xintPIrr {178.256/256.1780}, \xintPIrr {178000/25600000[17]}
\end{everbatim*}
Notice that the output always has the ending |[N]|, which is exactly the
opposite of \csbxint{Irr}'s behaviour. The interest of this macro is mainly in
handling fractions which somehow acquired a big |[N]| (perhaps from input in
scientific notation) and for which the reduced fraction would have a very
large number of digits. This large number of digits can considerably slow-down
computations done afterwards.
For example package \href{http://ctan.org/pkg/polexpr}{polexpr} uses
\csa{xintPIrr} when differentiating a polynomial, or in setting up a Sturm
chain for localization of the real roots of a polynomial. This is relevant to
polynomials whose coefficients were input in decimal notation, as this
automatically creates internally some |[N]|. Keeping and combining those
|[N]|'s during computations significantly increases their speed.
\subsection{\csh{xintJrr}}\label{xintJrr}
This also puts the fraction\etype{\Ff} into its unique irreducible form:
\begin{everbatim*}
\xintJrr {178.256/256.178}
\end{everbatim*}
This is (supposedly, not tested for ages) faster than \csa{xintIrr} for
fractions having some big common factor in the numerator and the denominator.
\begin{everbatim*}
\xintJrr {\xintiiPow{\xintiiFac {15}}{3}/%
\xintiiPrd{{\xintiiFac{10}}{\xintiiFac{30}}{\xintiiFac{5}}}}
\end{everbatim*}
But to notice the difference one would need computations with much bigger
numbers than in this example. As \csbxint{Irr}, \csa{xintJrr} does not remove
the trailing |/1| from a fraction reduced to an integer.
\subsection{\csh{xintPRaw}}\label{xintPRaw}
|PRaw|\etype{\Ff} stands for ``pretty raw''. It does like \csbxint{Raw} apart
from removing the |[N]| part if |N=0| and removing the |B| if |B=1|.
\begin{everbatim*}
\xintPRaw {123e10/321e10}, \xintPRaw {123e9/321e10}, \xintPRaw {\xintIrr{861/123}}
\end{everbatim*}
\subsection{\csh{xintDecToStringREZ}}\label{xintDecToStringREZ}
\csa{xintDecToStringREZ}\etype{\Ff} uses fixed point (decimal) notation
for the output. The |REZ| means that it trims (REmoves) trailing Zeros. The name
is a bit strange, because it its not limited to
\emph{decimal numbers} but accepts the same kind of inputs as most other
\xintfracname macros. The parsing of this input transforms it first
into an internal format having a numerator |A|, a denominator |B| and a
power of ten exponent |N|, standing for the fraction |A/B| times
\dtt{10} to the power |N|. Then the following recipe applies:
\begin{itemize}[noitemsep]
\item the zero value is printed as \dtt{\xintDecToStringREZ{0}} (no decimal point).
\item trailing zeros of |A| and |B| are removed and |N| is adjusted,
\item if the new |B| is not \dtt{1}, it will appear in the output as |/B|,
\item fixed point decimal notation is used for |AeN|:
\begin{itemize}[noitemsep]
\item if |N| is non-negative, the output is an integer with |N| trailing
zeros (and no decimal mark)
\item if |N| is negative a decimal point is used, and if |AeN| is less than
one in absolute value, output will start with \dtt{0.} (i.e. a decimal mark).
\end{itemize}
\end{itemize}
The following should be noted:
\begin{enumerate}[noitemsep]
\item the fraction |AeN/B| or even |A/B| is not pre-reduced into lowest terms,
\item the macro does not check if |B| contains only powers of \dtt{2} and
\dtt{5}, so |1/2| is printed as \dtt{\xintDecToString{1/2}}, not as \dtt{0.5}.
\end{enumerate}
The definitive behaviour remains to be decided regarding these last two points.
\begin{everbatim*}
\xintDecToStringREZ{0}, \xintDecToStringREZ{1/2}, \xintDecToStringREZ{0.5000}\newline
\xintDecToStringREZ{1.23456789e5}, \xintDecToStringREZ {1.23456789e-3}\newline
\xintDecToStringREZ{12345e-1}, \xintDecToStringREZ {12345e-2},
\xintDecToStringREZ{12345e-3}\newline
\xintDecToStringREZ{12345e-4}, \xintDecToStringREZ {12345e-5},
\xintDecToStringREZ{12345e-6}\newline
\xintDecToStringREZ{1.234567890000e12}, \xintDecToStringREZ{1.23456000e-5/10}\newline
\xintDecToStringREZ{70/14} % is not reduced to lowest terms
\end{everbatim*}
See \csbxint{FloatToDecimal} for a variant which first rounds the input
to some given number of significant digits.
\subsection{\csh{xintDecToString}}\label{xintDecToString}
\csa{xintDecToString}\etype{\Ff} uses fixed point notation for the output.
Is behaviour remains
somewhat undecided in so far as whether it should identify inputs
which correspond to decimal numbers (i.e. fractions with only powers of
two and five in their denominator, once reduced to lowest terms).
As with \csbxint{DecToStringREZ}, the name is a bit strange as inputs are in no
way limited to decimal numbers but are of the most general type accepted by
the \xintfracname macros.
It is the same macro as \csbxint{DecToStringREZ} except that it does not
remove trailing zeros, in fact \csbxint{DecToStringREZ}|{f}| is defined as
\csbxint{DecToString}|{|\csbxint{REZ}|{f}}|.
\begin{everbatim*}
\xintDecToString{0}, \xintDecToString{1/2}, \xintDecToString{0.5000}\newline
\xintDecToString{1.23456789e5}, \xintDecToString {1.23456789e-3}\newline
\xintDecToString{12345e-1}, \xintDecToString {12345e-2}, \xintDecToString{12345e-3}%
\newline
\xintDecToString{12345e-4}, \xintDecToString {12345e-5}, \xintDecToString{12345e-6}%
\newline
\xintDecToString{1.234567890000e12}, \xintDecToString{1.23456000e-5/10}\newline
\xintDecToString{70/14}
\end{everbatim*}
Since |1.4e|, \csbxint{DecToString} is the default for
\csbxint{iexprPrintOne}, which governs the \csbxint{ieval} output format: in
this use case there is never a |/B| fractional part and the output is always
either an integer (if \csbxint{ieval} was used without optional argument) or a
decimal string
\begin{everbatim}
\def\xintiexprPrintOne{\xintDecToString}
\end{everbatim}
Any replacement of \csbxint{DecToString} as the expansion of
\csbxint{iexprPrintOne} should obey the following blueprint:
\begin{itemize}[noitemsep]
\item to\xtype{} be expandable, but not necessarily \fexpan dable,
\item to accept on input |A| or |A[N]|.
\end{itemize}
\subsection{\csh{xintFracToSci}}\label{xintFracToSci}
\csa{xintFracToSci}\etype{\Ff} was initially at |1.4| a private macro
which served as default customization of \csbxint{exprPrintOne} and,
despite being documented in the user manual, was not supposed to be used
at user level (not being \fexpan dable it could not be nested within
macros of \xintfracname, and besides accepted a limited range of
inputs).
It has been upgraded at |1.4l| to behave like all other \xintfracname
macros.
Here is what it does:
\begin{itemize}[noitemsep,nosep]
\item it first parses the input like any other \xintfracname macro and
convert it into the ``raw'' |A/B[N]| format,
\item it then produces this output: |A/B| if |N=0| (and |/B| is omitted
if not |1|), and for |N| not zero, the
output numerator will be |AeN| written in scientific notation exactly like it
would by \csbxint{PFloat} but without of course prior rounding to a
given number of digits; the trailing zeros in the
significand will be removed always (the \csbxint{PFloatMinTrimmed}
configuration is ignored). Then this value in scientific notation (or
in decimal fixed point notation if the scientific exponent is in the
\csbxint{PFloatNoSciEmin} to \csbxint{PFloatNoSciEmax} range) will be
attached to a trailing denominator |/B| (omitted if it is |/1|).
\end{itemize}
Please note:
\begin{itemize}
\item there is no reduction of the fraction |A/B| to lowest terms,
\item trailing zeros in the integer denominator |B| are not moved and
incorporated into the final scientific exponent,
\item no attempt is made to check if |B| is a product of only |2|'s and
|5|'s and thus could be integrated into some pure decimal notation for
the numerator or at least its significand.
\end{itemize}
Changes of \csbxint{PFloat} at |1.4k| have an impact here.
In particular the zero value will give \dtt{0} whether the input was
some |0|, |0e-5|, |0/3|, |0.00|, etc\dots, whereas at |1.4e| it would
have been \dtt{0.0} for cases triggering some \csbxint{PFloat}
subroutine.
The general blueprint is still to be considered \emph{unstable}.
The output routine of \csbxint{eval} is customizable via redefining
\csbxint{exprPrintOne} whose current default is (equivalent to):
\begin{everbatim}
\def\xintexprPrintOne{\xintFracToSci}
\end{everbatim}
\subsection{\csh{xintFracToDecimal}}
\label{xintFracToDecimal}
\csa{xintFracToDecimal}\etype{\Ff} is a variant of \csbxint{FracToSci} which
differs from it in so far as it outputs a numerator using decimal notation,
i.e. with as many zeros as are needed (and no more) and no scientific
exponent. The denominator goes through ``as is'' except if it is |1|, then it
is omitted.
In other terms its behaviour is currently intermediate between
\csbxint{DecToString} and \csbxint{DecToStringREZ}, as it does not
remove trailing zeros of the denominator. Consider its behaviour as
\emph{unstable}.
It can be used to customize \csbxint{exprPrintOne}:
\begin{everbatim}
\def\xintexprPrintOne{\xintFracToDecimal}
\end{everbatim}
It was initially at |1.4k| a private macro which served as an alternative to
\csb{xintFracToSci} default customization of \csbxint{exprPrintOne} and,
despite being documented in the user manual, was not supposed to be used at
user level (not being \fexpan dable it could not be nested within macros of
\xintfracname, and besides accepted a limited range of inputs).
It has been upgraded at |1.4l| to behave like all other \xintfracname
macros.
\subsection{\csh{xintTrunc}}\label{xintTrunc}
\csa{xintTrunc}|{x}{f}|\etype{\numx\Ff} returns the start of the decimal
expansion of the fraction |f|, truncated to:
\begin{itemize}
\item if |x>0|, |x| digits after the decimal mark,
\item if |x=0|, an integer,
\item if |x<0|, an integer multiple of |10^{-x}| (in scientific notation).
\end{itemize}
The output is the sole digit token \dtt{0} if and only if the input was exactly
zero; else it contains always either a decimal mark (even if |x=0|) or a
scientific part and it conserves the sign of |f| (even if the truncated value
represents the zero value).
Truncation is done towards zero.
\begin{everbatim*}
\begin{multicols}{2}
\noindent\xintFor* #1 in {\xintSeq[-1]{7}{-14}}:{\xintTrunc{#1}{-11e12/7}\newline}%
\xintTrunc{10}{1e-11}\newline \xintTrunc{10}{1/65536}\par
\end{multicols}
\end{everbatim*}
\begin{framed}
\textbf{Warning:} \emph{it is not yet decided is the current behaviour is
definitive.}
Currently \xintfracname has no notion of a positive zero or a negative zero.
Hence transitivity of \csbxint{Trunc} is broken for the case where the first
truncation gives on output \dtt{0.00...0} or \dtt{-0.00...0}: a second
truncation to less digits will then output \dtt{0}, whereas if it had been
applied directly to the initial input it would have produced \dtt{0.00...0}
or respectively \dtt{-0.00...0} (with less zeros after decimal mark).
If \xintfracname distinguished zero, positive zero, and
negative zero then it would be possible to maintain transitivity.
The problem would also be fixed, even without distinguishing a negative zero
on input, if \csbxint{Trunc} always produced \dtt{0.00...0} (with no sign)
when the mathematical result is zero, discarding the information on original
input being positive, zero, or negative.
I have multiple times hesitated about what to do and must postpone again
final decision.
\end{framed}
\subsection{\csh{xintXTrunc}}\label{xintXTrunc}
\csa{xintXTrunc}|{x}{f}|\xtype{\numx\Ff} is similar to \csbxint{Trunc} with
the following important differences:
\begin{itemize}[nosep]
\item it is completely expandable but not
\fexpan dable, as is indicated by the hollow star in the margin,
\item hence it can not be used as argument to the other package macros, but as
it \fexpan ds its |{f}| argument, it accepts arguments expressed with other
\xintfracname macros,
\item it requires |x>0|,
\item contrarily to \csbxint{Trunc} the number of digits on output is not
limited to about \dtt{19950} and may go well beyond \dtt{100000} (this is
mainly useful for outputting a decimal expansion to a file),
\item when the mathematical result is zero, it always prints it as
\dtt{0.00...0} or \dtt{-0.00...0} with |x| zeros after the decimal mark.
\end{itemize}
\textbf{Warning:}
transitivity is broken too (see discussion of \csbxint{Trunc}), due to the
sign in the last item. Hence \emph{the definitive policy is yet to be fixed.}
Transitivity is here in the sense of using a first |\edef| and then a second
one, because it is not possible to nest \csb{xintXTrunc} directly as argument
to itself. Besides, although the number of digits on output isn't limited,
nevertheless |x| should be less than about |19970| when the number of digits
of the input (assuming it is expressed as a decimal number) is even bigger:
|\xintXTrunc{30000}{\Z}| after |\edef\Z{\xintXTrunc{60000}{1/66049}| raises an
error in contrast with a direct |\xintXTrunc{30000}{1/66049}|. But
|\xintXTrunc{30000}{123.456789}| works, because here the number of digits
originally present is smaller than what is asked for, thus the routine only
has to add trailing zeros, and this has no limitation (apart from \TeX\ main
memory).
\csbxint{XTrunc} will expand fully in an |\edef| or a |\write| (|\message|,
|\wlog|, \dots) or in an \csbxint{expr}-ession, or as list argument to
\csbxint{For*}.
Here is an example session where the
user checks that the decimal expansion of $1/66049=1/257^2$ has the maximal
period length $257*256=65792$ (this period length must be a divisor of
$\phi(66049)$ and to check it is the maximal one it is enough to show that
neither $32896$ nor $256$ are periods.)
\begingroup\small
\everb|@
$ rlwrap etex -jobname worksheet-66049
This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016) (preloaded format=etex)
restricted \write18 enabled.
**xintfrac.sty
entering extended mode
(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintfrac.sty
(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xint.sty
(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintcore.sty
(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintkernel.sty))))
*% we load xinttools for \xintKeep, etc... \xintXTrunc itself has no more
*% any dependency on xinttools.sty since 1.2i
*\input xinttools.sty
(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xinttools.sty)
*\def\m#1;{\message{#1}}
*\m \the\numexpr 257*257\relax;
66049
*\m \the\numexpr 257*256\relax;
65792
*% Thus 1/66049 will have a period length dividing 65792.
*% Let us first check it is indeed periodical.
*\edef\Z{\xintXTrunc{66000}{1/66049}}
*% Let's display the first decimal digits.
*\m \xintXTrunc{208}{\Z};
0.00001514027464458205271843631243470756559523989765174340262532362337052794137
6856576178291874214598252812306015231116292449545034746930309315810988811337037
6538630410755651107511090251177156353616254598858423
*% let's now fetch the trailing digits
*\m \xintKeep{65792-66000}{\Z};% 208 trailing digits
0000151402746445820527184363124347075655952398976517434026253236233705279413768
5657617829187421459825281230601523111629244954503474693030931581098881133703765
38630410755651107511090251177156353616254598858423
*% yes they match! we now check that 65792/2 and 65792/257=256 aren't periods.
*\m \xintXTrunc{256}{\Z};
0.00001514027464458205271843631243470756559523989765174340262532362337052794137
6856576178291874214598252812306015231116292449545034746930309315810988811337037
6538630410755651107511090251177156353616254598858423291798513225029902042423049
554118911717058547442
*\m \xintXTrunc{256+256}{\Z};
0.00001514027464458205271843631243470756559523989765174340262532362337052794137
6856576178291874214598252812306015231116292449545034746930309315810988811337037
6538630410755651107511090251177156353616254598858423291798513225029902042423049
5541189117170585474420505987978621932201850141561567926842192917379521264515738
3154930430438008145467758785144362518736089872670290239064936637950612424109373
3440324607488379839210283274538600130206361943405653378552286938485064119063119
8049932625777831609865402958409665551333
*% now with 65792/2=32896. Problem: we can't do \xintXTrunc{32896+100}{\Z}
*% but only direct \xintXTrunc{32896+100}{1/66049}. Anyway we want to nest it
*% hence let's do it all with (slower) \xintKeep, \xintKeepUnbraced.
*\m \xintKeep {-100}{\xintKeepUnbraced{2+65792/2+100}{\Z}};
9999848597253554179472815636875652924344047601023482565973746763766294720586231
434238217081257854017
*% This confirms 32896 isn't a period length.
*% To conclude let's write the 66000 digits to the log.
*\wlog{\Z}
*% We want always more digits:
*\wlog{\xintXTrunc{150000}{1/66049}}
*\bye
|
\endgroup % $ à cause de fontification de AUCTeX.
The acute observer will have noticed that there is something funny when one
compares the first digits with those after the middle-period:
\begin{everbatim}
0000151402746445820527184363124347075655952398976517434026253236233705279413768...
9999848597253554179472815636875652924344047601023482565973746763766294720586231...
\end{everbatim}
Mathematical exercise: can you explain why the two indeed add to |9999...9999|?
You can try your hands at this simpler one:
\begin{everbatim*}
1/49=\xintTrunc{42+5}{1/49}...\newline
\xintTrim{2}{\xintTrunc{21}{1/49}}\newline
\xintKeep{-21}{\xintTrunc{42}{1/49}}
\end{everbatim*}
This was again an example of the type |1/N| with |N| the square of a prime.
One can also find counter-examples within this class: |1/31^2| and |1/37^2|
have an odd period length (|465| and respectively |111|) hence they can not
exhibit the symmetry.
\begin{framed}
Mathematical challenge: prove generally that if the period length of the
decimal expansion of |1/p^r| (with |p| a prime distinct from |2| and |5| and
|r| a positive exponent) is even, then the previously observed symmetry
about the two halves of the period adding to a string of nine's applies.
\end{framed}
\subsection{\csh{xintTFrac}}\label{xintTFrac}
\csa{xintTFrac}|{f}|\etype{\Ff} returns the fractional part,
|f=trunc(f)+frac(f)|. Thus if |f<0|, then |-10| one has
|0<= frac(f)<1|. The |T| stands for `Trunc', and there should exist also
similar macros associated respectively with `Round', `Floor', and `Ceil', each
type of rounding to an integer deserving arguably to be associated with a
fractional ``modulo''. By sheer laziness, the package currently implements
only the ``modulo'' associated with `Truncation'. Other types of modulo may be
obtained more cumbersomely via a combination of the rounding with a subsequent
subtraction from |f|.
Notice that the result is filtered through \csbxint{REZ}, and will thus be of
the form |A/B[N]|, where neither |A| nor |B| has trailing zeros. But the
output fraction is not reduced to smallest terms.
The function call in expressions (\csbxint{expr}, \csbxint{floatexpr}) is
|frac|. Inside |\xintexpr..\relax|, the function |frac| is mapped to
\csa{xintTFrac}. Inside |\xintfloatexpr..\relax|, |frac| first applies
\csa{xintTFrac} to its argument (which may be an exact fraction with more
digits than the floating point precision) and only in a second stage makes the
conversion to a floating point number with the precision as set by |\xintDigits|
(default is \dtt{16}).
\begin{everbatim*}
\xintTFrac {1235/97}, \xintTFrac {-1235/97}\newline
\xintTFrac {1235.973}, \xintTFrac {-1235.973}\newline
\xintTFrac {1.122435727e5}\par
\end{everbatim*}
\subsection{\csh{xintRound}}\label{xintRound}
\csa{xintRound}|{x}{f}|\etype{\numx\Ff} returns the start of the decimal
expansion of the fraction |f|, rounded to:
\begin{itemize}
\item if |x>0|, |x| digits after the decimal mark,
\item if |x=0|, an integer,
\item if |x<0|, an integer multiple of |10^{-x}| (in scientific notation).
\end{itemize}
The output is the sole digit token \dtt{0} if and only if the input was
exactly zero; else it contains always either a decimal mark (even if |x=0|) or
a scientific part and it conserves the sign of |f| (even if the rounded value
represents the zero value).
\begin{everbatim*}
\begin{multicols}{2}
\noindent\xintFor* #1 in {\xintSeq[-1]{7}{-14}}:{\xintRound{#1}{-11e12/7}\newline}%
\xintRound{10}{1e-11}\newline \xintRound{10}{1/65536}\newline
\end{multicols}
\end{everbatim*}%
Rounding is done with half-way numbers going towards infinity of
the same sign.
\subsection{\csh{xintFloor}}\label{xintFloor}
|\xintFloor {f}|\etype{\Ff} returns the largest relative integer |N| with
|N|${}\leqslant{}$|f|.
\begin{everbatim*}
\xintFloor {-2.13}, \xintFloor {-2}, \xintFloor {2.13}
\end{everbatim*}
Note the trailing |[0]|, see \csbxint{iFloor} if it is not desired.
\subsection{\csh{xintCeil}}\label{xintCeil}
|\xintCeil {f}|\etype{\Ff} returns the smallest relative integer |N| with
|N|${}>{}$|f|.
\begin{everbatim*}
\xintCeil {-2.13}, \xintCeil {-2}, \xintCeil {2.13}
\end{everbatim*}
\subsection{\csh{xintiTrunc}}\label{xintiTrunc}
\csa{xintiTrunc}|{x}{f}|\etype{\numx\Ff} returns the integer equal to |10^x|
times what \csa{xintTrunc}|{x}{f}| would produce. Attention that leading zeros
are automatically removed: the output is in strict integer format.
\begin{everbatim*}
\begin{multicols}{2}
\noindent\xintFor* #1 in {\xintSeq[-1]{7}{-14}}:{\xintiTrunc{#1}{-11e12/7}\newline}%
\xintiTrunc{10}{1e-11}\newline \xintiTrunc{10}{1/65536}\par
\end{multicols}
\end{everbatim*}
\subsection{\csh{xintTTrunc}}\label{xintTTrunc}
\csa{xintTTrunc}|{f}|\etype{\Ff} truncates to an integer (truncation towards
zero). This is the same as |\xintiTrunc {0}{f}| and also the same as
\csbxint{Num}.
\subsection{\csh{xintiRound}}\label{xintiRound}
\csa{xintiRound}|{x}{f}|\etype{\numx\Ff} returns the integer equal to |10^x|
times what \csa{xintRound}|{x}{f}| would return. The output has no leading
zeroes, it is always in strict integer format.
\begin{everbatim*}
\begin{multicols}{2}
\noindent\xintFor* #1 in {\xintSeq[-1]{7}{-14}}:{\xintiRound{#1}{-11e12/7}\newline}%
\xintiRound{10}{1e-11}\newline \xintiRound{10}{1/65536}\par
\end{multicols}
\end{everbatim*}
\subsection{\csh{xintiFloor}}\label{xintiFloor}
|\xintiFloor {f}|\etype{\Ff} does the same as \csbxint{Floor} but without the
trailing |/1[0]|.
\begin{everbatim*}
\xintiFloor {-2.13}, \xintiFloor {-2}, \xintiFloor {2.13}
\end{everbatim*}
\subsection{\csh{xintiCeil}}\label{xintiCeil}
|\xintiCeil {f}|\etype{\Ff} does the same as \csbxint{Ceil} but its output is
without the |/1[0]|.
\begin{everbatim*}
\xintiCeil {-2.13}, \xintiCeil {-2}, \xintiCeil {2.13}
\end{everbatim*}
\subsection{\csh{xintE}}\label{xintE}
|\xintE {f}{x}|\etype{\Ff\numx} multiplies the fraction |f| by $10^x$. The
\emph{second} argument |x| must obey the \TeX{} bounds. Example:
\begin{everbatim*}
\count 255 123456789 \xintE {10}{\count 255}
\end{everbatim*}
Don't feed this example to \csbxint{Num}!
\subsection{\csh{xintCmp}}\label{xintCmp}
This\etype{\Ff\Ff} compares two fractions |F| and |G| and produces
|-1|, |0|, or |1| according to |FG|.
For choosing branches according to the result of comparing |f| and |g|, see
\csbxint{ifCmp}.
\subsection{\csh{xintEq}}\label{xintEq}
|\xintEq{f}{g}|\etype{\Ff\Ff} returns 1 if |f=g|, 0 otherwise.
\subsection{\csh{xintNotEq}}\label{xintNotEq}
|\xintNotEq{f}{g}|\etype{\Ff\Ff} returns 0 if |f=g|, 1 otherwise.
\subsection{\csh{xintGeq}}\label{xintGeq}
This\etype{\Ff\Ff} compares the \emph{absolute values} of two
fractions.
|\xintGeq{f}{g}| outputs |1| if {\catcode`| 12 $|f|\geqslant|g|$} and |0|
if not.
Important: the macro compares \emph{absolute values}.
\subsection{\csh{xintGt}}\label{xintGt}
|\xintGt{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$>$|g|, \dtt{0} otherwise.
\subsection{\csh{xintLt}}\label{xintLt}
|\xintLt{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$<$|g|, \dtt{0} otherwise.
\subsection{\csh{xintGtorEq}}\label{xintGtorEq}
|\xintGtorEq{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$\geqslant$|g|, \dtt{0} otherwise.
Extended by \xintfracname to fractions.
\subsection{\csh{xintLtorEq}}\label{xintLtorEq}
|\xintLtorEq{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$\leqslant$|g|, \dtt{0} otherwise.
\subsection{\csh{xintIsZero}}\label{xintIsZero}
|\xintIsZero{f}|\etype{f} returns \dtt{1} if |f=0|, \dtt{0} otherwise.
\subsection{\csh{xintIsNotZero}}\label{xintIsNotZero}
|\xintIsNotZero{f}|\etype{f} returns \dtt{1} if |f!=0|, \dtt{0} otherwise.
\subsection{\csh{xintIsOne}}\label{xintIsOne}
|\xintIsOne{f}|\etype{f} returns \dtt{1} if |f=1|, \dtt{0} otherwise.
\subsection{\csh{xintOdd}}\label{xintOdd}
|\xintOdd{f}|\etype{f} returns \dtt{1} if the integer obtained by truncation is
odd, and \dtt{0} otherwise.
\subsection{\csh{xintEven}}\label{xintEven}
|\xintEven{f}|\etype{f} returns \dtt{1} if the integer obtained by truncation is
even, and \dtt{0} otherwise.
\subsection{\csh{xintifSgn}}\label{xintifSgn}
\csh{xintifSgn}\marg{f}\marg{A}\marg{B}\marg{C}\etype{\Ff nnn} executes either the
\meta{A}, \meta{B} or \meta{C} code, depending on its first argument being
respectively negative, zero, or positive.
\subsection{\csh{xintifZero}}\label{xintifZero}
\csa{xintifZero}\marg{f}\marg{IsZero}\marg{IsNotZero}\etype{\Ff nn} expandably
checks if the first mandatory argument |N| (a number, possibly a fraction if
\xintfracname is loaded, or a macro expanding to one such) is zero or not. It
then either executes the first or the second branch.
Beware that both branches must be present.
\subsection{\csh{xintifNotZero}}\label{xintifNotZero}
\csa{xintifNotZero}\marg{N}\marg{IsNotZero}\marg{IsZero}\etype{\Ff nn}
expandably checks if the first mandatory argument |f| is not
zero or is zero. It then either executes the first or the second branch.
Beware that both branches must be present.
\subsection{\csh{xintifOne}}\label{xintifOne}
\csa{xintifOne}\marg{N}\marg{IsOne}\marg{IsNotOne}\etype{\Ff nn} expandably
checks if the first mandatory argument |f| is one or not one. It
then either executes the first or the second branch. Beware that both branches
must be present.
\subsection{\csh{xintifOdd}}\label{xintifOdd}
\csa{xintifOdd}\marg{N}\marg{odd}\marg{not odd}\etype{\Ff nn} expandably
checks if the first mandatory argument |f|, after truncation to an integer, is
odd or even. It then executes accordingly the first or the second branch.
Beware that both branches must be present.
\subsection{\csh{xintifCmp}}\label{xintifCmp}
\csa{xintifCmp}\marg{f}\marg{g}\marg{if fg}\etype{\Ff\Ff nnn} compares its first two arguments and chooses accordingly
the correct branch.
\subsection{\csh{xintifEq}}\label{xintifEq}
\csa{xintifEq}\marg{f}\marg{g}\marg{YES}\marg{NO}\etype{\Ff\Ff nn} checks
equality of its two first arguments and executes accordingly the |YES| or the
|NO| branch.
\subsection{\csh{xintifGt}}\label{xintifGt}
\csa{xintifGt}\marg{f}\marg{g}\marg{YES}\marg{NO}\etype{\Ff\Ff nn}
checks if $f>g$ and in that case executes the |YES| branch.
\subsection{\csh{xintifLt}}\label{xintifLt}
\csa{xintifLt}\marg{f}\marg{g}\marg{YES}\marg{NO}\etype{\Ff\Ff nn}
checks if $f}}
\end{everbatim}
Examples:
\begin{everbatim*}
\xintFloatToDecimal{6.02e23}\newline
\xintFloatToDecimal{6.02000000000000e23}\newline
\xintFloatToDecimal[20]{1/7e10}\newline
\xintFloatToDecimal[30]{1/7e10}
\end{everbatim*}
See \csbxint{DecToString}.
\subsection{\csh{xintPFloat}}
\label{xintPFloat}
|\xintPFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} is like \csbxint{Float} but
``pretty-prints'' the output.
This macro was initially added at |1.1| as a (very primitive) "prettifying
printer" for floating point number, and was then somewhat influenced by Maple,
for example the zero value was printed as "\dtt{0.}". Then at |1.4e| there was
breaking change and the rules became somewhat similar to observed Python
behaviour: mantissas trimmed of trailing zeros (whether or not scientific
notation was used in the output) and integers printed with a trailing
"\dtt{.0}", in particular the zero value was printed as "\dtt{0.0}".
|1.4k| brought some breaking changes, which are reversible
via customizing macros:
\begin{itemize}
\item Integers (when scientific notation is dropped according to
criteria mentioned next) without a "\dtt{.0}"
suffix.
\item Same for the zero value, now "\dtt{\xintPFloat{0}}".
\item Significands are trimmed of trailing zeros only if that removes at least
\dtt{4} zeros. The rationale is that automatic removal of trailing zeros
(which was influenced at |1.4e| from practice with Python in interactive
mode) proves annoying visually with aligned values in tables, as this
creates voids, so we want to do this only when really the
presence of trailing zeros is not some kind of numerical fluke.
\end{itemize}
These changes impact the \csbxint{floateval} output as
\csbxint{floatexprPrintOne} defaults to using \csbxint{PFloat}.
\begin{framed}
In\IMPORTANTf\ this documentation ``trailing zeros'' refers not to how
the input looked like, but
to the corresponding mantissa of width |P| or \csbxint{theDigits}.
\end{framed}
The default rules are thus now:
\begin{enumerate}[nolistsep]
\item The input is float-rounded to either |Digits| or the optional argument.
\item zero is printed as \dtt{\xintPFloat{0}}.
\item \dtt{x.yz...eN} is printed in decimal fixed point if
$-4\leq\text{|N|}\leq+5$ else it is printed in scientific notation.
\item Trailing zeros of the mantissa are trimmed if, and only if there are at least \dtt{4}
of them.
\item In case of fixed point output format, and the value is an integer, the
integer is printed with no decimal mark.
\item In case of scientific notation output format, and the mantissa has only
one digit, no decimal mark is used.
\end{enumerate}
% The old rules were:
% \begin{enumerate}[nosep]
% \item The input is float-rounded to either |Digits| or the optional argument,
% \item zero is printed as \dtt{0.},
% \item \dtt{x.yz...eN} is printed ``as is'' if the exponent |N| is at least
% \dtt{6} or at most \dtt{-6},
% \item else fixed point decimal notation is used,
% \item and there is no trimming of trailing zeroes.
% \end{enumerate}
\begingroup\color{everbatimxfgcolor}
\begin{multicols}2
\def\test #1{\item #1${}\to{}$\xintPFloat{#1}}%
\string\xintDigits\ at \xinttheDigits
\begin{itemize}[nosep,font=\normalcolor]
\test {0}
\test {1.2340000e-7}\test {1.2340000e-6}\test {1.2340000e-5}\test {1.2340000e-4}
\test {1.2340000e-3}\test {1.2340000e-2}\test {1.2340000e-1}
\test {1.2340000e0}\test {1.2340000e1}\test {1.2340000e2}\test {1.2340000e3}
\test {1.2340000e4}\test {1.2340000e5}\test {1.2340000e6}\test {1.2340000e7}
\test {1e-7/7}\test {1e-6/7}\test {1e-5/7}\test {1e-4/7}
\test {1e-3/7}\test {1e-2/7}\test {1e-1/7}
\test {1e0/7}\test {1e1/7}\test {1e2/7}\test {1e3/7}
\test {1e4/7}\test {1e5/7}\test {1e6/7}\test {1e7/7}
\end{itemize}
\end{multicols}
\endgroup
\subsubsection{Customizing macros of \csh{xintPFloat}}
\label{xintPFloatE}
\label{xintPFloatZero}
\label{xintPFloatIntSuffix}
\label{xintPFloatLengthOneSuffix}
\label{xintPFloatNoSciEmin}
\label{xintPFloatNoSciEmax}
\label{xintPFloatMinTrimmed}
A number of macros allow to customize the behaviour of \csbxint{PFloat}:
\begin{itemize}
\item \csa{xintPFloatE} allows to modify the separator of the
scientific notation. Here is its default:
%
\footnote{For \TeX perts: it is allowed to define
\csa{xintPFloatE} as a macro which grabs the exponent as an argument
delimited by a dot, and produces \fexpan dably an output also delimited by
a dot (which gets removed via further internal processing).}
%
\begin{everbatim}
\def\xintPFloatE{e}
\end{everbatim}
\item \csa{xintPFloatZero} says how to print the zero value.
The default:
\begin{everbatim}
\def\xintPFloatZero{0}
\end{everbatim}
\item \csa{xintPFloatIntSuffix} is postfixed to integer values
(when scientific notation is not used). Its default at |1.4k| is to add
nothing. It replaces the formerly hard-coded "\dtt{.0}" from |1.4e| (prior
to that trailing zeros from the full significand of |P| or
\csbxint{theDigits} digits were not trimmed).
\begin{everbatim}
\def\xintPFloatIntSuffix{}
\end{everbatim}
\item \csa{xintPFloatLengthOneSuffix} is postfixed to trimmed
mantissas having only one digit, when scientific notation is used. Its
default at |1.4k| is to add nothing. It replaces formerly hard-coded
"\dtt{.0}".
\begin{everbatim}
\def\xintPFloatLengthOneSuffix{}
\end{everbatim}
\item \csa{xintPFloatNoSciEmax} is the maximal scientific exponent
which will trigger use of decimal fixed point notation and
\csa{xintPFloatNoSciEmin} is the minimal one. Their defaults at |1.4k| are the
same as the formerly hard-coded behaviour from |1.4e|:
\begin{everbatim}
\def\xintPFloatNoSciEmax{5}
\def\xintPFloatNoSciEmin{-4}
\end{everbatim}
For example (with the package default width of \dtt{16} digits for mantissas
of floating point numbers):
\begin{everbatim*}
\begingroup
\def\xintPFloatNoSciEmin{-20}
\xintPFloat{1e-19/7}\newline
\xintPFloat{1e-20/7}\par
\def\xintPFloatNoSciEmax{19}
\xintPFloat{1e20/7}\newline
\xintPFloat{1e21/7}\par
\endgroup
\end{everbatim*}
\item \csa{xintPFloatMinTrimmed} is the minimal number
of trailing zeros which have to be present to activate actual trimming.
The default definition is:
\begin{everbatim}
\def\xintPFloatMinTrimmed{4}
\end{everbatim}
Defining it to expand to \dtt{-1} or \dtt{0} will enable the trimming of
trailing zeros always, and setting it to a value at least equal to |P|
(or \csbxint{theDigits} if no |[P]|) will prevent it
altogether.
This setting is ignored for the case of an integer value, if the
criteria for using fixed point notation are met, and for the case of a
one-digit mantissa in scientific notation.
\end{itemize}
To mimick approximately the Python behaviour in interactive sessions,
one can use the following configuration:
\begin{everbatim}
\def\xintPFloatZero{0.0}%
\def\xintPFloatIntSuffix{.0}%
\def\xintPFloatLengthOneSuffix{.0}%
\def\xintPFloatNoSciEmax{15}%
\def\xintPFloatNoSciEmin{-4}%
\def\xintPFloatMinTrimmed{-1}%
\end{everbatim}
\begingroup\color{everbatimxfgcolor}
\def\xintPFloatZero{0.0}%
\def\xintPFloatIntSuffix{.0}%
\def\xintPFloatLengthOneSuffix{.0}%
\def\xintPFloatNoSciEmax{15}%
\def\xintPFloatNoSciEmin{-4}%
\def\xintPFloatMinTrimmed{-1}%
\def\test#1{#1${}\to{}$\xintPFloat{#1}\newline}%
\test{0.}
\test{1234.}
\test{6e100}
\test{1234567812345678.12345678}
\test{12345678123456781.2345678}
\test{12345678.12340}
\test{12345678.123400}
\test{0.1234567812345678}
\test{0.00012345678123456785}
\test{0.000012345678123456785}\par
\endgroup
%
The above using the default \csbxint{Digits} setting of \dtt{16} digits.
This can not naturally match exactly CPython which uses internally radix
|2| not |10|, and has (by default) mantissas with \dtt{53=1+52} bits.
Same, but playing with \ctanpackage{xintsession} in its |&fp| mode:
\begin{everbatim}
>>> &fp
fp mode (16 digits)
>>> \\def\xintPFloatZero{0.0}
(executing \\def\xintPFloatZero {0.0} in background)
)
Runaway argument?
def\xintPFloatZero {0.0}\message {
}\xs_fetch_aa \endinput
! File ended while scanning use of \\.
\par
<*> xintsession^^M
? S
OK, entering \scrollmode...
*\xintsession
You are back to the xintexpr interactive session!
(current mode: fp (Digits=16), with Digits=16)
">>> " means central computing is waiting for input
"... " means that multi-line input continues. Use `;' to terminate it.
Say `&bye' at any time to terminate the session and the TeX run.
>>> \def\xintPFloatZero{0.0}
(executing \def \xintPFloatZero {0.0} in background)
>>> \def\xintPFloatIntSuffix{.0}\def\xintPFloatLengthOneSuffix{.0}
(executing \def \xintPFloatIntSuffix {.0}\def \xintPFloatLengthOneSuffix {.0} i
n background)
>>> \def\xintPFloatNoSciEmax{15}\def\xintPFloatNoSciEmin{-4}
(executing \def \xintPFloatNoSciEmax {15}\def \xintPFloatNoSciEmin {-4} in back
ground)
>>> \def\xintPFloatMinTrimmed{-1}
(executing \def \xintPFloatMinTrimmed {-1} in background)
>>> 0., 1234., 6e100;
@_1 0.0, 1234.0, 6.0e100
>>> 1234567812345678.12345678;
@_2 1234567812345678.0
>>> 12345678123456781.2345678;
@_3 1.234567812345678e16
>>> 12345678.12340;
@_4 12345678.1234
>>> 12345678.123400;
@_5 12345678.1234
>>> 0.1234567812345678;
@_6 0.1234567812345678
>>> 0.00012345678123456785;
@_7 0.0001234567812345679
>>> 0.000012345678123456785;
@_8 1.234567812345679e-5
>>> &bye
\end{everbatim}
This is with version |0.4alpha (2021-11-01)| of
\ctanpackage{xintsession}. Probably some ``magic'' shortcuts will be
added in future to its interface for this kind of tasks, in place of
the |\def|.
% \subsection{\csh{xintFloatE}}\label{xintFloatE}
% %! {\small New with |1.097|.}
% |\xintFloatE [P]{f}{x}|\etype{{\upshape[\numx]}\Ff\numx} multiplies the input
% |f| by $10^x$, and
% converts it to float format according to the optional first argument or current
% value of |\xinttheDigits|.
% \begin{everbatim*}
% \xintFloatE {1.23e37}{53}
% \end{everbatim*}
% There is since |1.4b| an unfortunate proximity in name with \csbxint{PFloatE}
% despite the two things having absolutely nothing in common.
\subsection{\csh{xintFloatAdd}}\label{xintFloatAdd}
|\xintFloatAdd [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f|
and |g| with their float approximations |f'| and |g'| to |P| significant
places or to the precision from |\xintDigits|. It then produces
the sum |f'+g'|, correctly rounded to nearest with the same number of
significant places.
\subsection{\csh{xintFloatSub}}\label{xintFloatSub}
|\xintFloatSub [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f|
and |g| with their float approximations |f'| and |g'| to |P| significant
places or to the precision from |\xintDigits|. It then produces
the difference |f'-g'| correctly rounded to nearest |P|-float.
\subsection{\csh{xintFloatMul}}\label{xintFloatMul}
|\xintFloatMul [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f|
and |g| with their float approximations |f'| and |g'| to |P| (or
|\xinttheDigits|) significant places. It then correctly rounds
the product |f'*g'| to nearest |P|-float.
See \autoref{ssec:floatingpoint} for more.
\begin{framed}
It is high time the author improved this algorithm to avoid computing
an exact product of up to |2P| digits, only to discard roughly half of
them when rounding to |P| digits!
This issue\NewWithf{2.0a1} has been partly addressed for multiplication
in \csbxint{floateval} (aka |\calxeval|), which uses
specialized truncated-product algorithms at certain precisions.
For larger precisions, however, the full product is still computed
before rounding. This will need some improvements in the future.
\end{framed}
\subsection{\csh{xintFloatDiv}}\label{xintFloatDiv}
|\xintFloatDiv [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f|
and |g| with their float approximations |f'| and |g'| to |P| (or
|\xinttheDigits|) significant places. It then correctly rounds
the fraction |f'/g'| to nearest |P|-float.
See \autoref{ssec:floatingpoint} for more.
Notice in the special situation with |f| and |g| integers that |\xintFloatDiv
[P]{f}{g}| will \emph{not necessarily} give the correct rounding of the
exact fraction |f/g|. Indeed the macro arguments are each first individually
rounded to |P| digits of precision. The correct syntax to get the correctly
rounded integer fraction |f/g| is \csbxint{Float}|[P]{f/g}|.
\subsection{\csh{xintFloatPow}}\label{xintFloatPow}
|\xintFloatPow [P]{f}{x}|\etype{{\upshape[\numx]}\Ff\numx} uses either the
optional argument |P| or in its absence the value of |\xinttheDigits|. It
computes a floating approximation to |f^x|.
The exponent |x| will be handed over to a |\numexpr|, hence count registers are
accepted on input for this |x|. And the absolute value \verb+|x|+ must obey the
\TeX{} bound.
The argument |f| is first rounded to |P| significant figures to give
|f'|. The output |Z| is such that the exact |f'^x| differs from
|Z| by an absolute error less than |0.52 ulp(Z)|.
\begin{everbatim*}
\xintFloatPow {3.1415}{1234567890}
\end{everbatim*}
\subsection{\csh{xintFloatPower}}\label{xintFloatPower}
\csa{xintFloatPower}|[P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Numf} computes a
floating point value |f^g| where the exponent |g| is not constrained to be at
most the \TeX{} bound \dtt{\number "7FFFFFFF}. It may even be a fraction
|A/B| but will be truncated to an integer. The exponent of the
\emph{output} however \emph{must} at any rate obey the \TeX{} bound.
The argument |f| is first rounded to |P| significant figures to give
|f'|. The output |Z| is such that the exact |f'^g| differs from
|Z| by an absolute error less than |0.52 ulp(Z)|.
Prior to \dtt{2.0a1} this macro was used in \csbxint{floateval} for
|f**g| (or \func{pow}) when the exponent |g| was recognized as an
integer. This is no longer the case: the |exp(g*log(f))| route is used
by \csbxint{floateval} even if |g| is an integer.\CHANGED{2.0a1}
The internal implementation remains in use by \csbxint{eval} for
\emph{integer} exponents when an exact computation would produce more
than about \dtt{10000} digits in the numerator or denominator, or when
the absolute value of the exponent is at least \dtt{10000}. See
\csbxint{Pow}. It is explained there that the recognition of an integer
exponent by \csbxint{eval} is based on its input format, not on its
mathematical value.
The integer exponent |g| may have more than |P| (or \csbxint{theDigits})
digits, it is handled exactly. And as said above its absolute value may
exceed the \TeX\ bound.
Compare the following example (where the exponent is larger than the \TeX{} bound)
\begin{everbatim*}
\xintFloatPower {3.1415}{3703703670}
\end{everbatim*}
\newline
with Python's built-in floating-point arithmetic:
\begin{everbatim}
>>> 3.1415**3703703670
Traceback (most recent call last):
File "", line 1, in
3.1415**3703703670
~~~~~~^^~~~~~~~~~~
OverflowError: (34, 'Result too large')
\end{everbatim}
% Notice that this is a bound on the distance from
% |f'^g| to |Z|, where |f'| is the rounded value of the original input |f|;
% the distance from |f^g| to |Z| can be much worse if |g| is very
% large. Roughly, when |g| is negligible compared to |10^P|, we get an extra
% difference of up to about |50g ulp(Z)| which completely dwarfs the |0.52
% ulp(Z)|. Thus, if |f| has strictly more than |P| digits, then the computation
% must be done with an elevated working precision |P'|. For example with
% |g=1000| we should use |P'=P+6| to achieve a total error at worst slightly
% bigger than |0.55 ulp(Z)| after the final rounding from |P'| to |P| digits to
% get |Z|.
% Examples:%
% %
% \footnote{|\np| is formatting macro from the \url{http://ctan.org/pkg/numprint}
% package.}
% %
% \begin{everbatim*}
% \np{\xintFloatPower [8]{3.1415}{3e9}}\newline% Notice that 3e9>2^31
% \np{\xintFloatPower [48]{1.1547}{\xintiiPow {2}{35}}}\newline
% \end{everbatim*}%
% $2^{35}=\xintiiPow {2}{35}$ exceeds \TeX's bound, but what
% counts is the exponent of the result which, while dangerously close to
% $2^{31}$ is not quite there yet.
% With expressions:
% \begin{everbatim*}
% {\xintDigits:=48\relax \np{\xintthefloatexpr 1.1547^2^35\relax}}
% \end{everbatim*}
% There is a subtlety here that the |2^35| will be evaluated as a floating point
% number but fortunately it only has \dtt{11} digits, hence the final evaluation
% is done with a correct exponent. It would have been safer, and also more
% efficient to code the above rather as:
% \begin{everbatim}
% \xintthefloatexpr 1.1547^\xintiiexpr 2^35\relax\relax
% \end{everbatim}
% Here is an example with
% |12^16| as exponent, which has $18$ digits (\dtt{={\xintiiPow{12}{16}}}).
% \begin{everbatim*}
% {\xintDigits:=12\relax \np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}}\newline
% \np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}\newline
% {\xintDigits:=27\relax \np{\xintthefloatexpr (1+1e-8)^12^16\relax}}\newline
% {\xintDigits:=48\relax \np{\xintthefloatexpr (1+1e-8)^12^16\relax}}
% \end{everbatim*}
% There is an important difference between |\xintFloatPower[Q]{X}{Y}| and
% |\xintthefloatexpr[Q] X^Y\relax|: in the former case the computation is done
% with |Q| digits or precision,%
% %
% \footnote{if |X| and |Y| themselves stand for some
% floating point macros with arguments, their respective evaluations obey the
% precision |\xinttheDigits| or as set optionally in the macro calls
% themselves.}
% %
% whereas with \csbxint{thefloatexpr}|[Q]| the evaluation of the
% expression proceeds with |\xinttheDigits| digits of precision, and the final
% result is then rounded to |Q| digits: thus this makes real sense only if used
% with |Q<\xinttheDigits|.
\subsection{\csh{xintFloatSqrt}}\label{xintFloatSqrt}
\csa{xintFloatSqrt}|[P]{f}|\etype{{\upshape[\numx]}\Ff} computes a floating
point approximation of $\sqrt{\text{|f|}}$, either using the optional precision |P| or
the value of |\xinttheDigits|.
More precisely since |1.2f| the macro achieves so-called \emph{correct
rounding}:\IMPORTANT{} the produced value is the rounding to |P| significant
places of the abstract exact value, \emph{if the input has itself at most |P|
digits} (and an arbitrary exponent).
\begin{everbatim*}
\xintFloatSqrt [89]{10}\newline
\xintFloatSqrt [89]{100}\newline
\xintFloatSqrt [89]{123456789}\par
\end{everbatim*}
And now some tests to check that correct rounding applies correctly (sic):
\begin{everbatim*}
The argument has 16 digits, hence escapes initial rounding:\newline
\xintFloatSqrt {5625000075000001}\newline
This one gets rounded hence same value is computed:\newline
\xintFloatSqrt {5625000075000001.4}\newline
but actual value is more like:\newline
\xintFloatSqrt [24]{5625000075000001.4}\newline
\xintFloatSqrt [32]{5625000075000001.4}\newline
The argument has 48 digits, hence escapes initial rounding:\newline
\xintFloatSqrt [48]{562500000000000000000000750000000000000000000001}\newline
\xintFloatSqrt [64]{562500000000000000000000750000000000000000000001}\newline
\xintFloatSqrt [80]{562500000000000000000000750000000000000000000001}\newline
\end{everbatim*}
(we observe in passing illustrations that rounding to nearest is not
transitive.)\par
\subsection{\csh{xintFloatFac}}\label{xintFloatFac}
\csa{xintFloatFac}|[P]{f}|\etype{{\upshape[\numx]}\Numf} returns the
factorial with either \csa{xinttheDigits} or |P| digits of precision.
The exact theoretical value differs from the calculated one |Y| by an absolute
error strictly less than |0.6 ulp(Y)|.
\begin{everbatim*}
$1000!\approx{}$\xintFloatFac [30]{1000}
\end{everbatim*}
The computation proceeds via doing explicitely the product.%
%
\footnote{An approach based upon the Stirling formula could not be
done at time of implementation because of lack of exponential and
logarithm. This is now supported. So perhaps
at some point in future Gamma function will be implemented.}
%
The maximal allowed argument is $99999999$, but already $100000!$ currently
takes, for \dtt{16} digits of precision, a few seconds on my laptop (it
returns \dtt{2.824229407960348e456573}).
The |factorial| function is available in \csbxint{floatexpr}:
\begin{everbatim*}
\xintthefloatexpr factorial(1000)\relax % same as 1000!
\end{everbatim*}
\subsection{\csh{xintFloatBinomial}}\label{xintFloatBinomial}
\csa{xintFloatBinomial}|[P]{x}{y}|\etype{{\upshape[\numx]}\Numf\Numf} computes
binomial coefficients with either \csa{xinttheDigits} or |P| digits of
precision.
When |x<0| an out-of-range error is raised. Else if |y<0| or if |x binomial (9999.,5000.);
% 3008
% 0.795895131768 10
%
% > Digits:=32;
% Digits := 32
%
% > binomial (9999.,5000.);
% 3008
% 0.795895131768 10
% apparemment le binomial de Maple ne sait pas calculer avec plus de
% précision!
% et son dernier chiffre est faux! Pourtant GAMMA(9999.) fonctionne. Sauf si
% je n'ai pas compris quelque chose il me semble donc que le binomial de Maple
% est bogué...binomial(100.,50.); marche lui et binomial(4999.,2000.); aussi,
% bon clairement on a un bug de Maple ! oui binomial(8999.,5000.); ainsi que
% binomial(10999.,5000.); fonctionnent avec Digits:=32 mais **pas**
% binomial(9999.,5000.)... binomial(10000.,5000.); et binomial(9998.,5000.);
% sont OK. Est-ce qu'on gagne quelque chose pour un bug report ?
% > binomial(9999.,5000.);
% 3008
% 0.795895131768 10
% > binomial(10000.,5000.);
% 3009
% 0.1591790263532438948337597273641521 10
% > binomial(9998.,5000.);
% 3008
% 0.3979077671466477799149739359402922 10
% en plus je lui demande 32 chiffres et il m'en sort 34.
The associated function in \csbxint{floatexpr} is \func{binomial}:
\begin{everbatim*}
\xintthefloatexpr binomial(3000,1500)\relax
\end{everbatim*}
The computation is based on the formula |(x-y+1)...x/y!| (here one arranges
|y<=x-y| naturally).
\subsection{\csh{xintFloatPFactorial}}\label{xintFloatPFactorial}
\csa{xintFloatPFactorial}|[P]{x}{y}|\etype{{\upshape[\numx]}\Numf\Numf}
computes the product |(x+1)...y|.
The arguments must be integers (they are expanded inside |\numexpr|)
and the allowed range is $-100000000\leqslant x, y\leqslant99999999$. If
$x\geqslant y$ the product is considered empty hence returns one (as a
floating point value).
See also \csbxint{iiPFactorial}.
The exact theoretical value differs from the calculated one |Y| by an absolute
error strictly less than |0.6 ulp(Y)|.
The associated function in \csbxint{floatexpr} is \func{pfactorial}:
\begin{everbatim*}
\xintthefloatexpr pfactorial(2500,5000)\relax
\end{everbatim*}
\xintDigits:=16\relax
\clearpage
\let\xintfracnameUp\undefined
\csname xintbinhexnameUp\endcsname
\def\n{|{N}|}
\def\m{|{M}|}
\def\x{|{x}|}
\section{Macros of the \xintbinhexname package}
\RaisedLabel{sec:binhex}
\localtableofcontents
\subsection{Introduction}
This package provides expandable conversions of (big) integers between
the hexadecimal, decimal, octal (since |1.4n|) and binary bases.
First version of this package was in the |1.08| (|2013/06/07|) release
of \xintname. Its routines remained unmodified until their complete
rewrite at release |1.2m| (|2017/07/31|). Macros became faster, but the
inputs got limited to a few thousand digits, whereas the |1.08| versions
could handle (slowly...) tens of thousands of digits. At |1.4n| some
internals were refactored to use the \cs{expanded} primitive (which was
not available in 2017).\NewWith{1.4n} The maximal sizes got increased, see
\autoref{ssec:binhexsizes}. More significant probably, the octal radix
was added to the ones covered.
|1.4p| added \csbxint{LowerHex} and \csbxint{UpperHex}.\NewWith{1.4p}
For each provided conversion macro, its argument is first \fexpan
ded. This expansion is supposed to give a sequence of digits, with
perhaps a (unique) leading minus sign, which gets prepended to output
(note that \csbxint{DecToHex}|{-0}| thus expands to \dtt{\xintDecToHex{-0}}).
Let's insist that inputs can not start (after expansion) with a |0b|,
|0o|, |0x|, |#x|, |"|, |'|, or similar prefix notation: they must
consist only of digits as fitting to the binary, octal, decimal, or
hexadecimal radix. Situation is different if using \xintexprname-essions,
see \autoref{ssec:exprbinhex} next.
Low-level unrecoverable errors will occur if for
example an octal input contains the decimal digit |8|.
Hexadecimal digits in input must be uppercased. Category codes for
them may be indifferently \emph{letter} or \emph{other}. In output they
are of category \emph{letter} (and uppercased).
Leading zeroes in the input are allowed, and depending on the macro may
show up or not in the output. Note in particular:
\begin{itemize}[noitemsep]
\item Inputs with no leading zeros give outputs with no leading zeros.
\item All rules have (deliberate) exceptions, check the docs of
\csbxint{CHexToBin} and
\csbxint{COctToBin} which are variants of \csbxint{HexToBin} and
\csbxint{OctToBin}.
\item Outputs (if non vanishing) from \csbxint{DecToHex} or \csbxint{DecToOct}
have no leading zeros whether or not the inputs had some.
\item \csbxint{BinToHex} and \csbxint{BinToOct} always use the minimal number of
hexadecimal resp.\@ octal digits as needed to represent the original binary digits,
inclusive of their leading zeroes. For example
\csbxint{BinToHex}|{0000001}| outputs \dtt{\xintBinToHex{0000001}} and
\csbxint{BinToOct}|{0000001}| outputs \dtt{\xintBinToOct{0000001}}.
\end{itemize}
\subsection{\xintexprname-essions}
\label{ssec:exprbinhex}
Inside \xintexprname-essions,\NewWith{1.4n} hexadecimal can be input
using either |"| or |0x| prefixes, octal using either |'| or |0o|, and
binary using |0b|. Prior to |1.4n| only |"| was implemented and it was
needed to load \xintbinhexname additionally to \xintexprname. This is
now done automatically.
Hexadecimal letters must be uppercased. In both of \csbxint{eval} and
\csbxint{floateval} a ``fractional part'' after the full stop as
separator is allowed for all three bases. Here is an example using the
three non-decimal bases:
\begin{everbatim*}
\xinteval{subsm({x, y, x==y}, x="FF.FF * '777.777 * 0b11111.11111;
y=(16^2-16^-2)(8^3-8^-3)(2^5-2^-5);)}
\end{everbatim*}
The
|p| postfix notation from some programming languages, which stands for
an extra power of two, is however not implemented so far.
With \csbxint{iieval}\NewWith{1.4n}, which handles only integers, there
is an optional parameter |[h]|, |[o]|, or |[b]| for automatic conversion
of the output (this works also with comma separated inputs and even
nested bracketed inputs). Here is an example illustrating the new
more condensed syntax:
\begin{everbatim*}
\xintiieval[b]{0b1011100101001110 * 0b111100011}
\end{everbatim*}
Compare with how one would have had to input it prior to |1.4n|:
\begin{everbatim*}
\xintDecToBin{\xintiieval{\xintBinToDec{1011100101001110}*\xintBinToDec{111100011}}}
\end{everbatim*}
Note that if while parsing an octal number the digits |8| or |9| is
encountered, this does not trigger un error but terminates the octal
input fetched so far and inserts a tacit multiplication. Same for
binary input if encountering a digit other than |0| or |1|.
\subsection{\csh{xintHexToDec}}\label{xintHexToDec}
Converts from hexadecimal to decimal.\etype{f}
\texttt{\string\xintHexToDec
\string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent
\dtt{->\printnumber{\xintHexToDec{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}}
\subsection{\csh{xintHexToOct}}\label{xintHexToOct}
Converts from hexadecimal to octal.\etype{f}
\mbox{}\NewWith{1.4n}%
\texttt{\string\xintHexToOct
\string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent
\dtt{->\printnumber{\xintHexToOct{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}}
\subsection{\csh{xintHexToBin}}\label{xintHexToBin}
Converts from hexadecimal to binary. Up to three leading zeroes of the binary output
are trimmed.\etype{f}
\texttt{\string\xintHexToBin
\string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent
\dtt{->\printnumber{\xintHexToBin{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}}
\subsection{\csh{xintCHexToBin}}\label{xintCHexToBin}
Converts from hexadecimal to binary.\etype{f} Same as \csbxint{HexToBin}, but
an input with |N| hexadecimal digits will give an output with exactly |4N|
binary digits, leading zeroes are not trimmed.
\texttt{\string\xintCHexToBin
\string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent
\dtt{->\printnumber{\xintCHexToBin{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}}
This can be combined with \csbxint{BinToHex} for round-trips preserving
leading zeroes for |4N| binary digits numbers, whereas using
\csbxint{HexToBin} gives reproducing round-trips only for |4N| binary numbers
numbers not starting with |0000|.
\begin{everbatim*}
\xintBinToHex{0001111}\par
\end{everbatim*}
Chaining, we end up with 4N-3 digits, as three binary zeroes are trimmed:
\begin{everbatim*}
\xintHexToBin{\xintBinToHex{0001111}}\par
\end{everbatim*}
But the next will always reproduce the initial input zero-filled to length 4N:
\begin{everbatim*}
\xintCHexToBin{\xintBinToHex{0001111}}\par
\end{everbatim*}
Another example (visible space characters manually inserted):\newline
$000000001111101001010001\xrightarrow{\text{\string\xintBinToHex}}%$
\xintBinToHex{000000001111101001010001}\xrightarrow{\text{\string\xintHexToBin\hphantom{X}}}
\text{\textvisiblespace\textvisiblespace\textvisiblespace}
\xintHexToBin{\xintBinToHex{000000001111101001010001}}$\newline%$
$000000001111101001010001\xrightarrow{\text{\string\xintBinToHex}}%$
\xintBinToHex{000000001111101001010001}\xrightarrow{\text{\string\xintCHexToBin}}
\xintCHexToBin{\xintBinToHex{000000001111101001010001}}$%$
\par
\subsection{\csh{xintDecToHex}}\label{xintDecToHex}
Converts from decimal to hexadecimal.\etype{f}
\texttt{\string\xintDecToHex \string{\printnumber{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}\string}}\endgraf\noindent\dtt{->\printnumber{\xintDecToHex{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}}}
\subsection{\csh{xintDecToOct}}\label{xintDecToOct}
Converts from decimal to octal.\etype{f}
\mbox{}\NewWith{1.4n}\texttt{\string\xintDecToOct \string{\printnumber{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}\string}}\endgraf\noindent\dtt{->\printnumber{\xintDecToOct{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}}}
\subsection{\csh{xintDecToBin}}\label{xintDecToBin}
Converts from decimal to binary.\etype{f}
\texttt{\string\xintDecToBin \string{\printnumber{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}\string}}\endgraf\noindent\dtt{->\printnumber{\xintDecToBin{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}}}
\subsection{\csh{xintOctToHex}}\label{xintOctToHex}
Converts from octal to hexadecimal.\etype{f}
\mbox{}\NewWith{1.4n}%
\texttt{\string\xintOctToHex
\string{\printnumber{4324471370632244651340507676412402744247076026137040661070442727362552730135470644713643334710661401451155374676654443040246143}\string}}\endgraf\noindent
\dtt{->\printnumber{\xintOctToHex{4324471370632244651340507676412402744247076026137040661070442727362552730135470644713643334710661401451155374676654443040246143}}}
\subsection{\csh{xintOctToDec}}\label{xintOctToDec}
Converts from octal to decimal.\etype{f}
\mbox{}\NewWith{1.4n}%
\texttt{\string\xintOctToDec
\string{\printnumber{4324471370632244651340507676412402744247076026137040661070442727362552730135470644713643334710661401451155374676654443040246143}\string}}\endgraf\noindent
\dtt{->\printnumber{\xintOctToDec{4324471370632244651340507676412402744247076026137040661070442727362552730135470644713643334710661401451155374676654443040246143}}}
\subsection{\csh{xintOctToBin}}\label{xintOctToBin}
Converts from octal to binary.\etype{f} Up to two leading zeroes of the
binary output are trimmed.
\mbox{}\NewWith{1.4n}%
\texttt{\string\xintOctToBin
\string{\printnumber{14324471370632244651340507676412402744247076026137040661070442727362552730135470644713643334710661401451155374676654443040246143}\string}}\endgraf\noindent
\dtt{->\printnumber{\xintOctToBin{14324471370632244651340507676412402744247076026137040661070442727362552730135470644713643334710661401451155374676654443040246143}}}
\subsection{\csh{xintCOctToBin}}\label{xintCOctToBin}
Converts from octal to binary.\etype{f}
Same as \csbxint{OctToBin}, except that an input with |N|
octal digits will give an output with exactly |3N| binary digits,
leading zeroes are not trimmed.
\mbox{}\NewWith{1.4n}%
\texttt{\string\xintCOctToBin
\string{\printnumber{14324471370632244651340507676412402744247076026137040661070442727362552730135470644713643334710661401451155374676654443040246143}\string}}\endgraf\noindent
\dtt{->\printnumber{\xintCOctToBin{14324471370632244651340507676412402744247076026137040661070442727362552730135470644713643334710661401451155374676654443040246143}}}
\subsection{\csh{xintBinToHex}}\label{xintBinToHex}
Converts from binary to hexadecimal.\etype{f}
The input is first extended if need-be by leading zeros in order to have
|4N| binary digits, then the output will have |N| hexadecimal digits
(thus, if the input did not have a leading zero, the output will not either).
\texttt{\string\xintBinToHex
\string{\printnumber{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}\string}}\endgraf\noindent
\dtt{->\printnumber{\xintBinToHex{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}}}
\subsection{\csh{xintBinToDec}}\label{xintBinToDec}
Converts from binary to decimal.\etype{f}
\texttt{\string\xintBinToDec
\string{\printnumber{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}\string}}\endgraf\noindent
\dtt{->\printnumber{\xintBinToDec{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}}}
\subsection{\csh{xintBinToOct}}\label{xintBinToOct}
Converts from binary to octal.\etype{f}
The input is first extended if need-be by leading zeros in order to have
|3N| binary digits, then the output will have |N| octal digits
(thus, if the input did not have a leading zero, the output will not either).
\mbox{}\NewWith{1.4n}%
\texttt{\string\xintBinToOct
\string{\printnumber{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}\string}}\endgraf\noindent
\dtt{->\printnumber{\xintBinToOct{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}}}
\subsection{\csh{xintLowerHex}}\label{xintLowerHex}
The output\etype{f} is the lowercase version of the input (which can be
with mixed case). An empty input is allowed.\NewWith{1.4p} Letters on input can be of
catcode \emph{letter} or \emph{other}. Letters in output are of catcode
\emph{letter}.
\begin{everbatim*}
\xintLowerHex{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F}\newline
\xintLowerHex{\xintDecToHex{12379813738877118345}}
\end{everbatim*}
As it \fexpan ds its argument, you can as shown above use it to wrap usage
of one of the package macros converting to hexadecimal.
\subsection{\csh{xintUpperHex}}\label{xintUpperHex}
The output\etype{f} is the uppercase version of the input (which can be
with mixed case). An empty input is allowed.\NewWith{1.4p} Letters on input can be of
catcode \emph{letter} or \emph{other}. Letters in output are of catcode
\emph{letter}.
\begin{everbatim*}
\xintUpperHex{11a9397c66949a97051f7d0a817914e3e0b17c41b11c48baef2b5760bb38d272f}\newline
\xintHexToDec{\xintUpperHex{abcdef0123456789}}
\end{everbatim*}
As shown above, use it to wrap the argument of \csbxint{HexToDec} if for
example some lowercase, or mixed case, hexadecimal input needs to get
converted to decimal.
\subsection{Maximal sizes of inputs}\label{ssec:binhexsizes}
\autoref{tab:binhexsizes} recapitulates the maximal allowed sizes, as
found out with the \TeX{} installation of the author. The tests are done
putting the macro inside an \cs{edef} and compiling with the |etex| binary.
The value in the second column is the maximal |N| such that the macro
does not raise an error on an input with |N| digits (if nested in
another macro, the maximal input size may become lower than stated).
The third column gives the corresponding maximal size of the output.
These maximal sizes depend on \TeX\ parameters such as input stack size,
expansion depth, and parameter stack size. The fourth column gives the
\TeX\ parameter cited in the error message when trying with |N+1|
digits. When the limiting parameter is the main memory size, the upper
limits depend on external factors such as how many macros are loaded in
\TeX{} memory (for example they would be lower in a \LaTeX{} document or
if \xintexprname is loaded), so they are here given simply as
indications. They are so large anyhow that basically in practice, this
means no real limitation.
Regarding the conversions to and from decimal radix, they allow a more
limited range, but are still able to handle inputs with ten thousand
digits, one can thus consider in practice that their size limitations
are also only of theoretical interest.
\medskip
\begingroup
\makeatletter\def\@captype{table}\capstart
\centering
\begin{tabular}{rrrr}
\hline
&Max\ length\ of\ input&->\ length\ of\ output&Limiting factor\\
\csbxint{DecToHex}&16042&13323&expansion depth=10000\\
\csbxint{DecToOct}&15040&16654&expansion depth=10000\\
\csbxint{DecToBin}&16042&53291&expansion depth=10000\\
\csbxint{HexToDec}&11072&13333&expansion depth=10000\\
\csbxint{OctToDec}&14763&13333&expansion depth=10000\\
\csbxint{BinToDec}&44290&13333&expansion depth=10000\\
\csbxint{HexToOct}&553514&738019&main memory size=5000000\\
\csbxint{HexToBin}&553514&\the\numexpr4*553514\relax&main memory size=5000000\\
\csbxint{OctToHex}&711660&533745&main memory size=5000000\\
\csbxint{OctToBin}&711660&2134980&main memory size=5000000\\
\csbxint{BinToHex}&1992650&498163&main memory size=5000000\\
\csbxint{BinToOct}&1868109&622703&main memory size=5000000\\
%\csbxint{CHexToBin}&553513&2214052&main memory size=5000000.\\
%\csbxint{COctToBin}&711660&2134980&main memory size=5000000.\\
\hline
\end{tabular}
\captionof{table}{Maximal sizes for \xintbinhexname 1.4n macros with TeXLive 2025}\label{tab:binhexsizes}
\endgroup
% \medskip
% These sizes are larger (and very significantly so for the |bin<->hex|
% conversions) than with the previous release. For comparison
% \autoref{tab:binhexsizes14m} was computed using |1.4m 2022/06/10| and
% TeXLive 2025 with its default memory settings which are: input stack
% size at \dtt{10000}, expansion depth at \dtt{10000}, parameter stack
% size at \dtt{20000}. The previous last update to that table in this
% documentation had been done using \xintbinhexname |1.2n| and TeXLive
% 2021, the input stack size was only at \dtt{5000} and it was then the
% limiting factor in all cases and the maximal input sizes in 2021 were
% (in almost all cases) about half of the displayed values.
% %! (except for
% %! \csbxint{HexToDec} maximal input size which was at \dtt{8298} digits).
% \medskip
% \begingroup
% \makeatletter\def\@captype{table}\capstart
% \centering
% \begin{tabular}{rrrr}
% \hline
% &Max\ length\ of\ input&->\ length\ of\ output&Limiting factor\\
% \csbxint{DecToHex}&12035&9995&input stack size=10000\\
% \csbxint{DecToBin}&12035&39980&input stack size=10000\\
% \csbxint{HexToDec}&11072&13333&expansion depth=10000\\
% \csbxint{BinToDec}&39984&12037&expansion depth=10000\\
% \csbxint{HexToBin}&9996&39984&expansion depth=10000\\
% % \csbxint{CHexToBin}&9996&39984&expansion depth=10000\\
% \csbxint{BinToHex}&39984&9996&expansion depth=10000\\
% \hline
% \end{tabular}
% \captionof{table}{Maximal sizes for \xintbinhexname 1.4m 2022/06/10,
% but with TeXLive 2025 memory settings}\label{tab:binhexsizes14m}
% \endgroup
\clearpage
\let\xintbinhexnameUp\undefined
\csname xintgcdnameUp\endcsname
\def\n{|{N}|}
\def\m{|{M}|}
\def\x{|{x}|}
\section{Macros of the \xintgcdname package}
\RaisedLabel{sec:gcd}
\localtableofcontents
\subsection{Introduction}
This package was included in the original release |1.0| (|2013/03/28|) of the
\xintbundlename.
At |1.3d| macros \csbxint{iiGCD} and \csbxint{iiLCM} are copied over to
\xintname, hence \func{gcd} and \func{lcm} functions in \csbxint{iiexpr} were
available simply from loading only \xintexprname, and the \xintgcdname dependency
got removed.
\begin{framed}
From |1.1| to |1.3f| the package loaded only \xintcorename,
not \xintname and neither \xinttoolsname.
But at |1.4| it loads automatically both \xintname and \xinttoolsname (the
latter being a requirement since |1.09h| of the \csbxint{TypesetEuclideAlgorithm} and
\csbxint{TypesetBezoutAlgorithm} macros).
The macros \csbxint{iiGCD} and \csbxint{iiLCM} got relocated into
\xintname. \IMPORTANTf The macros \csbxint{GCD}, \csbxint{LCM},
\csbxint{GCDof}, and \csbxint{LCMof} are \emph{removed}:
\xintfracname provides under these names more powerful macros handling
general fractions and not only integers.
\end{framed}
\subsection{\csh{xintBezout}}\label{xintBezout}
|\xintBezout|\n\m\etype{\Numf\Numf} returns three numbers |U|, |V|,
|D| within braces where |D| is the (non-negative) GCD, and \dtt{UN + VM = D}.
\begin{everbatim*}
\oodef\X{\xintBezout {10000}{1113}}\meaning\X\par
\xintAssign {\xintBezout {10000}{1113}}\to\U\V\D
U: \meaning\U, V: \meaning\V, D: \meaning\D\par
AU+BV: \xinttheiiexpr 10000*\U+1113*\V\relax\par
\noindent\oodef\X{\xintBezout {123456789012345}{9876543210321}}\meaning\X\par
\xintAssign \X\to\U\V\D
U: \meaning\U, V: \meaning\V, D: \meaning\D\par
AU+BV: \xinttheiiexpr 123456789012345*\U+9876543210321*\V\relax
\end{everbatim*}
\subsection{\csh{xintEuclideAlgorithm}}\label{xintEuclideAlgorithm}
|\xintEuclideAlgorithm|\n\m\etype{\Numf\Numf} applies the Euclide algorithm
and keeps a copy of all quotients and remainders.
\begin{everbatim*}
\edef\X{\xintEuclideAlgorithm {10000}{1113}}\meaning\X
\end{everbatim*}
The first item is the number of steps, the second is |N|, the
third is the GCD, the fourth is |M| then the first quotient and
remainder, the second quotient and remainder, \dots until the
final quotient and last (zero) remainder.
\subsection{\csh{xintBezoutAlgorithm}}\label{xintBezoutAlgorithm}
|\xintBezoutAlgorithm|\n\m\etype{\Numf\Numf} applies the Euclide algorithm
and keeps a copy of all quotients and remainders. Furthermore it computes the
entries of the successive products of the 2 by 2 matrices
$\left(\vcenter{\halign {\,#&\,#\cr q & 1 \cr 1 & 0 \cr}}\right)$ formed from
the quotients arising in the algorithm.
\begin{everbatim*}
\edef\X{\xintBezoutAlgorithm {10000}{1113}}\printnumber{\meaning\X}
\end{everbatim*}
The first item is the number of steps, the second is |N|, then
|0|, |1|, the GCD, |M|, |1|, |0|, the first quotient, the first
remainder, the top left entry of the first matrix, the bottom left
entry, and then these four things at each step until the end.
\subsection{\csh{xintTypesetEuclideAlgorithm}}\label{xintTypesetEuclideAlgorithm}
This macro is just an example of how to organize the data returned by
\csa{xintEuclideAlgorithm}.\ntype{\Numf\Numf} Copy the source code to a new
macro and modify it to what is needed.
\leftedline{|\xintTypesetEuclideAlgorithm {123456789012345}{9876543210321}|}
\xintTypesetEuclideAlgorithm {123456789012345}{9876543210321}
\subsection{\csh{xintTypesetBezoutAlgorithm}}%
\label{xintTypesetBezoutAlgorithm}
This macro is just an example of how to organize the data returned by
\csa{xintBezoutAlgorithm}.\ntype{\Numf\Numf} Copy the source code to a new
macro and modify it to what is needed.
\leftedline{|\xintTypesetBezoutAlgorithm {10000}{1113}|}
\xintTypesetBezoutAlgorithm {10000}{1113}
\clearpage
\let\xintgcdnameUp\undefined
\csname xintseriesnameUp\endcsname
\def\n{|{N}|}
\def\m{|{M}|}
\def\x{|{x}|}
\section{Macros of the \xintseriesname package}
\RaisedLabel{sec:series}
\localtableofcontents
\subsection{Introduction}
This package was first released with version |1.03| (|2013/04/14|) of the
\xintbundlename.
The \Ff{} expansion type of various macro arguments is only a \Numf{} if only
\xintname but not \xintfracname is loaded. The macro \csbxint{iSeries} is
special and expects summing big integers obeying the strict format, even if
\xintfracname is loaded.
The arguments serving as indices are of the \numx{} expansion type.
In some cases one or two of the macro arguments are only expanded at a later
stage not immediately.
\begin{framed}
Since |1.3|, \csbxint{Add} and \csbxint{Sub} use systematically the least
common multiple of the denominators. Some of the comments in this chapter
refer to the earlier situation where often the denominators were simply
multiplied together. \emph{They have yet to be updated to reflect the new
situation brought by the |1.3| release.} Some of these comments may now be
off-synced from the actual computation results and thus may be wrong.
\end{framed}
%% \clearpage
\subsection{\csh{xintSeries}}\label{xintSeries}
\csa{xintSeries}|{A}{B}{\coeff}|\etype{\numx\numx\Ff} computes
$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|. The initial and final indices
must obey the |\numexpr| constraint of expanding to numbers at most |2^31-1|.
The |\coeff| macro must be a one-parameter \fexpan dable macro, taking on
input an explicit number |n| and producing some number or fraction |\coeff{n}|;
it is expanded at the time it is
needed.%
%
\begin{everbatim*}
\def\coeff #1{\xintiiMON{#1}/#1.5} % (-1)^n/(n+1/2)
\fdef\w {\xintSeries {0}{50}{\coeff}} % we want to re-use it
\fdef\z {\xintJrr {\w}[0]} % the [0] for a microsecond gain.
% \xintJrr preferred to \xintIrr: a big common factor is suspected.
% But numbers much bigger would be needed to show the greater efficiency.
\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} = \xintTeXFrac\z \]
\end{everbatim*}
The definition of |\coeff| as |\xintiiMON{#1}/#1.5| is quite suboptimal. It
allows |#1| to be a big integer, but anyhow only small integers are accepted
as initial and final indices (they are of the \numx{} type). Second, when the
\xintfracname parser sees the |#1.5| it will remove the dot hence create a
denominator with one digit more. For example |1/3.5| turns internally into
|10/35| whereas it would be more efficient to have |2/7|. For info here is the
non-reduced |\w|:
\[\xintTeXFrac\w\]
It would have been bigger still in releases earlier than |1.1|: now, the
\xintfracname \csbxint{Add} routine does not multiply blindly denominators
anymore, it checks if one is a multiple of the other. However it does not
practice systematic reduction to lowest terms.
A more efficient way to code |\coeff| is illustrated next.
\begin{everbatim*}
\def\coeff #1{\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}%
% The [0] in \coeff is a tiny optimization: in its presence the \xintfracname parser
% sees something which is already in internal format.
\fdef\w {\xintSeries {0}{50}{\coeff}}
\[\sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12}=\xintTeXFrac\w\]
\end{everbatim*}
The reduced form |\z| as displayed above only differs from this one by a
factor of \dtt{\xintNum {\xintDenominator\w/\xintDenominator\z}}.
\setlength{\columnsep}{0pt}
\everb|@
\def\coeffleibnitz #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]}
\cnta 1
\loop
% in this loop we recompute from scratch each partial sum!
% we can afford that, as \xintSeries is fast enough.
\noindent\hbox to 2em{\hfil\texttt{\the\cnta.} }%
\xintTrunc {12}{\xintSeries {1}{\cnta}{\coeffleibnitz}}\dots
\endgraf
\ifnum\cnta < 30 \advance\cnta 1 \repeat
|
\begin{multicols}{3}
\def\coeffleibnitz #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]} \cnta 1
\loop
\noindent\hbox to 2em{\hfil\dtt{\the\cnta.} }%
\xintTrunc {12}{\xintSeries {1}{\cnta}{\coeffleibnitz}}\dots
\endgraf
\ifnum\cnta < 30 \advance\cnta 1 \repeat
\end{multicols}
\subsection{\csh{xintiSeries}}\label{xintiSeries}
\def\coeff #1{\xintiTrunc {40}
{\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}%
\csa{xintiSeries}|{A}{B}{\coeff}|\etype{\numx\numx f} computes
$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}| where |\coeff{n}|
must \fexpan d to a (possibly long) integer in the strict format.
\everb|@
\def\coeff #1{\xintiTrunc {40}{\xintiiMON{#1}/#1.5}}%
% better:
\def\coeff #1{\xintiTrunc {40}
{\the\numexpr 2*\xintiiMON{#1}\relax/\the\numexpr 2*#1+1\relax [0]}}%
% better still:
\def\coeff #1{\xintiTrunc {40}
{\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}%
% (-1)^n/(n+1/2) times 10^40, truncated to an integer.
\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx
\xintTrunc {40}{\xintiSeries {0}{50}{\coeff}[-40]}\dots\]
|
\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx \xintTrunc
{40}{\xintiSeries {0}{50}{\coeff}[-40]}\]
We should have cut out at
least the last two digits: truncating errors originating with the first
coefficients of the sum will never go away, and each truncation
introduces an uncertainty in the last digit, so as we have 40 terms, we
should trash the last two digits, or at least round at 38 digits. It is
interesting to compare with the computation where rounding rather than
truncation is used, and with the decimal
expansion of the exactly computed partial sum of the series:
\everb|@
\def\coeff #1{\xintiRound {40} % rounding at 40
{\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}%
% (-1)^n/(n+1/2) times 10^40, rounded to an integer.
\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx
\xintTrunc {40}{\xintiSeries {0}{50}{\coeff}[-40]}\]
\def\exactcoeff #1%
{\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}%
\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12}
= \xintTrunc {50}{\xintSeries {0}{50}{\exactcoeff}}\dots\]
|
\def\coeff #1{\xintiRound {40}
{\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}%
% (-1)^n/(n+1/2) times 10^40, rounded to an integer.
\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx
\xintTrunc {40}{\xintiSeries {0}{50}{\coeff}[-40]}\]
\def\exactcoeff #1%
{\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}%
\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12}
= \xintTrunc {50}{\xintSeries {0}{50}{\exactcoeff}}\dots\]
This shows indeed that our sum of truncated terms
estimated wrongly the 39th and 40th digits of the exact result%
%
\footnote{as the series is alternating, we can roughly expect an error
of $\sqrt{40}$ and the last two digits are off by 4 units, which is
not contradictory to our expectations.}
%
and that the sum of rounded terms fared a bit better.
\subsection{\csh{xintRationalSeries}}\label{xintRationalSeries}
\noindent \csa{xintRationalSeries}|{A}{B}{f}{\ratio}|\etype{\numx\numx\Ff\Ff}
evaluates $\sum_{\text{|n=A|}}^{\text{|n=B|}}$|F(n)|, where |F(n)| is specified
indirectly via the data of |f=F(A)| and the one-parameter macro |\ratio| which
must be such that |\macro{n}| expands to |F(n)/F(n-1)|. The name indicates that
\csa{xintRationalSeries} was designed to be useful in the cases where
|F(n)/F(n-1)| is a rational function of |n| but it may be anything expanding to
a fraction. The macro |\ratio| must be an expandable-only compatible macro and
expand to its value after iterated full expansion of its first item. |A| and
|B| are fed to a |\numexpr| hence may be count registers or arithmetic
expressions built with such; they must obey the \TeX{} bound. The initial term
|f| may be a macro |\f|, it will be expanded to its value representing |F(A)|.
\begin{everbatim*}
\def\ratio #1{2/#1[0]}% 2/n, to compute exp(2)
\cnta 0 % previously declared count
\begin{quote}
\loop \fdef\z {\xintRationalSeries {0}{\cnta}{1}{\ratio }}%
\noindent$\sum_{n=0}^{\the\cnta} \frac{2^n}{n!}=
\xintTrunc{12}\z\dots=
\xintTeXFrac\z=\xintTeXFrac{\xintIrr\z}$\vtop to 5pt{}\par
\ifnum\cnta<20 \advance\cnta 1 \repeat
\end{quote}
\end{everbatim*}
\begin{everbatim*}
\def\ratio #1{-1/#1[0]}% -1/n, comes from the series of exp(-1)
\cnta 0 % previously declared count
\begin{quote}
\loop
\fdef\z {\xintRationalSeries {0}{\cnta}{1}{\ratio }}%
\noindent$\sum_{n=0}^{\the\cnta} \frac{(-1)^n}{n!}=
\xintTrunc{20}\z\dots=\xintTeXFrac{\z}=\xintTeXFrac{\xintIrr\z}$%
\vtop to 5pt{}\par
\ifnum\cnta<20 \advance\cnta 1 \repeat
\end{quote}
\end{everbatim*}
\def\ratioexp #1#2{\xintDiv{#1}{#2}}% #1/#2
\medskip We can incorporate an indeterminate if we define |\ratio| to be
a macro with two parameters: |\def\ratioexp
#1#2{\xintDiv{#1}{#2}}|\texttt{\%}| x/n: x=#1, n=#2|.
Then, if |\x| expands to some fraction |x|, the
macro %
%
\leftedline{|\xintRationalSeries {0}{b}{1}{\ratioexp{\x}}|}
will compute $\sum_{n=0}^{n=b} x^n/n!$:\par
\begin{everbatim*}
\cnta 0
\def\ratioexp #1#2{\xintDiv{#1}{#2}}% #1/#2
\loop
\noindent
$\sum_{n=0}^{\the\cnta} (.57)^n/n! = \xintTrunc {50}
{\xintRationalSeries {0}{\cnta}{1}{\ratioexp{.57}}}\dots$
\vtop to 5pt {}\endgraf
\ifnum\cnta<50 \advance\cnta 10 \repeat
\end{everbatim*}
Observe that in this last example the |x| was directly inserted; if it
had been a more complicated explicit fraction it would have been
worthwile to use |\ratioexp\x| with |\x| defined to expand to its value.
In the further situation where this fraction |x| is not explicit but
itself defined via a complicated, and time-costly, formula, it should be
noted that \csa{xintRationalSeries} will do again the evaluation of |\x|
for each term of the partial sum. The easiest is thus when |x| can be
defined as an |\edef|. If however, you are in an expandable-only context
and cannot store in a macro like |\x| the value to be used, a variant of
\csa{xintRationalSeries} is needed which will first evaluate this |\x| and then
use this result without recomputing it. This is \csbxint{RationalSeriesX},
documented next.
Here is a slightly more complicated evaluation:
\begin{everbatim*}
\cnta 1
\begin{multicols}{2}
\loop \fdef\z {\xintRationalSeries
{\cnta}
{2*\cnta-1}
{\xintiiPow {\the\cnta}{\cnta}/\xintiiFac{\cnta}}
{\ratioexp{\the\cnta}}}%
\fdef\w {\xintRationalSeries {0}{2*\cnta-1}{1}{\ratioexp{\the\cnta}}}%
\noindent
$\sum_{n=\the\cnta}^{\the\numexpr 2*\cnta-1\relax} \frac{\the\cnta^n}{n!}/%
\sum_{n=0}^{\the\numexpr 2*\cnta-1\relax} \frac{\the\cnta^n}{n!} =
\xintTrunc{8}{\xintDiv\z\w}\dots$ \vtop to 5pt{}\endgraf
\ifnum\cnta<20 \advance\cnta 1 \repeat
\end{multicols}
\end{everbatim*}
\subsection{\csh{xintRationalSeriesX}}\label{xintRationalSeriesX}
\noindent\csa{xintRationalSeriesX}|{A}{B}{\first}{\ratio}{\g}|%
\etype{\numx\numx\Ff\Ff f} is a parametrized version of \csa{xintRationalSeries}
where |\first| is now a one-parameter macro such that |\first{\g}| gives the
initial term and |\ratio| is a two-parameter macro such that |\ratio{n}{\g}|
represents the ratio of one term to the previous one. The parameter |\g| is
evaluated only once at the beginning of the computation, and can thus itself be
the yet unevaluated result of a previous computation.
Let |\ratio| be such a two-parameter macro; note the subtle differences
between%
%
\leftedline{|\xintRationalSeries {A}{B}{\first}{\ratio{\g}}|}
%
\leftedline{and |\xintRationalSeriesX {A}{B}{\first}{\ratio}{\g}|.} First the
location of braces differ...\@{} then, in the former case |\first| is a
\emph{no-parameter} macro expanding to a fractional number, and in the latter,
it is a
\emph{one-parameter} macro which will use |\g|. Furthermore the |X| variant
will expand |\g| at the very beginning whereas the former non-|X| former variant
will evaluate it each time it needs it (which is bad if this
evaluation is time-costly, but good if |\g| is a big explicit fraction
encapsulated in a macro).
The example will use the macro \csbxint{PowerSeries} which computes
efficiently exact partial sums of power series, and is discussed in the
next section.
\begin{everbatim*}
\def\firstterm #1{1[0]}% first term of the exponential series
% although it is the constant 1, here it must be defined as a
% one-parameter macro. Next comes the ratio function for exp:
\def\ratioexp #1#2{\xintDiv {#1}{#2}}% x/n
% These are the (-1)^{n-1}/n of the log(1+h) series:
\def\coefflog #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]}%
% Let L(h) be the first 10 terms of the log(1+h) series and
% let E(t) be the first 10 terms of the exp(t) series.
% The following computes E(L(a/10)) for a=1,...,12.
\begin{multicols}{3}\raggedcolumns
\cnta 0
\loop
\noindent\xintTrunc {18}{%
\xintRationalSeriesX {0}{9}{\firstterm}{\ratioexp}
{\xintPowerSeries{1}{10}{\coefflog}{\the\cnta[-1]}}}\dots
\endgraf
\ifnum\cnta < 12 \advance \cnta 1 \repeat
\end{multicols}
\end{everbatim*}
These completely exact operations rapidly create numbers with many digits. Let
us print in full the raw fractions created by the operation illustrated above:
\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm}
{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1[-1]}}}
|E(L(1[-1]))=|\dtt{\printnumber{\z}} (length of numerator:
\xintLen {\xintNumerator \z})
\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm}
{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{12[-2]}}}
|E(L(12[-2]))=|\dtt{\printnumber{\z}} (length of numerator:
\xintLen {\xintNumerator \z})
\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm}
{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{123[-3]}}}
|E(L(123[-3]))=|\dtt{\printnumber{\z}} (length of numerator:
\xintLen {\xintNumerator \z})
We see that the denominators here remain the same, as our input only had various
powers of ten as denominators, and \xintfracname efficiently assemble (some
only, as we can see) powers of ten. Notice that 1 more digit in an input
denominator seems to mean 90 more in the raw output. We can check that with some
other test cases:
\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm}
{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1/7}}}
|E(L(1/7))=|\dtt{\printnumber{\z}} (length of numerator:
\xintLen {\xintNumerator \z}; length of denominator:
\xintLen {\xintDenominator \z})
\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm}
{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1/71}}}
|E(L(1/71))=|\dtt{\printnumber{\z}} (length of numerator:
\xintLen {\xintNumerator \z}; length of denominator:
\xintLen {\xintDenominator \z})
\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm}
{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1/712}}}
|E(L(1/712))=|\dtt{\printnumber{\z}} (length of numerator:
\xintLen {\xintNumerator \z}; length of denominator:
\xintLen {\xintDenominator \z})
Thus
decimal numbers such as |0.123| (equivalently
|123[-3]|) give less computing intensive tasks than fractions such as |1/712|:
in the case of decimal numbers the (raw) denominators originate in the
coefficients of the series themselves, powers of ten of the input within
brackets being treated separately. And even then the
numerators will grow with the size of the input in a sort of linear way, the
coefficient being given by the order of series: here 10 from the log and 9 from
the exp, so 90. One more digit in the input means 90 more digits in the
numerator of the output: obviously we can not go on composing such partial sums
of series and hope that \xintname will joyfully do all at the speed of light!
Hence, truncating the output (or better, rounding) is the only way to go if one
needs a general calculus of special functions. This is why the package
\xintseriesname provides, besides \csbxint{Series}, \csbxint{RationalSeries}, or
\csbxint{PowerSeries} which compute \emph{exact} sums,
\csbxint{FxPtPowerSeries} for fixed-point computations and a (tentative naive)
\csbxint{FloatPowerSeries}.
\subsection{\csh{xintPowerSeries}}\label{xintPowerSeries}
\csa{xintPowerSeries}|{A}{B}{\coeff}{f}|\etype{\numx\numx\Ff\Ff}
evaluates the sum
$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot \text{|f|}^{\text{|n|}}$. The
initial and final indices are given to a |\numexpr| expression. The |\coeff|
macro (which, as argument to \csa{xintPowerSeries} is expanded only at the time
|\coeff{n}| is needed) should be defined as a one-parameter expandable macro,
its input will be an explicit number.
The |f| can be either a fraction directly input or a macro |\f| expanding to
such a fraction. It is actually more efficient to encapsulate an explicit
fraction |f| in such a macro, if it has big numerators and denominators (`big'
means hundreds of digits) as it will then take less space in the processing
until being (repeatedly) used.
This macro computes the \emph{exact} result (one can use it also for
polynomial evaluation), using a Horner scheme which helps avoiding a
denominator build-up (this problem however, even if using a naive additive
approach, is much less acute since release |1.1| and its new policy regarding
\csbxint{Add}).
\begin{everbatim*}
\def\geom #1{1[0]} % the geometric series
\def\f {5/17[0]}
\[ \sum_{n=0}^{n=20} \Bigl(\frac 5{17}\Bigr)^n
=\xintTeXFrac{\xintIrr{\xintPowerSeries {0}{20}{\geom}{\f}}}
=\xintTeXFrac{\xinttheexpr (17^21-5^21)/12/17^20\relax}\]
\end{everbatim*}
\begin{everbatim*}
\def\coefflog #1{1/#1[0]}% 1/n
\def\f {1/2[0]}%
\[ \log 2 \approx \sum_{n=1}^{20} \frac1{n\cdot 2^n}
= \xintTeXFrac {\xintIrr {\xintPowerSeries {1}{20}{\coefflog}{\f}}}\]
\[ \log 2 \approx \sum_{n=1}^{50} \frac1{n\cdot 2^n}
= \xintTeXFrac {\xintIrr {\xintPowerSeries {1}{50}{\coefflog}{\f}}}\]
\end{everbatim*}
\begin{everbatim*}
\setlength{\columnsep}{0pt}
\begin{multicols}{3}
\cnta 1 % previously declared count
\loop % in this loop we recompute from scratch each partial sum!
% we can afford that, as \xintPowerSeries is fast enough.
\noindent\hbox to 2em{\hfil\texttt{\the\cnta.} }%
\xintTrunc {12}
{\xintPowerSeries {1}{\cnta}{\coefflog}{\f}}\dots
\endgraf
\ifnum \cnta < 30 \advance\cnta 1 \repeat
\end{multicols}
\end{everbatim*}
\begin{everbatim*}
\def\coeffarctg #1{1/\the\numexpr\ifodd #1 -2*#1-1\else2*#1+1\fi\relax }%
% the above gives (-1)^n/(2n+1). The sign being in the denominator,
% **** no [0] should be added ****,
% else nothing is guaranteed to work (even if it could by sheer luck)
% Notice in passing this aspect of \numexpr:
% **** \numexpr -(1)\relax is ilegal !!! ****
\def\f {1/25[0]}% 1/5^2
\[\mathrm{Arctg}(\frac15)\approx \frac15\sum_{n=0}^{15} \frac{(-1)^n}{(2n+1)25^n}
= \xintTeXFrac{\xintIrr {\xintDiv {\xintPowerSeries {0}{15}{\coeffarctg}{\f}}{5}}}\]
\end{everbatim*}
\subsection{\csh{xintPowerSeriesX}}\label{xintPowerSeriesX}
%{\small\hspace*{\parindent}New with release |1.04|.\par}
\noindent This is the same as \csbxint{PowerSeries}\ntype{\numx\numx\Ff\Ff}
apart
from the fact that the last parameter |f| is expanded once and for all before
being then used repeatedly. If the |f| parameter is to be an explicit big
fraction with many (dozens) digits, rather than using it directly it is slightly
better to have some macro |\g| defined to expand to the explicit fraction and
then use \csbxint{PowerSeries} with |\g|; but if |f| has not yet been evaluated
and will be the output of a complicated expansion of some |\f|, and if, due to
an expanding only context, doing |\edef\g{\f}| is no option, then
\csa{xintPowerSeriesX} should be used with |\f| as last parameter.
%
\begin{everbatim*}
\def\ratioexp #1#2{\xintDiv {#1}{#2}}% x/n
% These are the (-1)^{n-1}/n of the log(1+h) series:
\def\coefflog #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]}%
% Let L(h) be the first 10 terms of the log(1+h) series and
% let E(t) be the first 10 terms of the exp(t) series.
% The following computes L(E(a/10)-1) for a=1,..., 12.
\begin{multicols}{3}\raggedcolumns
\cnta 1
\loop
\noindent\xintTrunc {18}{%
\xintPowerSeriesX {1}{10}{\coefflog}
{\xintSub
{\xintRationalSeries {0}{9}{1[0]}{\ratioexp{\the\cnta[-1]}}}
{1}}}\dots
\endgraf
\ifnum\cnta < 12 \advance \cnta 1 \repeat
\end{multicols}
\end{everbatim*}
\subsection{\csh{xintFxPtPowerSeries}}\label{xintFxPtPowerSeries}
\csa{xintFxPtPowerSeries}|{A}{B}{\coeff}{f}{D}|\etype{\numx\numx}
computes
$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot \text{|f|}^{\,\text{|n|}}$ with each
term of the series truncated to |D| digits\etype{\Ff\Ff\numx}
after the decimal point. As
usual, |A| and |B| are completely expanded through their inclusion in a
|\numexpr| expression. Regarding |D| it will be similarly be expanded each
time it is used inside an \csa{xintTrunc}. The one-parameter macro |\coeff|
is similarly expanded at the time it is used inside the
computations. Idem for |f|. If |f| itself is some complicated macro it is
thus better to use the variant \csbxint{FxPtPowerSeriesX} which expands it
first and then uses the result of that expansion.
The current (|1.04|) implementation is: the first power |f^A| is
computed exactly, then \emph{truncated}. Then each successive power is
obtained from the previous one by multiplication by the exact value of
|f|, and truncated. And |\coeff{n}|\raisebox{.5ex}{|.|}|f^n| is obtained
from that by multiplying by |\coeff{n}| (untruncated) and then
truncating. Finally the sum is computed exactly. Apart from that
\csa{xintFxPtPowerSeries} (where |FxPt| means `fixed-point') is like
\csa{xintPowerSeries}.
There should be a variant for things of the type $\sum c_n \frac {f^n}{n!}$ to
avoid having to compute the factorial from scratch at each coefficient, the same
way \csa{xintFxPtPowerSeries} does not compute |f^n| from scratch at each |n|.
Perhaps in the next package release.
\def\coeffexp #1{1/\xintiiFac {#1}[0]}% [0] for faster parsing
\def\f {-1/2[0]}%
\newcount\cnta
\edef\foo{\the\multicolsep}
\setlength{\multicolsep}{0pt}
\begin{multicols}{3}[%
\centeredline{$e^{-\frac12}\approx{}$}]%
\cnta 0
\noindent\loop
$\xintFxPtPowerSeries {0}{\cnta}{\coeffexp}{\f}{20}$\\
\ifnum\cnta<19
\advance\cnta 1
\repeat\par
\end{multicols}
\multicolsep\foo\relax
\everb|@
\def\coeffexp #1{1/\xintiiFac {#1}[0]}% 1/n!
\def\f {-1/2[0]}% [0] for faster input parsing
\cnta 0 % previously declared \count register
\noindent\loop
$\xintFxPtPowerSeries {0}{\cnta}{\coeffexp}{\f}{20}$\\
\ifnum\cnta<19 \advance\cnta 1 \repeat\par
|
%
\leftedline{|\xintFxPtPowerSeries {0}{19}{\coeffexp}{\f}{25}=|
\dtt{\xintFxPtPowerSeries {0}{19}{\coeffexp}{\f}{25}}}
\fdef\z{\xintIrr {\xintPowerSeries {0}{19}{\coeffexp}{\f}}}
%
\texttt{\hyphenchar\font45 }%
It is no difficulty for \xintfracname to compute exactly, with the help
of \csa{xintPowerSeries}, the nineteenth partial sum, and to then give
(the start of) its exact decimal expansion:
%
\leftedline{|\xintPowerSeries {0}{19}{\coeffexp}{\f}| ${}=
\displaystyle\xintTeXFrac{\z}$%
\vphantom{\vrule height 20pt depth 12pt}}%
%
\leftedline{${}=\xintTrunc {30}{\z}\dots$} Thus, one should always
estimate a priori how many ending digits are not reliable: if there are
|N| terms and |N| has |k| digits, then digits up to but excluding the
last |k| may usually be trusted. If we are optimistic and the series is
alternating we may even replace |N| with $\sqrt{\text{|N|}}$ to get the number |k|
of digits possibly of dubious significance.
\subsection{\csh{xintFxPtPowerSeriesX}}\label{xintFxPtPowerSeriesX}
\noindent\csa{xintFxPtPowerSeriesX}|{A}{B}{\coeff}{\f}{D}|%
\ntype{\numx\numx}
computes, exactly as
\csa{xintFxPtPowerSeries}, the sum of
|\coeff{n}|\raisebox{.5ex}{|.|}|\f^n|\etype{\Ff\Ff\numx} from |n=A| to |n=B| with each term
of the series being \emph{truncated} to |D| digits after the decimal
point. The sole difference is that |\f| is first expanded and it
is the result of this which is used in the computations.
Let us illustrate this on the numerical exploration of the identity
%
\leftedline{|log(1+x) = -log(1/(1+x))|}
%
Let |L(h)=log(1+h)|, and |D(h)=L(h)+L(-h/(1+h))|. Theoretically thus,
|D(h)=0| but we shall evaluate |L(h)| and |-h/(1+h)| keeping only 10
terms of their respective series. We will assume $\text{|h|}<0.5$. With only
ten terms kept in the power series we do not have quite 3 digits
precision as $2^{10}=1024$. So it wouldn't make sense to evaluate things
more precisely than, say circa 5 digits after the decimal points.
\begin{everbatim*}
\cnta 0
\def\coefflog #1{\the\numexpr\ifodd#1 1\else-1\fi\relax/#1[0]}% (-1)^{n-1}/n
\def\coeffalt #1{\the\numexpr\ifodd#1 -1\else1\fi\relax [0]}% (-1)^n
\begin{multicols}2
\loop
\noindent \hbox to 2.5cm {\hss\texttt{D(\the\cnta/100): }}%
\xintAdd {\xintFxPtPowerSeriesX {1}{10}{\coefflog}{\the\cnta [-2]}{5}}
{\xintFxPtPowerSeriesX {1}{10}{\coefflog}
{\xintFxPtPowerSeriesX {1}{10}{\coeffalt}{\the\cnta [-2]}{5}}
{5}}\endgraf
\ifnum\cnta < 49 \advance\cnta 7 \repeat
\end{multicols}
\end{everbatim*}
Let's say we evaluate functions on |[-1/2,+1/2]| with values more or less also
in |[-1/2,+1/2]| and we want to keep 4 digits of precision. So, roughly we need
at least 14 terms in series like the geometric or log series. Let's make this
15. Then it doesn't make sense to compute intermediate summands with more than 6
digits precision. So we compute with 6 digits
precision but return only 4 digits (rounded) after the decimal point.
This result with 4 post-decimal points precision is then used as input
to the next evaluation.
\begin{everbatim*}
\begin{multicols}2
\loop
\noindent \hbox to 2.5cm {\hss\texttt{D(\the\cnta/100): }}%
\dtt{\xintRound{4}
{\xintAdd {\xintFxPtPowerSeriesX {1}{15}{\coefflog}{\the\cnta [-2]}{6}}
{\xintFxPtPowerSeriesX {1}{15}{\coefflog}
{\xintRound {4}{\xintFxPtPowerSeriesX {1}{15}{\coeffalt}
{\the\cnta [-2]}{6}}}
{6}}%
}}\endgraf
\ifnum\cnta < 49 \advance\cnta 7 \repeat
\end{multicols}
\end{everbatim*}
Not bad... I have cheated a bit: the `four-digits precise' numeric
evaluations were left unrounded in the final addition. However the inner
rounding to four digits worked fine and made the next step faster than
it would have been with longer inputs. The morale is that one should not
use the raw results of \csa{xintFxPtPowerSeriesX} with the |D| digits
with which it was computed, as the last are to be considered garbage.
Rather, one should keep from the output only some smaller number of
digits. This will make further computations faster and not less precise.
I guess there should be some macro to do this final truncating, or
better, rounding, at a given number |D'200 \textcolor{red}{#1}\else #1\fi}
$$\xintFtoCx {+\cfrac1\\ \highlight}{104348/33215}\endcfrac$$
|
Due to the different and extremely cumbersome syntax of |\cfrac| under
\LaTeX{} it proves a bit tortuous to obtain there the same effect.
Actually, it is partly for this purpose that |1.09m| added \csbxint
{GGCFrac}. We thus use \csa{xintFtoCx} with a suitable separator, and\;
then the whole thing as argument to \csbxint{GGCFrac}:
\begin{everbatim*}
\def\highlight #1{\ifnum #1>200 \fcolorbox{blue}{white}{\boldmath\color{red}$#1$}%
\else #1\fi}
\[\xintGGCFrac {\xintFtoCx {+1/\highlight}{208341/66317}}\]
\end{everbatim*}
\subsection{\csh{xintFtoGC}}\label{xintFtoGC}
\csa{xintFtoGC}|{f}|\etype{\Ff} does the same as \csa{xintFtoCx}|{+1/}{f}|. Its
output may thus be used in the package macros expecting such an `inline
format'.
% This continued fraction is a \emph{simple} one, not a
% \emph{generalized} one, but as it is produced in the format used for
% user input of generalized continued fractions, the macro was called
% \csa{xintFtoGC} rather than \csa{xintFtoC} for example.
%
\begin{everbatim*}
566827/208524=\xintFtoGC {566827/208524}
\end{everbatim*}
\subsection{\csh{xintFGtoC}}\label{xintFGtoC}
\csa{xintFGtoC}|{f}{g}|\etype{\Ff\Ff} computes the common initial coefficients
to
two given fractions |f| and |g|. Notice that any real number |fx>g|
will then necessarily share with |f| and |g| these common initial coefficients
for its regular continued fraction. The coefficients are output as a sequence of
braced numbers. This list can then be manipulated via macros from
\xinttoolsname, or other macros of \xintcfracname.
\begin{everbatim*}
\fdef\test{\xintFGtoC{-5262046/89233}{-5314647/90125}}\texttt{\meaning\test}
\end{everbatim*}
\begin{everbatim*}
\fdef\test{\xintFGtoC{3.141592653}{3.141592654}}\texttt{\meaning\test}
\end{everbatim*}
\begin{everbatim*}
\fdef\test{\xintFGtoC{3.1415926535897932384}{3.1415926535897932385}}\meaning\test
\end{everbatim*}
\begin{everbatim*}
\xintRound {30}{\xintCstoF{\xintListWithSep{,}{\test}}}
\end{everbatim*}
\begin{everbatim*}
\xintRound {30}{\xintCtoF{\test}}
\end{everbatim*}
\begin{everbatim*}
\fdef\test{\xintFGtoC{1.41421356237309}{1.4142135623731}}\meaning\test
\end{everbatim*}
\subsection{\csh{xintFtoCC}}\label{xintFtoCC}
\csa{xintFtoCC}|{f}|\etype{\Ff} returns the `centered' continued fraction of
|f|, in `inline format'. %
\begin{everbatim*}
566827/208524=\xintFtoCC {566827/208524}
\end{everbatim*}
\begin{everbatim*}
\[\xintTeXFrac{566827/208524} = \xintGCFrac{\xintFtoCC{566827/208524}}\]
\end{everbatim*}
\subsection{\csh{xintCstoF}}\label{xintCstoF}
\csa{xintCstoF}|{a,b,c,d,...,z}|\etype{f} computes the fraction corresponding to
the coefficients, which may be fractions or even macros expanding to such
fractions. The final fraction may then be highly reducible.
Starting with
release |1.09m| spaces before commas are allowed and trimmed automatically
(spaces after commas were already silently handled in earlier releases).
\begin{everbatim*}
\[\xintGCFrac {-1+1/3+1/-5+1/7+1/-9+1/11+1/-13}=
\xintTeXsignedFrac{\xintCstoF {-1,3,-5,7,-9,11,-13}}=\xintTeXsignedFrac{\xintGCtoF
{-1+1/3+1/-5+1/7+1/-9+1/11+1/-13}}\]
\end{everbatim*}
\begin{everbatim*}
\[\xintGCFrac{{1/2}+1/{1/3}+1/{1/4}+1/{1/5}}=
\xintTeXFrac{\xintCstoF {1/2,1/3,1/4,1/5}}\]
\end{everbatim*}
%
A generalized continued fraction may produce a reducible fraction
(\csa{xintCstoF} tries its best not to accumulate in a silly way superfluous
factors but will not do simplifications which would be obvious to a human, like
simplification by 3 in the result above).
\subsection{\csh{xintCtoF}}\label{xintCtoF}
\csa{xintCtoF}|{{a}{b}{c}...{z}}|\etype{f} computes the fraction corresponding
to the coefficients, which may be fractions or even macros.
\begin{everbatim*}
\xintCtoF {\xintApply {\xintiiPow 3}{\xintSeq {1}{5}}}
\end{everbatim*}
\begin{everbatim*}
\[ \xintTeXFrac{14946960/4805083}=\xintCFrac {14946960/4805083}\]
\end{everbatim*}
In the example above the power of $3$ was already pre-computed via the expansion
done by |\xintApply|, but if we try with |\xintApply { \xintiiPow 3}| where the
space will stop this expansion, we can check that |\xintCtoF| will itself
provoke the needed coefficient expansion.% ok
\subsection{\csh{xintGCtoF}}\label{xintGCtoF}
\csa{xintGCtoF}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} computes the fraction
defined by the inline generalized continued fraction. Coefficients may be
fractions but must then be put within braces. They can be macros. The plus signs
are mandatory.
\begin{everbatim*}
\[\xintGCFrac {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}} =
\xintTeXFrac{\xintGCtoF {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}} =
\xintTeXFrac{\xintIrr{\xintGCtoF
{1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}}}\]
\end{everbatim*}
\begin{everbatim*}
\[ \xintGCFrac{{1/2}+{2/3}/{4/5}+{1/2}/{1/5}+{3/2}/{5/3}} =
\xintTeXFrac{\xintGCtoF {{1/2}+{2/3}/{4/5}+{1/2}/{1/5}+{3/2}/{5/3}}} \]
\end{everbatim*}
The macro tries its best not to accumulate superfluous factor in the
denominators, but doesn't reduce the fraction to irreducible form before
returning it and does not do simplifications which would be obvious to a human.
\subsection{\csh{xintCstoCv}}\label{xintCstoCv}
\csa{xintCstoCv}|{a,b,c,d,...,z}|\etype{f} returns the sequence of the
corresponding convergents, each one within braces.
It is allowed to use fractions as coefficients (the computed
convergents have then no reason to be the real convergents of the final
fraction). When the coefficients are integers, the convergents are irreducible
fractions, but otherwise it is not necessarily the case.
\begin{everbatim*}
\xintListWithSep:{\xintCstoCv{1,2,3,4,5,6}}
\end{everbatim*}
\begin{everbatim*}
\xintListWithSep:{\xintCstoCv{1,1/2,1/3,1/4,1/5,1/6}}
\end{everbatim*}
\begin{everbatim*}
\[\xintListWithSep{\to}{\xintApply\xintTeXFrac{\xintCstoCv {\xintPow
{-.3}{-5},7.3/4.57,\xintCstoF{3/4,9,-1/3}}}}\]
\end{everbatim*}
\subsection{\csh{xintCtoCv}}\label{xintCtoCv}
\csa{xintCtoCv}|{{a}{b}{c}...{z}}|\etype{f} returns the sequence of the
corresponding convergents, each one within braces.
\begin{everbatim*}
\fdef\test{\xintCtoCv {11111111111}}\texttt{\meaning\test}
\end{everbatim*}
\subsection{\csh{xintGCtoCv}}\label{xintGCtoCv}
\csa{xintGCtoCv}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} returns the list of
the corresponding convergents. The coefficients may be fractions, but must then
be inside braces. Or they may be macros, too.
The convergents will in the general case be reducible. To put them into
irreducible form, one needs one more step, for example it can be done
with |\xintApply\xintIrr|.
\begin{everbatim*}
\[\xintListWithSep{,}{\xintApply\xintTeXFrac
{\xintGCtoCv{3+{-2}/{7/2}+{3/4}/12+{-56}/3}}}\]
\[\xintListWithSep{,}{\xintApply\xintTeXFrac{\xintApply\xintIrr
{\xintGCtoCv{3+{-2}/{7/2}+{3/4}/12+{-56}/3}}}}\]
\end{everbatim*}
\subsection{\csh{xintFtoCv}}\label{xintFtoCv}
\csa{xintFtoCv}|{f}|\etype{\Ff} returns the list of the (braced) convergents of
|f|, with no separator. To be treated with \csbxint{AssignArray} or
\csbxint{ListWithSep}.
\begin{everbatim*}
\[\xintListWithSep{\to}{\xintApply\xintTeXFrac{\xintFtoCv{5211/3748}}}\]
\end{everbatim*}
\subsection{\csh{xintFtoCCv}}\label{xintFtoCCv}
\csa{xintFtoCCv}|{f}|\etype{\Ff} returns the list of the (braced) centered
convergents of |f|, with no separator. To be treated with \csbxint{AssignArray}
or \csbxint{ListWithSep}.
\begin{everbatim*}
\[\xintListWithSep{\to}{\xintApply\xintTeXFrac{\xintFtoCCv{5211/3748}}}\]
\end{everbatim*}
\subsection{\csh{xintCntoF}}\label{xintCntoF}
\csa{xintCntoF}|{N}{\macro}|\etype{\numx f} computes the fraction |f| having
coefficients |c(j)=\macro{j}| for |j=0,1,...,N|. The |N| parameter is given to a
|\numexpr|. The values of the coefficients, as returned by |\macro| do not have
to be positive, nor integers, and it is thus not necessarily the case that the
original |c(j)| are the true coefficients of the final |f|.
\begin{everbatim*}
\def\macro #1{\the\numexpr 1+#1*#1\relax} \xintCntoF {5}{\macro}
\end{everbatim*}
This example shows that the fraction is output with a trailing number in square
brackets (representing a power of ten), this is for consistency with what do
most macros of \xintfracname, and does not have to be always this annoying |[0]|
as the coefficients may for example be numbers in scientific notation. To avoid
these trailing square brackets, for example if the coefficients are known to be integers, there is always the possibility to filter the output via
\csbxint{PRaw}, or \csbxint{Irr} (the latter is overkill in the case of integer
coefficients, as the fraction is guaranteed to be irreducible then).
\subsection{\csh{xintGCntoF}}\label{xintGCntoF}
\csa{xintGCntoF}|{N}{\macroA}{\macroB}|\etype{\numx ff} returns the fraction |f|
corresponding to the inline generalized continued fraction
|a0+b0/a1+b1/a2+....+b(N-1)/aN|, with |a(j)=\macroA{j}| and |b(j)=\macroB{j}|.
The |N| parameter is given to a |\numexpr|.
\begin{everbatim*}
\def\coeffA #1{\the\numexpr #1+4-3*((#1+2)/3)\relax }%
\def\coeffB #1{\the\numexpr \ifodd #1 -\fi 1\relax }% (-1)^n
\[\xintGCFrac{\xintGCntoGC {6}{\coeffA}{\coeffB}} =
\xintTeXFrac{\xintGCntoF {6}{\coeffA}{\coeffB}}\]
\end{everbatim*}
There is also \csbxint{GCntoGC} to get the `inline format' continued
fraction.
\subsection{\csh{xintCntoCs}}\label{xintCntoCs}
\csa{xintCntoCs}|{N}{\macro}|\etype{\numx f} produces the comma separated list
of the corresponding coefficients, from |n=0| to |n=N|. The |N| is given to a
|\numexpr|. %
\begin{everbatim*}
\xintCntoCs {5}{\macro}
\end{everbatim*}
\begin{everbatim*}
\[ \xintTeXFrac{\xintCntoF{5}{\macro}}=\xintCFrac{\xintCntoF {5}{\macro}}\]
\end{everbatim*}
\subsection{\csh{xintCntoGC}}\label{xintCntoGC}
%
\csa{xintCntoGC}|{N}{\macro}|\etype{\numx f} evaluates the |c(j)=\macro{j}| from
|j=0| to |j=N| and returns a continued fraction written in inline format:
|{c(0)}+1/{c(1)}+1/...+1/{c(N)}|. The parameter |N| is given to a |\numexpr|.
The coefficients, after expansion, are, as shown, being enclosed in an added
pair of braces, they may thus be fractions.
\begin{everbatim*}
\def\macro #1{\the\numexpr\ifodd#1 -1-#1\else1+#1\fi\relax/\the\numexpr 1+#1*#1\relax}
\fdef\x{\xintCntoGC {5}{\macro}}\meaning\x
\[\xintGCFrac{\xintCntoGC {5}{\macro}}\]
\end{everbatim*}
\subsection{\csh{xintGCntoGC}}\label{xintGCntoGC}
\csa{xintGCntoGC}|{N}{\macroA}{\macroB}|\etype{\numx ff} evaluates the
coefficients and then returns the corresponding
|{a0}+{b0}/{a1}+{b1}/{a2}+...+{b(N-1)}/{aN}| inline generalized fraction. |N| is
givent to a |\numexpr|. The coefficients are enclosed into pairs
of braces, and may thus be fractions, the fraction slash will not be
confused in further processing by the continued fraction slashes.
%
\begin{everbatim*}
\def\an #1{\the\numexpr #1*#1*#1+1\relax}%
\def\bn #1{\the\numexpr \ifodd#1 -\fi 1*(#1+1)\relax}%
$\xintGCntoGC {5}{\an}{\bn}=\xintGCFrac {\xintGCntoGC {5}{\an}{\bn}} =
\displaystyle\xintTeXFrac {\xintGCntoF {5}{\an}{\bn}}$\par
\end{everbatim*}
\subsection{\csh{xintCstoGC}}\label{xintCstoGC}
\csa{xintCstoGC}|{a,b,..,z}|\etype{f} transforms a comma separated list (or
something expanding to such a list) into an `inline format' continued fraction
|{a}+1/{b}+1/...+1/{z}|. The coefficients are just copied and put within braces,
without expansion. The output can then be used in \csbxint{GCFrac} for example.
\begin{everbatim*}
\[\xintGCFrac {\xintCstoGC {-1,1/2,-1/3,1/4,-1/5}}=\xintTeXsignedFrac{\xintCstoF {-1,1/2,-1/3,1/4,-1/5}}\]
\end{everbatim*}
\subsection{\csh{xintiCstoF}, \csh{xintiGCtoF}, \csh{xintiCstoCv}, \csh{xintiGCtoCv}}\label{xintiCstoF}
\label{xintiGCtoF}
\label{xintiCstoCv}
\label{xintiGCtoCv}
Essentially\etype{f} the same as the corresponding macros without the
`i', but for integer-only input. Infinitesimally faster, mainly for
internal use by the package.
\subsection{\csh{xintGCtoGC}}\label{xintGCtoGC}
\csa{xintGCtoGC}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} expands (with the
usual meaning) each one of the coefficients and returns an inline continued
fraction of the same type, each expanded coefficient being enclosed within
braces.
%
\begin{everbatim*}
\fdef\x {\xintGCtoGC {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/%
\xintiiFac {6}+\xintCstoF {2,-7,-5}/16}} \meaning\x
\end{everbatim*}
To be honest I have forgotten for which purpose I wrote this macro in the first
place.
\subsection{Euler's number \texorpdfstring{$e$}{e}}\label{ssec:e-convergents}
Let us explore
the convergents of Euler's number $e$.
\smallskip The volume of computation is kept minimal by the following steps:
\begin{itemize}
\item a comma separated list of the first 36 coefficients is produced by
\csbxint{CntoCs},
\item this is then given to \csbxint{iCstoCv} which produces the list of the
convergents (there is also \csbxint{CstoCv}, but our
coefficients being integers we used the infinitesimally
faster \csbxint{iCstoCv}),
\item then the whole list was converted into a sequence of one-line paragraphs,
each convergent becomes the argument to a macro printing it
together with its decimal expansion with 30 digits after the decimal point.
\item A count register |\cnta| was used to give a line count serving as a visual
aid: we could also have done that in an expandable way, but well, let's relax
from time to time\dots
\end{itemize}
\begin{everbatim*}
\def\cn #1{\the\numexpr\ifcase \numexpr #1+3-3*((#1+2)/3)\relax
1\or1\or2*(#1/3)\fi\relax }
% produces the pattern 1,1,2,1,1,4,1,1,6,1,1,8,... which are the
% coefficients of the simple continued fraction of e-1.
\cnta 0
\def\mymacro #1{\advance\cnta by 1
\noindent
\hbox to 3em {\hfil\small\dtt{\the\cnta.} }%
$\xintTrunc {30}{\xintAdd {1[0]}{#1}}\dots=
\xintTeXFrac{\xintAdd {1[0]}{#1}}$}%
\xintListWithSep{\vtop to 6pt{}\vbox to 12pt{}\par}
{\xintApply\mymacro{\xintiCstoCv{\xintCntoCs {35}{\cn}}}}
\end{everbatim*}
\smallskip
% The actual computation of the list of all 36 convergents accounts for
% only 8\% of the total time (total time equal to about 5 hundredths of a second
% in my testing, on my laptop): another 80\% is occupied with the computation of
% the truncated decimal expansions (and the addition of 1 to everything as the
% formula gives the continued fraction of $e-1$).
One can with no problem compute
much bigger convergents. Let's get the 200th convergent. It turns out to
have the same first 268 digits after the decimal point as $e-1$. Higher
convergents get more and more digits in proportion to their index: the 500th
convergent already gets 799 digits correct! To allow speedy compilation of the
source of this document when the need arises, I limit here to the 200th
convergent.
% (getting the 500th took about 1.2s on my laptop last time I tried,
% and the 200th convergent is obtained ten times faster).
\begin{everbatim*}
\fdef\z {\xintCntoF {199}{\cn}}%
\begingroup\parindent 0pt \leftskip 2.5cm
\indent\llap {Numerator = }\printnumber{\xintNumerator\z}\par
\indent\llap {Denominator = }\printnumber{\xintDenominator\z}\par
\indent\llap {Expansion = }\printnumber{\xintTrunc{268}\z}\dots\par\endgroup
\end{everbatim*}
One can also use a centered continued fraction: we get more digits but there are
also more computations as the numerators may be either
$1$ or $-1$.
\ifnum\NoSourceCode=1
\clearpage
\def\xintRunningHeader{{\inheadertrue\catcode`,12\relax
\DOCxintfrontpage,
\DOCxintexprintro,
\xintbundlename}}
\part{The \xintexprname and allied packages source code (not
included, see \textcolor{verbcolor}{\texttt{xintsource.pdf}})}
\markboth{\makebox[0pt]{\xintRunningHeader}}{\makebox[0pt]{\xintRunningHeader}}
\vspace{1cm}
\begin{framed}
%\small % not now that there is the Part which is rather large
This documentation has been compiled without including the
commented source code, which is available in the separate file
|xintsource.pdf|,
and will open in a PDF viewer via:
%
\centeredline{|texdoc xintsource.pdf|}
To produce a file |xint-calx.pdf| including both the user
documentation and the source code:
\begin{itemize}
\item acquire |xint-calx.dtx| from
\centeredline{\url{https://www.ctan.org/tex-archive/macros/generic/xint}}
\item execute |latex xint-calx.dtx| sufficiently many times (at least three), then
|dvipdfmx|, or use |pdflatex|.
\end{itemize}
One can first execute |etex| on |xint-calx.dtx| to
extract files.
\end{framed}
\fi
\clearpage
\let\xintcfracnameUp\undefined
\ifnum\doxintsource=1
+fi
+catcode`\ 0
\catcode0 15 % retour à la normale, peu importe
\catcode`\+ 12
\makeatletter
\@gobble\fi
\StopEventually{\end{document}\endinput}
\makeatletter
\let\csh\cshnolabel
% \clearpage
% \newgeometry{%hmarginratio=4:3,
% hscale=0.7,vscale=0.75}% ATTENTION \newgeometry fait
% % un reset de vscale si on ne le
% % précise pas ici !!!
\AddToHook{env/macrocode/before}{\par@beforemacrocode}
\def\par@beforemacrocode{\par}
% for \csbxint etc...
\let\xintlabelprefix\xintimplabelprefix
\def\xintdocMacrocodeFallbackColorCmd{\normalcolor}
\def\xintdocPrivateColorCmd{\color{privatecommentcolor}}%
\def\xintdocPublicColorCmd{\normalcolor}
% stuff going to .toc file (and hence possibly impacting all TOCs regarding the looks
% of titles originating in the implementation part)
\etocdepthtag.toc {implementation}
\addtocontents{toc}{\gdef\string\tocstylesectionbracedcolor{{tocstylesectionimpcolor}}}
\etocignoredepthtags
\inmanualmaintocfalse % already the case anyhow
\etocsetnexttocdepth{section}
% make room for some small text on TOC page under the TOC
\def\tocstylesectionVSKIP{\vskip\medskipamount}
\etocsettocstyle {}{}
\ifnum\doxintsource=1 % xintsource.pdf
\medskip
\tableofcontents
\else
\ifnum\NoSourceCode=0 % xint-all.pdf
% this one needs to be reset as it is modified for the TOCs of the user
% manual. This way TOCs of Part III will be in xint-all.pdf as in
% xintsource.pdf
\let\etoctoclineleaders\orig@etoctoclineleaders
\fi
\bookmark[dest=imp,level=part]{Implementation}
\begin{minipage}[t][8\baselineskip][c]{\linewidth}
\RaisedTarget{imp}
\part{The \xintexprnameimp and allied packages source code}
\RaisedLabel[15]{partiii}
\end{minipage}
%! ne fonctionne pas ici
%! \RaisedLabel[15]{partiii}
%!
%! \smash n'est pas \long... mais \smash l'est mais \makesm@sh ne l'est pas
%! bon de tout façon plus de \par ici
%! \protected à cause du \smash sinon
%! ! TeX capacity exceeded, sorry [input stack size=10000].
%!
%! \protect \foreignlanguage {english}{\protect \bbl@restore@ac...
%! l.97 ...er}}{\makebox[0pt]{\xintImpRunningHeader}}
%!
%! Not using \hypersetup with linkcolor because a few pages are with
%! a TOC à cheval on two pages, and my eTOCs are configured to do
%! \hypersetup{hidelinks}
\protected\def\DOCxintfrontpage
{\smash{\vbox{\hbox{\perhapshyperref[frontpage]{{\color{xintnamecolor}TOC}}}%
\kern1ex
\hbox{\perhapshyperref[partiii]{{\color{xintnameimpcolor}TOC}}}}}}%
\medskip
\localtableofcontents
\fi
\medskip
\def\etocaftertochook{\addvspace{\bigskipamount}}
\etocsettocdepth{subsubsection}% 2015/09/15
% this is a parameter of the custom tocstyling for sections which we
% set to this value only after having typeset the main TOC of xintsource.pdf
% or TOC of Part III of xint-all.pdf
\def\tocstyleMARGEPAGENO{1.25em}
% modify the page headers
\def\xintImpRunningHeader{{\inheadertrue\catcode`,12\relax
\DOCxintfrontpage,
\xintkernelnameimp,
\xinttoolsnameimp,
\xintbinhexnameimp,
\calxcorenameimp,
\calxintnameimp,
\calxfpnameimp,
\xintcorenameimp,
\xintnameimp,
\xintfracnameimp,
\xintgcdnameimp,
\xintseriesnameimp,\newline
\xintcfracnameimp,
\calxtrignameimp, \calxtrigdatanameimp,
\calxlognameimp, \calxlogdatanameimp, \calxnameimp,
\xintexprnameimp}}
\markboth{\makebox[0pt]{\xintImpRunningHeader}}{\parbox{\linewidth}{\xintImpRunningHeader}}
\clearpage
\section{An introduction and a brief timeline}
This is \expandafter|\calxbndlversion| of \expandafter|\calxbndldate|.
The |xintchanges.md| file, included in the
\href{https://ctan.org/pkg/xint}{CTAN} upload, contains the complete list of
changes relevant to user level since the initial release of the package:
%
\centeredline{|texdoc xintchanges.md|}
It exists in HTML format at the package web page:
\centeredline{\url{https://jfbu.github.io/xint/CHANGES.html}}
\edef\foo{\columnsep\the\columnsep}
\columnsep5\fontcharwd\font`X\relax
\begin{multicols}{2}\small\raggedcolumns\columnsep9\fontcharwd\font`X\relax
At |1.4m| I added hyperlinks to the macro code. Each instance of a macro
in the code is linked with target the location of its definition (via |\def|
or |\let| or variants). This has been done via a heist on \ctanpackage{doc}
(|v2| version) automated indexing which has been transformed here into
automated hyperlinking.
Furthermore the codeline where the macro is defined will link to its
description in the user manual part of |xint.pdf|. In (optional build)
|xintsource.pdf| the link is more
modestly targeting the sectioning heading referencing the macro name, if
available. In |xint.pdf| the macros documented in the user manual
are marked with a \emph{source} link on top of them, targeting their
source code.
The sad truth however is that my code is poorly documented. The comments
\begin{itemize}[nosep]
\item are often too scarce,
\item have occasional excessive verbosity,
\item and are generally inadequate or irrelevant.
\end{itemize}
The macro comments have had a distinct tendency to record the changes across
releases or even those occurring during pre-release development phase,
rather than explaining the interface, or perhaps an algorithm. As I am
aware of that, I have a mechanism of \myenquote{private comments} which are
removed by the |dtx| build script. But then I sometimes use it en masse as
it would be too much work to clean-up the existing comments, and as a result
the code is not commented at all anymore... A typical example is with
\csbxint{iiSquareRoot} which is amply documented in the private sources but
only 10\% of it could be of any value to any other reader than myself and it
would be simply the description of what |#1|, |#2|, ... stand for. As a
result I converted at some point everything into
private comments. Extracting the useful parts describing the macro
parameters and checking they are actually still valid would be very
time-consuming. The real problem here is that the actual underlying
algorithms are rarely if ever described.
\end{multicols}
\foo
%\normalsize
\begin{itemize}
\item Release |2.0a1| of |2026/11/01|.
This is a major release in which the internals have been entirely
rewritten for speed. A new \calxnameimp package provides the functionality
of \csbxint{floateval} and \csbxint{iieval}, also available under the aliases
|\calxeval| and |\calxinteval|, respectively. The files \dtt{xintlog.sty}
and \dtt{xinttrig.sty} are gone, replaced by support files in the \dtt{calx}
namespace.
The \calxnameimp package adds almost no new user interface. The main novelty
is |\calxsetup|, which can be used to configure the signal handlers.
By default, no error condition is trapped in the sense of deliberately
raising a low-level TeX error. Instead, such conditions generate
\dtt{NaN}, \dtt{+Infinity}, or \dtt{-Infinity}, which propagate through subsequent
calculations.
The computations of trigonometric functions, logarithms, exponentials,
and powers are now roughly eight times faster.
The legacy interface of \xintfracnameimp is preserved unchanged. Its macros
do not accept non-finite values and still trap error conditions such as
division by zero. Loading \xintexprnameimp automatically loads \calxnameimp and
adds \csbxint{eval} for computations with fractions. Most documents should
compile unchanged, without requiring any modification to their sources.
\item Version |1.4q| dated |2026/10/31| was never released.
\begin{itemize}[nosep]
\item \xintexprname: since |1.4a|, |round(x,n)| and |floor(x,n)|
admit a negative second argument. This worked fine if the result
was involved in any operation, but depending on release since
|1.4a| and whether using \csbxint{floateval} or \csbxint{eval}
if the expression contained nothing else, it would either print
with garbage or cause a low-level \TeX{} error.
\item \xintexprname: binary, octal, or hexadecimal inputs all support
a fractional part; but due to an oversight regarding internal
numeric types, when the
integer part was zero, it could happen that the result was
erroneously given as zero, for example this was teh case
with |\xinteval{"0.0001}|.
\end{itemize}
\item Version |1.4p| dated |2026/03/01| was never released.
\begin{itemize}[nosep]
\item \xintkernelname: document (in the source code part of |xint.pdf|)
\csbxint{resettimer}, \csbxint{elapsedtime}
and \csbxint{theseconds}, already added at |1.4n|.
\item \xintbinhexname: add \csbxint{LowerHex} and \csbxint{UpperHex}.
\item \xinttoolsname: an array created via \csbxint{AssignArray}
can be used with negative indices.
\item \xintexprname: add all hyperbolic functions and their inverses.
\end{itemize}
\item Release |1.4o| of |2025/09/06| (with an |1.4n| the day before) is mainly
a maintenance release, after a few years in a dormant state. The long
expected overhaul of floating point is again postponed.
\begin{itemize}[nosep]
\item \xintbinhexname handles the octal base, and can manage (much) larger inputs,
\item |0x|, |0o|, and |0b| prefixes, and |'| added to the \csbxint{eval} syntax,
\item |[h]|, |[o]|, |[b]| optional parameter of \csbxint{iieval},
\item Babel active characters are auto-tamed in \csbxint{eval} (hotfix at |1.4o|,
the feature worked at |1.4n| with \csbxint{iieval} but not with the others),
\item Compatibility with Op\TeX{},
\item Compatibility with Con\TeX t (only |mkxl|).
\end{itemize}
The
extensive hyperlinking added in 2022 to the docs is better shown to user
because xint.pdf now (again) contains both the user manual and the commented
source code. The packaging was trimmed.
\item Release |1.4m| of |2022/06/09| is mainly a documentation upgrade, which
added hyperlinks inside the commented macro code, as well as from the user
manual to the source code (in |xint-all.pdf|, which is an optional
build). It adds compatibility with \ctanpackage{miniltx}. It also
inaugurates usage of the engine string comparison primitive.
\item Release |1.4i| of |2021/06/11|: extension of the
«simultaneous assignments» concept (backwards compatible).
\item Release |1.4g| of |2021/05/25|:
powers are now parsed in a right associative way. Removal of the
single-character operators |&|, \verb=|=, and |=| (deprecated at |1.1|).
Reformatted expandable error messages.
\item Release |1.4e| of |2021/05/05|: logarithms and exponentials up to 62
digits, trigonometry still mainly done at high level but with guard digits
so all digits up to the last one included can be trusted for faithful
rounding and high probability of correct rounding.
\item Release |1.4| of |2020/01/31|: \xintexprnameimp overhaul to use
|\expanded| based expansion control. Many new features, in particular
support for input and output of nested structures. Breaking changes, main
ones being the (provisory) drop of |x*[a, b,...]|, |x+[a, b,...]| et al.\@
syntax and the requirement of |\expanded| primitive (currently required only
by \xintexprnameimp).
\item Release |1.3e| of |2019/04/05|: packages \xinttrignameimp, \xintlognameimp;
\csa{xintdefefunc} ``non-protected'' variant of \csbxint{deffunc} (at |1.4|
the two got merged and \csa{xintdefefunc} became a deprecated alias for
\csbxint{deffunc}).
Indices removed from |xintsource.pdf|.
% Their functionality is advantageously
% made available via the search function in PDF viewers. Already the local
% tables of contents are useful enough most of the time.
\item Release |1.3d| of |2019/01/06|: fix of |1.2p| bug for division with a
zero dividend and a one-digit divisor, \csbxint{eval} et al. wrappers,
|gcd()| and |lcm()| work with fractions.
\item Release |1.3c| of |2018/06/17|: documentation better hyperlinked,
indices added to |xintsource.pdf|. Colon in |:=| now optional for
\csbxint{defvar} and \csbxint{deffunc}.
\item Release |1.3b| of |2018/05/18|: randomness related additions (still WIP).
\item Release |1.3a| of |2018/03/07|: efficiency fix of the mechanism for
recursive functions.
\item Release |1.3| of |2018/03/01|: addition and subtraction use
systematically least common multiple of denominators. Extensive
under-the-hood refactoring of \csbxint{NewExpr} and \csbxint{deffunc} which
now allow recursive definitions. Removal of |1.2o| deprecated macros.
\item Release |1.2q| of |2018/02/06|: fix of |1.2l| subtraction bug
in special situation; tacit multiplication extended to cases such as
|10!20!30!|.
\item Release |1.2p| of |2017/12/05|: maps |//| and |/:| to the floored, not
truncated, division. Simultaneous assignments possible with \csbxint{defvar}.
Efficiency improvements in \xinttoolsnameimp.
\item Release |1.2o| of |2017/08/29|: massive deprecations of those macros
from \xintcorenameimp and \xintnameimp which filtered their arguments via
\csbxint{Num}.
\item Release |1.2n| of |2017/08/06|: improvements of \xintbinhexnameimp.
\item Release |1.2m| of |2017/07/31|: rewrite of \xintbinhexnameimp in the
style of the |1.2| techniques.
\item Release |1.2l| of |2017/07/26|: under the hood efficiency improvements
in the style of the |1.2| techniques; subtraction refactored. Compatibility
of most \xintfracnameimp macros with arguments using non-delimited
|\the\numexpr| or |\the\mathcode| etc...
\item Release |1.2i| of |2016/12/13|: under the hood efficiency improvements
in the style of the |1.2| techniques.
\item Release |1.2| of |2015/10/10|: complete refactoring of the core
arithmetic macros and faster \csbxint{expr} parser.
\item Release |1.1| of |2014/10/28|: extensive changes in \xintexprnameimp.
Addition and subtraction do not multiply denominators blindly but sometimes
produce smaller ones. Also with that release, packages \xintkernelnameimp
and \xintcorenameimp got extracted from \xinttoolsnameimp and \xintnameimp.
\item Release |1.09g| of |2013/11/22|: the \xinttoolsnameimp package is
extracted from \xintnameimp; addition of \csbxint{loop} and \csbxint{iloop}.
\item Release |1.09c| of |2013/10/09|: \csbxint{For}, \csa{xintNewNumExpr}
(ancestor of \csbxint{NewExpr}/\csbxint{deffunc} mechanism).
\item Release |1.09a| of |2013/09/24|: support for functions by \xintexprnameimp.
\item Release |1.08| of |2013/06/07|: the \xintbinhexnameimp package.
\item Release |1.07| of |2013/05/25|: support for floating point numbers
added to \xintfracnameimp and first release of the \xintexprnameimp package
(provided
\csbxint{expr} and \csbxint{floatexpr}).
\item Release |1.04| of |2013/04/25|: the \xintcfracnameimp package.
\item Release |1.03| of |2013/04/14|: the \xintfracnameimp and
\xintseriesnameimp packages.
\item Release |1.0| of |2013/03/28|: initial release of the \xintnameimp and
\xintgcdnameimp packages.
\end{itemize}
%\clearpage
% \macrocode
% ==========
% 2014/11/04 did some hack with active characters à la upquote for straight
% quotes, but this is now irrelevant as we use suitable font from newtxtt with
% straight quotes.
% doc.sty does \AtBeginDocument{\let\macro@font\MacroFont} and formerly I
% overwrote \macro@font to use a newtxtt font with a slashed 0 in the
% implementation part.
% 2022/05/17 removes this, but I still need to redefine \macro@font to remove some
% stuff I formerly added to \MacroFont and which is only useful for the user manual.
\def\macro@font {\ttfamily }
% no problem as * is not "special" so the active catcode will not be reset
\AddToHook{env/macrocode/begin}{\makestarlowast}
\AddToHook{env/macrocode/after}{\@nobreakfalse}
\AddToHook{env/macrocode/begin}{\partopsep0pt\relax}
\begingroup
\catcode`\|=\z@ \catcode`\[=\@ne \catcode`\]=\tw@
\catcode`\{=12 \catcode`\}=12
% Let % be active to use a color for it and gray-out
% comments left in code (there are few)
\catcode`\%=13 \catcode`\ =\active \catcode`\\=\active
|gdef|xmacro@code#1% \end{macrocode}[#1|end[macrocode]]
|endgroup
\begingroup\catcode`\%=\active\catcode`\^^M 13
\gdef%{\begingroup\color{macrocodecommentcolor}\@percentchar\odef
{\expandafter\endgroup
}}\endgroup
\def\xintMakePrivateLetters{\catcode`: 11 \catcode`? 11 \catcode`@ 11
\catcode`^ 11 \catcode`_ 11 }
\def\xintexprMakePrivateLetters{\xintMakePrivateLetters \catcode`! 11 }
\let\MakePrivateLetters\xintMakePrivateLetters
\odef\init@crossref{\init@crossref%
\everypar{\refstepcounter{CodelineNo}%
\llap{{\xintdocMacrocodeFallbackColorCmd\theCodelineNo}\
\hskip\@totalleftmargin}%
}%
\catcode`\%\active
}%
\def\scan@macro{%
% we do not insert it yet
% \special@escape@char
\step@checksum
% \ifscan@allowed
\let\macro@namepart\@empty
% we need this for reasons explained below
\let\macro@spacepart\@empty
\def\next{\futurelet\next\macro@switch}%
% \else \let\next\@empty \fi
\next
}
% unchanged:
% \def\macro@switch{\ifcat\noexpand\next a%
% \let\next\macro@name
% \else \let\next\short@macro \fi
% \next}
\def\short@macro#1{\special@escape@char#1}
% \def\macro@name#1{\edef\macro@namepart{\macro@namepart#1}%
% \futurelet\next\more@macroname}
% \def\more@macroname{\ifcat\noexpand\next a%
% \let\next\macro@name
% \else \let\next\macro@finish \fi
% \next}
\def\more@macroname{\ifcat\noexpand\next a%
\expandafter\macro@name
% we keep the \next for usage later and start filtering out of the way spaces
% this is caused by necessity of handling things such as \let\foo\bar
% but also not be fooled by \let#6\macro
\else \expandafter\macro@gatherspaces \fi
}
\def\macro@gatherspaces{%
\ifx\next\@xobeysp
\expandafter\macro@gatherspaces@i
\else
\expandafter\macro@finish
\fi}%
\def\macro@gatherspaces@i#1{%
\odef\macro@spacepart{\macro@spacepart#1}% #1 = active space
\futurelet\next\macro@gatherspaces}%
\newif\iflabelmacro@allowed
\newcounter{xintMacroCnt}
\def\xintimplabelprefix{src-}
\let\xintdoclabelprefix\empty
\let\xintlabelprefix\xintimplabelprefix
\catcode`_ 11
\def\@name@namedef{@namedef}%
\def\macro@finish{%
\iflabelmacro@allowed
\expandafter\in@\expandafter{\expandafter.\macro@namepart,}%
{.csname,.expandafter,.noexpand,.else,%
.t,.w,.x,.y,.z,.XINT_x,.XINT_y,%
.XINT_tmpa,.XINT_tmpb,.XINT_tmpc,.XINT_tmpd,.XINT_tmpe,% _ is letter here
.XINT_expr_defbin_b,.XINT_expr_defbin_c,.XINT_expr_defbin_d,%
.empty,.space,}%
\ifin@
{\xintdocMacrocodeFallbackColorCmd\special@escape@char\macro@namepart}%
\else
\ifcsname alreadydefined-\macro@namepart\endcsname
\hyperref[xintmacro-\macro@namepart]{\special@escape@char\macro@namepart}%
\else
% this will make a rather large number of macro names in the string pool...
\global\expandafter\let\csname alreadydefined-\macro@namepart\endcsname\@empty
\label{xintmacro-\macro@namepart}%
\stepcounter{xintMacroCnt}%
% try to link to a labeled reference in the user documentation (xint-all.pdf)
\ifcsname r@\xintdoclabelprefix\macro@namepart\endcsname
{\hypersetup{linkcolor=macrocodelinktouserdoccolor}%
\hyperref[\xintdoclabelprefix\macro@namepart]%
{\textbf{\special@escape@char\macro@namepart}}}%
\else
% try to link to a labeled section in implementation part
\ifcsname r@\xintimplabelprefix\macro@namepart\endcsname
{\hypersetup{linkcolor=macrocodelinktosectioncolor}%
\hyperref[\xintimplabelprefix\macro@namepart]%
{\textbf{\special@escape@char\macro@namepart}}}%
\else
\textcolor{macrocodenewmacrocolor}{\special@escape@char\macro@namepart}%
\fi\fi
\fi
\fi
\labelmacro@allowedfalse
\expandafter\in@\expandafter{\expandafter.\macro@namepart,}{.expandafter,}%
\ifin@
\ifx\next\scan@macro\labelmacro@allowedtrue\fi
\fi
\else % end of labelmacro@allowedtrue branch
\expandafter\in@\expandafter{\expandafter.\macro@namepart,}%
{.@namedef,.CALX_fdef,}%
\ifin@\stepcounter{xintMacroCnt}\fi
\ifx\next\scan@macro
\expandafter\in@\expandafter{\expandafter.\macro@namepart,}%
{.def,.edef,.let,.gdef,.xdef,.odef,.oodef,.fdef,}%
\ifin@\labelmacro@allowedtrue\fi
\fi
\ifcsname r@xintmacro-\macro@namepart\endcsname
\hyperref[xintmacro-\macro@namepart]{\special@escape@char\macro@namepart}%
\else
{\xintdocMacrocodeFallbackColorCmd\special@escape@char\macro@namepart}%
\fi
\fi
% \ifnot@excluded
% \edef\@tempa{\noexpand\SpecialIndex{\bslash\macro@namepart}}%
% \@tempa
% \fi
\macro@spacepart
}%
\catcode`_ 8
{\sbox0{\color{macrocodenoncscolor}\xdef\foo{\current@color}}}
\ifpdf
\ifluatex
\edef\xintdoc@macrocode@pushcolor
{\pdfextension colorstack\noexpand\@pdfcolorstack push{\foo}\relax}
\def\xintdoc@macrocode@popcolor
{\pdfextension colorstack\@pdfcolorstack pop\relax}
\else
\edef\xintdoc@macrocode@pushcolor
{\pdfcolorstack\noexpand\@pdfcolorstack push{\foo}\relax}
\def\xintdoc@macrocode@popcolor{\pdfcolorstack\@pdfcolorstack pop\relax}
\fi
\else
\ifxetex
\edef\xintdoc@macrocode@pushcolor{\special{color push \foo}}
\def\xintdoc@macrocode@popcolor{\special{color pop}}
\else
\ifnum\Withdvipdfmx=1
\edef\xintdoc@macrocode@pushcolor{\special{color push \foo}}
\def\xintdoc@macrocode@popcolor{\special{color pop}}
\fi
\fi
\fi
\AddToHook{env/macrocode/before}{\xintdoc@macrocode@pushcolor}
\AddToHook{env/macrocode/end}{\xintdoc@macrocode@popcolor}
% let's use some more quiet color for links inside the code
\AddToHook{env/macrocode/begin}{\hypersetup{linkcolor=macrocodelinktocodelinecolor}}
% let code line numbers really be fully in the margin
\MacroIndent\z@
% HACK OF \@sect
% ==============
% goal is to add labels but without having to modify currently
% existing mark-up in sources. But KOMA makes an extra step needed.
% 2018/06/11
%
% 2026/02/28 (KOMA 3.49) redefines \scr@sect, not \@sect.
\let\original@sect\scr@sect
\def\scr@sect#1#2#3#4#5#6[#7]#8{%
\original@sect{#1}{#2}{#3}{#4}{#5}{#6}[{#7}]%
{\begingroup
% TODO: check if that 2018 comment is still valid:
%not possible because of KOMA wrappers
%\def\csh##1{\csa{##1}\label{\xintdoclabelprefix\detokenize{##1}}}%
\let\csh\cshintitle
\let\cshn\cshnintitle
#8%
\endgroup}%
}%
\def\cshintitle#1{\csa{#1}%
\label{\xintlabelprefix\detokenize{#1}}%
%\expandafter\DescribeMacro\csname#1\endcsname
}
% \csan: no backslash
\def\cshnintitle#1{\csan{#1}\label{\xintlabelprefix\detokenize{#1}}}
\def\storedlinecounts {}
\def\StoreCodelineNo #1{%
\edef\storedlinecounts{\storedlinecounts
{{#1}{\the\c@CodelineNo}{\the\c@xintMacroCnt}}%
}%
\global\c@CodelineNo \z@
\global\c@xintMacroCnt \z@
}
\def\FixInterMacrocodeVspace{%
\def\par@beforemacrocode{\gdef\par@beforemacrocode{\par}}%
\edef\xintdoc@macrocode@pushcolor{\xdef\noexpand\xintdoc@macrocode@pushcolor
{\xintdoc@macrocode@pushcolor}}%
\def\macro@font{\ttfamily\unskip\unskip\unskip\unskip\unskip\unskip
\global\def\macro@font{\ttfamily}%
\xintdoc@macrocode@pushcolor % ai hésité à le mettre au début de \@item
}%
\let\saved@@item\@item
\def\@item[##1]{\let\saved@addpenalty\addpenalty
\let\addpenalty\@gobble
\saved@@item[{##1}]%
\let\addpenalty\saved@addpenalty
\global\let\@item\saved@@item}%
}%
% This is obsolete it is when I was issueing at top level a \color not black.
% This is executed in a group
%\renewcommand\etocbeforetitlehook{\normalcolor}
% lverb environment (formerly \lverb|...|)
% =================
%
% This started as "long \verb" with same syntax, to be used in the code
% comments and spare endless hassle of adding mark-up for verbatim stuff. It
% also used \MicroFont like the custom \verb mainly used in user manual but
% also in xintsource for parts written "normally" (but using anyhow monospace
% font with variable space and hyphenation) which use |...| mark-up.
%
% It was turned into an environment June 3, 2022 (1.4m) and a mechanism with
% active backslash was added to identify control sequence names and add
% hyperlinks if available (labels are autogenerated from sectioning headings).
%
% lverb is a verbatim environment with free flowing of whitespace.
% It MUST be used with % characters at start of lines:
%
%\begin{lverb}
% all lines start with % and preferably with %
%\end{lverb}
%
% There must not be a space between % and \end{lverb}
%
% Inside the environment:
% - % is active and must be exclusively located at start of lines
% - \ is active and identifies control sequence names, with the _, :, ^, ?,
% and @ as letters. The \ should not follow immediately the %, except for
% the end of the environment %\end{lverb}
%
% It would arguably be better to have used specific mark-up in source but
% * then we need some way to have catcode 1 and 2 characters
% * well, I added no mark-up. I could spend one hour
% TeX-programming to reconstruct the source with mark-up
% but...
% - $ is a catcode 0 escape
% - space and end of lines are normal, text flows normally and uses the
% newtxttz font currently
% - & serves as comment character
% - (, :, and ) serve to enter, continue, and exit a sub-mode which does obey
% spaces and lines. One can use & at end of a line to let it flow with the
% next one if desired. They must immediately follow the % at start of line.
% - A dash after the % (%-) inserts a \par
% - also the * is active via \makestarlowast Apart from %, \, $, and & special
% characters are like in verbatim. So a macro \oneargcs is defined if one
% needs an escape for a macro with one parameter:
\catcode`_ 11
\def\oneargcs{\catcode`{1\catcode`}2 \onearg_cs}
\def\onearg_cs#1#2{#1{#2}\catcode`{12\catcode`}12\relax}
% This \oneargcs is to be used as $oneargcs${}
{\catcode32\active%
\gdef\myobeyspaces{\catcode32\active\def {\leavevmode\kern\fontcharwd\font`X}}}
%
% Let \ fetch control sequences names in lverb environments.
% For this the characters _, ^, : and ? are considered letters.
% \XINT_sptoken is defined in xinttools which is loaded here
% even if only typesetting xintsource.pdf
% \xint_dothis/\xint_orthat in xintkernel loaded by xinttools
\def\lverbbackslash{\bgroup\toks@{}\futurelet\lverb_token\lverb_bs}%
\def\lverb_bs{%
\ifx\lverb_token\XINT_sptoken\xint_dothis{\lverb_bs_end}\fi
% \ifx\lverb_token\lverbpercent should never happen
\ifcat\noexpand\lverb_token\relax\xint_dothis{\lverb_bs_end}\fi
\ifcat\lverb_token a\xint_dothis{\lverb_bs_i}\fi
\if\lverb_token _\xint_dothis{\lverb_bs_i}\fi
\if\lverb_token ^\xint_dothis{\lverb_bs_i}\fi
% TODO quel mark-up pour autoriser : and ? sans espace pour ponctuation
% TODO anglo-saxonne ?
% A bit cumbersome but $null or $empty can be used if : is used for
% punctuation and not as last letter of a cs, such as \foo$empty:
% I checked all instances with : and ? as last character found
% by this and added $empty in sources (June 3, 2022).
\if\lverb_token :\xint_dothis{\lverb_bs_i}\fi
\if\lverb_token ?\xint_dothis{\lverb_bs_i}\fi
\xint_orthat{\lverb_bs_end}%
}%
\def\lverb_bs_i#1{\toks@\expandafter{\the\toks@#1}\futurelet\lverb_token\lverb_bs}%
\def\lverb_bs_end{\expandafter\lverbcs\expandafter{\the\toks@}\egroup}%
\let\lverbcs\cs
% The % is active in the environment
% Some complications to change color of private lines and then restore
% (the ^^M is not active), so we split into two steps _a and _b
\newif\ifprivatecolorison
\def\lverbpercent {\catcode32\active\lverbpercent_a}%
\def\lverbpercent_a #1{%
\if\XINT_sptoken\detokenize{#1}\xint_dothis{%
\catcode32 10
\ifprivatecolorison\xintdocPublicColorCmd\fi
\privatecolorisonfalse
}\fi
% The %! mark-up is used for private things which are trimmed by the
% build-script out of the dtx.
\if!\detokenize{#1}\xint_dothis{%
\ifprivatecolorison
\else
\xintdocPrivateColorCmd
\privatecolorisontrue
\fi
\lverbpercent_b
}\fi
\xint_orthat{\lverbpercent_b{#1}}%
}%
\def\lverbpercent_b#1{%
\if\XINT_sptoken\detokenize{#1}\xint_dothis{\catcode32 10 }\fi
% Special mark-up after % to control linewrap
% %- says to start a new paragraph
\if-\detokenize{#1}\xint_dothis{\par #1}\fi
% %( start an obeylines+obeyspaces context
\if(\detokenize{#1}\xint_dothis{\par\bgroup\myobeyspaces\obeylines}\fi
\if:\detokenize{#1}\xint_dothis{}\fi
% I don't remember why this, it seems I want to kill next indentation
% after the obeylines context
\if)\detokenize{#1}\xint_dothis{\egroup\everypar{\hskip-\parindent\everypar{}}}\fi
% Introduce a \par token if we have two empty commented-out lines
% Or if we have a % at the end of the input line
\ifx#1\lverbpercent\xint_dothis{\catcode32 10 \par #1}\fi
% For tranformation of lverb into environment mark-up 2022/06/03
% The reason for the \detokenize{#1} upfront is that in original
% private sources there might a wrapper environment which has made
% the % alias to \lverbpercent already but not made the \ active
% and then %\begin{lverb} may be encountered with a
% catcode 0 backslash. If I did \if\@backslashchar\detokenize{#1}
% there would be trouble. This test identifies %\end in a
% somewhat fragile way but by convention my mark-up will never
% have %\ except for %\end{lverb}
\if\detokenize{#1}\@backslashchar\xint_dothis{\lverb@end}\fi
\xint_orthat{\catcode32 10 #1}%
}
\catcode`_ 8
% \long\def\lverb
\def\lverb@end end#1lverb#2{\end{lverb}}
\newenvironment{lverb}
{%
\sfcode`!=1000
\relax\ifhanged\else\par\smallskip\fi
\let\do\do@noligs \verbatim@nolig@list
\let\do\@makeother \dospecials
\catcode32 10 \catcode`\& 14 \catcode`\$ 0
\catcode`\% \active
\begingroup\lccode`\~`\%\lowercase{\endgroup\let~\lverbpercent}%
\catcode`\\ \active
\begingroup\lccode`\~`\\\lowercase{\endgroup\let~\lverbbackslash}%
\LverbFont
\ignorespaces
}{\par}
% This \@lverb was used before conversion into an environment
% \def\@lverb #1{\catcode`#1\active
% \lccode`\~`#1\lowercase{\def~}{\egroup\par}}%
\def\LverbFont {%
% pas concluant \itshape (June 3, 2022)
% pas concluant \bfseries
%\xintdocPublicColorCmd
\makestarlowast
}
% privatecodecomments
% ===================
% This is used in the xint*sty files (before being embedded in dtx)
% with %! lines. Those lines are removed from public xint-calx.dtx before
% upload to CTAN.
\newenvironment{privatecodecomments}
{\par \textbf{\textcolor{red}{COMMENTAIRES PRIVÉS.}}\par
\makestarlowast
\begingroup\lccode`\~`\%\lowercase{\endgroup\let~\lverbpercent}%
\catcode`\%\active}
{\par \textbf{\textcolor{red}{FIN DES COMMENTAIRES PRIVÉS.}}\par}
% \changed
% ========
% updated 2021/05/29 to use \xintreleasedate (always) and put
% second argument if non empty within square brackets.
% 2022/06/05 now says "Modified at", and does not display the optional
% argument, which contains actual date of the comment.
% I wonder if I should keep displaying release date.
% 2022/06/10 adds the \ifinchanged
\newif\ifhanged
\newcommand\changed[2][]{%
\par\smallskip\noindent
\textbf{Modified at #2\space(\xintreleasedate{#2})%\if\relax\detokenize{#1}\relax
%\else\space[commented #1]\fi
.}%
\hangindent\parindent
\hangedtrue
% This is absolutely NOT robust. By the way I added a hook to env/macrocode/before
% to do \par.
\everypar\expandafter\expandafter\expandafter
{\expandafter\the\expandafter\everypar
\expandafter\everypar\expandafter{\the\everypar}%
\hangedfalse}%
}
% \added
% ======
\newcommand\addedcalx[1]{\par Added at calx #1.}
% new 2022/05/16
\newcommand\added[2][]{%
\par\smallskip\noindent
\textbf{Added at #2\space(\xintreleasedate{#2})\if\relax\detokenize{#1}\relax
\else\space[on #1]\fi.}%
\hangindent\parindent
\hangedtrue
% This is absolutely NOT robust. By the way I added a hook to env/macrocode/before
% to do \par.
\everypar\expandafter\expandafter\expandafter
{\expandafter\the\expandafter\everypar
\expandafter\everypar\expandafter{\the\everypar}%
\hangedfalse}%
}
% hoping the \hangedfalse will not accumulate
% \xintreleasedate
% ================
% added 2021/05/29
% xint-dates.txt is produced from CHANGES.md by grep via Makefile rule
% 1.09 (2013/09/23) aajouté manuellement car pas dans CHANGES.md
% (il y avait un bug "a stray underscore in a code line of xintexpr.sty must
% be removed" et CTAN a annoncé seulement 1.09a)
%
\begingroup\endlinechar-1
\catcode`\`=\active
\def`#1 (#2)`{\expandafter\gdef\csname xintreleasedate_#1\endcsname{#2}}
`1.09 (2013/09/23)`% pas dans CHANGES.md car remplacé immédiatement par 1.09a
\@@input xint-dates.txt
\endgroup
\def\xintreleasedate#1{%
\ifcsname xintreleasedate_#1\endcsname
\csname xintreleasedate_#1\endcsname
\else
\immediate\write128{Pas de date pour #1 en ligne \the\inputlineno}%
\error
\fi
}
\expandafter\edef\csname xintreleasedate_\xintbndlversion\endcsname{\xintbndldate}
%% END OF MACRO DEFINITIONS FOR XINTSOURCE
\etocsettocstyle {\subsection* {Contents}
}
{}
% Hence, next will apply as well to the local tocs for the xintexpr, xinttrig,
% and xintlog parts which will be under the scope of \etocarticlestylenomarks.
% Memo: this is the sole place where we configure that hook.
\renewcommand\etocaftertitlehook{\etoctoccontentsline*{toctobookmark}{Contents}{2}}
\MakePercentIgnore
%\def\gardesactifs {^^A
%\catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11 }
%\def\gardesinactifs {^^A
%\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 }
%\gardesactifs
%\let\relax
%\let<*xintkernel>\gardesinactifs
%^^A--------------------------------------------------------
%<*xintkernel>^^A-------------------------------------------------
%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; sentence-end-double-space: t; eval: (auto-fill-mode -1); fill-paragraph-function: nil; -*-
% \clearpage\csname xintkernelnameUp\endcsname
% \let\MakePrivateLetters\xintMakePrivateLetters
% \section {Package \xintkernelnameimp implementation}
% \RaisedLabel{sec:kernelimp}
%
% \localtableofcontents
%
% \subsection{Introduction}
%
% This package provides the common minimal code base for loading management
% and catcode control and also a few programming utilities. With |1.2| a few
% more helper macros and all |\chardef|'s have been moved here. The package is
% loaded by both |xintcore.sty| and |xinttools.sty| hence by all other
% packages.
%
% \changed{1.1}
% Separated package.
%
% \changed{1.2i}
% \csbxint{replicate}, \csbxint{gobble}, \csbxint{LengthUpTo}
% and \csbxint{LastItem}, and faster \csbxint{Length}.
%
% \changed{1.3b}
% \csbxint{UniformDeviate}.
%
% \changed[2020/01/11]{1.4}
% \csbxint{Replicate}, \csbxint{Gobble}, \csbxint{LastOne}, \csbxint{FirstOne}.
%
% \changed{1.4l}
% Fix the |1.4| added bug that |\XINTrestorecatcodes| forgot to restore
% the catcode of |^||^A| which is set to |3| by |\XINTsetcatcodes|.
%
% \changed{1.4m}
% Fix incompatibility under \eTeX{} with \ctanpackage{miniltx}, if latter was
% loaded before \xintexprnameimp. The fix happens here because it relates to
% matters of |\ProvidesPackage|.
%
% \subsection{Catcodes, \protect\eTeX{} and reload detection}
%
% The code for reload detection was initially copied from \textsc{Heiko
% Oberdiek}'s packages, then modified.
%
% The method for catcodes was also initially directly inspired by these
% packages.
%
%\begin{lverb}
% 1.4l replaces Info level user messages issued in case of problems
% such as \numexpr not being available with Warning level messages (in the
% LaTeX terminolgy). Should arguably be Error level in that case.
%
% xintkernel.sty was the only xint package emitting such an Info, now Warning
% in case of being loaded twice (via \input in non-LaTeX). This was probably
% a left-over from initial development stage of the loading architecture for
% debugging. Starting with 1.4l, it will abort input silently in such case.
%
% Also at 1.4l I refactored a bit the loading code in the xint*sty files for
% no real reason other than losing time.
%\end{lverb}
% \begin{macrocode}
\begingroup\catcode61\catcode48\catcode32=10\relax%
\catcode13=5 % ^^M
\endlinechar=13 %
\catcode123=1 % {
\catcode125=2 % }
\catcode44=12 % ,
\catcode46=12 % .
\catcode58=12 % :
\catcode94=7 % ^
\def\space{ }\newlinechar10
\let\z\relax
\expandafter\ifx\csname numexpr\endcsname\relax
\expandafter\ifx\csname PackageWarningNoLine\endcsname\relax
\immediate\write128{^^JPackage xintkernel Warning:^^J%
\space\space\space\space
\numexpr not available, aborting input.^^J}%
\else
\PackageWarningNoLine{xintkernel}{\numexpr not available, aborting input}%
\fi
\def\z{\endgroup\endinput}%
\else
\expandafter\ifx\csname XINTsetupcatcodes\endcsname\relax
\else
\def\z{\endgroup\endinput}%
\fi
\fi
\ifx\z\relax\else\expandafter\z\fi%
% \end{macrocode}
% \subsubsection{\csh{XINTrestorecatcodes}, \csh{XINTsetcatcodes},
% \csh{XINTrestorecatcodesendinput}}
% \changed{1.4e}
%\begin{lverb}
% Renamed \XINT{set,restore}catcodes
% to be without underscores, to facilitate the reloading process
% for xintlog.sty and xinttrig.sty in uncontrolled contexts.
%\end{lverb}
% \changed{1.4l}
%\begin{lverb}
% Fix the 1.4 bug of omission of \catcode1 restore.
%
% Reordered all catcodes assignements for easier maintenance and dropped most
% disparate indications of which packages make use of which settings.
%
% The \XINTrestorecatcodes is somewhat misnamed as it is more a template
% to be used in an \edef to help define actual catcode restoring macros.
%
% However \edef needs usually { and } so there is a potential difficulty with
% telling people to do \edef\myrestore{\XINTrestorecatcodes}, and I almost
% added at 1.4l some \XINTsettorestore$empty:#1->\edef#1{\XINTrestorecatcodes} but
% well, this is not public interface anyhow. The reloading method of
% xintlog.sty and xinttrig.sty does protect itself though against such irreal
% usage possibility with non standard { or }.
%
% Removed at 1.4l the \XINT_setcatcodes and \XINT_restorecatcodes not used
% anywhere now. Used by old version of xintsession.tex, but not anymore since
% a while.
%\end{lverb}
% \changed{1.4n}
% Compatibility with Op\TeX. It has a cactode 11 letter, but \cs{abc_} or
% \cs{abc_d} will be interpreted un expectedly (but not \cs{abc_de}). So we
% must make sure this is deactivated during the whole duration of loading the
% \xintnameimp modules (perhaps it is mainly \xinttoolsnameimp which uses
% \cs{XINT_x}, \cs{XINT_y}, which is problematic).
%
% We need catcode letter |_| for tokenization of \cs{PrepareCatcodes} to let
% it define \csbXINT{restorecatcodes} conveniently for its usage in an
% \cs{edef} to query at that time the |_| status in Op\TeX.
% \begin{macrocode}
\catcode95=11 % _
\def\PrepareCatcodes
{%
\endgroup
\def\XINTrestorecatcodes
{% prepared for use in \edef
\catcode0=\the\catcode0 % ^^@
\catcode1=\the\catcode1 % ^^A
\catcode13=\the\catcode13 % ^^M
\catcode32=\the\catcode32 %
\catcode33=\the\catcode33 % !
\catcode34=\the\catcode34 % "
\catcode35=\the\catcode35 % #
\catcode36=\the\catcode36 % $
\catcode38=\the\catcode38 % &
\catcode39=\the\catcode39 % '
\catcode40=\the\catcode40 % (
\catcode41=\the\catcode41 % )
\catcode42=\the\catcode42 % *
\catcode43=\the\catcode43 % +
\catcode44=\the\catcode44 % ,
\catcode45=\the\catcode45 % -
\catcode46=\the\catcode46 % .
\catcode47=\the\catcode47 % /
\catcode58=\the\catcode58 % :
\catcode59=\the\catcode59 % ;
\catcode60=\the\catcode60 % <
\catcode61=\the\catcode61 % =
\catcode62=\the\catcode62 % >
\catcode63=\the\catcode63 % ?
\catcode64=\the\catcode64 % @
\catcode91=\the\catcode91 % [
\catcode93=\the\catcode93 % ]
\catcode94=\the\catcode94 % ^
\catcode95=\the\catcode95 % _
\catcode96=\the\catcode96 % `
\catcode123=\the\catcode123 % {
\catcode124=\the\catcode124 % |
\catcode125=\the\catcode125 % }
\catcode126=\the\catcode126 % ~
\endlinechar=\the\endlinechar\relax
\ifdefined\_ifmathsb\_ifmathsb\noexpand\_mathsbon\_fi\fi %
}%
% \end{macrocode}
%\begin{lverb}
% The \noexpand here before \endinput is required. This feels to me a bit
% surprising, but is a fact, and the source of this must be in the \edef
% implementation but I have not checked it out at this time.
%\end{lverb}
%
% \changed{1.4n}
% Compatibility with Op\TeX.
% \begin{macrocode}
\edef\XINTrestorecatcodesendinput
{%
\XINTrestorecatcodes\noexpand\endinput %
}%
\def\XINTsetcatcodes
{% standard settings with a few xint*sty specific ones
\catcode0=12 % for \romannumeral`&&@
\catcode1=3 % for safe separator &&A
\catcode13=5 % ^^M
\catcode32=10 %
\catcode33=12 % ! but used as LETTER inside xintexpr.sty
\catcode34=12 % "
\catcode35=6 % #
\catcode36=3 % $
\catcode38=7 % & SUPERSCRIPT for && as replacement of ^^
\catcode39=12 % '
\catcode40=12 % (
\catcode41=12 % )
\catcode42=12 % *
\catcode43=12 % +
\catcode44=12 % ,
\catcode45=12 % -
\catcode46=12 % .
\catcode47=12 % /
\catcode58=11 % : LETTER
\catcode59=12 % ;
\catcode60=12 % <
\catcode61=12 % =
\catcode62=12 % >
\catcode63=11 % ? LETTER
\catcode64=11 % @ LETTER
\catcode91=12 % [
\catcode93=12 % ]
\catcode94=11 % ^ LETTER
\catcode95=11 % _ LETTER
\catcode96=12 % `
\catcode123=1 % {
\catcode124=12 % |
\catcode125=2 % }
\catcode126=3 % ~ MATH SHIFT
\endlinechar=13 %
\ifdefined\_mathsboff\_mathsboff\fi % Compatibility with OpTeX
}%
\XINTsetcatcodes
}%
\PrepareCatcodes
% \end{macrocode}
% Other modules could possibly be loaded under a different catcode regime.
% (or with a different status of |_| under Op\TeX).
% \begin{macrocode}
\def\XINTsetupcatcodes {% for use by other modules
\edef\XINTrestorecatcodesendinput
{%
\XINTrestorecatcodes\noexpand\endinput %
}%
\XINTsetcatcodes
}%
% \end{macrocode}
% \subsection{Package identification}
%
% Inspired from \textsc{Heiko Oberdiek}'s packages.%
% \changed{1.09b}
% Re-usability in the other modules. Also I assume now that if |\ProvidesPackage|
% exists it then does define |\ver@.sty|, code of |HO| for some reason
% escaping me (compatibility with LaTeX 2.09 or other things ??) seems to set
% extra precautions. [nine years later I understood my mistake, see below].
%
% \changed{1.09c}
% Usage of \eTeX{} |\ifdefined|.
%
% \changed[2022/06/09]{1.4m}
% Nine years too late, I understand that the |HO| \myenquote{extra
% precautions} were there for some respectable reasons including
% |etex+miniltx| and surely other things I can not imagine. So let's now make
% sure |\ver@xintkernel.sty| and friends get defined on load, even if
% |\ProvidesPackage| exists! However I remain careless in using |\ifdefined|
% which could be fooled if some previous macro file ended up testing for
% |\ProvidesPackage| in a way letting it to |\relax|. I do not test for that.
% If I fixed that carelessness here I would have to fix it in other places
% where I use similarly |\ifdefined\RequirePackage| or
% |\ifdefined\PackageWarning| or whatever.
% \begin{macrocode}
\ifdefined\ProvidesPackage
\def\XINT_providespackage\ProvidesPackage#1[#2]{%
\ProvidesPackage{#1}[{#2}]%
\expandafter\ifx\csname ver@#1.sty\endcsname\relax
\expandafter\xdef\csname ver@#1.sty\endcsname{#2}%
\fi
}%
\else
\def\XINT_providespackage\ProvidesPackage#1[#2]{%
\immediate\write-1{Package: #1 #2}%
\expandafter\xdef\csname ver@#1.sty\endcsname{#2}%
}%
\fi
\XINT_providespackage
\ProvidesPackage {xintkernel}%
[2026/11/01 v2.0a1 Paraphernalia for the xint packages (JFB)]%
% \end{macrocode}
% \subsection{Constants}
% \begin{macrocode}
\chardef\xint_c_ 0
\chardef\xint_c_i 1
\chardef\xint_c_ii 2
\chardef\xint_c_iii 3
\chardef\xint_c_iv 4
\chardef\xint_c_v 5
\chardef\xint_c_vi 6
\chardef\xint_c_vii 7
\chardef\xint_c_viii 8
\chardef\xint_c_ix 9
\chardef\xint_c_x 10
%\chardef\xint_c_xi 11
\chardef\xint_c_xii 12
\chardef\xint_c_xiv 14
\chardef\xint_c_xvi 16
\chardef\xint_c_xvii 17
\chardef\xint_c_xviii 18
\chardef\xint_c_xx 20
\chardef\xint_c_xxii 22
\chardef\xint_c_ii^v 32
\chardef\xint_c_ii^vi 64
%\chardef\xint_c_c 100
\chardef\xint_c_ii^vii 128
\mathchardef\xint_c_ii^viii 256
\mathchardef\xint_c_ii^ix 512
\mathchardef\xint_c_ii^xii 4096
%\mathchardef\xint_c_m 1000
% \end{macrocode}
% Some of these usages of \cs{newcount} were in \xintcorenameimp or in
% \xintnameimp or in \xintbinhexnameimp possibly conditionally on whether
% (pdf)\cs{uniformdeviate} is available. At |1.4n|, let's not bother with
% outdated restrictions of \TeX.
%
% \changed{1.4p} new naming scheme without |^| regarding higher powers of ten,
% for matters of easier interconnection with \ctanpackage{poormanlog}.
% \begin{macrocode}
\ifdefined\m@ne\let\xint_c_mone\m@ne
\else\csname newcount\endcsname\xint_c_mone \xint_c_mone -1 %
\fi
\mathchardef\xint_c_e_iv 10000
\newcount\xint_c_e_v \xint_c_e_v 100000
%\newcount\xint_c_e_vi \xint_c_e_vi 1000000
%\newcount\xint_c_e_vii \xint_c_e_vii 10000000
\newcount\xint_c_e_viii \xint_c_e_viii 100000000
\newcount\xint_c_e_ix \xint_c_e_ix 1000000000
\newcount\xint_c_e_viii_mone \xint_c_e_viii_mone 99999999
\newcount\xint_c_nine_e_viii \xint_c_nine_e_viii 900000000
\newcount\xint_c_xi_e_viii_mone \xint_c_xi_e_viii_mone 1099999999
\newcount\xint_c_xii_e_viii \xint_c_xii_e_viii 1200000000
% \end{macrocode}
% \changed{1.4n}
% For some reason this next one used to be defined by \cs{newcount}
% but \cs{mathchardef} is ok.
% \begin{macrocode}
\mathchardef\xint_c_ii^xiv 16384 % "4000, 2**14
\newcount\xint_c_ii^xv \xint_c_ii^xv 32768 % 2**15
\newcount\xint_c_ii^xvi \xint_c_ii^xvi 65536 % 2**16
\newcount\xint_c_ii^xxi \xint_c_ii^xxi 2097152 % "200000, 2**21
% \end{macrocode}
% \subsection{Token management utilities}
% \added{1.2}
% Check if \cs{empty} and \cs{space} have their standard meanings
% and raise a warning if not.
% \changed{1.4}
% Warn user if needed, and force then \cs{empty} and \cs{space} to have
% their standard meanings. This will be triggered even if the sole
% difference is that they are \cs{long}.
% \changed{1.4n}
% The Warning used to be emitted only to the log file, make it go to
% console output as well. But why do I spend time on such silly things.
% \begin{macrocode}
\def\XINT_tmpa { }%
\ifx\XINT_tmpa\space\else
\immediate\write128{Package xintkernel Warning:}%
\immediate\write128{The \string\space\XINT_tmpa macro does not have its
meaning as in Plain or LaTeX, but is:}%
\immediate\write128{\XINT_tmpa\XINT_tmpa\XINT_tmpa\XINT_tmpa\meaning\space.}%
\let\space\XINT_tmpa
\immediate\write128{Forcing it to be the usual one. Fingers crossed.}%
\fi
\def\XINT_tmpa {}%
\ifx\XINT_tmpa\empty\else
\immediate\write128{Package xintkernel Warning:}%
\immediate\write128{The \string\empty\space macro does not have its
meaning as in Plain or LaTeX, but is:}%
\immediate\write128{\space\space\space\space\meaning\empty.}%
\let\empty\XINT_tmpa
\immediate\write128{Forcing it to be the usual one. Fingers crossed.}%
\fi
\let\XINT_tmpa\relax
\let\xint_gobble_\empty
\long\def\xint_gobble_i #1{}%
\long\def\xint_gobble_ii #1#2{}%
\long\def\xint_gobble_iii #1#2#3{}%
\long\def\xint_gobble_iv #1#2#3#4{}%
\long\def\xint_gobble_v #1#2#3#4#5{}%
\long\def\xint_gobble_vi #1#2#3#4#5#6{}%
\long\def\xint_gobble_vii #1#2#3#4#5#6#7{}%
\long\def\xint_gobble_viii #1#2#3#4#5#6#7#8{}%
% \end{macrocode}
% \changed{1.3b}
% Moved here |\xint_gobandstop_...| macros because this is handy for
% \csbxint{RandomDigits}.
%
% For legacy reasons most top level macros use |\romannumeral0| trigger. This
% is stopped by a space token. Later in the history of the package
% |\romanumeral`&&@| was used with |&| of catcode 7. Also there are a few
% instances of |\romannumeral| ended by |\z@|. But |\romannumeral0| remains
% the publicly documented one, with CamelCase macros using it as prefix to
% lowercased macros.
% \begin{macrocode}
\let\xint_gob_andstop_\space
\long\def\xint_gob_andstop_i #1{ }%
\long\def\xint_gob_andstop_ii #1#2{ }%
\long\def\xint_gob_andstop_iii #1#2#3{ }%
\long\def\xint_gob_andstop_iv #1#2#3#4{ }%
\long\def\xint_gob_andstop_v #1#2#3#4#5{ }%
\long\def\xint_gob_andstop_vi #1#2#3#4#5#6{ }%
\long\def\xint_gob_andstop_vii #1#2#3#4#5#6#7{ }%
\long\def\xint_gob_andstop_viii #1#2#3#4#5#6#7#8{ }%
\let\xint_stop_aftergobble\xint_gob_andstop_i
\long\def\xint_firstofone #1{#1}%
\long\def\xint_firstoftwo #1#2{#1}%
\long\def\xint_secondoftwo #1#2{#2}%
\long\def\xint_stop_atfirstofone #1{ #1}%
\long\def\xint_stop_atfirstoftwo #1#2{ #1}%
\long\def\xint_stop_atsecondoftwo #1#2{ #2}%
\long\def\xint_exchangetwo_keepbraces #1#2{{#2}{#1}}%
% \end{macrocode}
% Moved here from \xintnameimp at |1.4n|.
% \begin{macrocode}
\long\def\xint_firstofthree #1#2#3{#1}%
\long\def\xint_secondofthree #1#2#3{#2}%
\long\def\xint_thirdofthree #1#2#3{#3}%
\long\def\xint_stop_atfirstofthree #1#2#3{ #1}%
\long\def\xint_stop_atsecondofthree #1#2#3{ #2}%
\long\def\xint_stop_atthirdofthree #1#2#3{ #3}%
% \end{macrocode}
% \subsection{``gob til'' macros and UD style fork}
% \begin{macrocode}
\long\def\xint_gob_til_R #1\R {}%
\long\def\xint_gob_til_W #1\W {}%
\long\def\xint_gob_til_Z #1\Z {}%
\long\def\xint_gob_til_zero #10{}%
\long\def\xint_gob_til_one #11{}%
\long\def\xint_gob_til_zeros_iii #1000{}%
\long\def\xint_gob_til_zeros_iv #10000{}%
\long\def\xint_gob_til_eightzeroes #100000000{}%
\long\def\xint_gob_til_dot #1.{}%
\long\def\xint_gob_til_G #1G{}%
\long\def\xint_gob_til_minus #1-{}%
\long\def\xint_UDzerominusfork #10-#2#3\krof {#2}%
\long\def\xint_UDzerofork #10#2#3\krof {#2}%
\long\def\xint_UDsignfork #1-#2#3\krof {#2}%
\long\def\xint_UDwfork #1\W#2#3\krof {#2}%
\long\def\xint_UDXINTWfork #1\XINT_W#2#3\krof {#2}%
\long\def\xint_UDzerosfork #100#2#3\krof {#2}%
\long\def\xint_UDonezerofork #110#2#3\krof {#2}%
\long\def\xint_UDsignsfork #1--#2#3\krof {#2}%
\let\xint:\char
\long\def\xint_gob_til_xint:#1\xint:{}%
\long\def\xint_gob_til_^#1^{}%
\def\xint_bracedstopper{\xint:}%
\long\def\xint_gob_til_exclam #1!{}% This ! has catcode 12
\long\def\xint_gob_til_sc #1;{}%
% \end{macrocode}
% \subsection{\csh{xint_afterfi}}
% \begin{macrocode}
\long\def\xint_afterfi #1#2\fi {\fi #1}%
% \end{macrocode}
% \subsection{\csh{xint_bye}, \csh{xint_Bye}}
% \changed{1.09}
% |\xint_bye|
% \changed{1.2i}
%^^A test de lverb
%\begin{lverb}
% \xint_Bye for \xintDSRr and \xintRound. Also \xint_stop_afterbye.
%\end{lverb}
% \begin{macrocode}
\long\def\xint_bye #1\xint_bye {}%
\long\def\xint_Bye #1\xint_bye {}%
\long\def\xint_stop_afterbye #1\xint_bye { }%
% \end{macrocode}
% \subsection{\csh{xintdothis}, \csh{xintorthat}}
% \changed{1.1}
% \changed{1.2} Names without underscores.
%
% To be used this way:
%\begin{lverb}
%( \if..\xint_dothis{..}\fi
%: \if..\xint_dothis{..}\fi
%: \if..\xint_dothis{..}\fi
%: ...more such...
%: \xint_orthat{...}
%)
%\end{lverb}
% Ancient testing indicated it is more efficient to list first the more
% improbable clauses.
% \begin{macrocode}
\long\def\xint_dothis #1#2\xint_orthat #3{\fi #1}% 1.1
\let\xint_orthat \xint_firstofone
\long\def\xintdothis #1#2\xintorthat #3{\fi #1}%
\let\xintorthat \xint_firstofone
% \end{macrocode}
% \subsection{\csh{xint_zapspaces}}
% \changed{1.1}
% This little (quite fragile in the normal sense i.e. non robust in the normal
% sense of programming lingua) utility zaps leading, intermediate, trailing,
% spaces in completely expanding context (|\edef|, |\csname...\endcsname|).
% \centeredline{Usage: |\xint_zapspaces foo\xint_gobble_i|}
%
% Explanation: if there are leading spaces, then the first |#1| will be empty,
% and the first |#2| being undelimited will be stripped from all the remaining
% leading spaces, if there was more than one to start with. Of course
% brace-stripping may occur. And this iterates: each time a |#2| is removed,
% either we then have spaces and next |#1| will be empty, or we have no spaces
% and |#1| will end at the first space. Ultimately |#2| will be
% |\xint_gobble_i|.
%
% The
% |\zap@spaces| of LaTeX2e handles unexpectedly things such as
% \centeredline{|\zap@spaces 1 {22} 3 4 \@empty|} (spaces are not all
% removed). This does not happen with |\xint_zapspaces|.
%
% But for example |\foo{aa} {bb} {cc}| where |\foo| is a macro with three
% non-delimited arguments breaks expansion, as expansion of |\foo| will happen
% with |\xint_zapspaces| still around, and even if it wasn't it would have
% stripped the braces around |{bb}|, certainly breaking other things.
%
% Despite such obvious shortcomings it is enough for our purposes. It is
% currently used by \xintexprnameimp at various locations e.g. cleaning up
% optional argument of |\xintiexpr| and |\xintfloatexpr|; maybe in future
% internal usage will drop this in favour of a more robust utility.
%
% \changed{1.2e} |\xint_zapspaces_o|.
%
% \changed{1.2i} Made |\long|.
%
% ATTENTION THAT \xinttoolsnameimp HAS AN |\xintzapspaces| WHICH SHOULD NOT
% GET CONFUSED WITH THIS ONE.
% \begin{macrocode}
\long\def\xint_zapspaces #1 #2{#1#2\xint_zapspaces }% 1.1
\long\def\xint_zapspaces_o #1{\expandafter\xint_zapspaces#1 \xint_gobble_i}%
% \end{macrocode}
% \subsection{\csh{odef}, \csh{oodef}, \csh{fdef}}
% May be prefixed with |\global|. No parameter text.
% \begin{macrocode}
\def\xintodef #1{\expandafter\def\expandafter#1\expandafter }%
\def\xintoodef #1{\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter#1%
\expandafter\expandafter\expandafter }%
\def\xintfdef #1#2%
{\expandafter\def\expandafter#1\expandafter{\romannumeral`&&@#2}}%
\ifdefined\odef\else\let\odef\xintodef\fi
\ifdefined\oodef\else\let\oodef\xintoodef\fi
\ifdefined\fdef\else\let\fdef\xintfdef\fi
% \end{macrocode}
% \subsection{\csh{xintMessage}, \csh{ifxintverbose}}
% \changed{1.2c} For use by \csbxint{defvar} and \csbxint{deffunc} of
% \xintexprnameimp.
%
% \changed{1.2e} Uses |\write128| rather than |\write16| for compatibility
% with future extended range of output streams, in Lua\TeX{} in particular.
%
% \changed{1.3e} Set the |\newlinechar|.
% \begin{macrocode}
\edef\XINT_fourspaces{\space\space\space\space}%
\def\xintMessage #1#2#3{%
\edef\XINT_newlinechar{\the\newlinechar}%
\newlinechar10
\immediate\write128{Package #1 #2: (on line \the\inputlineno)}%
\immediate\write128{\XINT_fourspaces#3}%
\newlinechar\XINT_newlinechar\space
}%
\newif\ifxintverbose
% \end{macrocode}
% \subsection{\csh{ifxintglobaldefs}, \csh{XINT_global}}
% \changed{1.3c}
% \begin{macrocode}
\newif\ifxintglobaldefs
\def\XINT_global{\ifxintglobaldefs\global\fi}%
% \end{macrocode}
% \subsection{(WIP) Expandable error message}
% \changed[2017/07/26]{1.2l} But really belongs to next major release beyond |1.3|.
% Basically copied over from l3kernel code. Using |\ ! /| control sequence,
% which must be left undefined. |\xintError:| would be 6 letters more.
%
% \changed[2020/01/25]{1.4} Finally rather than |\ ! /| I use |\xint/|.
%
% \changed[2021/05/19]{1.4g} Rewrote to use not an undefined control
% sequence but trigger "Use of |\xint/| doesn't match its definition." message.
%
% \changed[2021/05/20]{1.4g} Things evolve fast and I switch to a third
% method which will exploit "Paragraph ended before |\foo| was complete" style
% error. See
% \centeredline{\url{https://github.com/latex3/latex3/issues/931#issuecomment-845367201}}
% However I can not fully exploit this because xint may be used with
% Plain etex which does not set |\newlinechar|.
% I can only use a poorman version with no usage of |^^J|. Also
% \ctanpackage{xintsession} could use the |^^J|, maybe I will integrate it
% there.
%
% \def\xintsession{\ctanpackage{xintsession}}
%
%\begin{lverb}
% I. Explanations on 2021/05/19 and 2021/05/20 before final change
%
% First I tried out things with undefined control sequence such as
%(\ an error was reported by xint ... %
%)
% whose output produces a nice symmetrical display with no \, and with ... both
% on left and right but this reduces drastically the available
% space for the actual error context. No go. But see 2021/05/20 update below!
%
% Having replaced \xint/ by "\xint ", I next opted provisorily for "\Hit
% RET at ?" control sequence, despite it being quite longer. And then I
% thought about using "\ xint error", possibly with an included ^^J in the name,
% or in the context.
%
% I experimented with ^^J in the context. But the context size is much
% constrained, and when \errorcontextlines is at its default value of 5 for
% etex, not -1 as done by LaTeX, having the info shifted to the right makes it
% actually more visible. (however I have now updated $xintsession$ to 0.2b which
% sets \errorcontextlines to 0)
%
% So I was finally back here to square one, apart from having replaced "\xint/"
% by the more longish "\ xint error", hesitating with "\xinterrupt"...
%
% Then I had the idea to replace the undefined control sequence method by a
% method with a macro \foo defined as \def\foo.{} but used as \foo for
% example. This gives something like this (the first line will be otherwise
% if engine is run with -file-line-error):
%( ! Use of \xint/ doesn't match its definition.
%: \xint/
%: Ooops, looks like we are missing a ] (hit RET)
%)
% \xint/ (where the space is the unexpected token, the definition
% expecting rather a full stop) makes for 7 characters
% to compare to \ xint error which had 12, so I gained back 5.
%
% Back to ^^J: I had overlooked that TeX in the first part of the error
% message will display \macro fully, so inserting ^^J in its name allows
% arbitrarily long expandable error messages... as pointed out by BLF in
% latex3/issues#931 as I read on the morning of 2021/05/20. This is very nice
% but requires to predefine control sequences for each message, and also the
% actual arguments #1, #2, ... values can appear only in the context.
%
% And the situation with ^^J is somewhat complicated:
%
% $xintsession$ sets the \newlinechar to 10, but this is not the case with bare
% usage of xintexpr with etex. And this matters. To discuss ^^J we have to
% separate two locations:
%(- it appears in the control sequence name,
%:- or in the context (which itself has two parts)
%)
%
% 1) When in the context, what happens with ^^J is independent of the setting of
% \newlinechar, and with TeXLive pdflatex the ^^J will induce a linebreak, but
% with xelatex it must be used with option -8bit.
%
% $noindent2) When in the control sequence name the behaviour in log/terminal of ^^J is
% influenced by the setting of \newlinechar. Although with pdflatex it will
% always induce a linebreak, the actual count of characters where TeX will
% forcefully break is influenced by whether ^^J is or not \newlinechar. And
% with xelatex if it is \newlinechar, it does not depend then if -8bit or not,
% but if not \newlinechar then it does and TeX forceful breaks also change
% as for pdflatex.
%
% So, the control sequence name trick can be used to obtain arbitrarily
% long messages, but the \newlinechar must be set.
%
% And in the context, we can try to insert some ^^J but this would need
% with xetex the -8bit option, and anyhow the context size is limited,
% and there is apparently no trick to get it larger.
%
% So, in view of all the above I decided not to use ^^J (rather $&$&J
% here) at all, whether here in the control sequence or the context or
% inserted in \XINT_signalcondition in the context!
%
% I also have a problem with usage from bnumexpr or polexpr for example,
% they would need their own to avoid perhaps displaying \xint/ or analogous.
%
% II. Finally I modified again the method (completely, and no more need for
% funny catcode 7 space as delimiter) as this allows a longer context message,
% starting at start of line, and which obeys ^^J if \newlinechar is set to
% it. It also allows to incorporate non-limited generic explanations as a
% postfix, with linebreaks if \newlinechar is known.
%
% But as $xintexprnameimp can be used with Plain+etex which does not set the
% \newlinechar, I can't use ^^J out of thee box. I can in $xintsession.
% What I decided finally is to make a conditional definition here.
%
% In both cases I include the "hit RET" (how rather "hit ") in the
% control sequence name serving to both provide extra information and trigger
% the error from being defined short and finding a \par.
%
% The maximal size was increased from 48 characters (method with \xint/ being
% badly delimited), to now 55 characters (using "! xint error:<^^J or space>"
% as prefix to the message). Longer messages are truncated at 56 characters
% with an appended "\ETC.".
%
% As it is late on this 2021/05/20, and in order to not have to change all
% usages, I keep \XINT_signalcondition (in $xintcorenameimp) as a one argument
% macro for time being, so will not include a more specific module name.
%
% The \par token has a special role here, and can't be (I)nserted without
% damage, but who would want to insert it in an expandable computation
% anyhow... and I don't need it in my custom error messages for sure.
%
% On 2021/05/21 I add a test about \newlinechar at time of package loading,
% and make two distinct definitions: one using ^^J in the control sequence,
% the other not using it.
%
% The -file-line-error toggle makes it impossible to control if the
% line-break on first line will match next lines. In the ^^J branch I insert
% "| " (no, finally "$ $ " with two spaces) at start of continuation lines.
% Also I preferred to ensure a good-looking first line break for the case it
% starts with a "! Paragraph ended ..." because a priori error messages will
% be read if -file-line-error was emitted only a fortiori (this toggle
% suggests some IDE launched TeX and probably -interaction=nonstopmode).
%
% I will perhaps make another definition in $xintsession$ (it currently loads
% xintexpr prior to having set the \newlinechar, so the no ^^J definition will
% be used, if nothing else is modified there).
%
% With some hesitation I do not insert a ^^J after "! xint error:", as
% Emacs/AucTeX will display only the first line prominently and then the rest
% (which is in file:line:error mode) in one block under "--- TeX said ---". I
% use the ^^J only in the generic helper message embedded in the control
% sequence. The cases with or without \newlinechar being 10 diverge a bit, as
% in the latter case I had to ensure acceptable linebreaks at 79 chars, and I
% did that first and then had spent enough time on the matter not to add more
% to backport the latest ^^J style message.
%\end{lverb}
% \changed[2022/06/05]{1.4m}
% Shorten the error message. I am always too verbose initially.
%
% \changed[2025/08/09]{1.4n}
% Let not use explicit \cs{par} token as delimiter, but implicit one
% from empty line. This is for compatibility with Op\TeX.
% Indeed, I observed that with Op\TeX, |{\foo\par}| wuth \cs{foo} being
% short reports an extra |}| rather than saying
% ``Paragraph ended before \cs{foo} was complete.''.
% \begin{macrocode}
\ifnum\newlinechar=10
\expandafter\def\csname
xint<...> is done, but will resume:&&J \space
hit at the ? prompt to try fixing the error above&&J \space
which has been encountered before expansion\endcsname
#1\xint:{}%
\def\XINT_expandableerror#1{%
\def\XINT_expandableerror##1{%
\expandafter
\XINT_expandableerrorcontinue
#1! xint error: ##1%
}}\expandafter\XINT_expandableerror\csname
xint<...> is done, but will resume:&&J \space
hit at the ? prompt to try fixing the error above&&J \space
which has been encountered before expansion\endcsname
\else
\expandafter\def\csname
xint<...> is done, but will resume: hit at \space
the ? prompt to try fixing the error encountered before expansion\endcsname
#1\xint:{}%
\def\XINT_expandableerror#1{%
\def\XINT_expandableerror##1{%
\expandafter
\XINT_expandableerrorcontinue
#1! xint error: ##1%
}}\expandafter\XINT_expandableerror\csname
xint<...> is done, but will resume: hit at \space
the ? prompt to try fixing the error encountered before expansion\endcsname
\fi
\def\XINT_expandableerrorcontinue#1%
{#1}%
% \end{macrocode}
% \subsection{\csh{xint_noxpd} (for \texttt{contex-mkxl} compatibility)}
% \added{1.4n}
%
% The \LaTeX3 code (in |l3names.dtx|) uses Con\TeX t's \cs{normalunexpanded}
% and \cs{normalexpanded} which appear to be available both in Mark~II and
% Mark~IV. But I will not do any testing with earlier |context|, so here I
% shall assume the \cs{expanded} behaves as expected and I can use
% \cs{notexpanded} for \cs{unexpanded}. This is abstracted into an alias
% \csbxint{_noxpd}.
%
% I don't know if there is mode of running |context| where the \cs{errhelp}
% tokens will be shown (trying |context --mkII| was not conclusive; by the way
% \cs{errmessage} in e-\TeX{} adds a full stop which is missing with
% |context|).
%
% About the \cs{let} primitive I am not sure it behaves fully as in other
% engines.
%
% Note that this uses \csbxint{Message} in case of old Con\TeX t so we had
% to have it defined first.
% \begin{macrocode}
\let\xint_noxpd\unexpanded
\ifdefined\contextversion
\let\xint_noxpd\notexpanded
\ifdefined\notexpanded
\else
\xintMessage{xintkernel}{Error}{This ConTeXt appears to be too old.}
\errhelp{xint only supports the ConTeXt-LMTX as of 2025/09/05.}%
\errmessage{The \noexpand\notexpanded primitive does not exist.}%
\fi
\fi
% \end{macrocode}
% \subsection{\csh{xintstrcmp}}
% \added[2022/06/05]{1.4m}
% For the \LuaTeX{} engine the code is copied over from |l3names.dtx|. I also
% looked at Heiko Oberdiek's |pdftexcmds.sty| and |pdftexcmds.lua|, but I
% removed |\luaescapestring| and used |token.scan_string()| as seen in
% |l3names.dtx| (and I did try to inform myself about this in the \LuaTeX{}
% manual, with limited success). I am not sure about the syntax below with the
% |local|'s. Should I use |\directlua0|? Testing was minimal.
% Memo: even with |pdftex|'s \cs{pdfstrcmp}, braces around the arguments
% are mandatory.
% \begin{macrocode}
\ifdefined\strcmp\let\xintstrcmp\strcmp
\else\ifdefined\pdfstrcmp\let\xintstrcmp\pdfstrcmp
\else\ifdefined\directlua\directlua{%
xintkernel = xintkernel or {}
local minus_tok = token.new(string.byte'-', 12)
local zero_tok = token.new(string.byte'0', 12)
local one_tok = token.new(string.byte'1', 12)
function xintkernel.strcmp()
local A = token.scan_string()
local B = token.scan_string()
if A < B then
tex.write(minus_tok, one_tok)
else
tex.write(A == B and zero_tok or one_tok)
end
end
}\def\xintstrcmp{%
\directlua{xintkernel.strcmp()}%
}%
\else
\xintMessage{xintkernel}{Error}{Could not set-up \string\xintstrcmp.}%
\errhelp{What kind of format are you using? Perhaps write the author? Bye now}%
\errmessage{Sorry, could not find or define string comparison primitive}\fi\fi\fi
% \end{macrocode}
% \subsection{\csh{xintresettimer}, \csh{xintelapsedtime}, \csh{xinttheseconds}}
% \added{1.4n}
% If |\resettimer| is defined, the code assumes
% |\elapsedtime| is, too.
%
% I completely forgot at |1.4n| release time to document these engine-agnostic
% utilities in the manual. They were originally in the |xint.dtx| preamble,
% to allow testing a build of the documentation also with the Unicode engines
% (but the release is done with |latex+dvipdfmx|). They are
% used only once there, for the example with |\xintUniformDeviate|.
%
% Perhaps I should for Lua\TeX{} copy the l3kernel code (here the code was
% picked from some |tex.sx| answer and was in my files for years) but I am not
% Lua-proficient enough to do this confidently... probably their |// 1| and
% |math.tointeger()| is more efficient than the |math.floor()| and there must
% be a reason why they use |gettimeofday()|, while |os.clock()| is only used
% to set the ``epoch''.
%
% I have been using for years the underlying syntax trick here for
% |\xinttheseconds|, and I usually never bother actually removing the catcode
% 12 |pt|, but well let's do it here.
%
% I hesitate whether with Lua\TeX{} I should avoid the scaled seconds
% intermediate in favor of the raw |os.clock()-basetime| data but I would have
% to waste time seeing what happens with |tex.write()| then. And it would not
% help really in comparing with PDF\TeX{} or Xe\TeX{}.
%
% \changed{1.4o}
%
% |xinttimer| replaces here in the Lua code |xintelapsedtimer|, which was
% a silly name used when I adopted in a haste at |1.4n| while improving the user
% manual on \csbxint{UniformDeviate}.
% \begin{macrocode}
\ifdefined\resettimer
\let\xintresettimer\resettimer \let\xintelapsedtime\elapsedtime
\else
\ifdefined\pdfresettimer
\let\xintresettimer\pdfresettimer\let\xintelapsedtime\pdfelapsedtime
\else
\ifdefined\directlua
\directlua{xinttimer_basetime=0}%
\def\xintresettimer{\directlua{xinttimer_basetime = os.clock()}}%
\def\xintelapsedtime{\numexpr
\directlua{tex.print(math.floor((os.clock()-xinttimer_basetime)*65536+0.5))}%
\relax}%
\fi\fi\fi
\def\xintstrippt{\expandafter\XINT_strippt\the}%
\expanded{\xint_noxpd{\def\XINT_strippt#1}\detokenize{pt}}{#1}%
\def\xinttheseconds{\xintstrippt\dimexpr\xintelapsedtime sp\relax}%
% \end{macrocode}
% \subsection{\csh{xintReverseOrder}}
% \changed{1.0} Does not expand its argument. The whole of xint codebase now
% contains only two calls to |\XINT_rord_main| (in \xintgcdnameimp).
%
% Attention: removes brace pairs (and swallows spaces).
%
% For digit tokens a faster reverse macro is provided by (|1.2|)
% \csbxint{ReverseDigits} in \xintnameimp.
%
% For comma separated items, |1.2g| has \csbxint{CSVReverse} in
% \xinttoolsnameimp.
% \begin{macrocode}
\def\xintReverseOrder {\romannumeral0\xintreverseorder }%
\long\def\xintreverseorder #1%
{%
\XINT_rord_main {}#1%
\xint:
\xint_bye\xint_bye\xint_bye\xint_bye
\xint_bye\xint_bye\xint_bye\xint_bye
\xint:
}%
\long\def\XINT_rord_main #1#2#3#4#5#6#7#8#9%
{%
\xint_bye #9\XINT_rord_cleanup\xint_bye
\XINT_rord_main {#9#8#7#6#5#4#3#2#1}%
}%
\def\XINT_rord_cleanup #1{%
\long\def\XINT_rord_cleanup\xint_bye\XINT_rord_main ##1##2\xint:
{%
\expandafter#1\xint_gob_til_xint: ##1%
}}\XINT_rord_cleanup { }%
% \end{macrocode}
% \subsection{\csh{xintLength}}
% \changed{1.0} Does not expand its argument. See \csbxint{NthElt}|{0}| from
% \xinttoolsnameimp which f-expands its argument.
%
% \changed{1.2g} Added \csbxint{CSVLength} to \xinttoolsnameimp.
%
% \changed{1.2i} Rewrote this venerable macro. New code about 40\%
% faster across all lengths. Syntax with |\romannumeral0| adds some
% slight (negligible) overhead; it is done to fit some general
% principles of structure of the xint package macros but maybe
% at some point I should drop it. And in fact it is often called
% directly via the |\numexpr| access point. (bad coding...)
%
% Remark: the argument may contain \cs{par} tokens. But generally
% speaking most other macros of the \xintnameimp bundle are not declared
% \cs{long}. As \csbxint{Length} produces a numeric quantity it is
% conceivable that it could serve in the input of some of the
% \xintnameimp macros. For example something such as
% |\xinteval{\xintLength{\par\par}^3}| or
% |\xintiiMul{\xintLength{\par\par\par}}{17}|. They both fail. I have
% known this issue for many years. It is only needed to make long those
% macros which grab the argument and \fexpan d it. After expansion, of
% course no \cs{par} tokens is admissible as numerical input. Still
% this is quite some work due to size of the codebase. Waiting for a
% real-life bug report... (\LaTeX3 people have fixed that on their side
% by making all declarations \cs{long} per default, and this may also
% perhaps increase slightly the efficiency, not checked).
% \begin{macrocode}
\def\xintLength {\romannumeral0\xintlength }%
\def\xintlength #1{%
\long\def\xintlength ##1%
{%
\expandafter#1\the\numexpr\XINT_length_loop
##1\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:
\xint_c_viii\xint_c_vii\xint_c_vi\xint_c_v
\xint_c_iv\xint_c_iii\xint_c_ii\xint_c_i\xint_c_\xint_bye
\relax
}}\xintlength{ }%
\long\def\XINT_length_loop #1#2#3#4#5#6#7#8#9%
{%
\xint_gob_til_xint: #9\XINT_length_finish_a\xint:
\xint_c_ix+\XINT_length_loop
}%
\def\XINT_length_finish_a\xint:\xint_c_ix+\XINT_length_loop
#1#2#3#4#5#6#7#8#9%
{%
#9\xint_bye
}%
% \end{macrocode}
% \subsection{\csh{xintLastItem}}
% \changed[2016/12/10]{1.2i}
% One level
% of braces removed in output. Output empty if input empty. Attention!
% This means
% that an empty input or an input ending with a {} empty brace pair
% both give same output.
%
% The |\xint:| token must not be among items. |\xintFirstItem| added
% at 1.4 for usage in xintexpr. It must contain neither |\xint:|
% nor |\xint_bye| in its first item.
%
% \begin{macrocode}
\def\xintLastItem {\romannumeral0\xintlastitem }%
\long\def\xintlastitem #1%
{%
\XINT_last_loop {}.#1%
{\xint:\XINT_last_loop_enda}{\xint:\XINT_last_loop_endb}%
{\xint:\XINT_last_loop_endc}{\xint:\XINT_last_loop_endd}%
{\xint:\XINT_last_loop_ende}{\xint:\XINT_last_loop_endf}%
{\xint:\XINT_last_loop_endg}{\xint:\XINT_last_loop_endh}\xint_bye
}%
\long\def\XINT_last_loop #1.#2#3#4#5#6#7#8#9%
{%
\xint_gob_til_xint: #9%
{#8}{#7}{#6}{#5}{#4}{#3}{#2}{#1}\xint:
\XINT_last_loop {#9}.%
}%
\long\def\XINT_last_loop_enda #1#2\xint_bye{ #1}%
\long\def\XINT_last_loop_endb #1#2#3\xint_bye{ #2}%
\long\def\XINT_last_loop_endc #1#2#3#4\xint_bye{ #3}%
\long\def\XINT_last_loop_endd #1#2#3#4#5\xint_bye{ #4}%
\long\def\XINT_last_loop_ende #1#2#3#4#5#6\xint_bye{ #5}%
\long\def\XINT_last_loop_endf #1#2#3#4#5#6#7\xint_bye{ #6}%
\long\def\XINT_last_loop_endg #1#2#3#4#5#6#7#8\xint_bye{ #7}%
\long\def\XINT_last_loop_endh #1#2#3#4#5#6#7#8#9\xint_bye{ #8}%
% \end{macrocode}
% \subsection{\csh{xintFirstItem}}
%\begin{lverb}
% 1.4. There must be neither \xint:
% nor \xint_bye in its first item.
%\end{lverb}
% \begin{macrocode}
\def\xintFirstItem {\romannumeral0\xintfirstitem }%
\long\def\xintfirstitem #1{\XINT_firstitem #1{\xint:\XINT_firstitem_end}\xint_bye}%
\long\def\XINT_firstitem #1#2\xint_bye{\xint_gob_til_xint: #1\xint:\space #1}%
\def\XINT_firstitem_end\xint:{ }%
% \end{macrocode}
% \subsection{\csh{xintLastOne}}
%\begin{lverb}
%
% As xintexpr 1.4 uses {c1}{c2}....{cN} storage when gathering comma separated
% values we need to not handle identically an empty list and a list with an
% empty item (as the above allows hierarchical structures). But \xintLastItem
% removed one level of brace pair so it is anadequate for the last() function.
%
% By the way it is logical to interpret «item» as meaning {cj} inclusive of
% the braces; but legacy xint user manual was not written in this spirit. And thus
% \xintLastItem did brace stripping, thus we need another name for maintaining
% backwards compatibility (although the cardinality of users is small).
%
% The \xint: token must not be found (visible) among the item contents.
%
%\end{lverb}
% \begin{macrocode}
\def\xintLastOne {\romannumeral0\xintlastone }%
\long\def\xintlastone #1%
{%
\XINT_lastone_loop {}.#1%
{\xint:\XINT_lastone_loop_enda}{\xint:\XINT_lastone_loop_endb}%
{\xint:\XINT_lastone_loop_endc}{\xint:\XINT_lastone_loop_endd}%
{\xint:\XINT_lastone_loop_ende}{\xint:\XINT_lastone_loop_endf}%
{\xint:\XINT_lastone_loop_endg}{\xint:\XINT_lastone_loop_endh}\xint_bye
}%
\long\def\XINT_lastone_loop #1.#2#3#4#5#6#7#8#9%
{%
\xint_gob_til_xint: #9%
{#8}{#7}{#6}{#5}{#4}{#3}{#2}{#1}\xint:
\XINT_lastone_loop {{#9}}.%
}%
\long\def\XINT_lastone_loop_enda #1#2\xint_bye{{#1}}%
\long\def\XINT_lastone_loop_endb #1#2#3\xint_bye{{#2}}%
\long\def\XINT_lastone_loop_endc #1#2#3#4\xint_bye{{#3}}%
\long\def\XINT_lastone_loop_endd #1#2#3#4#5\xint_bye{{#4}}%
\long\def\XINT_lastone_loop_ende #1#2#3#4#5#6\xint_bye{{#5}}%
\long\def\XINT_lastone_loop_endf #1#2#3#4#5#6#7\xint_bye{{#6}}%
\long\def\XINT_lastone_loop_endg #1#2#3#4#5#6#7#8\xint_bye{{#7}}%
\long\def\XINT_lastone_loop_endh #1#2#3#4#5#6#7#8#9\xint_bye{ #8}%
% \end{macrocode}
% \subsection{\csh{xintFirstOne}}
%\begin{lverb}
% For xintexpr 1.4 too. Jan 3, 2020.
%
% This is an experimental macro, don't use it. If input is nil (empty set) it
% expands to nil, if not it fetches first item and braces it. Fetching will
% have stripped one brace pair if item was braced to start with, which is
% the case in non-symbolic xintexpr data objects.
%
% I have not given much thought to this (make it shorter, allow all tokens,
% (we could first test if empty via combination with \detokenize), etc...)
% as I need to get xint 1.4 out soon. So in particular attention that
% the macro assumes the \xint: token is absent from first item of input.
%\end{lverb}
% \begin{macrocode}
\def\xintFirstOne {\romannumeral0\xintfirstone }%
\long\def\xintfirstone #1{\XINT_firstone #1{\xint:\XINT_firstone_empty}\xint:}%
\long\def\XINT_firstone #1#2\xint:{\xint_gob_til_xint: #1\xint:{#1}}%
\def\XINT_firstone_empty\xint:#1{ }%
% \end{macrocode}
% \subsection{\csh{xintLengthUpTo}}
% \changed{1.2i} For use by \csbxint{Keep} and \csbxint{Trim}
% (\xinttoolsnameimp). The argument N **must be non-negative**.
%
% |\xintLengthUpTo{N}{List}| produces |-0| if length(List)>N, else it returns
% N-length(List). Hence subtracting it from N always computes min(N,length(List)).
% \changed{1.2j} Changed ending and interface to core loop.
% \begin{macrocode}
\def\xintLengthUpTo {\romannumeral0\xintlengthupto}%
\long\def\xintlengthupto #1#2%
{%
\expandafter\XINT_lengthupto_loop
\the\numexpr#1.#2\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:
\xint_c_vii\xint_c_vi\xint_c_v\xint_c_iv
\xint_c_iii\xint_c_ii\xint_c_i\xint_c_\xint_bye.%
}%
\def\XINT_lengthupto_loop_a #1%
{%
\xint_UDsignfork
#1\XINT_lengthupto_gt
-\XINT_lengthupto_loop
\krof #1%
}%
\long\def\XINT_lengthupto_gt #1\xint_bye.{-0}%
\long\def\XINT_lengthupto_loop #1.#2#3#4#5#6#7#8#9%
{%
\xint_gob_til_xint: #9\XINT_lengthupto_finish_a\xint:%
\expandafter\XINT_lengthupto_loop_a\the\numexpr #1-\xint_c_viii.%
}%
\def\XINT_lengthupto_finish_a\xint:\expandafter\XINT_lengthupto_loop_a
\the\numexpr #1-\xint_c_viii.#2#3#4#5#6#7#8#9%
{%
\expandafter\XINT_lengthupto_finish_b\the\numexpr #1-#9\xint_bye
}%
\def\XINT_lengthupto_finish_b #1#2.%
{%
\xint_UDsignfork
#1{-0}%
-{ #1#2}%
\krof
}%
% \end{macrocode}
% \subsection{\csh{xintreplicate}, \csh{xintReplicate}}
% \changed{1.2i}
% This is cloned from LaTeX3's |\prg_replicate:nn|, see Joseph's post
% at
% \centeredline{http://tex.stackexchange.com/questions/16189/repeat-command-n-times}
% I
% posted there an alternative not using the chained |\csname|'s but it is a bit
% less efficient (except perhaps for thousands of repetitions).
% The code in Joseph's post does |abs(#1)| replications when input |#1| is negative
% and then activates an error triggering macro; here we simply do nothing when
% |#1| is negative.
% \centeredline{Usage: |\romannumeral\xintreplicate{N}{stuff}|}
%
% When |N| is already explicit digits (even |N=0|, but non-negative) one can
% call the macro as
% \centeredline{|\romannumeral\XINT_rep N\endcsname {foo}|}
% to skip the |\numexpr|.
%
% \changed[2020/01/11]{1.4}
% Added |\xintReplicate| ! The reason I did not before is that the prevailing
% habits in xint source code was to trigger with |\romannumeral0| not
% |\romannumeral| which is the lowercased named macros. Thus adding the
% camelcase one creates a couple |\xintReplicate/\xintreplicate| not obeying
% the general mold.
% \begin{macrocode}
\def\xintReplicate{\romannumeral\xintreplicate}%
\def\xintreplicate#1%
{\expandafter\XINT_replicate\the\numexpr#1\endcsname}%
\def\XINT_replicate #1{\xint_UDsignfork
#1\XINT_rep_neg
-\XINT_rep
\krof #1}%
\long\def\XINT_rep_neg #1\endcsname #2{\xint_c_}%
\def\XINT_rep #1{\csname XINT_rep_f#1\XINT_rep_a}%
\def\XINT_rep_a #1{\csname XINT_rep_#1\XINT_rep_a}%
\def\XINT_rep_\XINT_rep_a{\endcsname}%
\long\expandafter\def\csname XINT_rep_0\endcsname #1%
{\endcsname{#1#1#1#1#1#1#1#1#1#1}}%
\long\expandafter\def\csname XINT_rep_1\endcsname #1%
{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1}%
\long\expandafter\def\csname XINT_rep_2\endcsname #1%
{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1}%
\long\expandafter\def\csname XINT_rep_3\endcsname #1%
{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1}%
\long\expandafter\def\csname XINT_rep_4\endcsname #1%
{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1}%
\long\expandafter\def\csname XINT_rep_5\endcsname #1%
{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1}%
\long\expandafter\def\csname XINT_rep_6\endcsname #1%
{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1}%
\long\expandafter\def\csname XINT_rep_7\endcsname #1%
{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1}%
\long\expandafter\def\csname XINT_rep_8\endcsname #1%
{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1}%
\long\expandafter\def\csname XINT_rep_9\endcsname #1%
{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1#1}%
\long\expandafter\def\csname XINT_rep_f0\endcsname #1%
{\xint_c_}%
\long\expandafter\def\csname XINT_rep_f1\endcsname #1%
{\xint_c_ #1}%
\long\expandafter\def\csname XINT_rep_f2\endcsname #1%
{\xint_c_ #1#1}%
\long\expandafter\def\csname XINT_rep_f3\endcsname #1%
{\xint_c_ #1#1#1}%
\long\expandafter\def\csname XINT_rep_f4\endcsname #1%
{\xint_c_ #1#1#1#1}%
\long\expandafter\def\csname XINT_rep_f5\endcsname #1%
{\xint_c_ #1#1#1#1#1}%
\long\expandafter\def\csname XINT_rep_f6\endcsname #1%
{\xint_c_ #1#1#1#1#1#1}%
\long\expandafter\def\csname XINT_rep_f7\endcsname #1%
{\xint_c_ #1#1#1#1#1#1#1}%
\long\expandafter\def\csname XINT_rep_f8\endcsname #1%
{\xint_c_ #1#1#1#1#1#1#1#1}%
\long\expandafter\def\csname XINT_rep_f9\endcsname #1%
{\xint_c_ #1#1#1#1#1#1#1#1#1}%
% \end{macrocode}
% \subsection{\csh{xintgobble}, \csh{xintGobble}}
% \changed{1.2i}
% I hesitated about allowing as many as |9^6-1=531440| tokens to gobble, but
% |9^5-1=59058| is too low for playing with long decimal expansions.
% \centeredline{Usage: |\romannumeral\xintgobble{N}...|}
%
% \changed[2020/01/11]{1.4}
% Added |\xintGobble|.
% \begin{macrocode}
\def\xintGobble{\romannumeral\xintgobble}%
\def\xintgobble #1%
{\csname xint_c_\expandafter\XINT_gobble_a\the\numexpr#1.0}%
\def\XINT_gobble #1.{\csname xint_c_\XINT_gobble_a #1.0}%
\def\XINT_gobble_a #1{\xint_gob_til_zero#1\XINT_gobble_d0\XINT_gobble_b#1}%
\def\XINT_gobble_b #1.#2%
{\expandafter\XINT_gobble_c
\the\numexpr (#1+\xint_c_v)/\xint_c_ix-\xint_c_i\expandafter.%
\the\numexpr #2+\xint_c_i.#1.}%
\def\XINT_gobble_c #1.#2.#3.%
{\csname XINT_g#2\the\numexpr#3-\xint_c_ix*#1\relax\XINT_gobble_a #1.#2}%
\def\XINT_gobble_d0\XINT_gobble_b0.#1{\endcsname}%
\expandafter\let\csname XINT_g10\endcsname\endcsname
\long\expandafter\def\csname XINT_g11\endcsname#1{\endcsname}%
\long\expandafter\def\csname XINT_g12\endcsname#1#2{\endcsname}%
\long\expandafter\def\csname XINT_g13\endcsname#1#2#3{\endcsname}%
\long\expandafter\def\csname XINT_g14\endcsname#1#2#3#4{\endcsname}%
\long\expandafter\def\csname XINT_g15\endcsname#1#2#3#4#5{\endcsname}%
\long\expandafter\def\csname XINT_g16\endcsname#1#2#3#4#5#6{\endcsname}%
\long\expandafter\def\csname XINT_g17\endcsname#1#2#3#4#5#6#7{\endcsname}%
\long\expandafter\def\csname XINT_g18\endcsname#1#2#3#4#5#6#7#8{\endcsname}%
\expandafter\let\csname XINT_g20\endcsname\endcsname
\long\expandafter\def\csname XINT_g21\endcsname #1#2#3#4#5#6#7#8#9%
{\endcsname}%
\long\expandafter\edef\csname XINT_g22\endcsname #1#2#3#4#5#6#7#8#9%
{\expandafter\noexpand\csname XINT_g21\endcsname}%
\long\expandafter\edef\csname XINT_g23\endcsname #1#2#3#4#5#6#7#8#9%
{\expandafter\noexpand\csname XINT_g22\endcsname}%
\long\expandafter\edef\csname XINT_g24\endcsname #1#2#3#4#5#6#7#8#9%
{\expandafter\noexpand\csname XINT_g23\endcsname}%
\long\expandafter\edef\csname XINT_g25\endcsname #1#2#3#4#5#6#7#8#9%
{\expandafter\noexpand\csname XINT_g24\endcsname}%
\long\expandafter\edef\csname XINT_g26\endcsname #1#2#3#4#5#6#7#8#9%
{\expandafter\noexpand\csname XINT_g25\endcsname}%
\long\expandafter\edef\csname XINT_g27\endcsname #1#2#3#4#5#6#7#8#9%
{\expandafter\noexpand\csname XINT_g26\endcsname}%
\long\expandafter\edef\csname XINT_g28\endcsname #1#2#3#4#5#6#7#8#9%
{\expandafter\noexpand\csname XINT_g27\endcsname}%
\expandafter\let\csname XINT_g30\endcsname\endcsname
\long\expandafter\edef\csname XINT_g31\endcsname #1#2#3#4#5#6#7#8#9%
{\expandafter\noexpand\csname XINT_g28\endcsname}%
\long\expandafter\edef\csname XINT_g32\endcsname #1#2#3#4#5#6#7#8#9%
{\noexpand\csname XINT_g31\expandafter\noexpand\csname XINT_g28\endcsname}%
\long\expandafter\edef\csname XINT_g33\endcsname #1#2#3#4#5#6#7#8#9%
{\noexpand\csname XINT_g32\expandafter\noexpand\csname XINT_g28\endcsname}%
\long\expandafter\edef\csname XINT_g34\endcsname #1#2#3#4#5#6#7#8#9%
{\noexpand\csname XINT_g33\expandafter\noexpand\csname XINT_g28\endcsname}%
\long\expandafter\edef\csname XINT_g35\endcsname #1#2#3#4#5#6#7#8#9%
{\noexpand\csname XINT_g34\expandafter\noexpand\csname XINT_g28\endcsname}%
\long\expandafter\edef\csname XINT_g36\endcsname #1#2#3#4#5#6#7#8#9%
{\noexpand\csname XINT_g35\expandafter\noexpand\csname XINT_g28\endcsname}%
\long\expandafter\edef\csname XINT_g37\endcsname #1#2#3#4#5#6#7#8#9%
{\noexpand\csname XINT_g36\expandafter\noexpand\csname XINT_g28\endcsname}%
\long\expandafter\edef\csname XINT_g38\endcsname #1#2#3#4#5#6#7#8#9%
{\noexpand\csname XINT_g37\expandafter\noexpand\csname XINT_g28\endcsname}%
\expandafter\let\csname XINT_g40\endcsname\endcsname
\expandafter\edef\csname XINT_g41\endcsname
{\noexpand\csname XINT_g38\expandafter\noexpand\csname XINT_g31\endcsname}%
\expandafter\edef\csname XINT_g42\endcsname
{\noexpand\csname XINT_g41\expandafter\noexpand\csname XINT_g41\endcsname}%
\expandafter\edef\csname XINT_g43\endcsname
{\noexpand\csname XINT_g42\expandafter\noexpand\csname XINT_g41\endcsname}%
\expandafter\edef\csname XINT_g44\endcsname
{\noexpand\csname XINT_g43\expandafter\noexpand\csname XINT_g41\endcsname}%
\expandafter\edef\csname XINT_g45\endcsname
{\noexpand\csname XINT_g44\expandafter\noexpand\csname XINT_g41\endcsname}%
\expandafter\edef\csname XINT_g46\endcsname
{\noexpand\csname XINT_g45\expandafter\noexpand\csname XINT_g41\endcsname}%
\expandafter\edef\csname XINT_g47\endcsname
{\noexpand\csname XINT_g46\expandafter\noexpand\csname XINT_g41\endcsname}%
\expandafter\edef\csname XINT_g48\endcsname
{\noexpand\csname XINT_g47\expandafter\noexpand\csname XINT_g41\endcsname}%
\expandafter\let\csname XINT_g50\endcsname\endcsname
\expandafter\edef\csname XINT_g51\endcsname
{\noexpand\csname XINT_g48\expandafter\noexpand\csname XINT_g41\endcsname}%
\expandafter\edef\csname XINT_g52\endcsname
{\noexpand\csname XINT_g51\expandafter\noexpand\csname XINT_g51\endcsname}%
\expandafter\edef\csname XINT_g53\endcsname
{\noexpand\csname XINT_g52\expandafter\noexpand\csname XINT_g51\endcsname}%
\expandafter\edef\csname XINT_g54\endcsname
{\noexpand\csname XINT_g53\expandafter\noexpand\csname XINT_g51\endcsname}%
\expandafter\edef\csname XINT_g55\endcsname
{\noexpand\csname XINT_g54\expandafter\noexpand\csname XINT_g51\endcsname}%
\expandafter\edef\csname XINT_g56\endcsname
{\noexpand\csname XINT_g55\expandafter\noexpand\csname XINT_g51\endcsname}%
\expandafter\edef\csname XINT_g57\endcsname
{\noexpand\csname XINT_g56\expandafter\noexpand\csname XINT_g51\endcsname}%
\expandafter\edef\csname XINT_g58\endcsname
{\noexpand\csname XINT_g57\expandafter\noexpand\csname XINT_g51\endcsname}%
\expandafter\let\csname XINT_g60\endcsname\endcsname
\expandafter\edef\csname XINT_g61\endcsname
{\noexpand\csname XINT_g58\expandafter\noexpand\csname XINT_g51\endcsname}%
\expandafter\edef\csname XINT_g62\endcsname
{\noexpand\csname XINT_g61\expandafter\noexpand\csname XINT_g61\endcsname}%
\expandafter\edef\csname XINT_g63\endcsname
{\noexpand\csname XINT_g62\expandafter\noexpand\csname XINT_g61\endcsname}%
\expandafter\edef\csname XINT_g64\endcsname
{\noexpand\csname XINT_g63\expandafter\noexpand\csname XINT_g61\endcsname}%
\expandafter\edef\csname XINT_g65\endcsname
{\noexpand\csname XINT_g64\expandafter\noexpand\csname XINT_g61\endcsname}%
\expandafter\edef\csname XINT_g66\endcsname
{\noexpand\csname XINT_g65\expandafter\noexpand\csname XINT_g61\endcsname}%
\expandafter\edef\csname XINT_g67\endcsname
{\noexpand\csname XINT_g66\expandafter\noexpand\csname XINT_g61\endcsname}%
\expandafter\edef\csname XINT_g68\endcsname
{\noexpand\csname XINT_g67\expandafter\noexpand\csname XINT_g61\endcsname}%
% \end{macrocode}
% \subsection{Random number generation}
% \added{1.3b}
%
% We provide a more random version of the (PDF)\TeX{} \cs{pdfuniformdeviate}.
% I discusses the worries with the engine primitive with Bruno Le Floch in
% May 2018. Regarding |\pdfuniformdeviate x|:
%
% \begin{enumerate}
% \item with |x=2^{29}| or |x=2^{30}| the engine primitive produces only even
% numbers,
% \item with |x=3*2^{26}| the integers produced by the RNG when taken modulo
% three obey the proportion |1:1:2|, not |1:1:1|,
% \item with |x=3*2^{14}| there is analogous although weaker non-uniformity of
% the random integers when taken modulo 3,
% \item generally speaking pure powers of two should generate uniform random
% integers, but when the range is divisible by large powers of
% two, the non-uniformity may be amplified in surprising ways by modulo
% operations.
% \end{enumerate}
%
% Moreover, two seeds sharing the same low |k| bits generate sequences of
% 28-bits integers which are one-to-one identical modulo |2^k|!
%
% In order to mitigate the issues commented upon in the user manual,
% \csbxint{UniformDeviate} currently only uses the
% seven high bits from the underlying random stream, using multiple calls to
% |\pdfuniformdeviate 128|. From the Birthday Effect, after about |2^{11}| seeds
% one will likely pick a new one sharing its 22 low bits with an earlier one.
%
% \begin{enumerate}
% \item but as the final random integer is obtained by additional operations
% involving the range |x| (currently a modulo operation), for odd ranges it is
% more difficult for bit correlations to be seen,
% \item anyway as they are only
% |2^{28}| seeds in total, after only |2^{14}| seeds it is likely to encounter
% one already explored, and then random integers are identical, however
% complicated the RNG's raw output is malaxed, and whatever the target range
% |x|. And |2^{14}| is only eight times as large as |2^{11}|.
% \end{enumerate}
%
% It would be nice if the engine provided some user interface for
% letting its RNG execute a given number of iterations without the overhead
% of replicated executions of |\pdfuniformdeviate|. This could help gain
% entropy and would reduce correlations across series from distinct seeds.
%
% \changed{1.4n} Print a warning immediately if no uniformdeviate is available.
% \changed{1.4p} Do |s/\xint_undefined/\XINT_undefined/| for codebase coherence.
% \changed{1.4p} Rename |\xint_texuniformdeviate| into |\xinttexuniformdeviate|,
% so that it can be used in some examples of the user documentation.
% \subsubsection{\csh{xinttexuniformdeviate}}
% ATTENTION! with Con\TeX t, it will be redefined below as a \emph{macro with
% an argument}. So one can NOT make code working both with the usual
% engines/formats and with Con\TeX t. The definition we will use with Con\TeX t
% is purely for our internal usage. Saying this because at |1.4p| the user
% manual shows some usages of this \csa{xinttexuniformdeviate}, \emph{but
% this is not a user level command for Con\TeX t usage}.
% \begin{macrocode}
\ifdefined\pdfuniformdeviate \let\xinttexuniformdeviate\pdfuniformdeviate\fi
\ifdefined\uniformdeviate \let\xinttexuniformdeviate\uniformdeviate \fi
\ifx\xinttexuniformdeviate\relax\let\xinttexuniformdeviate\XINT_undefined\fi
% \end{macrocode}
% \subsubsection{\csh{xinttexuniformdeviate_dgts}}
%
% \added{1.4n} Needed for compatibility with Con\TeX t.
%
% One finds a macro \cs{randomnumber}
% (|/usr/local/texlive/2025/texmf-dist/tex/context/base/mkxl/supp-ran.mkxl|),
% which takes two arguments. Fortunately it seems that throughout the
% \xintnameimp code base, we use \csbxint{texuniformdeviate} always with a
% chardef or count argument with one sole exception where it is followed with
% digits terminated by \cs{xint:}. In order not to change anything to current
% code and to support Con\TeX t-LMTX we make here a suitable definition
% compatible with these use cases.
%
% \noindent Warning: I have no idea and will not check now if the RNG has the
% same issues for the less significant decimal digits as in PDFTeX, thus I
% don't know if the overhead in the definition below of \csbxint{UniformeDeviate}
% has any rationale in the LMTX context.
%
% MEMO: In the code below, I have not checked yet and do not remember (at time
% of preparing |1.4n|) if it is possible that the |#1| fetched by
% \csbxint{texuniformdeviate_dgts} has some chance to be zero (as I don't
% remember the details of the construction). Attention that
% |\randomnumber{0}{-1}| may output |-1|.
%
% \changed{1.4o} Remove the test whether some uniformdeviate already
% exists with Con\TeX t and use unconditionally |\randomnumber| without
% checking if it exists.
% \begin{macrocode}
\ifdefined\contextversion
\def\xinttexuniformdeviate#1{\randomnumber{0}{#1-1}}%
\def\xinttexuniformdeviate_dgts#1\xint:{\randomnumber{0}{#1-1}\xint:}%
\else
\let\xinttexuniformdeviate_dgts\xinttexuniformdeviate
\fi
% \end{macrocode}
% \subsubsection{\csh{xintUniformDeviate}}
% For negative |#1| the output (as per the doc I wrote in the user manual
% some years ago and that I trust) ranges from |#1+1| to zero inclusive.
% This is same behaviour as original primitive and the input must be
% within the \TeX{} bounds. Note that |\the\numexpr-0\relax| gives |0|.
%
% We make 5 calls to the primitive and the user doc says that when I tested
% the cost was about 13 times the one of the primitive.
% \begin{macrocode}
\ifdefined\xinttexuniformdeviate
\expandafter\xint_firstoftwo
\else\expandafter\xint_secondoftwo
\fi
{%
\def\xintUniformDeviate#1%
{\the\numexpr\expandafter\XINT_uniformdeviate_sgnfork\the\numexpr#1\xint:}%
\def\XINT_uniformdeviate_sgnfork#1%
{%
\if-#1\XINT_uniformdeviate_neg\fi \XINT_uniformdeviate{}#1%
}%
\def\XINT_uniformdeviate_neg\fi\XINT_uniformdeviate#1-%
{%
\fi-\numexpr\XINT_uniformdeviate\relax
}%
\def\XINT_uniformdeviate#1#2\xint:
{%(
\expandafter\XINT_uniformdeviate_a\the\numexpr%
-\xinttexuniformdeviate\xint_c_ii^vii%
-\xint_c_ii^vii*\xinttexuniformdeviate\xint_c_ii^vii%
-\xint_c_ii^xiv*\xinttexuniformdeviate\xint_c_ii^vii%
-\xint_c_ii^xxi*\xinttexuniformdeviate\xint_c_ii^vii%
+\xinttexuniformdeviate_dgts#2\xint:/#2)*#2\xint:+#2\fi\relax#1%
}%
\def\XINT_uniformdeviate_a #1\xint:
{%
\expandafter\XINT_uniformdeviate_b\the\numexpr#1-(#1%
}%
\def\XINT_uniformdeviate_b#1#2\xint:{#1#2\if-#1}%
}%
{%
\xintMessage{xintkernel}{Warning}%
{No \string\uniformdeviate like primitive identified, macros producing^^J%
\XINT_fourspaces "random numbers" will raise (expandable) errors.}%
\def\xintUniformDeviate#1%
{%
\the\numexpr
\XINT_expandableerror{(xintkernel) No uniformdeviate primitive!}%
0\relax
}%
}%
% \end{macrocode}
% \subsubsection{\csh{xintsetrandomseed}}
% \added{1.4p}
% This will remain undocumented at user level, apart from the fact thet some
% examples in the documentation use it. Contrarily to the timing primitives,
% it seems \LuaTeX{} (even without \LaTeX{} format) has it, so we only need to
% alias it, idem with \XeTeX{} and Op\TeX{} (which even has it under the two
% names). Regarding Con\TeX t, I do not have time to learn to use it and the
% following appears to work but anyhow its RNG seems to be some altogther
% different one than the \PDFTeX{} derived from \hologo{MetaPost} one. And
% using |\count255| is surely bad, but well.
% \begin{macrocode}
\ifdefined\contextversion
\def\xintsetrandomseed{\afterassignment\XINT_ctx_setrandomseed
\count255 }%
\def\XINT_ctx_setrandomseed{\ctxlua{math.randomseed(\the\count255)}}%
\else
\ifdefined\pdfsetrandomseed \let\xintsetrandomseed\pdfsetrandomseed\fi
\ifdefined\setrandomseed \let\xintsetrandomseed\setrandomseed\fi
\fi
\ifx\xintsetrandomseed\relax \let\xintsetrandomseed\XINT_undefined\fi
\XINTrestorecatcodesendinput%
% \end{macrocode}
% \StoreCodelineNo {xintkernel}
% \cleardoublepage\let\xintkernelnameUp\undefined
%\gardesactifs
%\let