summaryrefslogtreecommitdiff
path: root/macros/generic/xint/xint.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/generic/xint/xint.dtx
Initial commit
Diffstat (limited to 'macros/generic/xint/xint.dtx')
-rw-r--r--macros/generic/xint/xint.dtx40510
1 files changed, 40510 insertions, 0 deletions
diff --git a/macros/generic/xint/xint.dtx b/macros/generic/xint/xint.dtx
new file mode 100644
index 0000000000..f5312323f1
--- /dev/null
+++ b/macros/generic/xint/xint.dtx
@@ -0,0 +1,40510 @@
+% -*- coding: utf-8; time-stamp-format: "%02d-%02m-%:y at %02H:%02M:%02S %Z" -*-
+% This file: xint.dtx. Proudly produced by xint-dtxbuild.sh.
+% Extract all files via "etex xint.dtx" and do "make help"
+% or follow instructions from extracted README.md.
+%<*dtx>
+\def\xintdtxtimestamp {Time-stamp: <06-04-2019 at 18:55:58 CEST>}
+%</dtx>
+%<*drv>
+%% ---------------------------------------------------------------
+\def\xintdocdate {2019/04/05}
+\def\xintbndldate{2019/04/05}
+\def\xintbndlversion {1.3e}
+%</drv>
+%<readme>% README
+%<changes>% CHANGE LOG
+%<readme|changes>% xint 1.3e
+%<readme|changes>% 2019/04/05
+%<readme|changes>
+%<readme|changes> Source: xint.dtx 1.3e 2019/04/05 (doc 2019/04/05)
+%<readme|changes> Author: Jean-Francois Burnol
+%<readme|changes> Info: Expandable operations on big integers, decimals, fractions
+%<readme|changes> License: LPPL 1.3e
+%<readme|changes>
+%<*!readme&!changes&!dohtmlsh&!dopdfsh&!makefile>
+%% ---------------------------------------------------------------
+%% The xint bundle 1.3e 2019/04/05
+%% Copyright (C) 2013-2019 by Jean-Francois Burnol
+%<xintkernel>%% xintkernel: Paraphernalia for the xint packages
+%<xinttools>%% xinttools: Expandable and non-expandable utilities
+%<xintcore>%% xintcore: Expandable arithmetic on big integers
+%<xint>%% xint: Expandable operations on big integers
+%<xintfrac>%% xintfrac: Expandable operations on fractions
+%<xintexpr>%% xintexpr: Expandable expression parser
+%<xintbinhex>%% xintbinhex: Expandable binary and hexadecimal conversions
+%<xintgcd>%% xintgcd: Euclidean algorithm with xint package
+%<xintseries>%% xintseries: Expandable partial sums with xint package
+%<xintcfrac>%% xintcfrac: Expandable continued fractions with xint package
+%<xinttrig>%% xinttrig: Trigonometry for the xintexpr package
+%<xintlog>%% xintlog: Logarithms and exponentials for xintexpr
+%% ---------------------------------------------------------------
+%</!readme&!changes&!dohtmlsh&!dopdfsh&!makefile>
+%<*dtx>
+\bgroup\catcode2 0 \catcode`\\ 12 ^^Biffalse
+%</dtx>
+%<*readme>--------------------------------------------------------
+This `README` is also available as `README.pdf` and `README.html`.
+
+Change log is to be found in `CHANGES.pdf` or `CHANGES.html`.
+
+The user manual is `xint.pdf`, and the commented source code is
+available as `sourcexint.pdf`.
+
+Aim
+===
+
+The basic aim is provide *expandable* computations on integers,
+fractions, and floating point numbers. For example
+
+ \xinttheexpr reduce(37189719/183618963+11390170/17310720)^17\relax
+
+will evaluate exactly the fraction; the result has 462 characters
+(including the fraction slash.) One can also work with dummy variables:
+
+ \xinttheexpr mul(add(x(x+1)(x+2), x=y..y+15), y=171286,98762,9296)\relax
+
+evaluates to `15979066346135829902328007959448563667099190784`.
+
+Float computations are possible at an adjustable precision (default 16).
+
+ \xintDigits:=48;\xintthefloatexpr 123_456_789^1_000.5\relax
+ ->3.63692761822782679930738270515740797370813691938e8095
+
+(as this example shows the underscore character can be used to separate
+visually digits, one can also use the space character for that purpose).
+
+Square-root and the four operations achieve correct rounding in the
+given arbitrary precision.
+
+Trigonometric functions (direct and inverse) are available with a
+maximal precision of 60 digits.
+
+Logarithms and exponentials are available using the
+[poormanlog](http://www.ctan.org/pkg/poormanlog) package which provides
+only 8 or 9 digits of precision. This will be increased in future.
+
+Usage
+=====
+
+It is possible to use the package both with Plain
+(`\input xintexpr.sty`) or with LaTeX (`\usepackage{xintexpr}`).
+
+## With LaTeX
+
+ \usepackage{xint} % expandable arithmetic with big integers
+ \usepackage{xintfrac} % decimal numbers, fractions, floats
+ \usepackage{xinttools} % expandable and non expandable loops
+ \usepackage{xintexpr} % expressions with infix operators
+
+The `xinttrig` and `xintlog` packages are loaded automatically by
+`xintexpr` and will refuse to be loaded directly.
+
+Further packages: `xintbinhex`, `xintgcd`, `xintseries` and `xintcfrac`.
+
+Main dependencies are handled automatically. For example `xintexpr`
+automatically loads `xinttools` and `xintfrac` (which itself loads
+`xint`). Hexadecimal input requires explicit loading of `xintbinhex`.
+
+Package `xintcore` is the subset of `xint` providing only the five
+operations on big integers: `\xintiiAdd`, `\xintiiMul`, ...
+
+The LaTeX package [bnumexpr](http://www.ctan.org/pkg/bnumexpr) defines a
+more light-weight parser of arithmetical expressions using big integers,
+which supports only the four operations, the modulo operation, the power
+operation, and the factorial. By default it uses the macros from
+`xintcore` but this can be customized.
+
+The LaTeX package [polexpr](http://www.ctan.org/pkg/polexpr) is based
+upon `xintexpr` and allows formal algebra with polynomials, and finding
+all real roots with arbitrary precision.
+
+## With TeX
+
+One does for example:
+
+ \input xintexpr.sty
+
+This will automatically load `xintfrac.sty`, `xinttrig.sty`,
+`xintlog.sty` and `xinttools.sty`. The packages may be loaded in any
+catcode context such that letters, digits, `\` and `%` have their
+standard catcodes.
+
+`xintcore.sty` and `xinttools.sty` both import `xintkernel.sty`
+which has the catcode handler and package identifier and defines a
+few utilities such as `\oodef/\fdef`, `\xint_dothis/\xint_orthat`,
+or `\xintLength`.
+
+Since `1.3b`, `xintkernel.sty` also provides `\xintUniformDeviate` which
+is a wrapper of the engine `\pdfuniformdeviate` or `\uniformdeviate`
+done to guarantee more uniformity of the pseudo-random integers.
+
+Installation
+============
+
+## Method A: using the package manager of your TeX distribution
+
+`xint` is included in [TeXLive](http://tug.org/texlive/) (hence also
+[MacTeX](http://tug.org/mactex/)) and [MikTeX](http://www.miktex.org/).
+
+There can be a few days of delay between apparition of a new version on
+[CTAN](http://www.ctan.org/pkg/xint) and availability via the distribution
+package manager.
+
+## Method B: manual installation using `xint.tds.zip` and `unzip`
+
+Assumes a GNU/Linux-like system (or Mac OS X).
+
+1. obtain `xint.tds.zip` from CTAN:
+ <http://mirror.ctan.org/install/macros/generic/xint.tds.zip>
+
+2. cd to the download repertory and issue:
+
+ unzip xint.tds.zip -d <TEXMF>
+
+ where `<TEXMF>` is a suitable TDS-compliant destination repertory.
+ For example, with TeXLive:
+
+ - Linux, standard access rights, hence sudo is needed, installation
+ into the "local" tree:
+
+ sudo unzip xint.tds.zip -d /usr/local/texlive/texmf-local
+ sudo texhash /usr/local/texlive/texmf-local
+
+ - Mac OS X, installation into user home folder (no sudo needed,
+ and it is recommended to not have a ls-R file there, hence no texhash):
+
+ unzip xint.tds.zip -d ~/Library/texmf
+
+## Method C: manual installation using `Makefile` and `xint.dtx`
+
+The Makefile automatizes rebuilding from `xint.dtx` all documentation
+files as well as `xint.tds.zip`. It is for GNU/Linux-like (inc. Mac OS
+X) systems, with a teTeX like installation such as TeXLive. The
+[Latexmk](http://personal.psu.edu/jcc8/software/latexmk/)
+and [Pandoc](http://johnmacfarlane.net/pandoc/) softwares
+are required to build all the documentation.
+
+1. obtain `xint.dtx` and `Makefile` from
+ <http://mirror.ctan.org/macros/generic/xint>.
+
+2. put them in an otherwise empty working repertory, run `make` or
+ equivalently `make help` for further instructions.
+
+## Method D: installation starting with only `xint.dtx`
+
+Run `etex xint.dtx` to extract from `xint.dtx` all macro files as well
+as auxiliary files needed for building the documentation. Among them
+there is `Makefile.mk`. If you are on a GNU/Linux-type system, rename
+the file to `Makefile` and execute `make` on command line for further
+help. If you can't use `make` read the contents of the `Makefile` for
+instructions.
+
+Finishing the installation in a TDS hierarchy:
+
+- move the style files to `TDS:tex/generic/xint/`
+
+- `xint.dtx` goes to `TDS:source/generic/xint/`
+
+- The documentation (xint.pdf, README.md,...) goes to `TDS:doc/generic/xint/`
+
+Depending on the destination, it may then be necessary to refresh a
+filename database.
+
+License
+=======
+
+<div class="mono">
+Copyright (C) 2013-2019 by Jean-Francois Burnol
+
+This Work may be distributed and/or modified under the
+conditions of the LaTeX Project Public License version 1.3c.
+This version of this license is in
+
+> <http://www.latex-project.org/lppl/lppl-1-3c.txt>
+
+and version 1.3 or later is part of all distributions of
+LaTeX version 2005/12/01 or later.
+
+This Work has the LPPL maintenance status `author-maintained`.
+
+The Author of this Work is Jean-Francois Burnol.
+
+This Work consists of the source file xint.dtx and of its derived
+files: xintkernel.sty, xintcore.sty, xint.sty, xintfrac.sty,
+xintexpr.sty, xinttrig.sty, xintlog.sty, xintbinhex.sty,
+xintgcd.sty, xintseries.sty,
+xintcfrac.sty, xinttools.sty, xint.ins, xint.tex, README, README.md,
+README.html, README.pdf, CHANGES.md, CHANGES.html, CHANGES.pdf,
+pandoctpl.latex, doHTMLs.sh, doPDFs.sh, xint.dvi, xint.pdf,
+and Makefile.mk.</div>
+%</readme>--------------------------------------------------------
+%<*changes>-------------------------------------------------------
+
+`1.3e (2019/04/05)`
+----
+
+### Incompatible changes
+
+ - When defining functions, sub-expressions can only use the
+ `\xint(float)expr...\relax` syntax. One can *not* use there the
+ `\xint(float)eval` wrappers (anyhow they add overhead and can be
+ replaced with the lower level syntax).
+
+### Improvements and new features
+
+ - The **xinttrig** library is automatically loaded by **xintexpr**. It
+ provides direct and inverse trigonometrical functions using either
+ degrees or radians with a precision of up to (a bit less than) 60
+ digits. It is for the most part implemented using high level user
+ interface, but will probably get some optimizations in future (and
+ perhaps extension to more digits).
+ - The **xintlog** library is automatically loaded by **xintexpr**. It
+ uses [poormanlog](http://ctan.org/pkg/poormanlog) to provide
+ logarithms and exponentials with almost 9 digits of precision.
+ Extended precision is for a future release.
+ - **xintexpr**: `\xintdefefunc`, `\xintdeffloatefunc`, `\xintdefiiefunc`
+ define functions which are not protected against expansion in the
+ definition of other functions; refer to `xint.pdf` for the related
+ explanations.
+
+ Notice that whole area of `\xintdef(e)func`, `\xintNewExpr`,
+ `\xintNewFunction` is complex and to be considered still as work in
+ progress as it has a number of shortcomings.
+ - **xintexpr**: `inv()`, `ilog10()`, `sfloat()`, behaviour of
+ `qfloat()` slightly modified.
+ - **xintexpr**: `\xintensuredummy`, `\xintrestorelettervar`.
+ - The optional argument of `\xintfloatexpr` or `\xintfloateval` (it
+ must be at start of braced argument) can be negative; it then means
+ to trim (and round) from the output at float precision that many
+ least significant digits.
+
+### Bug fixes
+
+ - Some bugfixes related to user functions with no variables at all;
+ they were dysfunctional.
+
+`1.3d (2019/01/06)`
+----
+
+### Incompatible changes
+
+ - **xintexpr**: the `gcd()` and `lcm()` functions formerly converted
+ their arguments to integers via `\xintNum`. They now handle general
+ input with no such modification.
+
+ - **xintexpr**: former `\xinteval`, `\xintieval`, `\xintiieval`, and
+ `\xintfloateval` renamed to `\xintexpro`, `\xintiexpro`,
+ `\xintiiexpro`, and `\xintfloatexpro`.
+
+### Improvements and new features
+
+ - **xintexpr**: the `gcd()` and `lcm()` multi-arguments functions have
+ been refactored to handle general fractions. The dependency on
+ **xintgcd** is removed.
+
+ - **xintexpr**: three-way branching `\xintifsgnexpr`,
+ `\xintifsgnfloatexpr`, `\xintifsgniiexpr` conditional macros.
+
+ - **xintexpr**: `\xintunassignexprfunc`, `\xintunassigniiexprfunc`,
+ `\xintunassignfloatexprfunc` to "undefine" functions.
+
+ - **xintexpr**: `\xintunassignvar` really makes the (multi-letter) variable
+ unknown (formerly, it only gave it value zero),
+
+ - **xintexpr**: functions `isone()` and `isint()`.
+
+ - **xintexpr**: `\xinteval`, `\xintieval`, `\xintiieval`, and
+ `\xintfloateval` as synonyms to `\xinttheexpr...\relax` etc..., but
+ with the (comma-separated) expression as a usual braced macro
+ argument.
+
+### Bug fixes
+
+ - **xintcore**, **xintexpr** : division in `\xintiiexpr` was broken for
+ a zero dividend and a one-digit divisor (e.g. ``0//7``) since `1.2p`
+ due to a bug in `\xintiiDivMod` for such arguments. The bug was
+ signaled (thanks to Kpym for report) and fixed shortly after `1.3c`
+ release but I then completely forgot to upload a bugfix release to
+ CTAN at that time, apologies for that.
+
+`1.3c (2018/06/17)`
+----
+
+### Improvements and new features
+
+ - **xintexpr**: with `\xintglobaldefstrue`, `\xintdefvar`,
+ `\xintdeffunc`, `\xintNewExpr` et al. make definitions with global
+ scope.
+
+ - **xintexpr**: `qraw()` for fast input of (very many) comma separated
+ numbers (in suitable raw format).
+
+ - **xintexpr**: the colon in the `:=` part of the syntax for
+ `\xintdefvar` and variants is now optional; and if present it may be
+ an active character or have any (reasonable) catcode.
+
+ - **xintexpr**: `\xintdefvar`, `\xintdeffunc` and their variants try to
+ set the catcode of the semi-colon which delimits their arguments; of
+ course this will not work if that catcode is already frozen.
+
+ - `\xintUniformDeviate` is better documented and `sourcexint.pdf` is better
+ hyperlinked and includes indices for the macros defined by each package.
+
+### Bug fixes
+
+ - **xintfrac**: since `1.3` release, it loaded **xintgcd** in
+ contradiction to what the documentation says (hence also **xintexpr**
+ loaded **xintgcd** automatically). There is no actual dependency so
+ the loading is removed for now.
+
+`1.3b (2018/05/18)`
+----
+
+### Improvements and new features
+
+All additions related to randomness are marked as work-in-progress. They
+require an engine providing the `\(pdf)uniformdeviate` primitive.
+
+ - **xintkernel**: `\xintUniformDeviate`.
+
+ - **xint**: `\xintRandomDigits`, `\xintXRandomDigits`, `\xintiiRandRange`,
+ `\xintiiRandRangeAtoB`.
+
+ - **xintfrac**: support macros (not public, mainly because internal
+ format for floats is surely not final) for `random()` and `qrand()`.
+
+ - **xintexpr**: `random()`, `qrand()`, and `randrange(A[, B])`.
+
+ - **xintexpr**: when a function `foo()` is declared via `\xintdeffunc`
+ (et al.) to be parameter-less, it can be used as `foo()`; formerly
+ `foo(nil)` syntax was required.
+
+ - The usual provision of user manual "improvements".
+
+
+`1.3a (2018/03/07)`
+----
+
+### Removed
+
+ - **xintcore**, **xint**, **xintfrac**: removal of the internal macros
+ which were used at `1.2o` to add a deprecation mechanism; all
+ deprecated macros have been removed at `1.3` so there was no reason
+ to keep the code used for deprecating them.
+
+### Improvements and new features
+
+ - **xintexpr**: new conditionals `ifone()` and `ifint()`.
+
+ - **xintfrac**: `\xintREZ` is faster on inputs having one hundred
+ digits or more.
+
+ - Added to the user manual mention of macros such as `\xintDivFloor`,
+ `\xintMod`, `\xintModTrunc`, which had been left out so far.
+
+### Bug fixes
+
+ - **xintexpr**: the mechanism for adjunction to the expression parsers
+ of user defined functions was refactored and improved at previous
+ release `1.3`: in particular recursive definitions became possible.
+ But an oversight made these recursive functions quite inefficient (to
+ remain polite.) This release fixes the problem.
+
+
+`1.3 (2018/03/01)`
+----
+
+### Incompatible changes
+
+ - **xintcore**, **xint**, **xintfrac**: all macros deprecated at `1.2o`
+ got removed.
+
+ - **xintfrac**: addition and subtraction of `a/b` and `c/d` now use the
+ l.c.m. of the denominators. Similarly the macro supporting the modulo
+ operator `/:` uses a l.c.m. for the denominator of the result.
+
+ - **xintexpr**: the addition, subtraction, modulo `/:`, and the
+ `mod()` and `divmod()` functions produce generally smaller denominators
+ (see previous item).
+
+ - **xintexpr**: formerly, the internal macros which are internally
+ associated to user-declared functions were using comma separated
+ parameter texts. They now do not use such commas (their meanings,
+ which may again change in future, are written for information to the
+ log under `\xintverbosetrue`).
+
+### Improvements and new features
+
+ - **xintexpr**: user-defined functions may now be of a recursive
+ nature. This was made possible by a refactoring of the `\xintNewExpr`
+ mechanism. It became both leaner and more extensive than formerly.
+
+ - **xintfrac**: new macros `\xintPIrr` and `\xintDecToString`. The
+ latter is a backport of a `polexpr 0.4` utility, and it is to be
+ considered unstable.
+
+ - **xintexpr**: new function `preduce()` associated with `\xintPIrr`.
+
+
+`1.2q (2018/02/06)`
+----
+
+### Improvements and new features
+
+ - **xintexpr**: tacit multiplication extended to cases such as `3!4!5!`
+ or `(1+2)3`.
+
+### Bug fixes
+
+ - **xintcore**: sadly, refactoring at `1.2l` of subtraction left an
+ extra character in an inner macro causing breakage in some rare
+ circumstances. This should not have escaped our test suite!
+
+
+`1.2p (2017/12/05)`
+----
+
+### Incompatible changes
+
+ - **xintgcd**: `\xintBezout{a}{b}`'s output consists of `{u}{v}{d}`
+ with `u*a+v*b==d`, with `d` the GCD. Formerly it was
+ `{a}{b}{u}{v}{d}`, and with `u*a-v*b==d`.
+
+ - **xintgcd**: `\xintBezout{0}{0}` expands to `{0}{0}{0}`. Formerly
+ (since `1.2l`) it raised `InvalidOperation`.
+
+ - **xintcore**: `\xintiiMod` is now associated with floored division.
+ The former meaning (associated with truncated division) is available
+ as `\xintiiModTrunc`.
+
+ - **xintfrac**: `\xintMod` is now associated with floored division. The
+ former meaning is available as `\xintModTrunc`.
+
+ - **xintexpr**: the ``//`` operator and its associated modulo ``'mod'``
+ (or ``/:``) now correspond to floored division, like the Python
+ language `//`, `%`, and `divmod(x, y)`. Formerly they had been
+ associated to truncated division. This is breaking change for
+ operands of opposite signs.
+
+### Improvements and new features
+
+ - **xinttools**: `\xintListWithSep`, which had remained unchanged since
+ its introduction at `1.04 (2013/04/25)`, was rewritten for increased
+ speed.
+
+ - **xintexpr**: `\xintdefvar`'s syntax is extended to allow
+ simultaneous assignments. Examples:
+ `\xintdefvar x1, x2, x3 := 1, 3**10, 3**20;` or
+ `\xintdefiivar A, B := B, A 'mod' B;`
+ for already defined variables `A` and `B`.
+
+ - **xintexpr**: added `divmod()` to the built-in functions. It is
+ associated with floored division, like the Python language `divmod()`.
+ Related support macros added to **xintcore**, and **xintfrac**.
+
+### Bug fixes
+
+ - **xintgcd**: `\xintBezout{6}{3}` (for example) expanded to
+ `{6}{3}{-0}{-1}{3}`, but the `-0` should have been `0`.
+
+ - **xintgcd**: it still used macro `\xintiAbs` although the latter had
+ been deprecated from **xintcore**.
+
+ - **xintexpr**: in float expressions the `//` and `/:` (aka `'mod'`)
+ operators did not round their operands to the float precision prior
+ to computing with them, contrarily to other infix arithmetic
+ operators and to the `mod(f,g)` function; thus, `mod(f,g)` and
+ `f 'mod' g` were not completely equivalent.
+
+ - various documentation fixes; in particular, the partial dependency of
+ **xintcfrac** on **xinttools** had not been mentioned.
+
+
+`1.2o (2017/08/29)`
+----
+
+### Incompatible changes
+
+ - **xint**: `\xintAND`, `\xintOR`, ... and similar Boolean logic macros do
+ not apply anymore `\xintNum` (or `\xintRaw` if **xintfrac** is loaded), to
+ their arguments (often, from internal usage of `\xintSgn`), but only
+ f-expand them (using e.g. `\xintiiSgn`). This is kept un-modified even if
+ loading **xintfrac**.
+
+### Deprecated
+
+Deprecated macros raise an error but, generally, then expand as in former
+releases. They will all get removed at some future release.
+
+ - **xintcore**: `\xintiOpp`, `\xintiAbs`, `\xintiAdd`, `\xintiSub`,
+ `\xintiMul`, `\xintiDivision`, `\xintiQuo`, `\xintiRem`, `\xintiDivRound`,
+ `\xintiDivTrunc`, `\xintiMod`, `\xintiSqr`, `\xintiPow`, and `\xintiFac`
+ are deprecated. Only the `ii`-named variants get defined.
+
+ - **xintcore**: `\xintCmp` and `\xintSgn` are deprecated from **xintcore**
+ (which only defines `\xintiiCmp` and `\xintiiSgn`) as they actually belong
+ to **xintfrac**.
+
+ - **xintcore**: `\xintiiFDg`, resp. `\xintiiLDg`, are renamed `\xintFDg`,
+ resp. `\xintLDg`. Former denominations are deprecated.
+
+ - **xint**: `\xintMON`, `\xintMMON`, `\xintiMax`,
+ `\xintiMin`, `\xintiMaxof`, `\xintiMinof`, `\xintiSquareRoot`,
+ `\xintiSqrt`, `\xintiSqrtR`, `\xintiBinomial`, and `\xintiPFactorial` are
+ deprecated. Only `ii`-named variants get defined.
+
+ - **xint**: `\xintEq`, `\xintGeq`, `\xintGt`, `\xintLt`, `\xintGtorEq`,
+ `\xintLtorEq`, `\xintIsZero`, `\xintIsNotZero`, `\xintIsOne`,
+ `\xintOdd`, `\xintEven`, `\xintifSgn`,
+ `\xintifCmp`, `\xintifEq`, `\xintifGt`, `\xintifLt`, `\xintifZero`,
+ `\xintifNotZero`, `\xintifOne`, `\xintifOdd`, are deprecated. These macros
+ belong to **xintfrac**. Package **xint** defines only the `ii`-named
+ variants.
+
+ - **xint**: `\xintNeq` was renamed to `\xintNotEq` which however is only
+ provided by **xintfrac**. Package **xint** defines `\xintiiNotEq`, and
+ `\xintNeq` is deprecated.
+
+ - **xint**: `\xintNot` was renamed to `\xintNOT`, former denomination is
+ deprecated. See also item about Boolean logic macros in the *Incompatible
+ Changes* section.
+
+
+`1.2n (2017/08/06)`
+----
+
+### Incompatible changes
+
+ - **xintbinhex** does not load package **xintcore** anymore, but only
+ **xintkernel**.
+
+### Improvements and new features
+
+ - **xintbinhex** has only **xintkernel** as dependency.
+
+ - Macros of **xintbinhex** have been improved for speed and increased maximal
+ sizes of allowable inputs.
+
+
+`1.2m (2017/07/31)`
+----
+
+### Incompatible changes
+
+ - **xintbinhex**: the length of the input is now limited. The maximum
+ size depends on the macro and ranges from about `4000` to about
+ `19900` digits.
+
+ - **xintbinhex**: `\xintCHexToBin` is now the variant of
+ `\xintHexToBin` which does not remove leading binary zeroes: `N`
+ hex-digits give on output exactly `4N` binary digits.
+
+### Improvements and new features
+
+ - **xintbinhex**: all macros have been rewritten using techniques from
+ the 1.2 release (they had remained unmodified since `1.08` of
+ `2013/06/07`.) The new macros are faster but limited to a few
+ thousand digits. The `1.08` routines could handle tens of thousands
+ of digits, but not in a reasonable time.
+
+### Bug fixes
+
+ - user manual: the `Changes` section wrongly stated at `1.2l` that the
+ macros of **xintbinhex** had been made robust against non terminated
+ input such as ``\number\mathcode`\-``. Unfortunately the author fell
+ into the trap of believing his own documentation and he forgot to
+ actually implement the change. Now done.
+
+ - user manual: the PDF bookmarks were messed up.
+
+ - **xint**, **xintfrac**: `\xintGeq`, `\xintMax`, `\xintMin`, suffered
+ from some extra overhead. This was caused by use of some auxiliaries
+ from the very early days which got redefined at some stage. This is
+ fixed here with some additional efficiency improvements and pruning
+ of old code.
+
+
+`1.2l (2017/07/26)`
+----
+
+### Removed
+
+ - `\xintiiSumExpr`, `\xintiiPrdExpr` (**xint**) and `\xintSumExpr`,
+ `\xintPrdExpr` (**xintfrac**). They had not been formally deprecated,
+ but had been left un-documented since `1.09d (2013/10/22)`.
+
+ - internal macro `\xint_gob_til_xint_relax` removed.
+
+### Improvements and new features
+
+ - the underscore character `_` is accepted by the **xintexpr** parsers
+ as a digit separator (the space character already could be used for
+ improved readability of big numbers). It is not allowed as *first*
+ character of a number, as it would then be mis-interpreted as the
+ start of a possible variable name.
+
+ - some refactoring in **xintcore** auxiliary routines and in
+ `\xintiiSub` and `\xintiiCmp` for some small efficiency gains.
+
+ - code comments in **xintcore** are better formatted, but remain
+ sparse.
+
+ - **xintcore**, **xint**, **xintfrac**, ... : some macros were not
+ robust against arguments whose expansion looks forward for some
+ termination (e.g. ``\number\mathcode`\-``), and particularly, most
+ were fragile against inputs using non-terminated ``\numexpr`` (such
+ as `\xintiiAdd{\the\numexpr1}{2}` or `\xintRaw{\numexpr1}`). This was
+ not a bug per se, as the user manual did not claim such inputs were
+ legal, but it was slightly inconvenient. Most macros (particularly
+ those of **xintfrac**) have now been made robust against such inputs.
+ Some macros from **xintcore** primarily destined to internal usage
+ still accept only properly terminated arguments such as
+ ``\the\mathcode`\-<space>`` or ``\the\numexpr1\relax``.
+
+ The situation with expressions is unchanged: syntax such as
+ `\xintexpr \numexpr1+2\relax` is illegal as the ending `\relax` token
+ will get swallowed by the `\numexpr`; but it is needed by the
+ ``xintexpr``-ession parser, hence the parser will expand forward and
+ presumably end with in an "illegal token" error, or provoke some
+ low-level TeX error (N.B.: a closing brace `}` for example can not
+ terminate an ``xintexpr``-ession, the parser must find a `\relax`
+ token at some point). Thus there must be in this example a second
+ `\relax`.
+
+ - experimental code for error conditions; there is no complete user
+ interface yet, it is done in preparation for next major release and
+ is completely unstable and undocumented.
+
+### Bug fixes
+
+ - **xintbinhex**: since `1.2 (2015/10/10)`, `\xintHexToDec` was
+ broken due to an undefined macro (it was in `xint.sty`, but the
+ module by itself is supposedly dependent only upon `xintcore.sty`).
+
+ - **xintgcd**: macro `\xintBezout` produced partially wrong output if
+ one of its two arguments was zero.
+
+ - **xintfrac**: the manual said one could use directly `\numexpr`
+ compatible expressions in arithmetic macros (without even a
+ `\numexpr` encapsulation) if they were expressed with up to 8 tokens.
+ There was a bug if these 8 tokens evaluated to zero. The bug has been
+ fixed, and up to 9 tokens are now accepted. But it is simpler to use
+ `\the\numexpr` prefix and not to worry about the token count... The
+ ending `\relax` is now un-needed.
+
+
+`1.2k (2017/01/06)`
+----
+
+### Incompatible changes
+
+ - macro `\xintFloat` which rounds its input to a floating point number
+ does _not_ print anymore `10.0...0eN` to signal an upwards rounding
+ to the next power of ten. The mantissa has in all cases except the
+ zero input exactly one digit before the decimal mark.
+
+ - some floating point computations may differ in the least significant
+ digits, due to a change in the rounding algorithm applied to macro
+ arguments expressed as fractions and to an improvement in precision
+ regarding half-integer powers in expressions. See next.
+
+### Improvements and new features
+
+ - the initial rounding to the target precision `P` which is applied by
+ the floating point macros from **xintfrac** to their arguments
+ achieves the _exact (aka correct) rounding_ even for inputs which are
+ fractions with more than `P+2` digits in their numerators and
+ denominators (`>1`.) Hence the computed values depend only on the
+ arguments as rational numbers and not upon their representatives.
+ This is not relevant to _expressions_ (**xintexpr**), because the
+ `\xintfloatexpr` parser sees there `/` as an operator and does not
+ (apart from special constructs) get to manipulate fractions as such.
+
+ - `\xintnewdummy` is public interface to a `1.2e` macro which serves to
+ declare any given catcode 11 character as a dummy variable for
+ expressions (**xintexpr**). This is useful for Unicode engines (the
+ Latin letters being already all pre-declared as dummy variables.)
+
+ - added `\xintiSqrtR`, there was only `\xintiiSqrtR` alongside
+ `\xintiSqrt` and `\xintiiSqrt` (**xint**).
+
+ - added non public `\xintLastItem:f:csv` to **xinttools** for faster
+ `last()` function, and improved `\xintNewExpr` compatibility. Also
+ `\xintFirstItem:f:csv`.
+
+### Bug fixes
+
+ - the `1.2f` half-integer powers computed within `\xintfloatexpr` had a
+ silly rounding to the target precision just _before_ the final
+ square-root extraction, thus possibly losing some precision. The
+ `1.2k` implementation keeps guard digits for this final square root
+ extraction. As for integer exponents, it is guaranteed that the
+ computed value differs from the exact one by less than `0.52 ulp`
+ (for inputs having at most `\xinttheDigits` digits.)
+
+ - more regressions from `1.2i` were fixed: `\xintLen` (**xint**,
+ **xintfrac**) and `\xintDouble` (**xintcore**) had forgotten that
+ their argument was allowed to be negative. A regression test suite is
+ now in place and is being slowly expanded to cover more macros.
+
+ - `\xintiiSquareRoot{0}` now produces `{1}{1}`, which fits better the
+ general documented behaviour of this macro than `11`.
+
+
+`1.2j (2016/12/22)`
+----
+
+### Improvements and new features
+
+ - **xinttools** and **xintexpr**:
+
+ 1. slightly improves the speed of `\xintTrim`.
+
+ 2. speed gains for the handlers of comma separated lists
+ implementing Python-like slicing and item extraction. Relevant
+ non (user) documented macros better documented in
+ `sourcexint.pdf`.
+
+ - significant documentations tweaks (inclusive of suppressing things!),
+ and among them two beautiful hyperlinked tables with both horizontal
+ and vertical rules which bring the documentation of the **xintexpr**
+ syntax to a kind of awe-inspiring perfection... except that
+ implementation of some math functions is still lacking.
+
+### Bug fixes
+
+ - fix two `1.2i` regressions caused by undefined macros (`\xintNthElt`
+ in certain branches and `[list][N]` item extraction in certain
+ cases.) The test files existed but were not executed prior to
+ release. Automation in progress.
+
+
+`1.2i (2016/12/13)`
+----
+
+### Incompatible changes
+
+ - `\xintDecSplit` second argument must have no sign (former code
+ replaced it with its absolute value, a sign now may cause an error.)
+
+### Removed
+
+ - deprecated macros `\xintifTrue`, `\xintifTrueFalse`, `\xintQuo`,
+ `\xintRem`, `\xintquo`, `\xintrem`.
+
+### Improvements and new features
+
+ - **xintkernel**: `\xintLength` is faster. New macros:
+
+ - `\xintLastItem` to fetch the last item from its argument,
+
+ - `\romannumeral\xintgobble` for gobbling many (up to 531440)
+ upstream braced items or tokens.
+
+ - `\romannumeral\xintreplicate` which is copied over from the expl3
+ `\prg_replicate:nn` with some minor changes.
+
+ - **xinttools**: general token list handling routines `\xintKeep`,
+ `\xintTrim` and `\xintNthElt` are faster; but the novel `\xintTrim`
+ can only remove up to a maximum of 531440 items.
+
+
+ Also, `\xintFor` partially improves on some issues which are
+ reported upon in the documentation.
+
+ - some old macros have been rewritten entirely or partially using
+ techniques which **xint** started using in release `1.2`:
+
+ - **xintcore**: `\xintDouble`, `\xintHalf`, `\xintInc`, `\xintDec`,
+ `\xintiiLDg`, `\xintDSR` (originally from **xint**), a novel
+ `\xintDSRr`.
+
+ - **xint**: `\xintDSH`, `\xintDSx`, `\xintDecSplit`, `\xintiiE`.
+
+ - **xintfrac**: as a result of the above `\xintTrunc`, `\xintRound`
+ and `\xintXTrunc` got faster. But the main improvement for them is
+ with decimal inputs which formerly had not been treated separately
+ from the general fraction case. Also, `\xintXTrunc` does not
+ anymore create a dependency of **xintfrac** on **xinttools**.
+
+ - the documentation has again been (slightly) re-organized; it has a
+ new sub-section on the Miller-Rabin primality test, to illustrate
+ some use of `\xintNewFunction` for recursive definitions.
+
+ - the documentation has dropped the LaTeX "command" terminology (which
+ had been used initially in 2013 for some forgotten reasons and should
+ have been removed long ago) and uses only the more apt "macro", as
+ after all, all of **xint** is about expansion of macros (plus the use
+ of `\numexpr`).
+
+### Bug fixes
+
+ - `\xintDecSplitL` and `\xintDecSplitR` from **xint** produced their
+ output in a spurious brace pair (bug introduced in `1.2f`).
+
+
+`1.2h (2016/11/20)`
+----
+
+### Improvements and new features
+
+ - new macro `\xintNewFunction` in **xintexpr** which allows to extend
+ the parser syntax with functions in situations where `\xintdeffunc`
+ is not usable (typically, because dummy variables are used over a not
+ yet determined range of values because it depends on the variables).
+
+ - after three years of strict obedience to `xint` prefix, now
+ `\thexintexpr`, `\thexintiexpr`, `\thexintfloatexpr`, and
+ `\thexintiiexpr` are provided as synonyms to `\xinttheexpr`, etc...
+
+### Bug fixes
+
+ - the `(cond)?{foo}{bar}` operator from **xintexpr** mis-behaved in
+ certain circumstances (such as an empty `foo`).
+
+ - the **xintexpr** `1.2f` `binomial` function (which uses
+ `\xintiiBinomial` from **xint.sty** or `\xintFloatBinomial` from
+ **xintfrac.sty**) deliberately raised an error for `binomial(x,y)`
+ with `y<0` or `x<y`. This was unfortunate, and it now simply
+ evaluates to zero in such cases.
+
+ - similarly the `pfactorial` function was very strict and
+ `pfactorial(x,y)` deliberately raised an out-of-range error if not
+ used with non-negative integers with `x` less than `y`. It now avoids
+ doing that and allows negative arguments.
+
+ - the `add` and `mul` from **xintexpr**, which work with dummy
+ variables since `1.1`, raised an error since `1.2c 2015/11/16` when
+ the dummy variable was given an empty range (or list) of values,
+ rather than producing respectively `0` and `1` as formerly.
+
+
+`1.2g (2016/03/19)`
+----
+
+### Incompatible changes
+
+ - inside expressions, list item selector `[L][n]` counts starting at
+ zero, not at one. This is more coherent with `[L][a:b]` which was
+ already exactly like in Python since its introduction. A function
+ len(L) replaces earlier `[L][0]`.
+
+ - former `iter` keyword now called `iterr`. Indeed it matched with
+ `rrseq`, the new `iter` (which was somehow missing from `1.1`) is the
+ one matching `rseq`. Allows to iterate more easily with a "list"
+ variable.
+
+### Improvements and new features
+
+ - in **xintexpr.sty**: list selectors `[L][n]` and `[L][a:b]` are more
+ efficient: the earlier `1.1` routines did back and forth conversions
+ from comma separated values to braced tokens, the `1.2g` routines use
+ macros from **xinttools.sty** handling directly the encountered lists
+ of comma separated values.
+
+ - in **xinttools.sty**: slight improvements in the efficiency of the
+ `\xintNthElt`, `\xintKeep`, `\xintTrim` routines and new routines
+ handling directly comma separated values. The latter are not included
+ in the user manual (they are not `\long`, they don't make efforts to
+ preserve some braces, do not worry about spaces, all those worries
+ being irrelevant to the use in expressions for list selectors).
+
+ - a slight speed improvement to `\xintFloatSqrt` in its quest of
+ correct rounding.
+
+ - float multiplication and division handle more swiftly operands
+ (non-fractional) with few digits, when the float precision is large.
+
+ - the syntax of expressions is described in a devoted chapter of the
+ documentation; an example shows how to implement (expandably) the
+ Brent-Salamin algorithm for computation of Pi using `iter` in a float
+ expression.
+
+
+`1.2f (2016/03/12)`
+----
+
+### Incompatible changes
+
+ - no more `\xintFac` macro but `\xintiFac/\xintiiFac/\xintFloatFac`.
+
+### Improvements and new features
+
+ - functions `binomial`, `pfactorial` and `factorial` in both integer
+ and float versions.
+
+ - macros `\xintiiBinomial`, `\xintiiPFactorial`
+ (**xint.sty**) and `\xintFloatBinomial`, `\xintFloatPFactorial`
+ (**xintfrac.sty**). Improvements to `\xintFloatFac`.
+
+ - faster implementation and increased accuracy of float power macros.
+ Half-integer exponents are now accepted inside float expressions.
+
+ - faster implementation of both integral and float square root macros.
+
+ - the float square root achieves
+ *correct* (aka *exact*) rounding in arbitrary precision.
+
+ - modified behaviour for the `\xintPFloat` macro, used by
+ `\xintthefloatexpr` to prettify its output. It now opts for decimal
+ notation if and only if scientific notation would use an exponent between
+ `-5` and `5` inclusive. The zero value is printed `0.` with a dot.
+
+ - the float macros for addition, subtraction, multiplication, division now
+ first round their two operands to P, not P+2, significant places before
+ doing the actual computation (P being the target precision). The same
+ applies to the power macros and to the square root macro.
+
+ - the documentation offers a more precise (and accurate) discussion of
+ floating point issues.
+
+ - various under-the-hood code improvements; the floatexpr operations are
+ chained in a faster way, from skipping some unneeded parsing on results of
+ earlier computations. The absence of a real inner data structure for floats
+ (incorporating their precisions, for one) is however still a bit hair
+ raising: currently the lengths of the mantissas of the operands are computed
+ again by each float macro or expression operation.
+
+ - (TeXperts only) the macros defined (internally) from `\xintdeffunc` et al.
+ constructs do not incorporate an initial `\romannumeral` anymore.
+
+ - renewed desperate efforts at improving the documentation by random
+ shuffling of sections and well thought additions; cuts were considered and
+ even performed.
+
+### Bug fixes
+
+ - squaring macro `\xintSqr` from **xintfrac.sty** was broken due to a
+ misspelled sub-macro name. Dates back to `1.1` release of `2014/10/28`
+ `:-((`.
+
+ - `1.2c`'s fix to the subtraction bug from `1.2` introduced another bug,
+ which in some cases could create leading zeroes in the output, or even
+ worse. This could invalidate other routines using subtractions, like
+ `\xintiiSquareRoot`.
+
+ - the comparison operators were not recognized by `\xintNewIIExpr` and
+ `\xintdefiifunc` constructs.
+
+
+`1.2e (2015/11/22)`
+----
+
+### Improvements and new features
+
+ - macro `\xintunassignvar`.
+
+ - slight modifications of the logged messages in case of `\xintverbosetrue`.
+
+ - a space in `\xintdeffunc f(x)<space>:= expression ;` is now accepted.
+
+ - documentation enhancements: the _Quick Sort_ section with its included
+ code samples has been entirely re-written; the _Commands of the xintexpr
+ package_ section has been extended and reviewed entirely.
+
+### Bug fixes
+
+ - in **xintfrac**: the `\xintFloatFac` from release `1.2` parsed its
+ argument only through `\numexpr` but it should have used `\xintNum`.
+
+ - in **xintexpr**: release `1.2d` had broken the recognition of
+ sub-expressions immediately after variable names (with tacit
+ multiplication).
+
+ - in **xintexpr**: contrarily to what `1.2d` documentation said, tacit
+ multiplication was not yet always done with enhanced precedence. Now
+ yes.
+
+
+`1.2d (2015/11/18)`
+----
+
+### Improvements and new features
+
+ - the function definitions done by `\xintdeffunc` et al., as well as
+ the macro declarations by `\xintNewExpr` et al. now have only local
+ scope.
+
+ - tacit multiplication applies to more cases, for example (x+y)z, and
+ always ties more than standard * infix operator, e.g. x/2y is like
+ x/(2*y).
+
+ - some documentation enhancements, particularly in the chapter on
+ xintexpr.sty, and also in the code source comments.
+
+### Bug fixes
+
+ - in **xintcore**: release `1.2c` had inadvertently broken the
+ `\xintiiDivRound` macro.
+
+
+`1.2c (2015/11/16)`
+----
+
+### Improvements and new features
+
+ - macros `\xintdeffunc`, `\xintdefiifunc`, `\xintdeffloatfunc` and
+ boolean `\ifxintverbose`.
+
+ - on-going code improvements and documentation enhancements, but
+ stopped in order to issue this bugfix release.
+
+### Bug fixes
+
+ - in **xintcore**: recent release `1.2` introduced a bug in the
+ subtraction (happened when 00000001 was found under certain
+ circumstances at certain mod 8 locations).
+
+
+`1.2b (2015/10/29)`
+----
+
+### Bug fixes
+
+ - in **xintcore**: recent release `1.2` introduced a bug in the division
+ macros, causing a crash when the divisor started with 99999999 (it was
+ attempted to use with 1+99999999 a subroutine expecting only 8-digits
+ numbers).
+
+
+`1.2a (2015/10/19)`
+----
+
+### Improvements and new features
+
+ - added `\xintKeepUnbraced`, `\xintTrimUnbraced` (**xinttools**) and fixed
+ documentation of `\xintKeep` and `\xintTrim` regarding brace stripping.
+
+ - added `\xintiiMaxof/\xintiiMinof` (**xint**).
+
+ - TeX hackers only: replaced all code uses of ``\romannumeral-`0``
+ by the quicker ``\romannumeral`&&@`` (`^` being used as letter,
+ had to find another character usable with catcode 7).
+
+### Bug fixes
+
+ - in **xintexpr**: recent release `1.2` introduced a bad bug in the
+ parsing of decimal numbers and as a result `\xinttheexpr 0.01\relax`
+ expanded to `0` ! (sigh...)
+
+
+`1.2 (2015/10/10)`
+----
+
+### Removed
+
+ - the macros `\xintAdd`, `\xintSub`, `\xintMul`, `\xintMax`,
+ `\xintMin`, `\xintMaxof`, `\xintMinof` are removed from package
+ **xint**, and only exist in the versions from **xintfrac**. With only
+ **xintcore** or **xint** loaded, one _must_ use `\xintiiAdd`,
+ `\xintiiSub`, ..., or `\xintiAdd`, `\xintiSub`, etc...
+
+### Improvements and new features
+
+ - the basic arithmetic implemented in **xintcore** has been entirely
+ rewritten. The mathematics remains the elementary school one, but the
+ `TeX` implementation achieves higher speed (except, regarding
+ addition/subtraction, for numbers up to about thirty digits), the
+ gains becoming quite significant for numbers with hundreds of digits.
+
+ - the inputs must have less than 19959 digits. But computations with
+ thousands of digits take time.
+
+ - a previously standing limitation of `\xintexpr`, `\xintiiexpr`, and
+ of `\xintfloatexpr` to numbers of less than 5000 digits has been
+ lifted.
+
+ - a *qint* function is provided to help the parser gather huge integers
+ in one-go, as an exception to its normal mode of operation which
+ expands token by token.
+
+ - `\xintFloatFac` macro for computing the factorials of integers as
+ floating point numbers to a given precision. The `!` postfix operator
+ inside `\xintfloatexpr` maps to this new macro rather than to the
+ exact factorial as used by `\xintexpr` and `\xintiiexpr`.
+
+ - there is more flexibility in the parsing done by the macros from
+ **xintfrac** on fractional input: the decimal parts of both the
+ numerator and the denominator may arise from a separate expansion via
+ ``\romannumeral-`0``. Also the strict `A/B[N]` format is a bit
+ relaxed: `N` may be anything understood by `\numexpr` (it could even
+ be empty but that possibility has been removed by later `1.2f`
+ release.)
+
+ - on the other hand an isolated dot `.` is not legal syntax anymore
+ inside the expression parsers: there must be digits either before or
+ after. It remains legal input for the macros of **xintfrac**.
+
+ - added `\ht`, `\dp`, `\wd`, `\fontcharht`, etc... to the tokens
+ recognized by the parsers and expanded by `\number`.
+
+ - an obscure bug in package **xintkernel** has been fixed, regarding
+ the sanitization of catcodes: under certain circumstances (which
+ could not occur in a normal `LaTeX` context), unusual catcodes could
+ end up being propagated to the external world.
+
+ - an effort at randomly shuffling around various pieces of the
+ documentation has been done.
+
+
+`1.1c (2015/09/12)`
+----
+
+ - bugfix regarding macro `\xintAssign` from **xinttools** which did
+ not behave correctly in some circumstances (if there was a space
+ before `\to`, in particular).
+
+ - very minor code improvements, and correction of some issues
+ regarding the source code formatting in `sourcexint.pdf`, and
+ minor issues in `Makefile.mk`.
+
+
+`1.1b (2015/08/31)`
+----
+
+ - bugfix: some macros needed by the integer division routine from
+ **xintcore** had been left in **xint.sty** since release `1.1`. This
+ for example broke the `\xintGCD` from **xintgcd** if package **xint**
+ was not loaded.
+
+ - Slight enhancements to the documentation, particularly in the
+ `Read this first` section.
+
+
+`1.1a (2014/11/07)`
+----
+
+ - fixed a bug which prevented `\xintNewExpr` from producing correctly working
+ macros from a comma separated replacement text.
+
+ - `\xintiiSqrtR` for rounded integer square root; former `\xintiiSqrt`
+ already produced truncated integer square root; corresponding function
+ `sqrtr` added to `\xintiiexpr..\relax` syntax.
+
+ - use of straight quotes in the documentation for better legibility.
+
+ - added `\xintiiIsOne`, `\xintiiifOne`, `\xintiiifCmp`, `\xintiiifEq`,
+ `\xintiiifGt`, `\xintiiifLt`, `\xintiiifOdd`, `\xintiiCmp`, `\xintiiEq`,
+ `\xintiiGt`, `\xintiiLt`, `\xintiiLtorEq`, `\xintiiGtorEq`, `\xintiiNeq`,
+ mainly for efficiency of `\xintiiexpr`.
+
+ - for the same reason, added `\xintiiGCD` and `\xintiiLCM`.
+
+ - added the previously mentioned `ii` macros, and some others from `1.1`, to
+ the user manual. But their main usage is internal to `\xintiiexpr`, to skip
+ unnecessary overheads.
+
+ - various typographical fixes throughout the documentation, and a bit
+ of clean up of the code comments. Improved `\Factors` example of nested
+ `subs`, `rseq`, `iter` in `\xintiiexpr`.
+
+
+`1.1 (2014/10/28)`
+----
+
+### Incompatible changes
+
+ - in `\xintiiexpr`, `/` does _rounded_ division, rather than the
+ Euclidean division (for positive arguments, this is truncated division).
+ The `//` operator does truncated division,
+
+ - the `:` operator for three-way branching is gone, replaced with `??`,
+
+ - `1e(3+5)` is now illegal. The number parser identifies `e` and `E`
+ in the same way it does for the decimal mark, earlier versions treated
+ `e` as `E` rather as infix operators of highest precedence,
+
+ - the `add` and `mul` have a new syntax, old syntax is with `` `+` `` and
+ `` `*` `` (left quotes mandatory), `sum` and `prd` are gone,
+
+ - no more special treatment for encountered brace pairs `{..}` by the
+ number scanner, `a/b[N]` notation can be used without use of braces (the
+ `N` will end up as is in a `\numexpr`, it is not parsed by the
+ `\xintexpr`-ession scanner),
+
+ - in earlier releases, place holders for `\xintNewExpr` could either
+ be denoted `#1`, `#2`, ... or also `$1`, `$2`, ...
+ Only the usual `#` form is now accepted and the special cases previously
+ treated via the second form are now managed via a `protect(...)` function.
+
+ - **xintfrac**: `\xintFloor` and `\xintCeil` add a trailing `/1[0]` to their
+ (integer) output. New `\xintiFloor` and `\xintiCeil` do not.
+
+### Removed
+
+ - `\xintnumexpr`, `\xintthenumexpr`, `\xintNewNumExpr`: use
+ `\xintiexpr`, `\xinttheiexpr`, `\xintNewIExpr`.
+
+### Deprecated
+
+ - `\xintDivision`, `\xintQuo`, `\xintRem`: use `\xintiDivision`,
+ `\xintiQuo`, `\xintiRem`.
+
+ - `\xintMax`, `\xintMin`, `\xintAdd`, `\xintSub`, `\xintMul`
+ (**xint**): their usage without **xintfrac** is deprecated; use
+ `\xintiMax`, `\xintiMin`, `\xintiAdd`, `\xintiSub`, `\xintiMul`.
+
+ - the `&` and `|` as Boolean operators in `xintexpr`-essions are
+ deprecated in favour of `&&` and `||`. The single letter operators
+ might be assigned some other meaning in some later release (bitwise
+ operations, perhaps). Do not use them.
+
+### Improvements and new features
+
+ * new package **xintcore** has been split off **xint**. It contains the
+ core arithmetic macros (it is loaded by LaTeX package **bnumexpr**),
+
+ * neither **xint** nor **xintfrac** load **xinttools**. Only
+ **xintexpr** does,
+
+ * whenever some portion of code has been revised, often use has been made of
+ the `\xint_dothis` and `\xint_orthat` pair of macros for expandably
+ branching,
+
+ * these tiny helpful macros, and a few others are in package
+ **xintkernel** which contains also the catcode and loading order
+ management code, initially inspired by code found in Heiko Oberdiek's
+ packages,
+
+ * the source code, which was suppressed from `xint.pdf` in release
+ `1.09n`, is now compiled into a separate file `sourcexint.pdf`,
+
+ * faster handling by `\xintAdd`, `\xintSub`, `\xintMul`, ... of the case
+ where one of the arguments is zero,
+
+ * the `\xintAdd` and `\xintSub` macros from package **xintfrac** check if
+ one of the denominators is a multiple of the other, and only if this is
+ not the case do they multiply the denominators. But systematic reduction
+ would be too costly,
+
+ * this naturally will be also the case for the `+` and `-` operations
+ in `\xintexpr`,
+
+ * **xint** added `\xintiiDivRound`, `\xintiiDivTrunc`, `\xintiiMod`
+ for rounded and truncated division of big integers (next to
+ `\xintiiQuo` and `\xintiiRem`),
+
+ * with **xintfrac** loaded, the `\xintNum` macro does `\xintTTrunc`
+ (which is truncation to an integer, same as `\xintiTrunc {0}`),
+
+ * added `\xintMod` to **xintfrac** for modulo operation with
+ fractional numbers,
+
+ * added `\xintiFloor` and `\xintiCeil` to **xintfrac**,
+
+ * `\xintiexpr`, `\xinttheiexpr` admit an optional argument within brackets
+ `[d]`, they round the computation result (or results, if comma separated)
+ to `d` digits after decimal mark, (the whole computation is done exactly,
+ as in `xintexpr`),
+
+ * `\xintfloatexpr`, `\xintthefloatexpr` similarly admit an optional
+ argument which serves to keep only `d` digits of precision, getting rid
+ of cumulated uncertainties in the last digits (the whole computation is
+ done according to the precision set via `\xintDigits`),
+
+ * `\xinttheexpr` and `\xintthefloatexpr` _pretty-print_ if possible, the
+ former removing unit denominator or `[0]` brackets, the latter avoiding
+ scientific notation if decimal notation is practical,
+
+ * the `//` does truncated division and `/:` is the associated modulo,
+
+ * multi-character operators `&&`, `||`, `==`, `<=`, `>=`, `!=`,
+ `**`,
+
+ * multi-letter infix binary words `'and'`, `'or'`, `'xor'`, `'mod'`
+ (straight quotes mandatory),
+
+ * functions `even`, `odd`,
+
+ * `\xintdefvar A3:=3.1415;` for variable definitions (non expandable,
+ naturally), usable in subsequent expressions; variable names may contain
+ letters, digits, underscores. They should not start with a digit, the `@`
+ is reserved, and single lowercase and uppercase Latin letters are
+ predefined to work as dummy variables (see next),
+
+ * generation of comma separated lists `a..b`, `a..[d]..b`,
+
+ * Python syntax-like list extractors `[list][n:]`, `[list][:n]`,
+ `[list][a:b]` allowing negative indices, but no optional step argument,
+ and `[list][n]` (`n=0` for the number of items in the list),
+
+ * functions `first`, `last`, `reversed`,
+
+ * itemwise operations on comma separated lists `a*[list]`, etc.., possible
+ on both sides `a*[list]^b`, and obeying the same precedence rules as with
+ numbers,
+
+ * `add` and `mul` must use a dummy variable: `add(x(x+1)(x-1), x=-10..10)`,
+
+ * variable substitutions with `subs`:
+ `subs(subs(add(x^2+y^2,x=1..y),y=t),t=20)`,
+
+ * sequence generation using `seq` with a dummy variable: `seq(x^3,
+ x=-10..10)`,
+
+ * simple recursive lists with `rseq`, with `@` given the last value,
+ `rseq(1;2@+1,i=1..10)`,
+
+ * higher recursion with `rrseq`, `@1`, `@2`, `@3`, `@4`, and `@@(n)`
+ for earlier values, up to `n=K` where `K` is the number of terms of the
+ initial stretch `rrseq(0,1;@1+@2,i=2..100)`,
+
+ * iteration with `iter` which is like `rrseq` but outputs only the
+ last `K` terms, where `K` was the number of initial terms,
+
+ * inside `seq`, `rseq`, `rrseq`, `iter`, possibility to use `omit`,
+ `abort` and `break` to control termination,
+
+ * `n++` potentially infinite index generation for `seq`, `rseq`,
+ `rrseq`, and `iter`, it is advised to use `abort` or `break(..)` at
+ some point,
+
+ * the `add`, `mul`, `seq`, ... are nestable,
+
+ * `\xintthecoords` converts a comma separated list of an even number
+ of items to the format expected by the `TikZ` `coordinates` syntax,
+
+ * completely new version `\xintNewExpr`, `protect` function to handle
+ external macros. The dollar sign
+ `$` for place holders is not accepted anymore, only the standard macro
+ parameter `#`. Not all constructs are compatible with `\xintNewExpr`.
+% $ this docstripped line for emacs buffer fontification issues in doctex-mode
+
+### Bug fixes
+
+ - `\xintZapFirstSpaces` hence also `\xintZapSpaces` from package **xinttools**
+ were buggy when used with an argument either empty or containing only
+ space tokens.
+
+ - `\xintiiexpr` did not strip leading zeroes, hence
+ `\xinttheiiexpr 001+1\relax` did not obtain the expected result ...
+
+ - `\xinttheexpr \xintiexpr 1.23\relax\relax` should have produced `1`,
+ but it produced `1.23`
+
+ - the catcode of `;` was not set at package launching time.
+
+ - the `\XINTinFloatPrd:csv` macro name had a typo, hence `prd` was
+ non-functional in `\xintfloatexpr`.
+
+
+`1.09n (2014/04/01)`
+----
+
+ * the user manual does not include by default the source code
+ anymore: the `\NoSourceCode` toggle in file `xint.tex` has to
+ be set to 0 before compilation to get source code inclusion
+ (later release `1.1` made source code available as `sourcexint.pdf`).
+
+ * bug fix (**xinttools**) in `\XINT_nthelt_finish` (this bug was
+ introduced in `1.09i` of `2013/12/18` and showed up when the index
+ `N` was larger than the number of elements of the list).
+
+
+`1.09m (2014/02/26)`
+----
+
+ * new in **xinttools**: `\xintKeep` keeps the first `N` or last
+ `N` elements of a list (sequence of braced items); `\xintTrim`
+ cuts out either the first `N` or the last `N` elements from a
+ list.
+
+ * new in **xintcfrac**: `\xintFGtoC` finds the initial partial
+ quotients common to two numbers or fractions `f` and `g`;
+ `\xintGGCFrac` is a clone of `\xintGCFrac` which however does not
+ assume that the coefficients of the generalized continued
+ fraction are numeric quantities. Some other minor changes.
+
+
+`1.09kb (2014/02/13)`
+----
+
+ * bug fix (**xintexpr**): an aloof modification done by `1.09i` to
+ `\xintNewExpr` had resulted in a spurious trailing space present
+ in the outputs of all macros created by `\xintNewExpr`, making
+ nesting of such macros impossible.
+
+ * bug fix (**xinttools**): `\xintBreakFor` and `\xintBreakForAndDo`
+ were buggy when used in the last iteration of an `\xintFor` loop.
+
+ * bug fix (**xinttools**): `\xintSeq` from `1.09k` needed a `\chardef`
+ which was missing from `xinttools.sty`, it was in `xint.sty`.
+
+
+`1.09k (2014/01/21)`
+----
+
+ * inside `\xintexpr..\relax` (and its variants) tacit multiplication is
+ implied when a number or operand is followed directly with an
+ opening parenthesis,
+
+ * the `"` for denoting (arbitrarily big) hexadecimal numbers is
+ recognized by `\xintexpr` and its variants (package
+ **xintbinhex** is required); a fractional hexadecimal part
+ introduced by a dot `.` is allowed.
+
+ * re-organization of the first sections of the user manual.
+
+ * bug fix (**xinttools**, **xint**, ...): forgotten catcode check of
+ `"` at loading time has been added.
+
+
+`1.09j (2014/01/09)`
+----
+
+ * (**xint**) the core division routines have been re-written for some
+ (limited) efficiency gain, more pronounced for small divisors. As a
+ result the *computation of one thousand digits of $\pi$* is close
+ to three times faster than with earlier releases.
+
+ * some various other small improvements, particularly in the power
+ routines.
+
+ * (**xintfrac**) a macro `\xintXTrunc` is designed to produce
+ thousands or even tens of thousands of digits of the decimal
+ expansion of a fraction. Although completely expandable it has its
+ use limited to inside an `\edef`, `\write`, `\message`, \dots. It
+ can thus not be nested as argument to another package macro.
+
+ * (**xintexpr**) the tacit multiplication done in `\xintexpr..\relax`
+ on encountering a count register or variable, or a `\numexpr`,
+ while scanning a (decimal) number, is extended to the case of a sub
+ `\xintexpr`-ession.
+
+ * `\xintexpr` can now be used in an `\edef` with no `\xintthe` prefix;
+ it will execute completely the computation, and the error message
+ about a missing `\xintthe` will be inhibited. Previously, in the
+ absence of `\xintthe`, expansion could only be a full one (with
+ ``\romannumeral-`0``), not a complete one (with `\edef`). Note
+ that this differs from the behavior of the non-expandable
+ `\numexpr`: `\the` or `\number` (or `\romannumeral`) are needed
+ not only to print but
+ also to trigger the computation, whereas `\xintthe` is mandatory
+ only for the printing step.
+
+ * the default behavior of `\xintAssign` is changed, it now does not
+ do any further expansion beyond the initial full-expansion which
+ provided the list of items to be assigned to macros.
+
+ * bug fix (**xintfrac**): `1.09i` did an unexplainable change to
+ `\XINT_infloat_zero` which broke the floating point routines for
+ vanishing operands =:(((
+
+ * bug fix: the `1.09i` `xint.ins` file produced a buggy `xint.tex` file.
+
+
+`1.09i (2013/12/18)`
+----
+
+ * (**xintexpr**) `\xintiiexpr` is a variant of `\xintexpr` which is
+ optimized to deal only with (long) integers, `/` does a euclidean
+ quotient.
+
+ * *deprecated*: `\xintnumexpr`, `\xintthenumexpr`, `\xintNewNumExpr` are
+ renamed, respectively, `\xintiexpr`, `\xinttheiexpr`, `\xintNewIExpr`. The
+ earlier denominations are kept but are to be removed at some point.
+
+ * it is now possible within `\xintexpr...\relax` and its variants to
+ use count, dimen, and skip registers or variables without
+ explicit `\the/\number`: the parser inserts automatically
+ `\number` and a tacit multiplication is implied when a register
+ or variable immediately follows a number or fraction. Regarding
+ dimensions and `\number`, see the further discussion in
+ *Dimensions*.
+
+ * (**xintfrac**) conditional `\xintifOne`; `\xintifTrueFalse`
+ renamed to `\xintifTrueAelseB`; macros `\xintTFrac`
+ (`fractional part`, mapped to function `frac` in
+ `\xintexpr`-essions), `\xintFloatE`.
+
+ * (**xinttools**) `\xintAssign` admits an optional argument to
+ specify the expansion type to be used: `[]` (none, default), `[o]`
+ (once), `[oo]` (twice), `[f]` (full), `[e]` (`\edef`),... to define
+ the macros
+
+ * **xinttools** defines `\odef`, `\oodef`, `\fdef` (if the names have
+ already been assigned, it uses `\xintoodef` etc...). These tools are
+ provided for the case one uses the package macros in a non-expandable
+ context. `\oodef` expands twice the macro replacement text, and `\fdef`
+ applies full expansion. They are useful in situations where one does not
+ want a full `\edef`. `\fdef` appears to be faster than `\oodef` in almost
+ all cases (with less than thousand digits in the result), and even faster
+ than `\edef` for expanding the package macros when the result has a few
+ dozens of digits. `\oodef` needs that expansion ends up in thousands of
+ digits to become competitive with the other two.
+
+ * some across the board slight efficiency improvement as a result of
+ modifications of various types to *fork macros* and *branching
+ conditionals* which are used internally.
+
+ * bug fix (**xint**): `\xintAND` and `\xintOR` inserted a space token
+ in some cases and did not expand as promised in two steps `:-((`
+ (bug dating back to `1.09a` I think; this bug was without
+ consequences when using `&` and `|` in `\xintexpr-essions`, it
+ affected only the macro form).
+
+ * bug fix (**xintcfrac**): `\xintFtoCCv` still ended fractions with
+ the `[0]`'s which were supposed to have been removed since release
+ `1.09b`.
+
+ * *deprecated*: `\xintifTrueFalse`, `\xintifTrue`; use `\xintifTrueAelseB`.
+
+
+`1.09h (2013/11/28)`
+----
+
+ * parts of the documentation have been re-written or re-organized,
+ particularly the discussion of expansion issues and of input and
+ output formats.
+
+ * the expansion types of macro arguments are documented in the margin
+ of the macro descriptions, with conventions mainly taken over
+ from those in the `LaTeX3` documentation.
+
+ * a dependency of **xinttools** on **xint** (inside `\xintSeq`) has
+ been removed.
+
+ * (**xintgcd**) `\xintTypesetEuclideAlgorithm` and
+ `\xintTypesetBezoutAlgorithm` have been slightly modified
+ (regarding indentation).
+
+ * (**xint**) macros `xintiSum` and `xintiPrd` are renamed to
+ `\xintiiSum` and `\xintiiPrd`.
+
+ * (**xinttools**) a count register used in `1.09g` in the `\xintFor`
+ loops for parsing purposes has been removed and replaced by use of
+ a `\numexpr`.
+
+ * the few uses of `\loop` have been replaced by `\xintloop/\xintiloop`.
+
+ * all macros of **xinttools** for which it makes sense are now declared
+ `\long`.
+
+
+`1.09g (2013/11/22)`
+----
+
+ * a package **xinttools** is detached from **xint**, to make tools such
+ as `\xintFor`, `\xintApplyUnbraced`, and `\xintiloop` available
+ without the **xint** overhead.
+
+ * expandable nestable loops `\xintloop` and `\xintiloop`.
+
+ * bugfix: `\xintFor` and `\xintFor*` do not modify anymore the value of
+ `\count 255`.
+
+
+`1.09f (2013/11/04)`
+----
+
+ * (**xint**) `\xintZapFirstSpaces`, `\xintZapLastSpaces`,
+ `\xintZapSpaces`, `\xintZapSpacesB`, for expandably stripping away
+ leading and/or ending spaces.
+
+ * `\xintCSVtoList` by default uses `\xintZapSpacesB` to strip away
+ spaces around commas (or at the start and end of the comma
+ separated list).
+
+ * also the `\xintFor` loop will strip out all spaces around commas and
+ at the start and the end of its list argument; and similarly for
+ `\xintForpair`, `\xintForthree`, `\xintForfour`.
+
+ * `\xintFor` *et al.* accept all macro parameters from `#1` to
+ `#9`.
+
+ * for reasons of inner coherence some macros previously with one extra
+ `i` in their names (e.g. `\xintiMON`) now have a doubled
+ `ii` (`\xintiiMON`) to indicate that they skip the overhead of
+ parsing their inputs via `\xintNum`. Macros with a *single*
+ `i` such as `\xintiAdd` are those which maintain the
+ non-**xintfrac** output format for big integers, but do parse
+ their inputs via `\xintNum` (since release `1.09a`). They too may
+ have doubled-`i` variants for matters of programming optimization
+ when working only with (big) integers and not fractions or
+ decimal numbers.
+
+
+`1.09e (2013/10/29)`
+----
+
+ * (**xint**) `\xintintegers`, `\xintdimensions`, `\xintrationals`
+ for infinite `\xintFor` loops, interrupted with `\xintBreakFor` and
+ `\xintBreakForAndDo`.
+
+ * `\xintifForFirst`, `\xintifForLast` for the `\xintFor` and
+ `\xintFor*` loops,
+
+ * the `\xintFor` and `xintFor*` loops are now `\long`, the
+ replacement text and the items may contain explicit `\par`'s.
+
+ * conditionals `\xintifCmp`, `\xintifInt`, `\xintifOdd`.
+
+ * bug fix (**xint**): the `\xintFor` loop (not `\xintFor*`) did
+ not correctly detect an empty list.
+
+ * bug fix (**xint**): `\xintiSqrt {0}` crashed. `:-((`
+
+ * the documentation has been enriched with various additional examples,
+ such as the *the quick sort algorithm
+ illustrated* or the various ways of *computing prime numbers*.
+
+ * the documentation explains with more details various expansion
+ related issues, particularly in relation to conditionals.
+
+
+`1.09d (2013/10/22)`
+----
+
+ * bug fix (**xint**): `\xintFor*` is modified to gracefully
+ handle a space token (or more than one) located at the very end of
+ its list argument (as the space before `\do` in `\xintFor* #1 in
+ {{a}{b}{c}<space>} \do {stuff}`; spaces at other locations were
+ already harmless). Furthermore this new version _f-expands_ the
+ un-braced list items. After `\def\x{{1}{2}}` and `\def\y{{a}\x
+ {b}{c}\x }`, `\y` will appear to `\xintFor*` exactly as if it had
+ been defined as `\def\y{{a}{1}{2}{b}{c}{1}{2}}`.
+
+ * same bug fix for `\xintApplyInline`.
+
+
+`1.09c (2013/10/09)`
+----
+
+ * (**xintexpr**) added `bool` and `togl` to the `\xintexpr` syntax;
+ also added `\xintboolexpr` and `\xintifboolexpr`.
+
+ * added `\xintNewNumExpr`.
+
+ * the factorial `!` and branching `?`, `:`, operators (in
+ `\xintexpr...\relax`) have now less precedence than a function
+ name located just before,
+
+ * (**xint**) `\xintFor` is a new type of loop, whose replacement text
+ inserts the comma separated values or list items via macro
+ parameters, rather than encapsulated in macros; the loops are
+ nestable up to four levels (nine levels since `1.09f`) and their
+ replacement texts are allowed to close groups as happens with the
+ tabulation in alignments,
+
+ * `\xintForpair`, `\xintForthree`, `\xintForfour` are experimental
+ variants of `\xintFor`,
+
+ * `\xintApplyInline` has been enhanced in order to be usable for
+ generating rows (partially or completely) in an alignment,
+
+ * command `\xintSeq` to generate (expandably) arithmetic sequences
+ of (short) integers,
+
+ * again various improvements and changes in the documentation.
+
+
+`1.09b (2013/10/03)`
+----
+
+ * various improvements in the documentation,
+
+ * more economical catcode management and re-loading handling,
+
+ * removal of all those `[0]`'s previously forcefully added at the end
+ of fractions by various macros of **xintcfrac**,
+
+ * `\xintNthElt` with a negative index returns from the tail of the
+ list,
+
+ * macro `\xintPRaw` to have something like what `\xintFrac` does in
+ math mode; i.e. a `\xintRaw` which does not print the denominator
+ if it is one.
+
+
+`1.09a (2013/09/24)`
+----
+
+ * (**xintexpr**) `\xintexpr..\relax` and `\xintfloatexpr..\relax`
+ admit functions in their syntax, with comma separated values as
+ arguments, among them `reduce, sqr, sqrt, abs, sgn, floor, ceil,
+ quo, rem, round, trunc, float, gcd, lcm, max, min, sum, prd, add,
+ mul, not, all, any, xor`.
+
+ * comparison (`<`, `>`, `=`) and logical (`|`, `&`) operators.
+
+ * the command `\xintthe` which converts `\xintexpr`essions into
+ printable format (like `\the` with `\numexpr`) is more efficient,
+ for example one can do `\xintthe\x` if `\x` was defined to be an
+ `\xintexpr..\relax`:
+
+ \def\x{\xintexpr 3^57\relax}
+ \def\y{\xintexpr \x^(-2)\relax}
+ \def\z{\xintexpr \y-3^-114\relax}
+ \xintthe\z
+
+ * `\xintnumexpr .. \relax` (now renamed `\xintiexpr`) is `\xintexpr
+ round( .. ) \relax`.
+
+ * `\xintNewExpr` now works with the standard macro parameter character
+ `#`.
+
+ * both regular `\xintexpr`-essions and commands defined by
+ `\xintNewExpr` will work with comma separated lists of
+ expressions,
+
+ * commands `\xintFloor`, `\xintCeil`, `\xintMaxof`, `\xintMinof`
+ (package **xintfrac**), `\xintGCDof`, `\xintLCM`, `\xintLCMof`
+ (package **xintgcd**), `\xintifLt`, `\xintifGt`, `\xintifSgn`,
+ `\xintANDof`, ...
+
+ * The arithmetic macros from package **xint** now filter their operands
+ via `\xintNum` which means that they may use directly count
+ registers and `\numexpr`-essions without having to prefix them by
+ `\the`. This is thus similar to the situation holding previously
+ already when **xintfrac** was loaded.
+
+ * a bug (**xintfrac**) introduced in `1.08b` made `\xintCmp` crash
+ when one of its arguments was zero. `:-((`
+
+
+`1.08b (2013/06/14)`
+----
+
+ * (**xintexpr**) Correction of a problem with spaces inside
+ `\xintexpr`-essions.
+
+ * (**xintfrac**) Additional improvements to the handling of floating
+ point numbers.
+
+ * section *Use of count registers* documenting how count
+ registers may be directly used in arguments to the macros of
+ **xintfrac**.
+
+
+`1.08a (2013/06/11)`
+----
+
+ * (**xintfrac**) Improved efficiency of the basic conversion from
+ exact fractions to floating point numbers, with ensuing speed gains
+ especially for the power function macros `\xintFloatPow` and
+ `\xintFloatPower`,
+
+ * Better management by `\xintCmp`, `\xintMax`, `\xintMin` and
+ `\xintGeq` of inputs having big powers of ten in them.
+
+ * Macros for floating point numbers added to the **xintseries**
+ package.
+
+
+`1.08 (2013/06/07)`
+----
+
+ * (**xint** and **xintfrac**) Macros for extraction of square roots,
+ for floating point numbers (`\xintFloatSqrt`), and integers
+ (`\xintiSqrt`).
+
+ * new package **xintbinhex** providing *conversion routines* to and from
+ binary and hexadecimal bases.
+
+
+`1.07 (2013/05/25)`
+----
+
+ * The **xintexpr** package is a new core constituent (which loads
+ automatically **xintfrac** and **xint**) and implements the
+ expandable expanding parser
+
+ \xintexpr . . . \relax,
+
+ and its variant
+
+ \xintfloatexpr . . . \relax
+
+ allowing on input formulas using the infix operators `+`, `-`, `*`,
+ `/`, and `^`, and arbitrary levels of parenthesizing. Within a
+ float expression the operations are executed according to the
+ current value set by `\xintDigits`. Within an `\xintexpr`-ession the
+ binary operators are computed exactly.
+
+ To write the `\xintexpr` parser I benefited from the commented
+ source of the `l3fp` parser; the `\xintexpr` parser has its own
+ features and peculiarities. *See its documentation*.
+
+ * The floating point precision `D` is set (this is a local assignment
+ to a `\mathchar` variable) with `\xintDigits := D;` and queried
+ with `\xinttheDigits`. It may be set to anything up to
+ `32767`.[^1] The macro incarnations of the binary operations
+ admit an optional argument which will replace pointwise `D`; this
+ argument may exceed the `32767` bound.
+
+ * The **xintfrac** macros now accept numbers written in scientific
+ notation, the `\xintFloat` command serves to output its argument
+ with a given number `D` of significant figures. The value of `D`
+ is either given as optional argument to `\xintFloat` or set with
+ `\xintDigits := D;`. The default value is `16`.
+
+[^1]: but values higher than 100 or 200 will presumably give too slow
+evaluations.
+
+
+`1.06b (2013/05/14)`
+----
+
+ * Minor code and documentation improvements. Everywhere in the source
+ code, a more modern underscore has replaced the @ sign.
+
+
+`1.06 (2013/05/07)`
+----
+
+ * Some code improvements, particularly for macros of **xint** doing loops.
+
+ * New utilities in **xint** for expandable manipulations of lists:
+
+ \xintNthElt, \xintCSVtoList, \xintRevWithBraces
+
+ * The macros did only a double expansion of their arguments. They now
+ fully expand them (using ``\romannumeral-`0``). Furthermore, in the
+ case of arguments constrained to obey the TeX bounds they will be
+ inserted inside a `\numexpr..\relax`, hence completely expanded, one
+ may use count registers, even infix arithmetic operations, etc...
+
+
+`1.05 (2013/05/01)`
+----
+
+Minor changes and additions to **xintfrac** and **xintcfrac**.
+
+
+`1.04 (2013/04/25)`
+----
+
+ * New component **xintcfrac** devoted to continued fractions.
+
+ * **xint**: faster division.
+
+ * **xint**: added expandable macros `\xintListWithSep` and `\xintApply` to
+ handle token lists.
+
+ * **xintfrac**: added `\xintRound`.
+
+ * **xintseries** has a new implementation of `\xintPowerSeries` based
+ on a Horner scheme, and new macro `\xintRationalSeries`. Both to
+ help deal with the *denominator buildup* plague.
+
+ * `tex xint.dtx` extracts style files (no need for a `xint.ins`).
+
+ * Bug fix (**xintfrac**): `\xintIrr {0}` crashed.
+
+
+`1.03 (2013/04/14)`
+----
+
+ * New modules **xintfrac** (expandable operations on fractions) and
+ **xintseries** (expandable partial sums with xint package).
+
+ * Slightly improved division and faster multiplication (the best
+ ordering of the arguments is chosen automatically).
+
+ * Added illustration of Machin algorithm to the documentation.
+
+
+`1.0 (2013/03/28)`
+----
+
+Initial announcement:
+
+> The **xint** package implements with expandable TeX macros the basic
+ arithmetic operations of addition, subtraction, multiplication
+ and division, as applied to arbitrarily long numbers represented
+ as chains of digits with an optional minus sign.
+
+> The **xintgcd** package provides implementations of the Euclidean
+ algorithm and of its typesetting.
+
+> The packages may be used with Plain and with LaTeX.
+
+%</changes>------------------------------------------------------
+%<*makefile>------------------------------------------------------
+# This file: Makefile.mk (generated from xint.dtx)
+# Rename the file as Makefile, or keep is named as Makefile.mk
+# and download master Makefile from
+# http://mirror.ctan.org/macros/generic/xint
+# then run "make help"
+
+# Starting with xint 1.3c, uses Latexmk for easier compilation of
+# sourcexint.pdf as it includes indices. These indices for
+# source code were actually removed at 1.3e but usage of Latexmk
+# is maintained for the build (despite it being simpler now).
+
+# Originally tested on Mac OS X Mavericks with GNU Make 3.81,
+# TeXLive 2014 and Pandoc 1.13.1.
+
+# Note to myself: I wanted to use .RECIPEPREFIX = > but it is
+# supported only with GNU Make 3.82 and later.
+
+# this crazyness is to circumvent a problem with docstrip generation
+# of the Makefile; we do not want two empty lines becoming only one
+nullstring :=
+define newline
+$(nullstring)
+
+endef
+# will speed-up a little, I think.
+newline := $(newline)
+
+define helptext
+==== INSTRUCTIONS
+
+The Makefile is to automatize the extraction and compilation from
+xint.dtx of package files and documentation files, and for producing
+xint.tds.zip. It is for GNU/Linux like systems, with a teTeX like
+installation such as TeXLive. Tested on Mac OS X Mavericks with TL2014.
+
+For compiling the PDF files, packages newtx, newtxtt, etoc,... are used
+and should be up-to-date (as of 2014/10). Conversion to plain, html and
+pdf format of README.md and CHANGES.md (make PanPDF, make PanHTML)
+require Pandoc software. (tested with Pandoc 1.13.1).
+
+It is recommended to work with xint.dtx and Makefile in an otherwise
+initially empty temporary repertory.
+
+make help
+ prints this help (using more). It will also have already extracted
+ all files from xint.dtx.
+
+make helpless
+ prints this help (using less).
+
+make xint.pdf
+ extracts files and produces xint.pdf, using latex and dvipdfmx.
+ Uses Latexmk. No Pandoc needed. To get xint.pdf to include
+ the source code and indices, refer to instructions in xint.tex.
+
+make sourcexint.pdf
+ extracts files and produces sourcexint.pdf, using latex, makeindex
+ and dvipdfmx. Uses Latexmk. No Pandoc needed.
+
+make PanPDF
+ produces README.pdf and CHANGES.pdf, requires Pandoc.
+
+make PanHTML
+ produces README.html and CHANGES.html, requires Pandoc.
+
+make doc
+ produces all documentation.
+
+make all
+ produces all documentation, and creates xint.tds.zip.
+
+make xint.tds.zip
+ same as "make all"
+
+make clean
+ removes auxiliary files and repertories.
+
+make cleanall
+ removes all files, leaving only xint.dtx (and Makefile). If no
+ Makefile, use "etex xint.dtx" to regenerate Makefile.mk, rename
+ it as Makefile and run "make help".
+
+==== INSTALLING
+
+The following has been tested on a TeXLive installation:
+
+make installhome
+ creates xint.tds.zip, and unzips it in <TEXMFHOME>
+ (it assumes there is no ls-R file there)
+
+make installlocal
+ creates xint.tds.zip, and unzips it in <TEXMFLOCAL>
+ (and then does texhash <TEXMFLOCAL>)
+ IT MIGHT BE NEEDED TO RUN IT AS "sudo make installlocal"
+ This depends on how the access rights are configured.
+ In case of doubt run first "make doc" and then "make
+ installlocal". If the latter fails, "sudo make installlocal".
+
+make uninstallhome
+ removes all xint files and repertories from <TEXMFHOME>
+
+make uninstalllocal
+ removes all xint files and repertories from <TEXMFLOCAL>
+ (and then does texhash <TEXMFLOCAL>)
+ IT MIGHT BE NEEDED TO RUN IT AS "sudo make uninstalllocal"
+
+endef
+
+.PHONY: help helpless all extract doc PanPDF PanHTML clean cleanall\
+ installhome uninstallhome installlocal uninstalllocal
+
+# for printf with subst and \n, got it from
+# http://stackoverflow.com/a/5887751
+
+# I could do the trick with := here, for \n substitution, but this would add
+# tiny overhead to all other operations of make
+
+help:
+ @printf '$(subst $(newline),\n,$(helptext))' | more
+
+helpless:
+ @printf '$(subst $(newline),\n,$(helptext))' | less
+
+# RM = rm -f
+JF_tmpdir := $(shell mktemp -d TEMP_XINT_XXX)
+TEXMF_local = $(shell kpsewhich -var-value TEXMFLOCAL)
+TEXMF_home = $(shell kpsewhich -var-value TEXMFHOME)
+packages = xintkernel.sty xintcore.sty xint.sty xintfrac.sty xintexpr.sty\
+ xintgcd.sty xintbinhex.sty xintseries.sty xintcfrac.sty\
+ xinttools.sty xinttrig.sty xintlog.sty
+# Makefile.mk is not included in $(extracted). Its extraction rule is in
+# master Makefile file. We can not extract Makefile from xint.dtx via
+# docstrip, as .tex is always appended if a filename with no extension is
+# specified. If "make -f Makefile.mk" is run, Makefile.mk will not be
+# overwritten because tex xint.dtx does not extract it (etex xint.dtx does).
+extracted = $(packages) xint.tex xint.ins README.md CHANGES.md\
+ doHTMLs.sh doPDFs.sh pandoctpl.latex
+doc_pdf = README.pdf CHANGES.pdf
+doc_html = README.html CHANGES.html
+filesfortex = $(packages)
+filesforsource = xint.dtx Makefile
+filesfordoc = xint.pdf sourcexint.pdf README $(doc_pdf) $(doc_html)
+auxiliaryfiles = xint.dvi xint.aux xint.toc xint.log\
+ sourcexint.dvi sourcexint.aux sourcexint.toc sourcexint.log\
+ README.dvi README.aux README.toc README.out README.log\
+ CHANGES.dvi CHANGES.aux CHANGES.toc CHANGES.out CHANGES.log
+xint_cmd = latexmk xint
+sourcexint_cmd = latexmk -jobname=sourcexint\
+ -latex='latex %O "\chardef\dosourcexint=1 \input{%S}"' xint.tex
+
+all: $(extracted) doc xint.tds.zip
+ @echo 'make all done.'
+
+extract: $(extracted)
+
+$(extracted): xint.dtx
+ tex xint.dtx
+
+doc: xint.pdf sourcexint.pdf README PanPDF PanHTML
+ @echo 'make doc done.'
+
+xint.pdf: xint.dtx xint.tex
+ $(xint_cmd)
+ dvipdfmx xint.dvi
+
+sourcexint.pdf: xint.dtx xint.tex
+ $(sourcexint_cmd)
+ dvipdfmx sourcexint.dvi
+
+README: README.md
+ pandoc -t plain -o README README.md
+
+PanPDF: $(doc_pdf)
+
+$(doc_pdf): doPDFs.sh
+ chmod u+x doPDFs.sh && ./doPDFs.sh
+
+PanHTML: $(doc_html)
+
+$(doc_html): doHTMLs.sh
+ chmod u+x doHTMLs.sh && ./doHTMLs.sh
+
+xint.tds.zip: $(filesfordoc) $(filesforsource) $(filesfortex)
+ rm -fr $(JF_tmpdir)
+ mkdir -p $(JF_tmpdir)/doc/generic/xint
+ mkdir -p $(JF_tmpdir)/source/generic/xint
+ mkdir -p $(JF_tmpdir)/tex/generic/xint
+ chmod -R ugo+rwx $(JF_tmpdir)
+ cp -a $(filesfordoc) $(JF_tmpdir)/doc/generic/xint
+ cp -a $(filesforsource) $(JF_tmpdir)/source/generic/xint
+ cp -a $(filesfortex) $(JF_tmpdir)/tex/generic/xint
+ cd $(JF_tmpdir); chmod -R ugo+r doc source tex
+ umask 0022 && cd $(JF_tmpdir) &&\
+ zip -r xint.tds.zip doc source tex &&\
+ mv -f xint.tds.zip ../
+ rm -fr $(JF_tmpdir)
+ @echo 'make xint.tds.zip done.'
+
+xint.zip: $(filesfordoc) $(filesforsource) $(filesfortex) xint.tds.zip
+ mkdir -p $(JF_tmpdir)/xint
+ chmod ugo+rwx $(JF_tmpdir)/xint
+ cp -a $(filesfordoc) $(JF_tmpdir)/xint
+ cp -a $(filesforsource) $(JF_tmpdir)/xint
+ chmod -R ugo+r $(JF_tmpdir)/xint
+ mv xint.tds.zip $(JF_tmpdir)/
+ umask 0022 && cd $(JF_tmpdir) && zip -r xint.zip xint.tds.zip xint
+ mv $(JF_tmpdir)/xint.tds.zip ./
+ mv -f $(JF_tmpdir)/xint.zip ./
+ rm -fr $(JF_tmpdir)
+ @echo 'make xint.zip done.'
+
+installhome: xint.tds.zip
+ unzip xint.tds.zip -d $(TEXMF_home)
+
+uninstallhome:
+ cd $(TEXMF_home) && rm -fr doc/generic/xint \
+ source/generic/xint \
+ tex/generic/xint
+
+# cf http://stackoverflow.com/a/1909390
+# as kpsewhich is very slow (.5s) I want to evaluate once only.
+installlocal: xint.tds.zip
+ $(eval $@_tmp := $(TEXMF_local))
+ unzip xint.tds.zip -d $($@_tmp) && texhash $($@_tmp)
+
+uninstalllocal:
+ cd $(TEXMF_local) && rm -fr doc/generic/xint \
+ source/generic/xint \
+ tex/generic/xint && texhash .
+clean:
+ rm -fr auto/ TEMP*/
+ rm -f $(auxiliaryfiles)\
+ sourcexint.fls sourcexint.fdb_latexmk\
+ xint.fls xint.fdb_latexmk
+
+cleanall: clean
+ rm -f $(extracted) $(doc_pdf) $(doc_html)\
+ README README.tex CHANGES.tex\
+ xint.pdf sourcexint.pdf xint.tds.zip xint.zip Makefile.mk
+%</makefile>$-----------------------------------------------------
+%<*pandoctpl>-----------------------------------------------------
+\newcommand{\tightlist}{%
+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
+$if(dvipdfmx)$
+{\csname @for\endcsname\x:=hyperref,graphicx,color,xcolor\do
+ {\PassOptionsToPackage{dvipdfmx}\x}}
+ \PassOptionsToPackage{dvipdfmx-outline-open}{hyperref}
+ \PassOptionsToPackage{dvipdfm}{geometry}
+$endif$
+\documentclass[$papersize$,fontsize=$fontsize$]{scrartcl}
+\usepackage[T1]{fontenc}
+\usepackage[utf8]{inputenc}
+\usepackage[english]{babel}
+
+\usepackage{newtxtext}
+\usepackage{newtxtt}
+\usepackage{newtxmath}
+
+\usepackage{upquote}
+
+% pour les \texttt venant de la conversion par pandoc des `...`:
+\begingroup\makeatletter
+ \catcode`\'\active
+ \catcode`\*\active
+ \catcode`\`\active
+\@firstofone {\endgroup
+ \def\dostraightquotesandstar{% textcomp package is loaded by newtxtext
+ \let`\textasciigrave
+ \let'\textquotesingle
+ \edef*{\noexpand\raisebox{-.25\noexpand\height}{\string*}}%
+ \catcode39\active % '
+ \catcode96\active % `
+ \catcode42\active }% *
+}% for \texttt, let's just forget about math and italic correction things
+\DeclareRobustCommand\texttt {\bgroup
+ \dostraightquotesandstar\afterassignment\ttfamily\let\next=}
+
+$if(geometry)$
+\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}
+$endif$
+$if(tables)$
+\usepackage{longtable,booktabs}
+$endif$
+\usepackage[unicode=true,bookmarks]{hyperref}
+\hypersetup{breaklinks=true,%
+ pdfauthor={Jean-Fran\c cois Burnol},%
+ pdftitle={$title$ $author$ $date$},%
+ colorlinks=true,%
+ citecolor=$if(citecolor)$$citecolor$$else$blue$endif$,%
+ urlcolor=$if(urlcolor)$$urlcolor$$else$blue$endif$,%
+ linkcolor=$if(linkcolor)$$linkcolor$$else$magenta$endif$,%
+ pdfborder={0 0 0},%
+ pdfstartview=FitH,%
+ pdfpagemode=UseOutlines}
+%%\urlstyle{same} % don't use monospace font for urls
+
+\setlength{\parindent}{0pt}
+\setlength{\emergencystretch}{3em} % prevent overfull lines
+\usepackage{enumitem}
+%% reduce LaTeX's insane vertical spacing around verbatim blocks
+\setlength{\parskip}{\medskipamount}
+\setlist[trivlist]{topsep=0pt,partopsep=0pt,itemsep=0pt,parsep=0pt}
+
+$if(numbersections)$
+\setcounter{secnumdepth}{5}
+$else$
+\setcounter{secnumdepth}{0}
+$endif$
+
+$if(etoc)$\usepackage{etoc}$endif$
+
+\title{$title$}
+\author{$author$}
+\date{$date$}
+
+$for(header-includes)$
+$header-includes$
+$endfor$
+
+\begin{document}
+$if(title)$
+\maketitle
+$endif$
+
+$for(include-before)$
+$include-before$
+
+$endfor$
+
+$if(toc)$
+\setcounter{tocdepth}{$toc-depth$}
+$if(etoc)$
+\etocdefaultlines
+\etocmulticolstyle[$etoc$]{}
+$endif$
+\tableofcontents
+$endif$
+
+$body$
+
+$for(include-after)$
+$include-after$
+
+$endfor$
+\end{document}
+%</pandoctpl>-----------------------------------------------------
+%<*dohtmlsh>------------------------------------------------------
+#! /bin/sh
+# produces README.html and CHANGES.html from README.md and CHANGES.md
+# tested with pandoc 1.13.1
+
+pandoc -o README.html -s --toc -V highlighting-css=' body{margin-left : 10%; margin-right : 15%; margin-top: 4ex; font-size: 12pt;}
+ pre {white-space: pre-wrap; }
+ code {white-space: pre-wrap; }
+ .mono {font-family: monospace;}' README.md
+
+pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin-left : 10%; margin-right : 15%; margin-top: 4ex; font-size: 12pt;}
+ pre {white-space: pre-wrap;}
+ code {white-space: pre-wrap;}
+ #TOC {float: right; position: relative; top: 100px; margin-bottom: 100px;}' CHANGES.md
+
+%</dohtmlsh>------------------------------------------------------
+%<*dopdfsh>-------------------------------------------------------
+#! /bin/sh
+# produces README.pdf and CHANGES.pdf from README.md and CHANGES.md
+# via latex+dvipdfmx and custom pandoc latex template
+
+pandoc -o README.tex --template=pandoctpl --toc -V papersize=a4paper -V fontsize=11pt -V dvipdfmx --variable=geometry:footskip=1cm,left=2.5cm,right=2.5cm,top=2cm,bottom=3cm -V etoc=1 README.md
+rm -f README.aux README.toc README.out
+latex -interaction=nonstopmode README
+latex -interaction=nonstopmode README
+latex -interaction=nonstopmode README
+dvipdfmx README.dvi
+
+pandoc -o CHANGES.tex --template=pandoctpl --toc -V 'toc-depth'=2 -V papersize=a4paper -V fontsize=11pt -V dvipdfmx --variable=geometry:footskip=1cm,left=2.5cm,right=2.5cm,top=2cm,bottom=3cm -V etoc=2 CHANGES.md
+rm -f CHANGES.aux CHANGES.toc CHANGES.out
+latex -interaction=nonstopmode CHANGES
+latex -interaction=nonstopmode CHANGES
+latex -interaction=nonstopmode CHANGES
+dvipdfmx CHANGES.dvi
+%</dopdfsh>-------------------------------------------------------
+%<*drv>-----------------------------------------------------------
+%%
+%% To produce manually xint.pdf from xint.tex:
+%% - latex (thrice) then dvipdfmx,
+%% - or xelatex/pdflatex thrice.
+%%
+%% To produce manually sourcexint.pdf from xint.tex:
+%% latexmk -jobname=sourcexint\
+%% -latex="latex %O \\\\chardef\\\\dosourcexint=1 \\\\input{%S}"\
+%% xint.tex
+%% (quoting may differ, depending on the shell)
+%% dvipdfmx sourcexint.dvi
+%%
+%% It is naturally possible to replace latexmk by suitable latex
+%% and makeindex calls, but details are left out here.
+%%
+%% To get xint.pdf to include the source code and indices:
+%% - etex xint.dtx (this will regenerate this file),
+%% - replace 1 by 0 in \chardef line below,
+%% - make clean
+%% - make xint.pdf
+%% This will use latexmk. Without it execute latex thrice then dvipdfmx.
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesFile{xint.tex}%
+[\xintbndldate\space v\xintbndlversion\space driver file for xint documentation (JFB)]%
+\PassOptionsToClass{a4paper,fontsize=10pt}{scrdoc}
+\chardef\NoSourceCode 1 % set it to 0 if source code inclusion desired
+\input xint.dtx
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-PDF-from-DVI: "Dvipdfmx"
+%%% End:
+%</drv>-----------------------------------------------------------
+%<*ins>-----------------------------------------------------------
+%%
+%% `tex xint.ins' extracts all package files from xint.dtx, as well as
+%% xint.tex, README.md, CHANGES.md, doPDFs.sh, doHTMLs.sh, .latexmkrc
+%% and xint-gind.ist
+%%
+%% `etex xint.ins' additionally extracts Makefile.mk, which is needed
+%% for building documentation using `make'.
+%%
+\input docstrip.tex
+\askforoverwritefalse
+\generate{\nopreamble\nopostamble
+\file{README.md}{\from{xint.dtx}{readme}}
+\file{CHANGES.md}{\from{xint.dtx}{changes}}
+\file{doHTMLs.sh}{\from{xint.dtx}{dohtmlsh}}
+\file{doPDFs.sh}{\from{xint.dtx}{dopdfsh}}
+\ifx\numexpr\undefined\else\catcode9 11
+ \file{Makefile.mk}{\from{xint.dtx}{makefile}}\fi
+\usepreamble\defaultpreamble
+\usepostamble\defaultpostamble
+\file{pandoctpl.latex}{\from{xint.dtx}{pandoctpl}}
+\file{xint.tex}{\from{xint.dtx}{drv}}
+\file{xintkernel.sty}{\from{xint.dtx}{xintkernel}}
+\file{xinttools.sty}{\from{xint.dtx}{xinttools}}
+\file{xintcore.sty}{\from{xint.dtx}{xintcore}}
+\file{xint.sty}{\from{xint.dtx}{xint}}
+\file{xintbinhex.sty}{\from{xint.dtx}{xintbinhex}}
+\file{xintgcd.sty}{\from{xint.dtx}{xintgcd}}
+\file{xintfrac.sty}{\from{xint.dtx}{xintfrac}}
+\file{xintseries.sty}{\from{xint.dtx}{xintseries}}
+\file{xintcfrac.sty}{\from{xint.dtx}{xintcfrac}}
+\file{xintexpr.sty}{\from{xint.dtx}{xintexpr}}
+\file{xinttrig.sty}{\from{xint.dtx}{xinttrig}}
+\file{xintlog.sty}{\from{xint.dtx}{xintlog}}}
+\catcode32=13\relax% active space
+\let =\space%
+\Msg{********************************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* files into a directory searched by TeX:}
+\Msg{*}
+\Msg{* xintkernel.sty}
+\Msg{* xintcore.sty}
+\Msg{* xint.sty}
+\Msg{* xintbinhex.sty}
+\Msg{* xintgcd.sty}
+\Msg{* xintfrac.sty}
+\Msg{* xintseries.sty}
+\Msg{* xintcfrac.sty}
+\Msg{* xintexpr.sty}
+\Msg{* xinttrig.sty}
+\Msg{* xintlog.sty}
+\Msg{* xinttools.sty}
+\Msg{*}
+\Msg{* To produce the user manual run latex thrice on xint.tex}
+\Msg{* then dvipdfmx on xint.dvi, or if your system allows,}
+\Msg{* execute `make xint.pdf' (this requires Latexmk).}
+\Msg{*}
+\Msg{* The commented source code is generated from executing}
+\Msg{* `make sourcexint.pdf' (this requires Latexmk; if not}
+\Msg{* available check the details in Makefile.mk and .latexmkrc)}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{********************************************************************}
+\endbatchfile
+%</ins>-----------------------------------------------------------
+%<*dtx>-----------------------------------------------------------
+^^Bfi^^Begroup
+\chardef\noetex 0
+\ifx\numexpr\undefined\chardef\noetex 1 \fi
+\ifnum\noetex=1 \chardef\extractfiles 0 % extract files, then stop
+\else
+ \ifx\ProvidesFile\undefined
+ \chardef\extractfiles 0 % no LaTeX2e: etex, xetex, ... on xint.dtx
+ \else
+ \ifx\NoSourceCode\undefined
+ % latex/pdflatex/xelatex on xint.dtx, we will extract all files
+ \chardef\extractfiles 1 % 1 = extract and typeset, 2 = only typeset
+ \chardef\NoSourceCode 0 % 0 = include source code, 1 = do not
+ \NeedsTeXFormat{LaTeX2e}%
+ \PassOptionsToClass{a4paper,fontsize=10pt}{scrdoc}%
+ \else
+ % latex/pdflatex/xelatex on xint.tex
+ \chardef\extractfiles 2 % no extractions, but typeset
+ % \NoSourceCode is set-up in xint.tex
+ \fi
+ \ProvidesFile{xint.dtx}[bundle source (\xintbndlversion, \xintbndldate) %
+ and documentation (\xintdocdate)]%
+ \fi
+\fi
+\ifnum\extractfiles<2 % extract files
+\def\MessageDeFin{\newlinechar10 \let\Msg\message
+\Msg{^^J}%
+\Msg{********************************************************************^^J}%
+\Msg{*^^J}%
+\Msg{* To finish the installation you have to move the following^^J}%
+\Msg{* files into a directory searched by TeX:^^J}%
+\Msg{*^^J}%
+\Msg{* \space\space\space\space xintkernel.sty^^J}%
+\Msg{* \space\space\space\space xintcore.sty^^J}%
+\Msg{* \space\space\space\space xint.sty^^J}%
+\Msg{* \space\space\space\space xintbinhex.sty^^J}%
+\Msg{* \space\space\space\space xintgcd.sty^^J}%
+\Msg{* \space\space\space\space xintfrac.sty^^J}%
+\Msg{* \space\space\space\space xintseries.sty^^J}%
+\Msg{* \space\space\space\space xintcfrac.sty^^J}%
+\Msg{* \space\space\space\space xintexpr.sty^^J}%
+\Msg{* \space\space\space\space xinttools.sty^^J}%
+\Msg{* \space\space\space\space xinttrig.sty^^J}%
+\Msg{* \space\space\space\space xintlog.sty^^J}%
+\Msg{*^^J}%
+\Msg{* To produce the user manual run latex thrice on xint.tex^^J}%
+\Msg{* then dvipdfmx on xint.dvi, or if your system allows,^^J}%
+\Msg{* execute `make xint.pdf' (this requires Latexmk).^^J}%
+\Msg{*^^J}%
+\Msg{* The commented source code is generated from executing^^J}%
+\Msg{* `make sourcexint.pdf' (this requires Latexmk; if not^^J}%
+\Msg{* available check the details in Makefile.mk and .latexmkrc)^^J}%
+\Msg{*^^J}%
+\Msg{* Happy TeXing!^^J}%
+\Msg{*^^J}%
+\Msg{********************************************************************^^J}%
+}%
+\begingroup
+ \input docstrip.tex
+ \askforoverwritefalse
+ \catcode9 11 % do not kill TAB in producing Makefile.mk
+ \generate{\nopreamble\nopostamble
+ \file{README.md}{\from{xint.dtx}{readme}}
+ \file{CHANGES.md}{\from{xint.dtx}{changes}}
+ % pure tex will use ^^I notation for TAB character, don't want that.
+ % there is a problem with xelatex, as it generates ^^I also.
+ \ifnum\noetex=1 \else\ifx\XeTeXinterchartoks\undefined
+ \file{Makefile.mk}{\from{xint.dtx}{makefile}}\fi\fi
+ \file{doHTMLs.sh}{\from{xint.dtx}{dohtmlsh}}
+ \file{doPDFs.sh}{\from{xint.dtx}{dopdfsh}}
+ \usepreamble\defaultpreamble
+ \usepostamble\defaultpostamble
+ \file{pandoctpl.latex}{\from{xint.dtx}{pandoctpl}}
+ \file{xint.ins}{\from{xint.dtx}{ins}}
+ \file{xint.tex}{\from{xint.dtx}{drv}}
+ \file{xintkernel.sty}{\from{xint.dtx}{xintkernel}}
+ \file{xinttools.sty}{\from{xint.dtx}{xinttools}}
+ \file{xintcore.sty}{\from{xint.dtx}{xintcore}}
+ \file{xint.sty}{\from{xint.dtx}{xint}}
+ \file{xintbinhex.sty}{\from{xint.dtx}{xintbinhex}}
+ \file{xintgcd.sty}{\from{xint.dtx}{xintgcd}}
+ \file{xintfrac.sty}{\from{xint.dtx}{xintfrac}}
+ \file{xintseries.sty}{\from{xint.dtx}{xintseries}}
+ \file{xintcfrac.sty}{\from{xint.dtx}{xintcfrac}}
+ \file{xintexpr.sty}{\from{xint.dtx}{xintexpr}}
+ \file{xinttrig.sty}{\from{xint.dtx}{xinttrig}}
+ \file{xintlog.sty}{\from{xint.dtx}{xintlog}}}
+\endgroup
+\fi % end of file extraction (from etex/latex/pdflatex/... run on xint.dtx)
+\ifnum\extractfiles=0 % no LaTeX, files now extracted. Stop.
+ \MessageDeFin\expandafter\end
+\fi
+% From this point on, run is necessarily with e-TeX.
+% Check if \MessageDeFin got defined, if yes put it at end of run.
+\ifdefined\MessageDeFin\AtEndDocument{\MessageDeFin}\fi
+%-----------------------------------------------------------------
+% -*- coding: utf-8; mode: latex, fill-column: 78; -*-
+%
+\ifdefined\dosourcexint % this toggle is set from make sourcexint.pdf rule
+ \chardef\NoSourceCode 0
+\else
+ \chardef\dosourcexint 0
+\fi
+
+% default is to assume latex + dvipdfmx
+\chardef\Withdvipdfmx 1
+
+\RequirePackage{ifpdf}
+\RequirePackage{ifxetex}
+
+\ifpdf \chardef\Withdvipdfmx 0 \fi
+\ifxetex\chardef\Withdvipdfmx 0 \fi
+
+\ifnum\Withdvipdfmx=1
+\def\pgfsysdriver{pgfsys-dvipdfm.def}
+\documentclass [dvipdfm, dvipdfmx, dvipdfmx-outline-open]{scrdoc}
+\else
+\documentclass {scrdoc}
+\fi
+% Revert change to \smash and other macros at LaTeX 2018/12/01
+% https://github.com/latex3/latex2e/issues/108
+\makeatletter
+\let\leavevmode@ifvmode\empty % for \smash in \NewWith etc...
+\makeatother
+
+% Remove from sectioning commands insertion of marks, because we
+% will do it ourself.
+\usepackage{etoolbox}
+\makeatletter
+\patchcmd{\@sect}%
+ {\expandafter\csname#1mark\expandafter\endcsname\expandafter{\@currentheadentry}}%
+ {}{}{}
+\patchcmd{\@sect}%
+ {\expandafter\csname#1mark\expandafter\endcsname\expandafter{\@currentheadentry}}%
+ {}{}{}
+\makeatother
+
+\PassOptionsToPackage{bookmarks=true}{hyperref}
+
+\ifnum\NoSourceCode=1
+ \OnlyDescription
+\fi
+
+
+% counts used in particular in the samples from the documentation of the
+% xintseries.sty package
+\newcount\cnta
+\newcount\cntb
+\newcount\cntc
+
+\pagestyle{headings}
+
+\ifxetex
+\else
+ \usepackage[T1]{fontenc}
+ \usepackage[utf8]{inputenc}
+ \DeclareUnicodeCharacter{03B4}{\ensuremath{\delta}}%δ
+ \DeclareUnicodeCharacter{03BE}{\ensuremath{\xi}}%ξ
+ \DeclareUnicodeCharacter{03C0}{\ensuremath{\pi}}%π
+\fi
+
+\usepackage{multicol}
+\usepackage{geometry}
+\AtBeginDocument {\ttzfamily % package newtxtt loaded in preamble
+ \newgeometry{textwidth=\dimexpr92\fontcharwd\font`X\relax,
+ vscale=0.75}}
+
+\unless\ifnum\dosourcexint=1
+\usepackage{xintexpr}
+\usepackage{xintbinhex}
+\usepackage{xintgcd}
+\usepackage{xintseries}
+\usepackage{xintcfrac}
+\usepackage{amsmath}% for \cfrac usage
+\DeclareMathOperator{\sinc}{sinc}
+\usepackage{pifont}% for \ding{73} (hollow star)
+\fi
+
+\usepackage{xinttools}
+\xintverbosetrue
+
+\usepackage{enumitem}
+\usepackage{varioref}
+\usepackage{xspace}
+\usepackage[para]{footmisc}
+\usepackage{picture}
+\usepackage{graphicx}
+
+\usepackage[english]{babel}
+\usepackage[autolanguage,np]{numprint}
+\AtBeginDocument{\npthousandsep{,\hskip .5pt plus .1pt minus .1pt}}
+
+\usepackage[dvipsnames]{xcolor}
+\definecolor{joli}{RGB}{225,95,0}
+\definecolor{JOLI}{RGB}{225,95,0}
+\definecolor{BLUE}{RGB}{0,0,255}
+\definecolor{niceone}{RGB}{38,128,192}
+\usepackage{eso-pic}% après xcolor sinon Option clash for package xcolor.
+
+\ifnum\dosourcexint=1
+\else
+% Dependency graph done using TikZ (manually)
+ \usepackage{tikz}
+ \usetikzlibrary{shapes,arrows.meta}
+\fi
+
+\usepackage{framed}
+% SNUGFRAMED
+% ==========
+
+\makeatletter
+\newenvironment{snugframed}{%
+ \fboxsep \dimexpr2\fontcharwd\font`X\relax
+ \advance\linewidth-2\fboxsep
+ \advance\csname @totalleftmargin\endcsname \fboxsep
+ \def\FrameCommand##1{\hskip\@totalleftmargin
+ \hskip-\fboxsep
+ \fbox{##1}\hskip-\fboxsep
+ % There is no \@totalrightmargin, so:
+ \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}%
+ \MakeFramed {\advance\hsize-\width \@totalleftmargin\z@ \linewidth\hsize
+ \@setminipage}%
+ }{\par\unskip\@minipagefalse\endMakeFramed}
+\makeatother
+
+% HYPERREF
+% ========
+
+\usepackage[pdfencoding=unicode]{hyperref}
+
+\hypersetup{%
+linktoc=all,%
+breaklinks=true,%
+colorlinks=true,%
+urlcolor=niceone,%
+linkcolor=blue,%
+pdfauthor={Jean-Fran\c cois Burnol},%
+pdftitle={The xint bundle},%
+pdfsubject={Arithmetic with TeX},%
+pdfkeywords={Expansion, arithmetic, TeX},%
+pdfstartview=FitH,%
+pdfpagemode=UseOutlines}
+
+\usepackage{hypcap}
+\ifnum\dosourcexint=1
+\hypersetup{pdftitle={The xint bundle source code}}
+\fi
+\usepackage{bookmark}
+
+% FONTS
+% =====
+
+\usepackage[zerostyle=a,straightquotes,scaled=0.95]{newtxtt}
+\usepackage{newtxmath}
+
+\makeatletter
+
+
+
+\DeclareFontFamily{T1}{newtxttb}{\hyphenchar\font\m@ne}
+
+\DeclareFontShape{T1}{newtxttb}{m}{n}{
+ <-> s*[\newtxtt@scale]newtxttbq
+}{}
+\DeclareFontShape{T1}{newtxttb}{b}{n}{
+ <-> s*[\newtxtt@scale]newtxbttbq
+}{}
+\DeclareFontShape{T1}{newtxttb}{bx}{n}{
+ <-> ssub * newtxttb/b/n
+}{}
+\DeclareFontShape{T1}{newtxttb}{m}{sl}{
+ <-> s*[\newtxtt@scale]newtxttslbq
+}{}
+\DeclareFontShape{T1}{newtxttb}{m}{it}{
+ <-> ssub * newtxttb/m/sl
+}{}
+
+% Ajouté le 9 mars 2016
+
+\DeclareFontShape{T1}{newtxttb}{m}{sc}{%cap & small cap
+ <-> s*[\newtxtt@scale]newtxttscbq
+}{}
+\DeclareFontShape{T1}{newtxttb}{b}{sc}{%bold cap & small cap
+ <-> s*[\newtxtt@scale]newtxbttscbq
+}{}
+\DeclareFontShape{T1}{newtxttb}{b}{sl}{%bold slanted
+ <-> s*[\newtxtt@scale]newtxbttslbq
+}{}
+\DeclareFontShape{T1}{newtxttb}{b}{it}{%bold italic
+ <-> ssub * newtxttb/b/sl%
+}{}
+\DeclareFontShape{T1}{newtxttb}{bx}{sc}{%bold extended cap & small cap
+ <-> ssub * newtxttb/b/sc%
+}{}
+\DeclareFontShape{T1}{newtxttb}{bx}{sl}{%bold extended slanted
+ <-> ssub * newtxttb/b/sl%
+}{}
+\DeclareFontShape{T1}{newtxttb}{bx}{it}{%bold extended italic
+ <-> ssub * newtxttb/b/sl%
+}{}
+
+% Ajouté le 9 mars 2016
+\DeclareEncodingSubset{TS1}{newtxttb}{0}
+\DeclareFontFamily{TS1}{newtxttb}{\hyphenchar\font\m@ne}
+
+\DeclareFontShape{TS1}{newtxttb}{m}{n}{%medium
+ <-> s*[\newtxtt@scale]tcxtt%
+}{}
+\DeclareFontShape{TS1}{newtxttb}{m}{sc}{%cap & small cap
+ <->ssub * newtxttb/m/n%
+}{}
+\DeclareFontShape{TS1}{newtxttb}{m}{sl}{%slanted
+ <-> s*[\newtxtt@scale]tcxttsl%
+}{}
+\DeclareFontShape{TS1}{newtxttb}{m}{it}{%italic
+ <->ssub * newtxttb/m/sl%
+}{}
+\DeclareFontShape{TS1}{newtxttb}{b}{n}{%bold
+ <-> s*[\newtxtt@scale]tcxbtt%
+}{}
+\DeclareFontShape{TS1}{newtxttb}{b}{sc}{%bold cap & small cap
+ <->ssub * newtxttb/b/n%
+}{}
+\DeclareFontShape{TS1}{newtxttb}{b}{sl}{%bold slanted
+ <-> s*[\newtxtt@scale]tcxbttsl%
+}{}
+\DeclareFontShape{TS1}{newtxttb}{b}{it}{%bold italic
+ <->ssub * newtxttb/b/sl%
+}{}
+\DeclareFontShape{TS1}{newtxttb}{bx}{n}{%bold extended
+ <->ssub * newtxttb/b/n%
+}{}
+\DeclareFontShape{TS1}{newtxttb}{bx}{sc}{ %bold extended cap & small cap
+ <->ssub * newtxttb/b/sc%
+}{}
+\DeclareFontShape{TS1}{newtxttb}{bx}{sl}{%bold extended slanted
+ <->ssub * newtxttb/b/sl%
+}{}
+\DeclareFontShape{TS1}{newtxttb}{bx}{it}{%bold extended italic
+ <->ssub * newtxttb/b/it%
+}{}
+
+
+\makeatother
+
+% This is with a slashed 0 like the original txtt.
+\newcommand\ttbfamily {\fontfamily{newtxttb}\selectfont }
+
+\ifnum\dosourcexint=1
+\else
+\renewcommand\familydefault\ttdefault
+\usepackage[noendash]{mathastext}% pas de endash dans newtxtt
+\fi
+\frenchspacing
+% sans-serif in footnotes, TOC, titles, etc...
+\renewcommand\familydefault\sfdefault
+
+% TABLES OF CONTENTS
+% ==================
+
+\usepackage{tocloft}
+\usepackage{etoc}
+
+\def\gobbletodot #1.{}
+
+\newif\ifinmanualmaintoc
+\ifnum\dosourcexint=0
+ \inmanualmaintoctrue
+\fi
+\def\sectioncouleur{{cyan}}
+
+\def\MARGEPAGENO {1.5em}% changera pour la partie implémentation
+
+
+\def\SKIPSECTIONINTERSPACE{\vskip\bigskipamount}
+\etocsetstyle{section}{}
+ {\normalfont}
+ {\etociffirst{}{\SKIPSECTIONINTERSPACE}%
+ \rightskip \MARGEPAGENO\relax
+ \parfillskip -\MARGEPAGENO\relax
+ \bfseries
+ \leftskip \leftmarginii
+ \noindent\llap % \llap
+ {\makebox[\leftmarginii][l]% et \leftmargini le 12/10/2014
+ {\expandafter\textcolor\sectioncouleur {\etocnumber}}}%
+ \strut\etocname
+ \mdseries\nobreak\leaders\etoctoclineleaders\hfill\nobreak\strut
+ \makebox[\MARGEPAGENO][r]{\etocpage}\par
+ \let\ETOCsectionnumber\etocthenumber
+ }%
+ {}%
+
+\newdimen\margegauchetoc
+\AtBeginDocument{\margegauchetoc \dimexpr 5\fontcharwd\font`X\relax}
+\makeatletter
+\etocsetstyle{subsection}
+ {\begingroup\normalfont
+ \setlength{\premulticols}{0pt}%
+ \setlength{\multicolsep}{0pt}%
+ \setlength{\columnsep}{\leftmarginii}%
+ \setlength{\columnseprule}{.4pt}% n'influence pas séparation colonnes
+ \parskip\z@skip
+ \raggedcolumns
+ \addvspace{\smallskipamount}%
+ \begin{multicols}{2}
+ \leftskip \margegauchetoc % 12 octobre 2014
+ \ifinmanualmaintoc
+ \rightskip \MARGEPAGENO
+ \else
+ \rightskip \MARGEPAGENO plus 2em minus 1em
+ \fi
+ \parfillskip -\MARGEPAGENO\relax
+ }
+ {}
+ {\noindent
+ \etocifnumbered{\llap{\makebox[\margegauchetoc][l]{\ttzfamily\bfseries\etoclink
+ {\ifinmanualmaintoc\expandafter\textcolor\sectioncouleur
+ {\normalfont\bfseries\ETOCsectionnumber}\fi
+ .\expandafter\gobbletodot\etocthenumber}}}}{\kern-\margegauchetoc}%
+ \strut\etocname\nobreak
+ \unless\ifinmanualmaintoc\leaders\etoctoclineleaders\fi
+ \hfill\nobreak
+ \strut\makebox[\MARGEPAGENO][r]{\small\etocpage}\endgraf }
+ {\end{multicols}\endgroup
+ %\addvspace{\smallskipamount}
+ }%
+
+\etocsetstyle{subsubsection}
+ {\begingroup\normalfont\small
+ \leftskip \dimexpr\leftmargini+1em\relax }
+ {}
+ {\noindent
+ \llap{\makebox[\dimexpr\leftmargini+1em\relax][l]%
+ {\ttzfamily\bfseries\etoclink
+ {\HOOKLOCALTOC.\expandafter\gobbletodot\etocthenumber}}}%
+ \strut\etocname\nobreak
+ \leaders\etoctoclineleaders
+ \hfill\nobreak
+ \strut\makebox[\MARGEPAGENO][r]{\small\etocpage}\endgraf }
+ {\endgroup }%
+
+\let\HOOKLOCALTOC\empty% quick hack to get style I want in User defined functions
+\etocsetlevel{table}{6}
+
+\makeatother
+
+\addtocontents{toc}{\protect\hypersetup{hidelinks}}
+
+% =====================
+% MISCELLANEOUS MARK-UP
+% =====================
+
+
+\def\digitstt #1{\begingroup\color[named]{OrangeRed}#1\endgroup}
+\let\dtt\digitstt
+
+% \ctexttt is a remnant of 1.09n manual, don't have time to get rid of it now.
+\newcommand\ctexttt [1]{\begingroup\color[named]{DarkOrchid}%\bfseries
+ #1\endgroup}
+
+% \fexpan 22 octobre 2013
+\newcommand\fexpan {\hyperref[ssec:expansions]{\textit{f}-expan}}
+% Septembre 2015
+% Address updated to github repo's one, May 2018
+\def\liiibigint
+ {\href{https://github.com/latex3/latex3/tree/master/l3trial/l3bigint}{l3bigint}}
+
+% \fixmeaning
+\makeatletter
+\def\fixmeaning {\expandafter\fix@meaning\meaning}
+\expandafter\edef\expandafter\fix@meaning
+ \expandafter #\expandafter1\string\romannumeral#2#3%
+ {#1\string\romannumeral`\string^\string^@}
+\makeatother
+
+% Margin Notes
+% ============
+
+\makeatletter
+\def\MyMarginNote {\@ifnextchar[\@MyMarginNote{\@MyMarginNote[]}}%
+\let\inmarg\MyMarginNote
+\def\@MyMarginNote [#1]#2{\@bsphack
+ \vadjust{\vskip-\dp\strutbox
+ \smash{\hbox to 0pt
+ {\color[named]{PineGreen}\normalfont\small
+ \hsize 1.6cm\rightskip.5cm minus.5cm
+ \hss\vtop{#2}\ $\to$#1\ }}%
+ \vskip\dp\strutbox
+ }\strut\@esphack}
+\def\MyMarginNoteWithBrace #1#2{\@bsphack
+ \vadjust{\vskip-\dp\strutbox
+ \smash{\hbox to 0pt
+ {\color[named]{PineGreen}%\normalfont\small
+ \hss #1\ $\bigg\{$#2}}%
+ \vskip\dp\strutbox
+ }\strut\@esphack}
+\def\IMPORTANT {\MyMarginNoteWithBrace
+ {\raisebox{-.5\height}{\resizebox{2\width}{!}{\ding{43}}}}{\ }}
+\def\IMPORTANTf {\MyMarginNoteWithBrace
+ {\raisebox{-.5\height}{\resizebox{2\width}{!}{\ding{43}}}}%
+ {\kern\dimexpr\FrameSep+\FrameRule\relax\ }}
+\def\etype #1{\@bsphack
+ \vadjust{\vskip-\dp\strutbox
+ \smash{\hbox to 0pt {\hss\color[named]{PineGreen}%
+ \itshape \xintListWithSep{\,}{#1}\ $\star$\quad }}%
+ \vskip\dp\strutbox
+ }\strut\@esphack}
+\def\retype #1{\@bsphack
+ \vadjust{\vskip-\dp\strutbox
+ \smash{\hbox to 0pt {\hss\color[named]{PineGreen}%
+ \itshape \xintListWithSep{\,}{#1}\ \ding{73}\quad }}%
+ \vskip\dp\strutbox }\strut\@esphack}
+\def\ntype #1{\@bsphack
+ \vadjust{\vskip-\dp\strutbox
+ \smash{\hbox to 0pt {\hss\color[named]{PineGreen}%
+ \itshape \xintListWithSep{\,}{#1}\quad }}%
+ \vskip\dp\strutbox }\strut\@esphack}
+%
+\def\Numf {{\vbox{\halign{\hfil##\hfil\cr \footnotesize
+ \upshape Num\cr
+ \noalign{\hrule height 0pt \vskip1pt\relax}
+ \itshape f\cr}}}}
+\def\Ff {{\vbox{\halign{\hfil##\hfil\cr \footnotesize
+ \upshape Frac\cr
+ \noalign{\hrule height 0pt \vskip1pt\relax}
+ \itshape f\cr}}}}
+\def\numx {{\vbox{\halign{\hfil##\hfil\cr \footnotesize
+ \upshape num\cr
+ \noalign{\hrule height 0pt \vskip1pt\relax}
+ \itshape x\cr}}}}
+%
+\def\NewWith #1{\@bsphack
+ \vadjust{\vskip-\dp\strutbox
+ \smash{\hbox to 0pt {\hss\color[named]{PineGreen}%
+ \normalfont\small\bfseries
+ \hsize 1.5cm\rightskip.5cm minus.5cm
+ \vtop{\noindent New with #1}\ }}%
+ \vskip\dp\strutbox }\strut\@esphack}
+%
+\def\CHANGED #1{\@bsphack
+ \vadjust{\vskip-\dp\strutbox
+ \smash{\hbox to 0pt {\hss\color[named]{Red}%
+ \normalfont\small\bfseries
+ \hsize 1.5cm\rightskip.5cm minus.5cm
+ \vtop{\noindent Changed at #1!}\ }}%
+ \vskip\dp\strutbox }\strut\@esphack}
+
+\def\DEPRECATED #1{\@bsphack
+ \vadjust{\vskip-\dp\strutbox
+ \smash{\hbox to 0pt {\hss\color[named]{PineGreen}%
+ \normalfont\small\bfseries
+ \hsize 2cm\rightskip.5cm minus.5cm
+ \vtop{\noindent Deprecated! (#1)}\ }}%
+ \vskip\dp\strutbox }\strut\@esphack}
+%
+\def\CHANGEDf #1{\@bsphack
+ \vadjust{\vskip-\dp\strutbox
+ \smash{\hbox to 0pt {\hss\color[named]{Red}%
+ \normalfont\small\bfseries
+ \hsize 1.5cm\rightskip.5cm minus.5cm
+ \vtop{\noindent Changed at #1!}\
+ \kern\dimexpr\FrameSep+\FrameRule\relax}}%
+ \vskip\dp\strutbox }\strut\@esphack}
+%
+\def\NewWithf #1{\@bsphack
+ \vadjust{\vskip-\dp\strutbox
+ \smash{\hbox to 0pt {\hss\color[named]{PineGreen}%
+ \normalfont\small\bfseries
+ \hsize 1.5cm\rightskip.5cm minus.5cm
+ \vtop{\noindent New with #1}\
+ \kern\dimexpr\FrameSep+\FrameRule\relax}}%
+ \vskip\dp\strutbox }\strut\@esphack}
+
+\makeatother
+
+% \centeredline: OUR OWN LITTLE MACRO FOR CENTERING LINES
+% =======================================================
+
+% 7 mars 2013
+%
+% This macro allows to conveniently center a line inside a paragraph and still
+% allow use therein of \verb or other macros changing catcodes.
+% A proposito, the \LaTeX \centerline uses \hsize and not \linewidth !
+% (which in my humble opinion is bad)
+
+% Actually my \centeredline works nicely in list environments.
+
+% \ignorespaces added June 9, 2013
+
+% Note: \centeredline creates a group
+
+\makeatletter
+\newcommand*\centeredline {%
+ \ifhmode \\\relax
+ \def\centeredline@{\hss\egroup\hskip\z@skip\ignorespaces }%
+ \else
+ \def\centeredline@{\hss\egroup }%
+ \fi
+ \afterassignment\@centeredline
+ \let\next=}
+\def\@centeredline
+ {\hbox to \linewidth \bgroup \hss \bgroup \aftergroup\centeredline@ }
+
+% \leftedline
+% ===========
+
+% 12 octobre 2014
+
+\newif\ifinlefted
+
+\newcommand*\leftedline {%
+ \ifhmode \\\relax
+ \def\leftedline@{\hss\egroup\hskip\z@skip\ignorespaces }%
+ \else
+ \def\leftedline@{\hss\egroup }%
+ \fi
+ \afterassignment\@leftedline
+ \let\next=}
+\def\@leftedline
+ {\hbox to \linewidth \bgroup \inleftedtrue
+ \everbatimeverypar
+ \bgroup
+ \aftergroup\leftedline@ }
+
+\makeatother
+
+% verbatim macros and environments
+% ================================
+%
+% June 2013, then October 2014.
+% -----------------------------
+%
+\makeatletter
+\catcode`_ 11
+
+% some of my verbatim environments do not make the space active (\lverb e.g.). Then
+% \do@noligs must be modified, \char`#1 must be followed by a space token, else,
+% the `#1 expansion will swallow one space.
+\def\do@noligs #1{%
+ \catcode`#1\active
+ \begingroup
+ \lccode`~`#1\relax
+ \lowercase{%
+ \endgroup\def~{\leavevmode\kern\z@\char`#1 }}%
+}
+
+% \lowast
+\def\lowast{\raisebox{-.25\height}{*}}
+\catcode`* 13
+\def\makestarlowast {\let*\lowast\catcode`\*\active}%
+\catcode`* 12
+
+
+
+% \MacroFont and \MicroFont
+% =========================
+
+\def\restoreMicroFont {\def\MicroFont {\ttbfamily\makestarlowast
+ \ifinlefted\else\ifineverb\else\color[named]{Blue}\fi\fi}}
+\restoreMicroFont
+
+% Notice that \macrocode uses \macro@font which stores the \MacroFont meaning
+% in force at \begin{document}. But doc.sty's verbatim uses current \MacroFont
+% not the meaning at \begin{document}. Comprenne qui pourra...
+
+\def\restoreMacroFont {\def\MacroFont {\ttbfamily
+ \ifinlefted\else\ifineverb\else\color[named]{Blue}\fi\fi}}
+\restoreMacroFont
+
+% \verb
+% =====
+
+% Initially, June 2013, then Sep 9, 2014, and Oct 9-12 2014
+%
+% Initial motivation was simply that doc.sty and related classes \verb
+% macro is with a hard-coded \ttfamily. There were further issues.
+%
+% 1. With |stuff with space|, paragraph reformatting in the Emacs/AUCTeX
+% buffer caused havoc. Thus I wanted the input to accept linebreaks in
+% its contents.
+%
+% 2. Hence I did not want to have obeyed spaces obeyed, (Emacs reflowing
+% of paragraph in certain contexts often adds spaces at beginning of a line)
+%
+% 3. Also I wanted to allow hyphenated output, at least at some
+% locations. I did a first version which treated spaces, \, {, and }
+% specially.
+%
+% 4. At some point I wanted to add some colored background (I have
+% dropped that since due to pdf file size increase).
+%
+% 5. And also I got fed up from the non-compatibility with footnotes due
+% to catcode freeze.
+%
+% Because of 5. I opted for a \scantokens approach, hence for a macro
+% with delimited argument. Here is what I do now, this is compatible
+% with short verbs.
+
+\def\verb
+{%
+ \relax \ifmmode\else\leavevmode\null\fi
+ \bgroup
+ \let\do\@makeother \dospecials
+ \@ifstar{\@sverb}% \verb* is used in the index (obsolete: no indices at 1.3e),
+ % leave it using ambient font
+ {\MicroFont % used to change font (ttbfamily=slashed 0), color,
+ % will make * active via \makestarlowast
+ \catcode 32 10 \endlinechar 32 % allows to fetch across line breaks
+ \frenchspacing % done globally in document
+ \@@jfverb}%
+}%
+% Note (Oct 12, 2014): in the improbable situation a newlinechar is
+% found in the ##1, \scantokens will convert this to an end of line in
+% its "write" phase, which will be then ignored in its "read" phase due
+% to \endlinechar-1. This also avoids possible creation of \par which
+% would defeat \@@jfverb@@. Thus it is good.
+\def\@@jfverb #1{%
+ \ifcat\noexpand#1\noexpand~\catcode`#1\active\fi
+% No problem with the EOL for the line where the short verb delimiter stands.
+ \def\next ##1#1{%
+ \@vobeyspaces\everyeof{\relax}\endlinechar\m@ne
+ \expandafter\@@jfverb_a\scantokens\expandafter{##1}}%
+% hack with \@empty to prevent brace stripping if catcodes have been
+% frozen earlier, like in footnotes.
+ \next \@empty
+}
+
+% We don't want a \discretionary at the very start.
+% But then an empty argument is forbidden!
+\def\@@jfverb_a #1{#1\@@jfverb_b }
+
+\def\@@jfverb_b #1{\ifx\relax #1%
+ \egroup
+ \else
+% \penalty\z@, or rather (Oct 11, 2014) but I then adjust the textwidth
+% precisely:
+ \discretionary{\copy\SoftWrapIcon}{}{}%
+ #1\expandafter\@@jfverb_b\fi
+}
+
+% \SoftWrapIcon box for line-breaking using discretionaries
+% =========================================================
+
+\DeclareFontFamily{U}{MdSymbolC}{}
+\DeclareFontShape {U}{MdSymbolC}{m}{n}{<-> MdSymbolC-Regular}{}
+
+\newbox\SoftWrapIcon
+\colorlet {softwrapicon}{blue}
+
+% Emacs/AUCTeX uses very strange comment-like highlighting for \usefont{U}...
+\def\SetSoftWrapIcon{%
+ \setbox\SoftWrapIcon\hb@xt@\z@
+ {\hb@xt@\fontdimen2\font
+ {\hss{\color{softwrapicon}\usefont{U}{MdSymbolC}{m}{n}\char"97}\hss}%
+ \hss}%
+ }
+
+\AtBeginDocument {\SetSoftWrapIcon }% ttzfamily déjà fait
+
+\catcode`_ 8
+\makeatother
+
+% everbatim environment
+% =====================
+
+% October 13-14, 2014
+% Verbatim with an \everypar hook, mainly to have background color, followed by
+% execution of the contents (not limited by a group-scope)
+
+\makeatletter
+\catcode`_ 11
+
+\def\everbatimtop {\MacroFont\small }
+\let\everbatimbottom\relax
+\let\everbatimhook\relax
+
+\newif\ifineverb
+
+\def\everbatim {\s@everbatim\@everbatim }
+\@namedef{everbatim*}{\s@everbatim\expandafter\@everbatimx\expandafter
+ {\the\newlinechar}}
+
+\def\everbatimeverypar{\strut
+ {\color{yellow!5}\vrule\@width\linewidth }%
+ \kern-\linewidth
+ \kern\everbatimindent }
+\def\everbatimindent {\z@}
+% voir plus loin atbegindocument
+
+\def\endeverbatim {\if@newlist \leavevmode\fi\endtrivlist }
+\expandafter\let\csname endeverbatim*\endcsname \endeverbatim
+
+\def\s@everbatim {%
+ \ineverbtrue
+ \everbatimtop % put there size changes
+ \topsep \z@skip
+ \partopsep \z@skip
+ \itemsep \z@skip
+ \parsep \z@skip
+ \parskip \z@skip
+ \lineskip \z@skip
+ \let\do\@makeother \dospecials
+ \let\do\do@noligs \verbatim@nolig@list
+ \makestarlowast
+ \everbatimhook
+ \trivlist\item\relax
+ \leftskip \@totalleftmargin
+ \rightskip \z@skip
+ \parindent \z@
+ \parfillskip\@flushglue
+ \parskip \z@skip
+ \@@par
+ \def\par{\leavevmode\null\@@par\pagebreak[1]}%
+ \everypar\expandafter{\the\everypar \unpenalty
+ \everbatimeverypar
+ \everypar \expandafter{\the\everypar\everbatimeverypar}%
+ }%
+ \obeylines \@vobeyspaces
+}
+
+\begingroup
+\lccode`X 13
+\catcode`X \active
+\lccode`Y `* % this is because of \makestarlowast.
+% I have to think whether this is useful: obviously if I were to provide
+% everbatim and everbatim* in a package I wouldn't do that.
+\catcode`Y \active
+\catcode`| 0 \catcode`[ 1 \catcode`] 2 \catcode`* 12
+\catcode`{ 12 \catcode`} 12 |catcode`\\ 12
+|lowercase[|endgroup% both freezes catcodes and converts X to active ^^M
+|def|@everbatim #1X#2\end{everbatim}%
+ [#2|end[everbatim]|everbatimbottom ]
+|def|@everbatimx #1#2X#3\end{everbatimY}]%
+ {#3\end{everbatim*}%
+ \everbatimbottom
+ \newlinechar 13
+ \everbatimxprehook
+ \scantokens {#3}%
+ \newlinechar #1\relax
+ \everbatimxposthook
+}%
+
+% L'espace venant du endofline final mis par \scantokens sera inhibé si #3 se
+% termine par un % ou un \x, etc...
+
+\def\everbatimxprehook {\colorlet{everbsavedcolor}{.}\color[named]{OrangeRed}}
+\def\everbatimxposthook {\color{everbsavedcolor}}
+\ifpdf
+ \def\everbatimxprehook
+ {\pdfcolorstack\@pdfcolorstack push{0 1 0.5 0 k 0 1 0.5 0 K}\relax}
+ \def\everbatimxposthook
+ {\pdfcolorstack\@pdfcolorstack pop\relax}
+\else
+\ifxetex
+ \def\everbatimxprehook {\special{color push cmyk 0 1 0.5 0}}
+ \def\everbatimxposthook {\special{color pop}}
+\else
+\ifnum\Withdvipdfmx=1
+ \def\everbatimxprehook {\special{pdf:bcolor OrangeRed}}
+ \def\everbatimxposthook {\special{pdf:ecolor}}
+\fi\fi\fi
+
+
+
+% \everb
+% ======
+%
+% Original was called \dverb and I did it in June 2013.
+% Then after doing everbatim, I transformed \dverb, now called \everb
+% for itself being as compatible as standard verbatim with list making
+% surrounding environments.
+% Supposed to be used as
+% \everb|@ this will be ignored
+% stuff
+% escape character: "
+% | not necessarily starting a line.
+% I chose @ as comment character, mainly for pretty-formatting of the
+% source, this can be changed by \everbhook.
+
+% " comme caractère d'échappement. Par exemple pour colorier des parties.
+\def\restoreeverbhook{\def\everbhook{%
+ \def\"{\begingroup\catcode123 1 \catcode 125 2 \everbescape }%
+ \catcode`\" 0 \catcode`\@ 14
+}}\restoreeverbhook
+
+\def\everbescape #1;!{#1\endgroup }
+
+\def\everb {%
+ \bgroup
+ \let\everbatimhook\everbhook
+ \s@everbatim
+ \@everb
+}
+
+\def\@everb #1{\catcode`#1\active
+ \lccode`\~`#1%
+ \lowercase{\def~{\if@newlist \leavevmode\fi
+ \endtrivlist
+ \egroup
+ \@doendpe
+ \everbatimbottom }}%
+ }%
+
+\catcode`_8
+\makeatother
+
+
+% \printnumber
+% ============
+
+\catcode`_ 11
+\makeatletter
+\catcode`& 3
+\def\allowsplits_a {\futurelet\printnumber_token\allowsplits_b }%
+\def\allowsplits_b{\ifx\printnumber_token\@sptoken\space\fi\allowsplits_c }
+\def\allowsplits_c #1{\ifx &#1\xint_dothis\xint_gobble_i\fi
+ \if ,#1\xint_dothis {\discretionary{\rlap,}{}{,}}\fi
+ \xint_orthat{\discretionary
+ {\copy\SoftWrapIcon}%
+ {}%
+ {}#1}\allowsplits_a }%
+
+\def\printnumber #1{\expandafter\allowsplits_a \romannumeral-`0#1&}%
+\hyphenpenalty \z@
+
+\catcode`& 4
+\makeatother
+\catcode`_ 8
+
+% Parameters for lists
+% ====================
+\AtBeginDocument{%
+ \leftmargini \dimexpr4\fontcharwd\font`X\relax
+ \leftmarginii\dimexpr3\fontcharwd\font`X\relax
+ \leftmarginiii \leftmarginii
+ \leftmarginiv \leftmarginii
+ \parindent\dimexpr2\fontcharwd\font`X\relax
+ \leftmargin\leftmargini % pourquoi pas 0?
+% formerly everbatim indent was set to leftmargingi, reduce it (2017/08/26)
+% \edef\everbatimindent{\the\dimexpr\leftmargini\relax\space }%
+% setting it to \parindent does not work with \everb construct
+% \def\everbatimindent{\parindent}%
+ \edef\everbatimindent{\the\dimexpr2\fontcharwd\font`X\relax\space}%
+ \cftsubsecnumwidth 2\leftmarginii
+ \cftsubsubsecnumwidth 2\leftmargini
+ \cftsubsecindent 0pt
+ \cftsubsubsecindent \cftsubsecnumwidth
+}%
+
+% ==========
+% Hyperlinks
+% ==========
+
+% \csa, \csbxint, \csh etc...
+% ===========================
+
+% These definitions in force both in manual and implementation part
+\DeclareRobustCommand\csa[1]
+ {{\ttzfamily\char92\endlinechar-1
+ \makestarlowast \catcode`_ 12 \catcode`^ 12
+ \scantokens\expandafter{\detokenize{#1}}}}
+
+% csan: n means no backslash
+\DeclareRobustCommand\csan[1]
+ {{\ttzfamily\endlinechar-1
+ \makestarlowast \catcode`_ 12 \catcode`^ 12
+ \scantokens\expandafter{\detokenize{#1}}}}
+
+\newcommand\csh[1]
+ {\texorpdfstring{\csa{#1}}{\textbackslash\detokenize{#1}}}
+\newcommand\cshn[1]
+ {\texorpdfstring{\csan{#1}}{\detokenize{#1}}}
+% \csh and \cshn will be redefined in implementation section
+\let\cshnolabel\csh
+\let\cshnnolabel\cshn
+
+% These definitions will be re-done for implementation part
+% Don't bother about underscore and caret for time being.
+\DeclareRobustCommand\csb [1]
+ {\hyperref[\detokenize{#1}]%
+ {{\char92 \endlinechar-1 \makestarlowast
+ \scantokens\expandafter{\detokenize{#1}}}}}
+\DeclareRobustCommand\csbxint [1]
+ {\hyperref[\detokenize{xint#1}]%
+ {{\char92\mbox{xint}\-\endlinechar-1 \makestarlowast
+ \scantokens\expandafter{\detokenize{#1}}}}}
+
+% \func, \funcdesc, \keyword, \keyworddesc, \prec, \precdesc
+% ==========================================================
+
+\newcommand\func[1]{\hyperlink{\detokenize{func-#1}}{#1}()}
+\newcommand\funcdesc[2][x]{\item[#2({#1})]\hypertarget{\detokenize{func-#2}}{}}%
+
+\newcommand\keyword[1]{\hyperlink{\detokenize{kwd-#1}}{#1}}
+\newcommand\keyworddesc[1]{\item[#1]\hypertarget{\detokenize{kwd-#1}}{}}%
+
+\let\prec\relax % sinon, c'est \mathchar"321E
+\newcommand\prec[1]{\hyperlink{\detokenize{prec-#1}}{#1}}
+\newcommand\precdesc[1]{\item[$#1$]\hypertarget{\detokenize{prec-$#1$}}{}}%
+
+\newcommand\var[1]{\hyperlink{\detokenize{var-#1}}{#1}}
+\newcommand\vardesc[1]{\item[#1]\hypertarget{\detokenize{var-#1}}{}}%
+
+% \xintname, \xintnameimp etc...
+% ==============================
+
+
+\xintForpair #1#2 in
+{(xintkernel,kernel),
+ (xinttools,tools),
+ (xintcore,core),(xint,xint),(xintbinhex,binhex),(xintgcd,gcd),%
+ (xintfrac,frac),(xintseries,series),(xintcfrac,cfrac),(xintexpr,expr),%
+ (xinttrig, trig), (xintlog, log)}
+\do
+{%
+ \expandafter\def\csname #1name\endcsname
+ {\texorpdfstring
+ {\hyperref[sec:#2]%
+ {\relax{\color{joli}\MakeNameUp{#1}}}}%
+ {#1}%
+ \xspace }%
+ \expandafter\def\csname #1nameimp\endcsname
+ {\texorpdfstring
+ {\hyperref[sec:#2imp]%
+ {\relax{\color{blue}\MakeNameUp{#1}}}}%
+ {#1}%
+ \xspace }%
+}%
+
+ \def\DOCxintfrontpage
+ {\texorpdfstring
+ {\hyperref[frontpage]{\relax{\color{joli}TOC}}}%
+ {TOC}%
+ \xspace }%
+
+\makeatletter
+\protected\def\MakeNameUp#1{%
+ \ifcsname #1nameUp\endcsname
+ \expandafter\@firstoftwo\else
+ \expandafter\@secondoftwo
+ \fi
+ {\fbox{\textup{#1}}}{#1}}
+\makeatother
+
+% \RaisedLabel
+% ============
+
+% Samedi 16 juin 2018 à 15:23:22
+% trick to see header of target page
+% there is probably better way to use the already in place
+% anchor from \section, but no time to go into hyperref source
+\newcommand\RaisedLabel[2][6]{%
+\vspace*{-#1\baselineskip}%
+\begingroup
+ \let\leavevmode\relax\phantomsection
+ \label{#2}%
+\endgroup
+\vspace*{#1\baselineskip}%
+}
+
+% begin{document}
+% ===============
+% \ttzfamily done at begin document
+
+\begin{document}\thispagestyle{empty}
+\pdfbookmark[1]{Title page}{TOP}
+
+{%
+\normalfont\Large\parindent0pt \parfillskip 0pt\relax
+ \leftskip 2cm plus 1fil \rightskip 2cm plus 1fil
+\ifnum\dosourcexint=1
+ The \xintnameimp source code\par
+ \gdef\DOCxintfrontpage
+ {\texorpdfstring
+ {\hyperref[frontpage]{\relax{\color{blue}TOC}}}%
+ {TOC}%
+ \xspace }%
+\else
+ The \xintname bundle\par
+\fi
+\RaisedLabel{frontpage}
+}
+
+{\centering
+ \textsc{Jean-Fran\c cois Burnol}\par
+ \footnotesize
+ jfbu (at) free (dot) fr\par
+ Package version: \xintbndlversion\ (\xintbndldate);
+ documentation date: \xintdocdate.\par
+ {From source file \texttt{xint.dtx}. \xintdtxtimestamp.}\par
+}
+
+\medskip
+% Vendredi 15 juin 2018
+% Someone makes the comma active (not me! not sure if doc.sty or KOMA) and
+% this derails xspace.sty, in the headers, as it uses \scantokens on a list of
+% tokens, so it fails to recognize the commas which of course are of catcode12
+\def\xintRunningHeader{{\catcode`,12\relax
+ \DOCxintfrontpage,
+ \xintkernelname,
+ \xintcorename,
+ \xintname,
+ \xintfracname,
+ \xintexprname, \xinttrigname, \xintlogname,
+ \xintbinhexname,
+ \xintgcdname,
+ \xintseriesname,
+ \xintcfracname,
+ \xinttoolsname}}
+\markboth{\makebox[0pt]{\xintRunningHeader}}{\makebox[0pt]{\xintRunningHeader}}
+
+% Skips safely.
+\ifnum\dosourcexint=1
+\catcode`+ 0 \catcode0 9 % n'importe quoi sauf 15 (car ^^@)
+\catcode`\\ 12
++expandafter+iffalse+fi
+\fi
+%
+
+\newcommand\TeXnote{\par\smallskip\textbf{\TeX hackers note: }}
+
+\etocsetlevel{toctobookmark}{6}
+
+
+
+\etocsetlevel{table}{2}% subsection
+
+\renewcommand*{\etocbelowtocskip}{0pt}
+\renewcommand*{\etocinnertopsep}{0pt}
+\renewcommand*{\etoctoclineleaders}
+ {\hbox{\normalfont\normalsize\hbox to 1ex {\hss.\hss}}}
+\etocmulticolstyle [1]{%
+ \phantomsection\section* {Contents}
+ \etoctoccontentsline*{toctobookmark}{Contents}{1}%
+}
+
+\etocsettagdepth {description}{subsection}
+\etocsettagdepth {macros}{none}
+\etocsettagdepth {implementation}{none}
+
+\etocsettocdepth{subsection}
+\tableofcontents
+
+\renewcommand*\etocabovetocskip{\bigskipamount}
+\makeatletter
+\etocmulticolstyle [2]{\parskip\z@skip\raggedcolumns
+ \setlength{\columnsep}{\leftmarginii}%
+ \setlength{\columnseprule}{0pt}%
+}%
+\makeatother
+ \etocsettagdepth {description}{none}
+ \etocsettagdepth {macros} {section}
+\ifnum\NoSourceCode=1
+ \etocsettagdepth {implementation}{none}
+\else
+ \etocsettagdepth {implementation}{section}
+\fi
+
+\tableofcontents
+
+
+\etocignoredepthtags
+
+\etocmulticolstyle [1]{%
+ \phantomsection% \section* {Contents}
+ \etoctoccontentsline*{toctobookmark}{Contents}{2}%
+}
+
+\inmanualmaintocfalse
+
+\clearpage
+
+% ----
+% Fibonacci code
+% December 7, 2013. Expandably computing a big Fibonacci number
+% with the help of TeX+\numexpr+\xintexpr, (c) Jean-François Burnol
+\catcode`_ 11
+%
+% ajouté 7 janvier 2014 au xint.dtx pour 1.07j.
+%
+% Le 17 janvier je me décide de simplifier l'algorithme car l'original ne tenait
+% pas compte de la relation toujours vraie A=B+C dans les matrices symétriques
+% utilisées en sous-main [[A,B],[B,C]].
+%
+% la version ici est celle avec les * omis: car multiplication tacite devant les
+% sous-expressions depuis 1.09j, et aussi devant les parenthèses depuis 1.09k.
+\def\Fibonacci #1{%
+ \expandafter\Fibonacci_a\expandafter
+ {\the\numexpr #1\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro 0\relax}}
+%
+\def\Fibonacci_a #1{%
+ \ifcase #1
+ \expandafter\Fibonacci_end_i
+ \or
+ \expandafter\Fibonacci_end_ii
+ \else
+ \ifodd #1
+ \expandafter\expandafter\expandafter\Fibonacci_b_ii
+ \else
+ \expandafter\expandafter\expandafter\Fibonacci_b_i
+ \fi
+ \fi {#1}%
+}%
+\def\Fibonacci_b_i #1#2#3{\expandafter\Fibonacci_a\expandafter
+ {\the\numexpr #1/2\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro sqr(#2)+sqr(#3)\expandafter\relax\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro (2#2-#3)#3\relax}%
+}% end of Fibonacci_b_i
+\def\Fibonacci_b_ii #1#2#3#4#5{\expandafter\Fibonacci_a\expandafter
+ {\the\numexpr (#1-1)/2\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro sqr(#2)+sqr(#3)\expandafter\relax\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro (2#2-#3)#3\expandafter\relax\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro #2#4+#3#5\expandafter\relax\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro #2#5+#3(#4-#5)\relax}%
+}% end of Fibonacci_b_ii
+\def\Fibonacci_end_i #1#2#3#4#5{\xintthe#5}
+\def\Fibonacci_end_ii #1#2#3#4#5{\xinttheiiexpr #2#5+#3(#4-#5)\relax}
+\catcode`_ 8
+
+\def\Fibo #1.{\Fibonacci {#1}}
+
+\def\specialprintone #1%
+{%
+ \ifx #1\relax \else \makebox[877496sp]{#1}\hskip 0pt plus 2sp\relax
+ \expandafter\specialprintone\fi
+}%
+\def\specialprintnumber #1% first ``fully'' expands its argument.
+{\expandafter\specialprintone \romannumeral-`0#1\relax }%
+
+\AddToShipoutPicture*{%
+ \put(10.5cm,14.85cm)
+ {\makebox(0,0)
+ {\resizebox{17cm}{!}{\vbox
+ {\hsize 8cm\Huge\baselineskip.8\baselineskip\color{black!10}%
+ \specialprintnumber{F(1250)=}%
+ \specialprintnumber{\Fibonacci{1250}}}\par}%
+ }%
+ }%
+}
+
+
+\pdfbookmark[1]{Dependency graph}{DependencyGraph}
+
+
+
+
+\tikzstyle{block} = [rectangle, draw,
+ fill=yellow!10,
+% fill opacity=0.5,
+ draw=black!30,
+ line width=2pt,
+ text width=6em, text centered, rounded corners, minimum height=4em]
+\tikzstyle{line} = [draw, line width=1pt, color=black!30]
+
+\vspace*{\stretch{0.3333}}
+
+\begin{figure}[ht!]
+ \phantomsection\label{dependencygraph}
+\centeredline{%
+\begin{tikzpicture}[node distance = 2.5cm]
+ % Place nodes
+ \node [block] (kernel) {\xintkernelname};
+ \node [left of=kernel] (A) {};
+ \node [right of=kernel] (B) {};
+ \node [block, below right of=B] (core) {\xintcorename};
+ \node [block, below left of=A] (tools) {\xinttoolsname};
+ \node [block, right of=core, xshift=1cm] (bnumexpr) {\href{http://www.ctan.org/pkg/bnumexpr}{bnumexpr}};
+ \node [block, below of=core] (xint) {\xintname};
+ \node [block, left of=xint, xshift=-.5cm] (gcd) {\xintgcdname};
+ \node [block, left of=gcd] (binhex) {\xintbinhexname};
+ \node [block, below of=xint] (frac) {\xintfracname};
+ \node [block, below of=frac, yshift=-.5cm] (expr) {\xintexprname};
+ \node [block, below right of=expr, yshift=-.5cm, xshift=2.25cm] (polexpr) {\href{http://www.ctan.org/pkg/polexpr}{polexpr}};
+ \node [block, below of=expr, yshift=-.5cm] (trig) {\xinttrigname};
+ \node [block, left of=trig] (log) {\xintlogname};
+ \node [block, below right of=frac, xshift=1cm] (series) {\xintseriesname};
+ \node [block, right of=series] (cfrac) {\xintcfracname};
+ % Draw edges
+ \path [line,-{Stealth[length=5mm]}] (kernel) -- (core);
+ \path [line,-{Stealth[length=5mm]}] (kernel) -- (tools);
+ \path [line,-{Stealth[length=5mm]}] (core) -- (bnumexpr);
+ \path [line,-{Stealth[length=5mm]}] (core) to [out=180,in=90] (gcd.north);
+ \path [line,-{Stealth[length=5mm]}] (kernel) -- (binhex);
+ \path [line,-{Stealth[length=5mm]}] (core) -- (xint);
+ \path [line,-{Stealth[length=5mm]}] (xint) -- (frac);
+ \path [line,-{Stealth[length=5mm]}] (frac) -- (expr);
+ \path [line,-{Stealth[length=5mm]}] (expr) -- (polexpr);
+ \path [line,{Stealth[length=5mm]}-{Stealth[length=5mm]}] (expr) -- (trig);
+ \path [line,{Stealth[length=5mm]}-{Stealth[length=5mm]}] (expr) -- (log);
+ \path [line,-{Stealth[length=5mm]}] (expr) -- (polexpr);
+ \path [line,-{Stealth[length=5mm]}] (frac) to [out=0,in=90] (series.north);
+ \path [line,-{Stealth[length=5mm]}] (frac) to [out=0,in=90] (cfrac.north);
+ \path [line,dashed,-{Stealth[length=5mm]}] (binhex.south) -- (expr);
+% at 1.3d gcd() and lcm() needs no support from xintgcd
+% \path [line,dashed,-{Stealth[length=5mm]}] (gcd.south) -- (expr);
+ \path [line,dashed,-{Stealth[length=5mm]}] (tools) to [out=0, in=90]
+ (gcd.north);% je dois positionner mieux mais pas le temps de lire 700 pages
+ \path [line,dashed,-{Stealth[length=5mm]}] (tools.south west) to [out=270, in=225]
+ (cfrac.south west);% je dois positionner mieux mais pas le temps de lire 700 pages
+ \path [line,-{Stealth[length=5mm]}] (tools) to [out=270,in=180] (expr);
+ \end{tikzpicture}}\bigskip
+\end{figure}
+
+\vspace{2\baselineskip}
+
+\begin{addmargin}{2cm}
+\normalfont\footnotesize Dependency graph for the
+ \xintname bundle components: modules pointed to by arrows \textbf{automatically}
+ import the modules originating the continuous line ended by an arrow.
+ Dashed lines
+ indicate a partial dependency, and to enable the corresponding
+ functionalities of the lower module it is thus necessary to use
+ a suitable |\usepackage| (\LaTeX) or |\input| (Plain \TeX.)\par
+
+ \href{http://ctan.org/pkg/bnumexpr}{bnumexpr} is a
+ separate (\LaTeX{} only) package by the author which uses (by default)
+ \xintcorename as its mathematical engine.
+
+ \href{http://ctan.org/pkg/polexpr}{polexpr} is a
+ separate (\LaTeX{} only) package by the author which requires \xintexprname.
+
+ \xinttrigname and \xintlogname are loaded automatically by \xintexprname; they
+ will refuse to be loaded directly (but see \csbxint{reloadxinttrig}).
+\par
+\end{addmargin}
+
+\vfill
+
+\clearpage
+
+\etocdepthtag.toc {description}
+
+\section{Read this first}\RaisedLabel{sec:quickintro}
+
+This section provides recommended reading on first discovering the package.
+
+This is release \expandafter|\xintbndlversion|.
+\begin{enumerate}
+\item \func{log}, \func{exp}, \func{log10}, \func{pow10}, \func{pow} are implemented via
+ \href{http://ctan.org/pkg/poormanlog}{poormanlog}: this achieves only \dtt{8} or \dtt{9}
+ digits of precision.... This situation is provisory, I simply was lacking
+ the time. See \xintlogname.
+\item \func{sin}, \func{cos}, ..., \func{asin}, ... are implemented (using
+ high level user interface), up to about \dtt{60} digits of
+ precision, see \xinttrigname.
+\item |NaN|, |+Infty|, |-Infty|, etc... and a proper internal data structure
+ for storing floating point numbers are \emph{yet to be implemented}.
+\item \xintname can handle numbers with thousands of digits, but execution
+ times (and
+ \hyperref[ssec:memory]{memory considerations}) limit the practical range to
+ perhaps up to a few hundreds digits.
+\item Attention that exact operations with fractions do not reduce to lowest
+ terms (additions and subtractions use |l.c.m.| of denominators), see
+ \func{reduce}.
+\end{enumerate}
+
+
+
+
+\begin{addmargin}{1cm}
+\makeatletter
+\renewenvironment{description}
+ {\list{}{\topsep\baselineskip\partopsep\z@skip
+ \parsep\z@ \labelwidth\z@ \itemindent-\leftmargin
+ \let\makelabel\descriptionlabel}}
+ {\endlist}
+\makeatother
+
+%\noindent\null\par\kern-\baselineskip
+\leavevmode
+
+\begin{description}
+\item[\xinttoolsname] provides utilities of independent interest such as
+ expandable and non-expandable loops. \xintgcdname and \xintcfracname have a
+ partial dependency on it but it must be required by user explicitely.
+ \xintexprname loads it automatically.
+
+\item[\xintcorename] provides expandable macros implementing addition,
+ subtraction, multiplication, division, and power with arbitrarily long
+ numbers. It is loaded automatically by \xintname, and also by \LaTeX\
+ package \href{http://ctan.org/pkg/bnumexpr}{bnumexpr} in its default
+ configuration.
+
+\item[\xintname] extends \xintcorename with additional operations on big
+ integers. It loads automatically \xintcorename.
+
+\item[\xintfracname] extends the scope of \xintname to decimal numbers, to
+ numbers in scientific notation and also to fractions with arbitrarily
+ long such numerators and denominators separated by a forward slash. It loads
+ automatically \xintname.
+
+\item[\xintexprname] extends \xintfracname with expandable parsers doing
+ algebra (either exact, float, or limited to big integers) on comma separated
+ expressions using the standard infix notations and parentheses (or sub
+ \xintexprname-essions). It implements tacit multiplication, functions with
+ one or multiple arguments, Python-like slicing of lists, user-definable
+ variables and user-definable functions, boolean two way or three way
+ branching. Dummy variables can be used for summing or multiplying an
+ expression over a range, or for more complicated iterative evaluations
+ allowing \keyword{omit}, \keyword{abort},
+ and \keyword{break} keywords. It loads automatically
+ \xintfracname (hence \xintname and \xintcorename) and \xinttoolsname.
+ And \xinttrigname and \xintlogname since |1.3e|.
+
+\item[\xinttrigname] trigonometrical functions for \xintexprname,
+ automatically loaded\NewWith{1.3e} by it, can not be used separately.
+
+\item[\xintlogname] logarithm, exponential, power functions for \xintexprname,
+ automatically loaded\NewWith{1.3e} by it, can not be used separately.
+\end{description}
+
+
+Further modules:
+
+\begin{description}
+\item[\xintbinhexname] is for conversions to and from binary and
+ hexadecimal bases. Support in \xintexprname of the \TeX\ |"| prefix for
+ hexadecimal inputs requires this module to be loaded by user.
+
+\item[\xintgcdname] implements the Euclidean algorithm and its typesetting.
+ The macro \csbxint{Irr} (hence the \xintexprname function \func{reduce}) is
+ provided independently in \xintfracname. Also the \xintexprname functions
+ \func{gcd} and \func{lcm} are implemented directly so loading this
+ module is not needed for them (since |1.3d|).
+
+\item[\xintseriesname] provides some basic functionality for computing in an
+ expandable manner partial sums of series and power series with fractional
+ coefficients.
+
+\item[\xintcfracname] is provided to help with the computation and display of
+ continued fractions.
+\end{description}
+\end{addmargin}
+
+\begin{framed}
+All macros from the \xintname packages doing computations are
+\emph{expandable}, and naturally also the parsers provided by \xintexprname.
+
+ The reasonable range of use of the package arithmetics is with numbers of
+ \emph{up to a few hundred digits.}
+ Although numbers up to about \dtt{19950} digits are acceptable
+ inputs, the package is not at his peak efficiency when confronted with such
+ really big numbers having thousands of digits.\footnotemark
+\end{framed}
+
+\footnotetext{The maximal handled size for inputs to multiplication is
+ \dtt{19959} digits. This limit is observed with the current default values
+ of some parameters of the tex executable (input stack size at 5000,
+ maximal expansion depth at 10000). Nesting of macros will reduce it and it
+ is best to restrain numbers to at most \dtt{19900} digits. The output, as
+ naturally is the case with multiplication, may exceed the bound.}
+
+
+
+\subsection{First examples}
+
+With |\usepackage{xintexpr}| if using \LaTeX, or |\input xintexpr.sty\relax|
+for other formats, you can do computations such as the following.
+\begin{description}
+\item[with floats:]\leavevmode\par
+\begin{everbatim*}
+\xintfloateval{3.25^100/3.2^100, 2^1000000, sqrt(1000!)}\newline
+\xintfloateval{[-1] sind(37), cosd(37)}\newline % trim off last digit (via rounding)
+\xintfloateval{[8] log10(12345678), pow10(0.1234)}\newline % only 8 or 9 digits!
+\xintfloateval{[8] pow(2,1/3)}\newline % only 8 or 9 digits!
+\xintfloateval{[8] log(10), exp(1)}\par % only 8 or 9 digits!
+\end{everbatim*}
+ The \csbxint{floateval} macro using braces was introduced at |1.3d|.
+ Formerly, one did:
+\begin{everbatim}
+\thexintfloatexpr 10^-3.5\relax\ or rather \xintthefloatexpr 10^-3.5\relax
+\end{everbatim}
+Most of the manual is couched using the \csbxint{theexpr}|...\relax|
+which is the original one from first release of \xintexprname.
+
+ For powers with fractional exponents, see \hyperref[ssec:poormanloghack]{poormanloghack}.
+\item[with fractions:]\leavevmode\par
+Here is an example using a dummy a variable:
+\begin{everbatim*}
+$\sum_{i=1}^{25} (-1)^{i-1}\frac{1}{i^2} =
+ \xintFrac{\xinteval{reduce(add((-1)^(i-1)/i**2, i=1..25))}}$
+\end{everbatim*}
+\item[with integers:]\leavevmode\par
+\begin{everbatim*}
+\xintiieval{3^159+2^234}\newline
+\xintiieval{lcm(seq(n, n=100..110))}\par
+\end{everbatim*}
+\end{description}
+
+Float computations are done by default with \dtt{16} digits of precision.
+This can be changed via an assignment to |\xintDigits|:
+\begin{everbatim*}
+% use braces (or a LaTeX environment) to limit the scope of the \xintDigits assignment
+{\xintDigits := 88;\xintfloateval{3.25^100-3.2^100}}\par
+\end{everbatim*}
+Trigonometrical function need a reload after modifying the float precision,
+this is done by \csbxint{reloadxinttrig}.
+
+We can even try daring things:\footnote{The \cs{printnumber} is not part of
+ the package, see \autoref{ssec:printnumber}.}
+\begin{everbatim*}
+{\xintDigits:=500;\printnumber{\xintfloateval{sqrt(2)}}}
+\end{everbatim*}
+
+All operations executed by the parsers are based on underlying macros from
+packages \xintfracname and \xintname which are loaded automatically by
+\xintexprname. With \xintbinhexname loaded the
+parsers can handle hexadecimal notation on (even fractional) input.
+
+All macros doing computations ultimately rely on (and reduce to) the
+|\numexpr| primitive from \eTeX{}. These \eTeX{} extensions date back to 1999
+and are by default incorporated into the |pdftex| etc... executables from
+major modern \TeX{} installations since more than ten years now. Only the
+|tex| binary does not benefit from them, as it has to remain the original
+\textsc{D.~Knuth}'s software, but one can then use |etex| on the command line.
+PDF\TeX\ (in pdf or dvi output mode), Lua\TeX, Xe\TeX\ all include the \eTeX\
+extensions.
+
+\subsection{Quick overview (expressions with \xintexprname)}
+
+This section gives a first few examples of using the expression parsers which
+are provided by package \xintexprname. See \autoref{sec:xintexprsyntax} for
+a more detailed description, and perhaps read \autoref{ssec:threeparsers}
+before coming back here.
+
+Loading \xintexprname automatically also
+loads packages \xinttoolsname and \xintfracname. The latter loads \xintname
+which loads \xintcorename. All three provide the macros which ultimately do the
+computations associated in expressions with the various symbols like |+, *, ^,
+!| and functions such as |max, sqrt, gcd|. The package
+\xinttoolsname does not handle computations but provides some useful utilities.
+
+\begin{framed}
+ Release |1.2h| defines |\thexintexpr| as synonym to |\xinttheexpr|,
+ |\thexintfloatexpr| as synonym of |\xintthefloatexpr|, etc...
+\end{framed}
+
+\begin{framed}
+ Release |1.3d| defines \csbxint{eval}, \csbxint{ieval}, \csbxint{iieval},
+ \NewWithf{1.3d}
+ and \csbxint{floateval} which use braces to delimit their arguments, which
+ will be more familiar to \LaTeX\ users than the \csbxint{theexpr}|...\relax|
+ syntax. For example:
+\begin{everbatim*}
+\xinteval{1+2+3}, \xintfloateval{111/123}, \xintfloateval{[3] 111/123}
+\end{everbatim*}
+
+ This documentation however uses systematically |\xinttheexpr...\relax| or
+ |\thexintexpr...\relax| syntax for legacy reasons. In this input syntax the
+ |\relax| does not have to be physically present it may arise from pure
+ expansion (see \autoref{sec:expr}).
+
+ Notice that for the \csbxint{theiexpr} and \csbxint{thefloatexpr} parsers
+ which admit an optional argument, this optional argument will have to be
+ located \emph{inside} the braces when using |\xintieval| or |\xintfloateval|
+ input syntax, as examplified above.
+
+ The main reason is that it is sometimes useful to hide the square brackets, for
+ example when using the |\num| macro from package
+ \href{http://ctan.org/pkg/siunitx}{siunitx}.
+\end{framed}
+
+\begin{framed}
+ The square root extraction \func{sqrt} is allowed in |\xintexpr..\relax| but
+ naturally can't return an \emph{exact} value, it computes as if it was in
+ |\xintfloatexpr..\relax|.
+
+ The synonymous power operators |^| and |**| allow only integral exponents
+ (non-negative in the integer only parser \csbxint{iiexpr}) in \csbxint{expr}
+ and half-integral exponents in \csbxint{floatexpr}. Since |1.3e| fractional
+ powers via the \func{pow} function are available, see
+ \xintlogname.\NewWithf{1.3e} But they achieve currently only about \dtt{8}
+ digits of precision.
+\end{framed}
+
+Here is a (partial) list of the recognized symbols:
+\begin{itemize}
+\item the comma (to separate distinct computations or arguments to a
+ function),
+\item parentheses,
+\item \hyperref[tab:precedences]{operators}:
+ \begin{itemize}[nosep]
+\item |+|, |-|, |*|, |/|,
+\item powers via |^| or equivalently |**|, see \xintlogname for allowing with
+ them fractional exponents,
+\item |//| for floored division and |/:| its associated modulo,
+\item branching via |(x)?{x non zero}{x zero}| and |(x)??{x<0}{x=0}{x>0}|
+ syntax,
+\item boolean logic |!|, |&&| or |'and'|, \verb+||+ or |'or'|,
+\item comparison operators |=| (or |==|), |<|, |>|, |<=|, |>=|, |!=|,
+\item factorial via the post-fix operator |!|.
+ \end{itemize}
+\item the |"| is used to prefix hexadecimal input (uppercase, not lowercase);
+ but package \xintbinhexname must be loaded additionally to \xintexprname),
+%\item |'| for octal input (\emph{not yet}),
+\item various \hyperref[tab:functions]{functions}:
+ \begin{itemize}[nosep]
+ \item rounding and truncating \func{round}, \func{trunc} to a given fixed
+ point precision or with \func{float} to a given floating point precision,
+ \item the square-root \func{sqrt} achieves correct rounding in arbitrary
+ precision,
+ \item the \func{binomial} and (also partial) \func{factorial},
+ \item \func{gcd} and \func{lcm} for general fractional operands,
+ \item randomness related functions such as \func{random} and
+ \func{randrange} for random floats or integers; they require that \TeX\
+ engine provides \csa{pdfuniformdeviate} or \csa{uniformdeviate} primitive,
+ \item trigonometrical functions \xinttrigname,
+ \item logarithm and exponential \xintlogname.
+ \end{itemize}
+\item the capacity to work with dummy variables using functions or generators
+ such as \xintFor #1 in {add, mul, seq, subs, rseq, iter, rrseq, iterr}\do
+ {\func{#1}\xintifForLast{.}{, }}
+\end{itemize}
+See \autoref{xintexpr} for basic information and \autoref{sec:xintexprsyntax}
+for a complete description.
+
+
+The normal mode of operation of the parsers is to unveil the parsed material
+token by token. This means (apart from some exceptions) that all tokens may
+arise from expansion of encountered macros (or active characters). For example
+a closing parenthesis does not have to be immediately visible, it may arise
+later from expansion.
+
+However, this general behaviour has exceptions, in particular constructs with
+dummy variables need at some location immediately visible balanced parentheses
+and commas.
+
+The expansion stops only when the ending |\relax| has been found;
+it is then removed from the token stream, and the final computation result is
+inserted.
+
+Here is an example of a computation:
+\begin{everbatim*}
+\xinttheexpr (31.567^2 - 21.56*52)^3/13.52^5\relax
+\end{everbatim*}\newline
+This illustrates that
+|\xinttheexpr..\relax| does its computations \emph{exactly}. The same example
+as a floating point evaluation:
+\begin{everbatim*}
+\xintthefloatexpr (31.567^2 - 21.56*52)^3/13.52^5\relax
+\end{everbatim*}
+
+Again, all computations done by |\xinttheexpr..\relax| are completely exact.
+Thus, very quickly very big numbers are created (and computation times
+increase, not to say explode if one goes into handling numbers with thousands
+of digits). To compute something like |1.23456789^10000| it is thus better to
+opt for the floating point version:
+\begin{everbatim*}
+\xintthefloatexpr 1.23456789^10000\relax
+\end{everbatim*}
+\newline
+(we can deduce that the exact value has |80000+916=80916| digits).
+A bigger example (the scope of
+the assignment to |\xintDigits| is limited by the braces):
+\begin{everbatim*}
+{\xintDigits:=24; \xintthefloatexpr 1.23456789123456789^123456789\relax }
+\end{everbatim*}
+(<- notice the size of the power of ten: this surely largely exceeds your pocket
+calculator abilities).
+
+Some examples with dummy variables:
+\begin{everbatim*}
+\xinttheiiexpr add(i^5, i=100..200)\relax\par
+\noindent\xinttheexpr add(x/(x+1), x = 1000..1014)\relax\par
+\noindent\xinttheexpr reduce(add(x/(x+1), x = 1000..1014))\relax
+\end{everbatim*}
+\newline In this example, the fraction obtained by addition was thus already
+irreducible, but this is not always the case:
+\begin{framed}
+ By default, the basic operations on fractions are not followed in an
+ automatic manner by reduction to smallest terms: |A/B| multiplied by |C/D|
+ returns |AC/BD|, and |A/B| added to |C/D| uses |lcm(B, D)| as denominator.\CHANGEDf{1.3}
+\end{framed}
+
+Make sure to read \autoref{sec:expr}, \autoref{sec:xintexprsyntax} and
+\autoref{ssec:outputs}.
+
+\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 these macros (not provided by the package:)
+
+%
+\everb|@
+\def\allowsplits #1{\ifx #1\relax \else #1\hskip 0pt plus 1pt\relax
+ \expandafter\allowsplits\fi}%
+\def\printnumber #1{\expandafter\allowsplits \romannumeral-`0#1\relax }%
+% \printnumber thus first ``fully'' expands its argument.
+|
+
+It may be used like this:
+%
+\leftedline{|\printnumber {\xintiiQuo{\xintiiPow {2}{1000}}{\xintiiFac{100}}}|}
+%
+or as |\printnumber\mybiginteger| or |\printnumber{\mybiginteger}| if
+|\mybiginteger| was previously defined via a |\newcommand|, a |\def| or
+an |\edef|.
+
+An alternative is to suitably configure the thousand
+separator with the \href{http://ctan.org/pkg/numprint}{numprint} package
+(see \autoref{fn:np}. This will not allow linebreaks when used in math
+mode; I also tried \href{http://ctan.org/pkg/siunitx}{siunitx} but even
+in text mode could not get it to break numbers accross lines). Recently
+I became aware of the \href{http://ctan.org/pkg/seqsplit}{seqsplit}
+package%
+%
+\footnote{\url{http://ctan.org/pkg/seqsplit}}
+%
+which can be used to achieve this splitting accross lines, and does work
+in inline math mode (however it doesn't allow to separate digits by
+groups of three, for example).\par
+
+\subsection{Randomly chosen examples}
+
+This section is now quite old...
+
+Here are some examples of use of the package macros. The first one uses only
+the base module \xintname, the next one requires the \xintfracname package,
+which deals with decimal numbers, scientific numbers (lowercase \dtt{e}), and
+also fractions (it loads automatically \xintname). Then some examples with
+expressions, which require the \xintexprname package (it loads automatically
+\xintfracname). And finally some examples using \xintseriesname, \xintgcdname
+which are among the extra packages included in the \xintname distribution.
+
+The printing of the outputs will either use a custom |\printnumber| macro as
+described in the previous section, or sometimes the |\np| macro from the
+\href{http://www.ctan.org/pkg/numprint}{numprint} package (see
+\autoref{fn:np}).
+
+\begin{itemize}
+\item {$123456^{99}$: }\\
+|\xintiiPow {123456}{99}|:
+\dtt{\printnumber{\xintiiPow {123456}{99}}}
+
+\item {1234/56789 with 1500 digits after the decimal point: }\\
+|\xintTrunc {1500}{1234/56789}\dots|:
+\dtt{\printnumber {\xintTrunc {1500}{1234/56789}}\dots }
+
+\item {$0.99^{-100}$ with 200 (+1) digits after the decimal point.}\\
+ |\xinttheiexpr [201] .99^-100\relax|:
+ \dtt{\printnumber{\xinttheiexpr [201] .99^-100\relax}}\\
+ Notice that this is rounded, hence we asked |\xinttheiexpr| for one
+ additional digit. To get a truncated result with 200 digits after the decimal
+ mark, we should have issued
+ |\xinttheexpr trunc(.99^-100,200)\relax|, rather.
+
+\begin{snugframed}
+ The fraction |0.99^-100|'s denominator is first evaluated \emph{exactly}
+ (\emph{i.e.} the integer |99^100| is evaluated exactly and then used to
+ divide the suitable power of ten to get the requested digits); for
+ some longer inputs, such as for example |0.7123045678952^-243|, the
+ exact evaluation before truncation would be costly, and it is more efficient
+ to use floating point numbers:
+%
+\leftedline{|\xintDigits:=20;
+ \np{\xintthefloatexpr .7123045678952^-243\relax}|}%
+%
+\leftedline{\xintDigits:=20;\dtt{\np{\xintthefloatexpr .7123045678952^-243\relax }}}
+%
+\xintDigits:=16;%
+%
+Side note: the exponent |-243| didn't have to be put inside parentheses,
+contrarily to what happens with some professional computational
+software. |;-)|
+% 6.342,022,117,488,416,127,3 10^35
+% maple n'aime pas ^-243 il veut les parenthèses, bon et il donne, en Digits
+% = 24: 0.634202211748841612732270 10^36
+\end{snugframed}
+
+\item {$200!$:}\\
+|\xinttheiiexpr 200!\relax|:
+\dtt{\printnumber{\xinttheiiexpr 200!\relax}}
+
+\item {$2000!$ as a float. As \xintexprname does not handle |exp/log| so far,
+ the computation is done internally without the Stirling formula,
+ by repeated multiplications truncated suitably:}\\
+ |\xintDigits:=50;|\newline |\xintthefloatexpr 2000!\relax|:
+ {\xintDigits:=50;\dtt{\printnumber{\xintthefloatexpr 2000!\relax}}}
+
+\item Just to show off (again), let's print 300 digits (after the decimal
+ point) of the decimal expansion of $0.7^{-25}$:%
+%
+\footnote{the |\np| typesetting macro is from the |numprint| package.}
+%
+\begin{everbatim*}
+% % in the preamble:
+% \usepackage[english]{babel}
+% \usepackage[autolanguage,np]{numprint}
+% \npthousandsep{,\hskip 1pt plus .5pt minus .5pt}
+% \usepackage{xintexpr}
+% in the body:
+\np {\xinttheexpr trunc(.7^-25,300)\relax}\dots
+\end{everbatim*}
+
+This computation is with \csbxint{theexpr} from package \xintexprname, which
+allows to use standard infix notations and function names to access the package
+macros, such as here |trunc| which corresponds to the \xintfracname macro
+\csbxint{Trunc}. Regarding this computation, please keep in mind that
+\csbxint{theexpr} computes \emph{exactly} the result before truncating. As
+powers with fractions lead quickly to very big ones, it is good to know that
+\xintexprname also provides \csbxint{thefloatexpr} which does computations
+with floating point numbers.
+
+\item Computation of a Bézout identity with |7^200-3^200| and |2^200-1|:
+(with \xintgcdname)\par
+\begin{everbatim*}
+\xintAssign{\xinttheiiexpr 7^200-3^200\relax}
+ {\xinttheiiexpr 2^200-1\relax}\to\A\B
+\xintAssign\xintBezout{\A}{\B}\to\U\V\D
+\printnumber\U${}\times(7^{200}-3^{200})+{}$\printnumber{\V}%
+${}\times(2^{200}-1)=\D=\xinttheiiexpr \U*\A+\V*\B\relax$
+\end{everbatim*}
+
+\item The Euclide algorithm applied to \np{22206980239027589097} and
+\np{8169486210102119257}: (with \xintgcdname)%
+%
+\footnote {this example is computed tremendously faster than the other
+ ones, but we had to limit the space taken by the output hence picked
+ up rather small big integers as input.}\par
+\noindent\begingroup\parskip0pt\relax
+|\xintTypesetEuclideAlgorithm {22206980239027589097}{8169486210102119257}|\par
+\dtt
+{\xintTypesetEuclideAlgorithm {22206980239027589097}{8169486210102119257}}
+\endgroup
+\smallskip
+
+\item $\sum_{n=1}^{500} (4n^2 - 9)^{-2}$ with each term rounded to twelve digits,
+and the sum to nine digits:
+\begin{everbatim*}
+\def\coeff #1{\xintiRound {12}{1/\xintiiSqr{\the\numexpr 4*#1*#1-9\relax }[0]}}
+\xintRound {9}{\xintiSeries {1}{500}{\coeff}[-12]}
+\end{everbatim*}
+
+The complete series, extended to
+infinity, has value
+$\frac{\pi^2}{144}-\frac1{162}={}$%
+\dtt{\np{0.06236607994583659534684445}\dots}\,%
+%
+\footnote{\label{fn:np}This number is typeset using the
+ \href{http://www.ctan.org/pkg/numprint}{numprint} package, with
+ |\npthousandsep{,\hskip 1pt plus .5pt minus .5pt}|. But the breaking
+ across lines works only in text mode. The number itself was (of
+ course...) computed initially with \xintname, with 30 digits of $\pi$
+ as input. See \hyperref[ssec:Machin]{{how {\xintname} may compute
+ $\pi$ from scratch}}.}
+%
+I also used (this is a lengthier computation
+than the one above) \xintseriesname to evaluate the sum with \np{100000} terms,
+obtaining 16
+correct decimal digits for the complete sum. The
+coefficient macro must be redefined to avoid a |\numexpr| overflow, as
+|\numexpr| inputs must not exceed $2^{31}-1$; my choice
+was:
+\everb|@
+\def\coeff #1%
+{\xintiRound {22}{1/\xintiiSqr{\xintiiMul{\the\numexpr 2*#1-3\relax}
+ {\the\numexpr 2*#1+3\relax}}[0]}}
+|
+
+\restoreMacroFont
+\edef\Temp {\xintFloatPow [24]{2}{999999999}}
+
+\item {Computation of $2^{\np{999999999}}$ with |24| significant
+ figures:}
+%
+\leftedline{|\numprint{\xintFloatPow [24]{2}{999999999}}|}
+\leftedline{\dtt{\numprint{\Temp}}}
+%
+where the \href{http://www.ctan.org/pkg/numprint}{numprint} package was used
+(\autoref{fn:np}), directly in text mode (it can also naturally be used from
+inside math mode). \xintname provides a simple-minded \csbxint{Frac}
+typesetting macro,%
+%
+\footnote{Plain \TeX{} users of \xintname have \csbxint{FwOver}.}
+%
+which is math-mode only:
+%
+\leftedline{|$\xintFrac{\xintFloatPow [24]{2}{999999999}}$|}
+\leftedline{\dtt{$\xintFrac{\Temp}$}}
+%
+The exponent differs, but this is because
+|\xintFrac| does not use a decimal mark in the significand of the output.
+Admittedly most users will have the need of more powerful (and customizable)
+number formatting macros than |\xintFrac|.
+%
+\footnote{There should be a |\xintFloatFrac|, but it is lacking.}
+%
+We have already mentioned
+|\numprint| which is used above, there is also |\num| from package
+\href{http://www.ctan.org/pkg/siunitx}{siunitx}. The raw output from
+%
+\leftedline{\detokenize{\xintFloatPow[24]{2}{999999999}}}
+%
+is $\Temp$.
+
+\edef\x{\xintiiQuo{\xintiiPow {2}{1000}}{\xintiiFac{100}}}
+\edef\y{\xintLen{\x}}
+
+\item As an example of nesting package macros, let us consider the following
+code snippet within a file with filename |myfile.tex|:
+\everb|@
+\newwrite\outstream
+\immediate\openout\outstream \jobname-out\relax
+\immediate\write\outstream {\xintiiQuo{\xintiiPow{2}{1000}}{\xintiiFac{100}}}
+% \immediate\closeout\outstream
+|
+\noindent
+The tex run creates a file |myfile-out.tex|, and then writes to it the
+quotient from the Euclidean division of $2^{1000}$ by $100!$. The number of
+digits is |\xintLen{\xintiiQuo{\xintiiPow{2}{1000}}{\xintiiFac{100}}}| which
+expands (in two steps) and tells us that $[2^{1000}/100!]$ has \dtt{\y}
+digits. This is not so many, let us print them here:
+\dtt{\printnumber\x}.%
+
+\end{itemize}
+
+\subsection {More 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}
+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{License and installation instructions}
+
+\label{ssec:install}
+
+\xintname is made available under the
+\href{http://www.latex-project.org/lppl/lppl-1-3c.txt}{LaTeX Project Public
+ License 1.3c} and is included in the major \TeX\ distributions, thus there
+is probably no need for a custom install: just use the package manager to
+update if necessary \xintname to the latest version available.
+
+The |README| files on \href{http://www.ctan.org/pkg/xint}{CTAN} explain how to
+proceed with a custom installation.
+
+On \TeX\ distributions with a |"texdoc"| or similar utility,
+\centeredline{|texdoc --list xint|}
+will offer to display one of those files:
+\begin{itemize}[nosep]
+\item |xint.pdf| (this file),
+\item |sourcexint.pdf| (source code),
+\item |README|, |README.pdf|, |README.html|,
+\item |CHANGES.pdf|, and |CHANGES.html|.
+\end{itemize}
+
+% For manual installation, follow the instructions from the |README| file which
+% is to be found on \href{http://www.ctan.org/pkg/xint}{CTAN}; it is also
+% available there in PDF and HTML formats. The simplest method proposed is to
+% use the archive file \href{http://www.ctan.org/pkg/xint}{xint.tds.zip},
+% downloadable from the same location.
+
+% The next simplest one is to make use of the |Makefile|, which is also
+% downloadable from
+% \href{http://mirror.ctan.org/macros/generic/xint}{CTAN}. This is
+% for GNU/Linux systems and Mac OS X, and necessitates use of the command
+% line. If for some reason you have |xint.dtx| but no internet access,
+% you can recreate |Makefile| as a file with this name and the following
+% contents:
+
+% {\def\everbatimindent {0pt }%
+% \begin{everbatim}
+% include Makefile.mk
+% Makefile.mk: xint.dtx ; etex xint.dtx
+% \end{everbatim}}
+
+% Then run |make| in a working repertory where there is |xint.dtx| and the file
+% named |Makefile| and having only the two lines above. The |make| will extract
+% the package files from |xint.dtx| and display some further instructions.
+
+% If you have |xint.dtx|, no internet access and can not use the Makefile
+% method: |etex xint.dtx| extracts all files and among them the |README| as a
+% file with name |README.md|. Further help and options will be found therein.
+
+\subsection {Recent changes}
+
+This is release \expandafter|\xintbndlversion| of \expandafter|\xintbndldate|.
+
+For more information see
+|CHANGES.html|.\centeredline{Internet:
+ \url{http://mirrors.ctan.org/macros/generic/xint/CHANGES.html}}
+
+The formatted source code is available in file |sourcexint.pdf|:
+\centeredline{|texdoc sourcexint|}
+
+\noindent|1.3e| (|2019/04/05|):
+\begin{itemize}[nosep]
+\item An \xinttrigname library is automatically loaded by \xintexprname and
+ provides direct and inverse trigonometrical functions using either degrees
+ or radians (up to \dtt{60} digits). It is for the most part implemented
+ using high level user interface, but will probably get some optimizations in
+ future (and perhaps extension to more digits).
+\item An \xintlogname library is loaded automatically; it uses
+ \href{http://ctan.org/pkg/poormanlog}{poormanlog} to provide logarithms and
+ exponentials. Support for more digits is planned for the future: the
+ \href{http://ctan.org/pkg/poormanlog}{poormanlog} support achieves only
+ about \dtt{8} or \dtt{9} digits of precision. On the other hand the
+ functions are fast.
+ Perhaps we will keep the current functions achieving limited precision under
+ some other names in future (they are amply precise enough for plots).
+\item Under the hood refactoring of \csbxint{NewExpr} related matters for
+ support of user-defined functions; fixed bugs related to functions with no
+ variables. Added \csbxint{defefunc}, \csbxint{deffloatefunc},
+ \csbxint{defiiefunc} and documented the ``protected'' nature of the
+ functions defined by the original variants \csbxint{deffunc} et al. This
+ whole area is complex and to be still considered work in progress.
+\item Breaking change: only the \csbxint{expr}|...\relax| syntax is accepted
+ for sub-expressions when doing function definitions via \csbxint{deffunc}
+ and \csbxint{defefunc} et al. One can \textbf{not} use \csbxint{eval},
+ \csbxint{ieval}, \csbxint{floateval} for sub-evaluations inside such
+ definitions (anyway there are not efficient there because the parser will
+ have to recollect the digits of the value whereas \csbxint{expr} keeps some
+ private internal format).
+\item \func{inv}, \func{ilog10}.
+\item \func{sfloat}, slight modification of behaviour of \func{qfloat}.
+\item \csbxint{ensuredummy}, \csbxint{restorelettervar}.
+\item the optional argument of \csbxint{floatexpr} can be negative, it then
+ tells to round the result to a (rounded) float with a precision equal to
+ \csbxint{theDigits} diminished by this argument.
+\end{itemize}
+
+\noindent|1.3d| (|2019/01/06|):
+\begin{itemize}[nosep]
+\item \func{gcd} and \func{lcm} in \csbxint{expr}|...\relax| now handle
+ general arguments, without converting them to integers,
+\item It is not needed anymore to load package \xintgcdname to benefit from
+ \func{gcd} and \func{lcm} in the parsers.
+\item \csbxint{ifsgnexpr}, \csbxint{ifsgnfloatexpr}, \csbxint{ifsgniiexpr}.
+\item \csbxint{unassignexprfunc} and variants for the other parsers.
+\item \func{isone} and \func{isint}.
+\item \csbxint{eval}, \csbxint{ieval}, \csbxint{iieval}, and
+ \csbxint{floateval}. Attention: these names were formerly used with some other
+ (barely documented) meanings, for which |\xintexpro|, |\xintiexpro|,
+ etc... are now used.
+\item Sadly, in \csbxint{iiexpr}|...\relax| division with a zero dividend and
+ a one-digit divisor got broken at |1.2p|. Fixed. Thanks to \textsc{Kpym} for
+ report. Sorry for long delay in releasing the bugfix, which was done shortly
+ after |1.3c| release.
+\end{itemize}
+
+\section{The syntax of \xintexprname expressions}
+\label{sec:xintexprsyntax}
+
+\localtableofcontents
+
+\subsection{The three parsers}\label{ssec:threeparsers}
+
+There are three expression parsers and two subsidiary ones. They
+all admit comma separated expressions, and will then output a comma
+separated list of results.
+\begin{itemize}[nosep]
+\item \csbxint{theiiexpr}| ... \relax| does exact computations \emph{only on
+ integers.} The forward slash \dtt{/} does the \emph{rounded} integer
+ division to match behaviour of |\the\numexpr
+ <int>/<int>\relax|.\footnote{For floored integer division, see the \dtt{//}
+ operator.} There are two square root extractors \func{sqrt} and
+ \func{sqrtr} for truncated and rounded square roots. Scientific notation
+ |6.02e23| is \emph{not} accepted on input, one needs to wrap it as
+ |num(6.02e23)| which will convert to an integer notation
+ \dtt{\printnumber{\xinttheiiexpr num(6.02e23)\relax}}.
+\item \csbxint{thefloatexpr}| ... \relax| does computations with a given
+ precision \dtt{P}, as specified via a prior assignment |\xintDigits:=P;|.
+ The default is \dtt{P=16} digits. An optional argument controls the
+ precision for \emph{formatting the output} (this is not the precision of the
+ computations themselves). The four basic operations and the square root
+ realize \emph{correct rounding.}\footnote{when the inputs are already
+ floating point numbers with at most |P|-digits mantissas.}
+\item \csbxint{theexpr}| ... \relax| handles integers, decimal numbers,
+ numbers in scientific notation and fractions. The algebraic computations are
+ done \emph{exactly.} The \func{sqrt} function is available and obeys
+ either the |\xintDigits| precision or its second optional
+ argument.
+\end{itemize}
+
+Two derived parsers:
+\begin{itemize}[nosep]
+\item \csbxint{theiexpr}| ... \relax| does all computations like |\xinttheexpr
+ ... \relax| but rounds the result to the nearest integer. With an optional
+ positive argument |[D]|, the rounding is to the nearest fixed point number
+ with |D| digits after the decimal mark.
+\item \csbxint{theboolexpr}| ... \relax| does all computations like
+ |\xinttheexpr ... \relax| but converts the result to $1$ if it is not zero
+ (works also on comma separated expressions).
+ See also the booleans \csbxint{ifboolexpr}, \csbxint{ifbooliiexpr},
+ \csbxint{ifboolfloatexpr}, \csbxint{ifsgnexpr}, \csbxint{ifsgniiexpr},
+ \csbxint{ifsgnfloatexpr} (they do not handle comma separated expressions).
+\end{itemize}
+
+Release |1.3d| provides \csbxint{eval}, \csbxint{ieval},
+\NewWith{1.3d}
+\csbxint{iieval}, \csbxint{floateval}.
+
+\subsection{Built-in operators and their precedences}
+
+
+\def\MicroFont{\ttbfamily\makestarlowast\color[named]{DarkOrchid}}
+
+\makeatletter
+\def\@floatboxreset{\@setminipage}% faudra contrôler celui-là
+\makeatother
+\begin{table}[htbp]
+\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 non-operator syntax elements whose parsing
+ is always done prior to executing 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 and the intrinsic constituents of numbers: decimal mark |.|, |e| and |E| of scientific notation, hexadecimal prefix |"|.
+ \end{itemize}\par\kern-\baselineskip\relax}%
+ \\\hline\hline
+ Precedence&``Operators'' at this level\strut\\
+ \hline
+ \prec{$10$}& the factorial (postfix) operator |!| and the conditional branching operators |?| and |??|\strut\\\hline
+ \prec{$=$}& the minus sign |-| as unary operator acquires the
+ precedence level of the previous infix operator\strut\\\hline
+ \prec{$9$}&the power |^|, |**| operators\strut\\\hline
+ \prec{$8$}&the action of tacit multiplication\strut\\\hline
+ \prec{$7$}&the multiplication, division, and modulo operators |*|, |/|,
+ |//|, |/:| (aka |'mod'|)\strut
+ \\\hline
+ \prec{$6$}&the addition and subtraction |+|, |-|\strut\\\hline
+ \prec{$5$}&the comparison operators |<|, |>|, |==|, |<=|, |>=|, |!=|\strut\\\hline
+ \prec{$4$}&Boolean conjunction |&&| and its alias |'and'|\strut\\\hline
+ \prec{$3$}&Boolean disjunction \verb+||+ and |'or'|, and |'xor'|; also the
+ sequence generators |..|, |..[|, |]..|, and the Python slicer |:| have
+ this precedence\strut\\\hline
+ \prec{$2$}& the comma |,|\strut\\\hline
+ \prec{$1$}& the parentheses |(|, |)|, list brackets |[|, |]|, semi-colon |;| in an \func{iter} or
+ \func{rseq}\strut\\\hline\hline
+ \multicolumn{2}{|p{.6\textwidth}|}{%
+ \begin{itemize}[nosep]
+ \item In case of equal precedence, the rule is left-associativity: the first
+encountered operation is executed first.
+\hyperref[ssec:tacit multiplication]{Tacit multiplication} has an elevated
+precedence level hence seemingly breaks left-associativity: |(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.
+ \item List variants |^[|, |**[|, |]^|, |]**|,
+ |*[|, |/[|, |]*|, |]/|, |+[|, |-[|, |]+|, |]-|, share the precedence
+ level of their respective associated operators on numbers.
+ \item There may
+ be some evolution in future, perhaps to distinguish some of the constructs
+ which currently share the same precedence or to make room for added syntax
+ elements.
+ \end{itemize}
+}\\\hline
+ \end{tabular}
+ \caption{Precedence levels}
+ \label{tab:precedences}
+\etoctoccontentsline {table}{\textbf{(table)} \protect\emph{Precedence levels of operators}}
+\restorehtdpstrutbox
+\end{table}
+
+The \autoref{tab:precedences} is hyperlinked to the more detailed discussion
+at each level.
+
+\begin{description}[parsep=0pt,align=left,itemindent=0pt,
+ leftmargin=\leftmarginii, labelwidth=\leftmarginii, labelsep=0pt,
+ labelindent=0pt, listparindent=\leftmarginiii]
+
+\precdesc{\infty} At this highest level of precedence, one finds:
+\begin{itemize}[parsep=0pt,align=left,itemindent=0pt,
+ leftmargin=\leftmarginii, labelwidth=\leftmarginii, labelsep=0pt,
+ labelindent=0pt, listparindent=\leftmarginiii]
+\item \hyperref[ssec:builtinfunctions]{functions} and
+ \hyperref[ssec:uservariables]{variables}:
+ we approximately describe the situation as
+ saying they have highest precedence. Functions (even the logic functions
+ \func{!} and \func{?} whose names consists 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.)
+\item the |.| as decimal mark; the number scanner treats it as
+ an inherent, optional and unique component of a being formed number. One can
+ do things such as
+ %
+ \leftedline{\restoreMicroFont|\xinttheexpr 0.^2+2^.0\relax|}
+ %
+ which is |0^2+2^0| and produces \dtt{\xinttheexpr 0.^2+2^.0\relax}.
+
+ Since release |1.2| an isolated decimal mark |"."| is illegal
+ input in |\xintexpr..\relax|, although it remains legal as argument to the
+ macros of \xintfracname.
+\item the |e| and |E|, for scientific notation are intrinsic constituents of
+ number denotations,
+ like the decimal mark.
+\item the |"| for hexadecimal numbers: it is allowed only at locations where
+ the parser expects to start forming a numeric operand, once encountered it
+ triggers the hexadecimal scanner which looks for successive hexadecimal
+ digits as usual skipping spaces and expanding forward everything; letters
+ (only |ABCDEF|, not |abcdef|), an optional dot
+ (allowed directly in front) and an optional (possibly empty) fractional
+ part. The |"| functionality
+ \fbox{requires to load package \xintbinhexname}.%
+%
+\begin{everbatim*}
+\xinttheexpr "FEDCBA9876543210\relax\newline
+\xinttheiexpr 16^5-("F75DE.0A8B9+"8A21.F5746+16^-5)\relax
+\end{everbatim*}
+\end{itemize}
+
+\precdesc{10} The postfix operators |!| and the branching conditionals |?|, |??|.
+ \begin{description}[parsep=0pt,align=left,itemindent=0pt,
+ leftmargin=\leftmarginii, labelwidth=\leftmarginii, labelsep=0pt,
+ labelindent=0pt, listparindent=\leftmarginiii]
+
+ \item[{\color[named]{DarkOrchid}!}] computes the factorial of an integer.
+ Attention that the boolean equality test |==| must not follow directly
+ such a |<digits or variable>!| because the parser will handle |!=| as the
+ boolean inequality test... the remaining |=| then causes a parsing error.
+ It is even worse if one uses a single |=| following the |!| because no
+ error arises but an un-intended interpretation. Use parentheses:
+ |(3!)==10|.
+
+ \item[{\color[named]{DarkOrchid}?}] 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.}
+
+
+ \item[{\color[named]{DarkOrchid}??}] 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{=} The minus sign |-| as prefix unary operator inherits the
+ precedence of the infix operator it follows. |\xintexpr -3-4*-5^-7\relax|
+ evaluates as |(-3)-(4*(-(5^(-7))))| and |-3^-4*-5-7| as
+ |(-((3^(-4))*(-5)))-7|.
+
+ |2^-10| is perfectly accepted input, no need for parentheses
+
+
+
+ \precdesc{9} The power operator |^|, or equivalently |**|. It is left
+ associative: {\restoreMicroFont|\xinttheiexpr 2^2^3\relax|} evaluates to
+ \xinttheiexpr 2^2^3\relax, not \xinttheiexpr 2^(2^3)\relax. See
+ \csbxint{FloatPower} for additional information.
+
+ Also at this level the list operators |^[|, |**[|, |]^|, and |]**|.
+
+\precdesc{8} see \hyperref[ssec:tacit multiplication]{Tacit multiplication}.
+
+\precdesc{7} Multiplication and division |*|, |/|. The
+ division is left associative, too:
+ %
+ \begingroup\restoreMicroFont
+ %
+ |\xinttheiexpr 100/50/2\relax| evaluates to \xinttheiexpr 100/50/2\relax,
+ not \xinttheiexpr 100/(50/2)\relax.
+ %
+ \endgroup
+
+ Also the floored division |//| and its associated modulo |/:| (equivalently |'mod'|,
+ quotes mandatory).
+
+ Also at this level the list operators |*[|, |/[|, |]*| and |]/|.
+
+ In an \csbxint{iiexpr}-ession, |/| does \emph{rounded} division, to behave
+ like the |/| of |\numexpr|.
+
+ Infix operators all at the same level of precedence are
+ left-associative.\footnote{i.e. the first two operands are operated upon
+ first.}
+ Apply parentheses for disambiguation.
+\begin{everbatim*}
+\xinttheexpr 100000//13, 100000/:13, 100000 'mod' 13, trunc(100000/13,10),
+ trunc(100000/:13/13,10)\relax
+\end{everbatim*}
+
+\precdesc{6} Addition and subtraction |+|, |-|. According to the rule above, |-|
+ is left associative:
+ %
+ \begingroup\restoreMicroFont
+ %
+ |\xinttheiexpr 100-50-2\relax| evaluates to \xinttheiexpr 100-50-2\relax,
+ not \xinttheiexpr 100-(50-2)\relax.
+ %
+ \endgroup
+
+ Also the list operators |+[|, |-[|, |]+|, |]-| are at this precedence level.
+
+\precdesc{5} Comparison operators |<|, |>|, |=| (same as |==|), |<=|, |>=|, |!=| all
+ at the same level of precedence, use parentheses for disambiguation.
+
+\precdesc{4} Conjunction (logical and) |&&| or equivalently
+ |'and'| (quotes mandatory).%
+%
+\footnote{with releases earlier than |1.1|, only single
+ character operators |&| and \verb+|+ were available, because the parser
+ did not handle multi-character operators. Their usage in this rôle is now
+ deprecated,\IMPORTANT{} and they may be assigned some new meaning in the
+ future.}
+
+\precdesc{3} Inclusive disjunction (logical or) \verb+||+
+ and equivalently |'or'| (quotes mandatory).
+
+ Also the |'xor'| operator (quotes mandatory) is at this level.
+
+ Also the list generation operators |..|, |..[|, |]..| are at this level.
+
+ Also the |:| for Python slicing of lists.
+
+\precdesc{2} The comma: {\restoreMicroFont with |\xinttheexpr 2^3,3^4,5^6\relax|
+ one obtains as output \xinttheexpr 2^3,3^4,5^6\relax{}.}\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.}
+
+\precdesc{1} The parentheses. The list outer brackets |[|, |]| share the same
+ functional precedence as parentheses. The semi-colon |;| in an |iter| or
+ |rseq| has the same precedence as a closing parenthesis.\footnote{It is not
+ apt to describle the opening parenthesis as an operator, but the closing
+ parenthesis is more closely like a postfix unary operator. It has lowest
+ precedence because when it is encountered all postponed operations are
+ executed to finalize its operand. The start of this operand was decided by
+ the opening parenthesis.}
+\end{description}
+
+
+\restoreMicroFont
+
+\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}[htbp]
+ \capstart
+ \centering
+\xintAssignArray\xintCSVtoList{!, ?, |`*`|, |`+`|,
+abs, add, all, any, acos, acosd, Arg, Argd, asin, asind, atan, atand,
+atan2, atan2d,
+binomial, bool,
+ceil, cos, cosd, cot, cotd, cotg, csc, cscd,
+divmod, even, exp,
+factorial, first, float, floor, frac, gcd,
+if, ifint, ifone, ifsgn, ilog10, isint, isone, iter, iterr, inv,
+last, lcm, len, log, log10, max, min, mod, mul, not, num, odd,
+pArg, pArgd, pfactorial, pow, pow10, preduce,
+qfloat, qfrac, qint, qrand, qraw, quo,
+random, randrange, reduce, rem, reversed, round, rrseq, rseq,
+sec, secd, seq, sgn, sin, sinc, sind, sqr, sqrt, sqrtr, subs,
+tan, tand, tg, togl, trunc,
+xor}
+\to\Functions
+ \cnta\Functions{0}
+ \cntb\xinttheexpr ceil(\cnta/4)\relax\space
+\newcommand\builtinfunction[1]{\expandafter\expandafter\expandafter\func
+ \expandafter\expandafter\expandafter{\Functions{#1}}}%
+\begin{tabular}{|*{4}{p{2.5cm}|}}
+ \hline
+ \xintFor* #1 in {\xintSeq{1}{\cntb}}\do
+ {\builtinfunction{#1}&
+ \builtinfunction{#1+\cntb}&%
+ \builtinfunction{#1+2*\cntb}&%
+ \ifnumgreater{#1+3*\cntb}{\cnta}
+ {}
+ {\builtinfunction{#1+3*\cntb}}%
+ \\\hline}%
+\end{tabular}
+\caption{Functions (click on names)}\label{tab:functions}
+\etoctoccontentsline {table}{\textbf{(table)} \protect\emph{Functions in expressions}}
+\etocsetnexttocdepth{subsubsection}
+\localtableofcontents
+\end{table}
+
+
+Miscellaneous notes:
+\begin{itemize}[nosep]
+ \item since release |1.3d| \func{gcd}\NewWith{1.3d} and \func{lcm} are extended to apply
+ to fractions too, and they 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 is
+ currently the case for |pdftex|, |(u)ptex|, |luatex|, and will be for
+ |xetex| starting with \TeX Live 2019.\IMPORTANT
+
+ \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.
+\end{itemize}
+
+
+% \begin{description}[parsep=0pt,align=left,
+% leftmargin=0pt, itemindent=0pt,
+% labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt,
+% %! leftmargin+itemindent="labelindent"+labelwidth+labelsep
+% %! leftmargin=labelindent+labelwidth+labelsep* (enumitem)
+% %! Utiliser \mbox{} et non pas \noindent\par pour bon display
+% %! (enfin c'était nécessaire avant chgt dans keys ci-dessus, ai oublié ancien
+% %! attention que listparindent n'est apparemment pas hérité, faut le refaire
+% listparindent=\leftmarginiii]
+\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.\NewWith{1.3b}
+
+ 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*}
+ \pdfsetrandomseed 12345
+ \xintDigits:=37;%
+ \xintthefloatexpr random()\relax\newline
+ \xintthefloatexpr random()\relax\par
+\end{everbatim*}
+
+ \begin{framed}
+ Due to the way \csbxint{expr}|...\relax| are handled (see
+ \autoref{ssec:memory}), Monte-Carlo type simulations using expressions may
+ relatively easily exhaust \TeX{} memory.\IMPORTANT\ If possible use
+ \csbxint{NewFloatExpr} to construct from such expressions involving the
+ \func{random} function macros not creating the memory impact which is
+ described in \autoref{ssec:memory}.
+ \end{framed}
+
+ \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}.%
+ \NewWith{1.3b}
+\begin{everbatim*}
+ % still with 37 digits as prevailing float precision
+ \xintthefloatexpr qrand(), random()\relax\newline
+ \xintDigits:=16;%
+ \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*}
+
+\end{description}
+
+\subsubsection{Functions with a single (numeric) argument}
+
+\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<x<1| as then |num(x)| is
+ zero.
+\begin{everbatim*}
+\xinttheexpr num(3.1415^20), num(1e20)\relax
+\end{everbatim*}
+ The output is an explicit integer with as many zeros are as necessary. Even
+ in float expressions, there will be an intermediate stage where all needed digits
+ are there, but then the integer is immediately reparsed as a float to the target
+ precision, either because some operation applies to it, or from the output
+ routine of \csbxint{floatexpr} if it stood there alone. Hence,
+ inserting something like |num(1e10000)| is costly as it really creates ten
+ thousand zeros, even though later the whole thing becomes a float again. On
+ the other hand naturally |1e10000| without |num()| would be simply parsed as
+ a floating point number and would cause no specific overhead.
+
+ \funcdesc{frac} fractional part.
+ For all numbers |x=num(x)+frac(x)|, and |frac(x)| has the same sign as |x|
+ except when |x| is an integer, as then |frac(x)| vanishes.
+\begin{everbatim*}
+\xintthefloatexpr frac(-355/113), frac(-1129.218921791279)\relax
+\end{everbatim*}
+
+ \funcdesc{reduce} reduces a fraction to smallest terms
+\begin{everbatim*}
+\xinttheexpr reduce(50!/20!/20!/10!)\relax
+\end{everbatim*}
+
+Recall that this is NOT done automatically, for example when adding fractions.
+ \funcdesc{preduce} internally, fractions may have some power of ten part
+ (for example when they got input in scientific notation). This function
+ ignores the decimal part when doing the reduction. See \csbxint{PIrr}.
+\begin{everbatim*}
+\xinttheexpr preduce(10e3/2), reduce(10e3/2)\relax
+\end{everbatim*}
+
+ \funcdesc{abs} absolute value
+ \funcdesc{sgn} sign. See also \csbxint{ifsgnexpr}.
+ \funcdesc{inv} inverse.\NewWith{1.3e}
+ \funcdesc{floor} floor function.
+ \funcdesc{ceil} ceil function.
+ \funcdesc{sqr} square.
+\item[ilog10(x)]\hypertarget{func:ilog10-ii}
+ in |\xintiiexpr| the integer exponent $a$ such that $10^a\leq
+ \mathrm{abs}(x)< 10^{a+1}$;\NewWith{1.3e} returns (this may evolve in future)
+ \dtt{\xintiieval{ilog10(0)}} if $x$ vanishes (i.e. \dtt{0x7fff8000}).
+\begin{everbatim*}
+\xintiieval{ilog10(1), ilog10(-1234567), ilog10(-123456789123456789), ilog10(2**31)}\par
+\end{everbatim*}
+ See \func{ilog10} for the behaviour in \csbxint{expr}-essions.
+ \item[sqrt(x)]\hypertarget{func:sqrt-ii}
+ in |\xintiiexpr|, truncated square root; in |\xintexpr| or
+ |\xintfloatexpr| this is the floating point square root, and there is an
+ optional second argument for the precision. See \func{sqrt}.
+ \funcdesc{sqrtr} available \emph{only} in |\xintiiexpr|, rounded square root.
+ \item[factorial(x)]\hypertarget{func:factorial-ii} factorial function (like the
+ post-fix |!| operator.) When used in |\xintexpr| or
+ |\xintfloatexpr| there is an optional second argument. See \func{factorial}.
+ \funcdesc{?} is the truth value, $1$ if non zero, $0$ if zero. Must use parentheses.
+ \funcdesc{!} is logical not, $0$ if non zero, $1$ if zero. Must use parentheses.
+ \funcdesc{not} logical not.
+ \funcdesc{even} is the evenness of the truncation |num(x)|.
+\begin{everbatim*}
+\xintthefloatexpr [3] seq((x,even(x)), x=-5/2..[1/3]..+5/2)\relax
+\end{everbatim*}
+
+ \funcdesc{odd} is the oddness of the truncation |num(x)|.
+\begin{everbatim*}
+\xintthefloatexpr [3] seq((x,odd(x)), x=-5/2..[1/3]..+5/2)\relax
+\end{everbatim*}
+
+ \funcdesc{isint} evaluates to 1 if |x| is an integer, to 0 if
+ not.\NewWith{1.3d} See \func{ifint}.
+\begin{everbatim*}
+$\xinttheexpr -5/3..[1/3]..+5/3\relax
+\rightarrow \xinttheexpr seq(isint(x), x=-5/3..[1/3]..+5/3)\relax$
+\end{everbatim*}
+
+ \funcdesc{isone} evaluates to 1 if |x| is 1, to 0 if not.\NewWith{1.3d}
+See \func{ifone}.
+\begin{everbatim*}
+$\xintthefloatexpr subs(((x-1)/x, x/x, (x+1)/x), x=2**30)\relax
+\rightarrow
+\xintthefloatexpr seq(isone(y), y=subs(((x-1)/x, x/x, (x+1)/x), x=2**30))\relax$
+\end{everbatim*}
+
+ \funcdesc{qint} belong with \func{qfrac}, \func{qfloat}, \func{qraw} to a
+ special category:
+ \begin{enumerate}[nolistsep]
+ \item They require the closing parenthesis of their argument to be
+ immediately visible, it can not arise from expansion.
+ \item They grab the argument and store it directly; the format must be
+ compatible with what is expected at macro level.
+ \item And in particular the argument can not be a variable, it has to be
+ numerical.
+ \end{enumerate}
+
+ \func{qint} achieves the same result as |num|, but the argument is grabbed
+ as a whole without expansion and handed over to the
+ \csbxint{iNum} macro. The |q| stands for ``quick'', and |qint| is thought
+ out for use in \csbxint{iiexpr}|...\relax| with integers having dozens of
+ digits.
+
+ Testing showed that using |qint()| starts getting advantageous for inputs
+ having more (or \fexpan ding to more) than circa \dtt{20} explicit digits.
+ But for hundreds of digits the input gain becomes a negligible
+ proportion of (for example) the cost of a multiplication.
+
+ Leading signs and then
+ zeroes will be handled appropriately but spaces will not be systematically
+ stripped. They should cause no harm and will be removed as soon as the
+ number is used with one of the basic operators. This input mode \emph{does
+ not accept decimal part or scientific part}.
+\begin{everbatim}
+\def\x{....many many many ... digits}\def\y{....also many many many digits...}
+\xinttheiiexpr qint(\x)*qint(\y)+qint(\y)^2\relax\par
+\end{everbatim}
+
+ \funcdesc{qfrac} does the same as \dtt{qint} excepts that it accepts
+ fractions, decimal numbers, scientific numbers as they are understood by
+ the macros of package \xintfracname. Thus, it is for use in
+ \csbxint{expr}|...\relax|. It is not usable within an
+ |\xintiiexpr|-ession, except if hidden inside functions such as
+ \dtt{round} or \dtt{trunc} which then produce integers acceptable to the
+ integer-only parser. It has nothing to do with |frac| (sigh...).
+
+ \funcdesc{qfloat} does the same as \dtt{qfrac} and then converts to a float
+ with the precision given by the setting of |\xintDigits|. This can be used
+ in \csbxint{expr} to round a fraction as a float with the same result as
+ with the |float()| function (whereas using |\xintfloatexpr A/B\relax|
+ inside \csbxint{expr}|...\relax| would first round |A| and |B| to the
+ target precision); or it can be used inside
+ \csbxint{floatexpr}|...\relax| as a faster alternative to wrapping
+ the fraction in a sub-\csbxint{expr}-ession.
+ For example, the next two computations done with \dtt{16} digits
+ of precision do not give the same result:
+\begin{everbatim*}
+\xintthefloatexpr qfloat(12345678123456785001/12345678123456784999)-0.5\relax\newline
+\xintthefloatexpr 12345678123456785001/12345678123456784999-0.5\relax\newline
+\xintthefloatexpr 1234567812345679/1234567812345678-0.5\relax\newline
+\xintthefloatexpr \xintexpr12345678123456785001/12345678123456784999\relax-0.5\newline
+\end{everbatim*}%
+ because the second is equivalent to the third, whereas the
+ first one is equivalent to the fourth one. Equivalently one can use
+ |qfrac| to the same effect (the subtraction provoking the rounding of its
+ two arguments before further processing.)
+
+ Note that if the input needs no special rounding, the internal form of the
+ output keeps a short mantissa (it does not add padding zeros to make it of
+ length equal to the float precision). For example |qfloat(2[20])| would
+ keep internally the input format.\CHANGED{1.3e}
+\end{description}
+
+\subsubsection{Functions with an alphabetical argument}
+
+\begin{description}
+% [parsep=0pt,align=left,
+% leftmargin=0pt, itemindent=0pt,
+% labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt,
+% listparindent=\leftmarginiii]
+
+\funcdesc[name]{bool}
+ returns
+ $1$ if the \TeX{} conditional |\ifname| would act as |\iftrue| and
+ $0$ otherwise. This works with conditionals defined by |\newif| (in
+ \TeX{} or \LaTeX{}) or with primitive conditionals such as
+ |\ifmmode|. For example:
+ %
+ \leftedline{|\xintifboolexpr{25*4-if(bool(mmode),100,75)}{YES}{NO}|}
+ %
+ will return $\xintifboolexpr{25*4-if(bool(mmode),100,75)}{YES}{NO}$
+ if executed in math mode (the computation is then $100-100=0$) and
+ \xintifboolexpr{25*4-if(bool(mmode),100,75)}{YES}{NO} if not (the
+ \func{if} conditional is described below; the
+ \csbxint{ifboolexpr} test automatically encapsulates its first
+ argument in an |\xintexpr| and follows the first branch if the
+ result is non-zero (see \autoref{xintifboolexpr})).
+
+ The alternative syntax |25*4-\ifmmode100\else75\fi| could have been
+ used here, the usefulness of |bool(name)| lies in the availability
+ in the |\xintexpr| syntax of the logic operators of conjunction
+ |&&|, inclusive disjunction \verb+||+, negation |!| (or |not|), of
+ the multi-operands functions |all|, |any|, |xor|, of the two
+ branching operators |if| and |ifsgn| (see also |?| and |??|), which
+ allow arbitrarily complicated combinations of various |bool(name)|.
+\funcdesc[name]{togl}
+ returns $1$
+ if the \LaTeX{} package \href{http://www.ctan.org/pkg/etoolbox}{etoolbox}%
+ %
+ %
+%
+\footnote{\url{http://www.ctan.org/pkg/etoolbox}}
+ %
+ has been used to define a toggle named |name|, and this toggle is
+ currently set to |true|. Using |togl| in an |\xintexpr..\relax|
+ without having loaded
+ \href{http://www.ctan.org/pkg/etoolbox}{etoolbox} will result in an
+ error from |\iftoggle| being a non-defined macro. If |etoolbox| is
+ loaded but |togl| is used on a name not recognized by |etoolbox|
+ the error message will be of the type ``ERROR: Missing |\endcsname|
+ inserted.'', with further information saying that |\protect| should
+ have not been encountered (this |\protect| comes from the expansion
+ of the non-expandable |etoolbox| error message).
+
+ When |bool| or |togl| is encountered by the |\xintexpr| parser, the
+ argument enclosed in a parenthesis pair is expanded as usual from
+ left to right, token by token, until the closing parenthesis is
+ found, but everything is taken literally, no computations are
+ performed. For example |togl(2+3)| will test the value of a toggle
+ declared to |etoolbox| with name |2+3|, and not |5|. Spaces are
+ gobbled in this process. It is impossible to use |togl| on such
+ names containing spaces, but |\iftoggle{name with spaces}{1}{0}|
+ will work, naturally, as its expansion will pre-empt the
+ |\xintexpr| scanner.
+
+ There isn't in |\xintexpr...| a |test| function available analogous
+ to the |test{\ifsometest}| construct from the |etoolbox| package;
+ but any \emph{expandable} |\ifsometest| can be inserted directly in
+ an |\xintexpr|-ession as |\ifsometest10| (or |\ifsometest{1}{0}|),
+ for example |if(\ifsometest{1}{0},YES,NO)| (see the |if| operator
+ below) works.
+
+ A straight |\ifsometest{YES}{NO}| would do the same more
+ efficiently, the point of |\ifsometest10| is to allow arbitrary
+ boolean combinations using the (described later) \verb+&&+ and
+ \verb+||+ logic operators:
+ \verb+\ifsometest10 && \ifsomeothertest10 || \ifsomethirdtest10+,
+ etc... |YES| or |NO| above stand for material compatible with the
+ |\xintexpr| parser syntax.
+
+ See also \csbxint{ifboolexpr}, in this context.
+\end{description}
+
+\subsubsection{Functions with one mandatory and a second but optional argument}
+
+\begin{description}
+% [parsep=0pt,align=left,
+% leftmargin=0pt, itemindent=0pt,
+% labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt,
+% listparindent=\leftmarginiii]
+
+ \funcdesc[{x[, n]}]{round} Rounds its first argument to a fixed point number, having a
+ number of digits
+ after decimal mark given by the second argument. For example
+ |round(-2^9/3^5,12)=|\dtt{\xinttheexpr round(-2^9/3^5,12)\relax.}
+ \funcdesc[{x[, n]}]{trunc} Truncates its first argument to a fixed point number, having
+ a number of digits
+ after decimal mark given by the second argument. For example
+ |trunc(-2^9/3^5,12)=|\dtt{\xinttheexpr trunc(-2^9/3^5,12)\relax.}
+ \funcdesc[{x[, n]}]{float} Rounds its first argument to a floating point number, with a
+ precision given by the second argument.
+ |float(-2^9/3^5,12)=|\dtt{\xinttheexpr float(-2^9/3^5,12)\relax.}
+
+ % AUCTeX EXTREMEMENT PENIBLE AVEC L'INDENTATION FORCEE SOUS M-q
+
+ Note for this example and the earlier ones that when the surrounding
+ parser is \csbxint{floatexpr}|...\relax| the fraction first argument (here
+ |2^9/3^5|) will already have been computed as floating point number (with
+ numerator and denominator handled separately first), even before the
+ second argument is seen and a fortiori before the |round|, |trunc| or
+ |float| is executed. The general float precision is the one governing
+ these initial steps. To avoid that, use |\xintexpr2^9/3^5\relax| wrapper.
+ Then the rounding or truncation will be applied on the exact fraction.
+
+ \funcdesc[{x[, n]}]{sfloat} It is the same as \func{float},\NewWith{1.3e}
+ but in case of a short (non-fractional) input it gets stored internally
+ without adding zeros to make the mantissa have the \csbxint{theDigits}
+ length. One may wonder then what is the utility of \func{sfloat}? See for
+ an example of use the documentation of \csbxint{deffunc}. Notice however
+ that this is a bit experimental and may evolve in future when \xintname
+ gets a proper internal data structure for floating point numbers. The
+ non-normalized format is useful for multiplication or division, but float
+ additions and subtractions usually convert their arguments to a normalized
+ mantissa.
+
+ \funcdesc[{x[, n]}]{ilog10} If there is an optional argument |n|, returns the (relative) integer $a$ such that $10^a\leq
+ \mathrm{abs}(float(x, n)) < 10^{a+1}$.\NewWith{1.3e} In absence of the
+ optional argument:
+ \begin{itemize}[nosep]
+ \item in \csbxint{expr}, it returns the exponent $a$ such that $10^a\leq
+ \mathrm{abs}(x) < 10^{a+1}$.
+ \item in \csbxint{floatexpr}, the input is first rounded to
+ \csbxint{theDigits} float precision, then the exponent $a$ is evaluated.
+ \end{itemize}
+\begin{everbatim*}
+\xintfloateval{ilog10(99999999/10000000, 8), ilog10(-999999995/100000000, 8),
+ ilog10(-999999995/100000000, 9)}\newline
+\xinteval{ilog10(-999999995/100000000), ilog10(-999999995/100000000, 8)}
+\end{everbatim*}
+
+ If the input vanishes the function outputs
+ \dtt{\xinteval{ilog10(0)}} (i.e. |-0x7fff8000| which is near the
+ minimal TeX number |-0x7fffffff|). This is also subject to change.
+
+ The \hyperlink{func:ilog10-ii}{integer-only} variant for \csbxint{iiexpr}
+ admits no optional argument.
+
+ \funcdesc[{x[, n]}]{sqrt} in \csa{xintexpr}|...\relax| and \csa{xintfloatexpr}|...\relax|
+ it achieves the precision given by the optional second argument. For
+ legacy reasons the |sqrt| function in \csa{xintiiexpr} \emph{truncates}
+ (to an integer), whereas |sqrt| in \csa{xintfloatexpr}|...\relax| (and in
+ \csa{xintexpr}|...\relax| which borrows it) \emph{rounds} (in the sense of
+ floating numbers). There is |sqrtr| in \csa{xintiiexpr} for
+ \emph{rounding} to nearest integer.
+\begin{everbatim*}
+\xinttheexpr sqrt(2,31)\relax\ and \xinttheiiexpr sqrt(num(2e60))\relax
+\end{everbatim*}
+
+ There is an \hyperlink{func:sqrt-ii}{integer only} variant for
+ \csbxint{iiexpr}.
+
+ \funcdesc[{x[, n]}]{factorial} when the second optional argument is made
+ use of inside \csa{xintexpr}|...\relax|, this switches to the use of the
+ float version, rather than the exact one.
+\begin{everbatim*}
+\xinttheexpr factorial (100,32)\relax, {\xintDigits:=32;\xintthefloatexpr
+ factorial (100)\relax}\newline
+\xinttheexpr factorial (50)\relax\newline
+\xinttheexpr factorial (50, 32)\relax
+\end{everbatim*}
+
+ The \hyperlink{func:factorial-ii}{integer only variant} of course has no
+ optional second argument.
+
+ \funcdesc[{A[, B]}]{randrange} when used with a single argument |A| returns a random
+ integer |0 <= x < A|, and when used with two arguments |A| and |B| returns
+ a random integer |A <= x < B|. As in Python it is an «empty range» error
+ in first case if |A| is zero or negative and in second case if |B <= A|.
+ \NewWith{1.3b}
+
+ The function can be used in all three parsers. Of course the size is not
+ limited (but in the float parser, the integer will be rounded if involved
+ in any operation).
+\begin{everbatim*}
+ \pdfsetrandomseed 12345
+ \xinttheiiexpr randrange(10**20)\relax\newline
+ \xinttheiiexpr randrange(1234*10**16, 1235*10**16)\relax\newline
+ \printnumber{\xinttheiiexpr randrange(10**199,10**200)\relax}\par
+\end{everbatim*}
+ For the support macros see \csbxint{RandomDigits}, \csbxint{iiRandRange},
+ \csbxint{iiRandRangeAtoB}. For some details regarding how \xintname
+ uses the engine provided generator of pseudo-random numbers, see
+ \csbxint{UniformDeviate}.
+
+ \end{description}
+
+\subsubsection{Functions with two arguments}
+
+\begin{description}
+% [parsep=0pt,align=left,
+% leftmargin=0pt, itemindent=0pt,
+% labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt,
+% listparindent=\leftmarginiii]
+
+ \funcdesc[f, g]{quo} first truncates the arguments to convert them to integers then
+ computes the Euclidean quotient. Hence it computes an integer.
+ \funcdesc[f, g]{rem} first truncates the arguments to convert them to integers then
+ computes the Euclidean remainder. Hence it computes an integer.
+
+ \funcdesc[f, g]{mod} computes |f - g*floor(f/g)|. Hence its output is a
+ general fraction or floating point number or integer depending on the parser
+ where it is used.
+
+ Prior to |1.2p| it computed |f - g*trunc(f/g)|.
+
+ The |/:| and |'mod'| infix operators are both mapped to the same underlying
+ macro as this |mod(f, g)| function. At |1.3| this macro produces smaller
+ denominators when handling fractions than formerly.\CHANGED{1.3}
+\begin{everbatim*}
+\xinttheexpr mod(11/7,1/13), reduce(((11/7)//(1/13))*1/13+mod(11/7,1/13)),
+mod(11/7,1/13)- (11/7)/:(1/13), (11/7)//(1/13)\relax\newline
+\xintthefloatexpr mod(11/7,1/13)\relax\par
+\end{everbatim*}
+
+ Attention! the precedence rules mean that |29/5 /: 3/5| is handled like
+ |((29/5)/:3)/5|. This is coherent with behaviour of Python language for
+ example:
+\begin{everbatim}
+>>> 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 separated with a comma, 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|.
+\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;%
+\xintthefloatexpr if(12345678//23=537000, 1, 0), 12345678//23\relax\newline
+\xintthefloatexpr if(float(12345678//23)=537000, 1, 0)\relax\par
+\xintDigits := 16;%
+\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 prevailing 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 |x<y| and raises an error if |x<0| (or if
+ |x>99999999|.)
+\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.
+
+ \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 |?| operator.
+
+ \funcdesc[x,yes,no]{ifint} (twofold-way conditional)\mbox{}
+
+ checks if |x| is an integer and in that case chooses the ``yes'' branch.%
+ \NewWith{1.3a}
+ 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.%
+ \NewWith{1.3a}
+ 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 |??|
+ operator.
+
+ \end{description}
+
+\subsubsection{Functions with an arbitrary number of arguments}
+
+ Except for \func{qraw}, this argument may be generated by one or many
+ |a..b| or |a..[d]..b| constructs, separated by commas.
+
+\begin{description}
+% [parsep=0pt,align=left,
+% leftmargin=0pt, itemindent=0pt,
+% labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt,
+% listparindent=\leftmarginiii]
+
+ \funcdesc[a,b,c,...,z]{qraw} is provided for comma separated values. The
+ input must obide by the suitable format depending on the
+ parser:\NewWith{1.3c} strict integers, or raw fractions, or floats in
+ internal (non-documented) notation. Also, avoid spaces around the commas.
+ The usefulness is when some loop generates hundreds of comma separated
+ values. Without \func{qraw}, each new value means a new usage of a
+ |\csname..\endcsname| for storage of the growing list, with potential
+ impact on \TeX{} memory (see \autoref{ssec:memory}). See \func{qint},
+ \func{qfrac}, \func{qfloat}, the difference being that \func{qraw} does
+ no post-processing at all of its input, apart from complete expansion.
+ This allows it to accept comma separated values, as the internal storage
+ also uses commas.
+
+\funcdesc[x, y, ...]{all} inserts a logical |AND| in-between its arguments and evaluates the
+resulting logical assertion (as for all functions, all arguments are
+evaluated, see the |?| operator for ``lazy'' conditional branching; an example
+is to be found in \autoref{ssec:PrimesIV}.)
+\funcdesc[x, y, ...]{any} inserts a logical |OR| in-between its arguments and evaluates the
+resulting logical assertion,
+\funcdesc[x, y, ...]{xor} inserts a logical |XOR| in-between its arguments and evaluates
+the resulting logical assertion,
+\funcdesc[x, y, ...]{|`+`|} adds (left ticks mandatory):
+\begin{everbatim*}
+\xinttheexpr `+`(1,3,19), `+`(1*2,3*4,19*20)\relax
+\end{everbatim*}
+\funcdesc[x, y, ...]{|`*`|} multiplies (left ticks mandatory):
+\begin{everbatim*}
+\xinttheexpr `*`(1,3,19), `*`(1^2,3^2,19^2), `*`(1*2,3*4,19*20)\relax
+\end{everbatim*}
+\funcdesc[x, y, ...]{max} maximum of the (arbitrarily many) arguments,
+
+\funcdesc[x, y, ...]{min} minimum of the (arbitrarily many) arguments,
+
+\funcdesc[x, y, ...]{gcd} computes the positive generator of the fractional
+ideal of rational numbers $x\mathbb Z + y\mathbb Z + ... \subset \mathbb
+Q$.\CHANGED{1.3d} When the inputs are integers it is advantageous to use a sub
+\csbxint{iiexpr}-ession, as the integer-only macro is more efficient than the
+one accepting general fractional inputs. Notice that this may require some
+\func{num} wrapper when using variables, as they may well be in fraction
+format, and \csbxint{iiexpr} accepts only strict integers. Since |1.3d|, this
+function and \func{lcm} are available whether or not package \xintgcdname is
+loaded. Note that like other operations with fractions it does not always
+produce a fraction in irreducible format. This example shows also how to
+reduce an n-uple to its primitive part:
+\begin{everbatim*}
+\xinttheexpr gcd(7/300, 11/150, 13/60)\relax\newline
+$(7/300, 11/150, 13/60)\to
+(\xinttheexpr seq(reduce(x), x = [7/300, 11/150, 13/60]/gcd(7/300, 11/150, 13/60))\relax)$
+\end{everbatim*}
+
+Perhaps a future release will provide a |primpart()| function as built-in
+functionality.
+
+\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$.\CHANGED{1.3d} When the inputs are integers it is
+advantageous to use a sub \csbxint{iiexpr}-ession, as the integer-only macro
+is more efficient than the one accepting general fractional inputs.
+\begin{everbatim*}
+\xinttheexpr lcm(7/300, 11/150, 13/60)\relax
+\end{everbatim*}
+
+\funcdesc[x, y, ...]{first} first item of the list argument:
+\begin{everbatim*}
+\xinttheiiexpr first(last(-7..3), 58, 97..105)\relax
+\end{everbatim*}
+\funcdesc[x, y, ...]{last} last item of the list argument:
+\begin{everbatim*}
+\xinttheiiexpr last(-7..3, 58, first(97..105))\relax
+\end{everbatim*}
+\funcdesc[x, y, ...]{reversed} reverses the order of the comma separated list:
+\begin{everbatim*}
+\xinttheiiexpr first(reversed(123..150)), last(reversed(123..150))\relax
+\end{everbatim*}
+\funcdesc[x, y, ...]{len} computes the number of items in a comma separated
+ list. Earlier syntax was |[a,b,...,z][0]| but since |1.2g| this now returns
+ the first element of the list.
+\begin{everbatim*}
+\xinttheiiexpr len(1..50, 101..150, 1001..1050)\relax
+\end{everbatim*}
+ \end{description}
+
+\subsubsection{Functions requiring dummy variables}
+\hypertarget{ssec:dummies}{}
+
+The ``functions'' \xintFor #1 in {add, mul, seq, subs, rseq, iter, rrseq,
+ iterr} \do {\func{#1}\xintifForLast{}{, }} use delimited macros to
+identify the ``|,<letter>=|'' part.\footnote{In the current implementation any
+ token can be used rather than a |=|. What is looked for is a comma followed
+ by two tokens, the first one will be the |<letter>|.} This is done in a way
+allowing nesting via correctly balanced parentheses. The |<letter>| must not
+have been assigned a value before via \csbxint{defvar}.
+
+This |,<letter>=| must be visible when the parser has finished absorbing the
+function name and the opening parenthesis. For \func{rseq}, \func{iter},
+\func{rrseq} and \func{iterr} this is delayed to after the parser has
+assimilated a starting part delimited by a semi-colon; this mandatory segment
+may be generated entirely by expansion and the |,<letter>=| may appear during
+this expansion.
+
+After |,<letter>=|, the expansion and parsing will generate a list of values
+(for example from an |a..b| specification, there may be multiple ones
+themselves separated by commas). After this step is complete the parser will
+know the values which will be assigned to |<letter>|. The special
+|<letter>=<integer>++| syntax offers a variant not pre-computing the iterated
+over list (which currently must thus proceed by steps of one.)
+
+\func{seq}, \func{rseq}, \func{iter}, \func{rrseq},
+\func{iterr} but not \func{add}, \func{mul}, \func{subs} admit the
+\keyword{omit}, \keyword{abort}, and \keyword{break}|()| keywords. In the case
+of a potentially infinite list generated by the |<integer>++| syntax, use of
+\keyword{abort} or of \keyword{break}|()| is mandatory, naturally.
+
+Dummy variables are necessarily single-character letters, and all lowercase and
+uppercase Latin letters are pre-configured for that usage.
+
+\begin{description}
+% [parsep=0pt,align=left,
+% leftmargin=0pt, itemindent=0pt,
+% labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt,
+% listparindent=\leftmarginiii]
+
+\funcdesc[expr, letter=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|.
+
+|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.
+
+The substituted variable may be a comma separated list (this is impossible
+with |seq| which will always pick one item after the other from a list).
+\begin{everbatim*}
+\xinttheexpr subs([x]^2,x=-123,17,32)\relax
+\end{everbatim*}
+
+See the examples related to the |3x3| determinant in the
+\autoref{xintNewExpr} for an illustration of list substitution.
+
+\funcdesc[expr, letter=values]{add} addition
+\begin{everbatim*}
+\xinttheiiexpr add(x^3,x=1..50), add(x(x+1), x=1,3,19)\relax\newline
+\end{everbatim*}%
+See |`+`| for syntax without a dummy variable.
+
+\funcdesc[expr, letter=values]{mul} multiplication
+\begin{everbatim*}
+\xinttheiiexpr mul(x^2, x=1,3,19), mul(2n+1,n=1..10)\relax\newline
+\end{everbatim*}%
+See |`*`| for syntax without a dummy variable.
+
+\funcdesc[expr, letter=values]{seq} comma separated values generated according to a formula
+\begin{everbatim*}
+\xinttheiiexpr seq(x(x+1)(x+2)(x+3),x=1..10), `*`(seq(3x+2,x=1..10))\relax
+\end{everbatim*}
+\begin{everbatim*}
+\xinttheiiexpr seq(seq(i^2+j^2, i=0..j), j=0..10)\relax
+\end{everbatim*}
+
+\funcdesc[initial value; expr, letter=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*}
+
+\funcdesc[initial value; expr, letter=values]{iter} is exactly like |rseq|, except that it only prints
+ the last iteration. Strangely it was lacking from |1.1| release, or rather
+ what was available from |1.1| to |1.2f| is what is called now \func{iterr}
+ (described below).
+
+\hypertarget{BrentSalamin}{}
+ The new |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:= 91;
+\xintdeffloatfunc BS(a, b, t, p):= (a+b)/2, sqrt(a*b), t-p(a-b)^2, \xintiiexpr 2p\relax;
+\xintthefloatexpr [88] % use 3 guard digits (output value is *rounded*)
+ iter(1, 1/sqrt(2), 1, 1; % initial values
+ ([@][0]-[@][1]<2[-45])? % if a-b is small enough stop iterating and ...
+ {break(([@][0]+[@][1])^2/[@][2])} % ... do final computation,
+ {BS(@)}, % else do iteration via pre-defined (for convenience) function BS.
+ i=1++) % This generates infinite iteration. The i is not used.
+\relax
+\xintDigits:=16;%
+\end{everbatim*}\newline
+ You can try with |\xintDigits:=1001;| and |2[-501]| in place of
+ |\xintDigits:=91;| and |2[-45]|, but don't make a final rounding to only
+ |88| digits of course ... and better wrap the whole thing in |\message| or
+ |\immediate\write128| because it will run in the right margin (about
+ \dtt{7}s on my laptop last time I tried). By the way here is how the |BS|
+ function is defined internally:
+\begin{everbatim}
+ Function BS for \xintfloatexpr parser associated to \XINT_flexpr_userfunc_B
+S with meaning macro:#1#2#3#4->\XINTinFloatDiv {\XINTinFloatAdd {#1}{#2}}{2},\X
+INTinFloatSqrtdigits {\XINTinFloatMul {#1}{#2}},\XINTinFloatSub {#3}{\XINTinFlo
+atMul {#4}{\XINTinFloatPowerH {\XINTinFloatSub {#1}{#2}}{2}}},\xintiiMul {2}{#4
+}
+\end{everbatim}
+
+
+
+\funcdesc[initial values; expr, letter=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
+ the complete list of all initial terms if there are more than one and may
+ thus be a ``list'' object. This is impossible with |rrseq|. This construct
+ is effective for scalar finite order recursions, and may be perhaps a bit
+ more efficient than using the |rseq| syntax with a ``list'' value.
+\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, letter=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*}
+\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 may be placed within the generating expression of a
+\func{seq}, \func{rseq}, \func{iter}, \func{rrseq}, or
+\func{iterr}: :
+\begin{description}
+ \keyworddesc{abort} stop here and now.
+
+ \keyworddesc{omit} omit this value.
+
+ \keyworddesc{break} |break(stuff)| to abort and have |stuff| as last value.
+
+ \keyworddesc{<integer>++} serves to generate a potentially infinite list. In
+ conjunction with an \keyword{abort} or \keyword{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=<integer>++| syntax (any letter is allowed in place of |i|) works only
+in the form |<letter>=<integer>++|, something like |x=10,17,30++| is not
+legal. The |<integer>| 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(i)}{@2+@1}, i=1++)\relax
+\end{everbatim*}
+\end{description}
+
+Some additional examples are to be found in \autoref{ssec:moredummies}.
+
+\subsubsection{Trigonometrical functions}
+
+See \xinttrigname.
+
+\subsubsection{Logarithm, exponential and power functions}
+
+See \xintlogname.
+
+\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}
+ 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 when a division was the last seen operator, as the
+ normal rule for the \xintexprname parsers is left-associativity in case of
+ equal precedence.
+\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{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 truncated division, which
+here for positive arguments is like Euclidean division; in
+|\xintexpr...\relax|, |a/:b| is such that |a = b*(a//b)+a/:b|, with |a//b| the
+algebraic quotient |a/b| truncated to an integer.). 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| bound is
+\xinttheiiexpr subs(iterr(0,1;(@1>N)?{break(i)}{@1+@2},i=1++),N=2^64)\relax{}
+and the previous number was its index.
+\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{\xinttheiiexpr iterr(#1,#1;even(i)?
+ {(@2<=1)?{break(i/2)}{odd(@2)?{3@2+1}{@2//2}}}
+ {(@1>@2)?{@1}{@2}},i=0++)\relax }
+With initial value 1161, the maximal number attained is \syrMax{1161} and that latter
+number is the number of steps which was needed to reach 1.\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{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.
+\begin{everbatim*}
+% definitions
+\xintdefvar Pi:=3.141592653589793238462643;%
+\xintdefvar x_1 := 10;\xintdefvar x_2 := 20;\xintdefvar y@3 := 30;%
+\xintdefiivar List := seq(x(x+1)/2, x=0..10);%
+% usage
+$x_1\cdot x_2\cdot y@3+1=\xinttheiiexpr x_1*x_2*y@3+1\relax$\newline
+$\pi^{100}\approx\xintthefloatexpr Pi^100\relax$\newline
+\xinttheiiexpr List\relax\ contains \xinttheiiexpr [List][7]\relax.\par
+\end{everbatim*}
+
+For catcodes issues (particularly, for the semi-colon used to delimit the
+fetched expression), see the discussion of \csbxint{exprSafeCatcodes}.
+\begin{framed}
+ Both syntaxes |\xintdefvar foo := <expr>;| and |\xintdefvar foo = <expr>;|
+ are accepted.\NewWithf{1.3c}
+\end{framed}
+Spaces in the variable name or around the equal sign are removed and are
+immaterial.
+
+As shown above a variable can be assigned a "list" value.
+Simultaneous assignments are allowed:
+\begin{everbatim*}
+\xintdefvar x1, x2, x3 := 3, 10^2, -1;%
+\xintdefiivar A, B := 1500, 135;%
+\xintloop
+\xintifboolexpr{B}
+ {\xintdefiivar A, B := B, A 'mod' B;\iftrue}
+ {\iffalse}
+\repeat
+The last non zero remainder is \xinttheiiexpr A\relax.
+\end{everbatim*}
+
+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 the variables |x0|, |x1|, \dots, |x10| for future usage.
+
+Legal variable names are composed of letters, digits, |_| and |@| and characters.
+A variable name must start with a letter:
+\begin{itemize}[nosep]
+\item the first character can not be a digit,
+\item and names starting with |@| or |_| are reserved (worldwide,
+ extra-terrestrial locations included if under UNO supervision) by author for
+ internal purposes.
+\end{itemize}
+
+|x_1x| is a licit variable name, as well as |x_1x_| and |x_1x_2| and |x_1x_2y|
+etc... hence tacit multiplication fails in cases like |x_1x_2| with |x_1| and
+|x_2| defined as variables; the parser goes not go to the effort of tracing
+back its steps, and it is too late when it realizes |x_1x_2| isn't a valid
+variable name. An explicit infix |*| operator is needed.
+
+Single letter names |a..z| and |A..Z| are pre-declared by the package for use
+as special type of variables called ``dummy variables''. It is allowed to
+overwrite their original meanings and assign them values. See further
+\csbxint{unassignvar}.
+
+The assignments are done with \csa{xintdefvar}, \csa{xintdefiivar}, or
+\csa{xintdeffloatvar} and the variable value will be computed using respectively
+\csbxint{expr}, \csbxint{iiexpr} or \csbxint{floatexpr}. It can then be used
+in all three parsers if the parser understands the format. Currently this
+means that variables using \csa{xintdefvar} or \csa{xintdeffloatvar} can not
+be used in the \csbxint{iiexpr} parser, and variables defined via
+\csa{xintdefiivar} can be used in all parsers.
+
+When defining a variable with \csa{xintdeffloatvar}, it is important to know
+that the rounding to \csbxint{theDigits} digits of precision happens inside
+\csa{xintfloatexpr} only if an operation is executed. Thus, for a variable
+definition which uses no operations (and \emph{only} for them), the value is
+recorded inside the variable with all its digits preserved. If
+\csbxint{theDigits} changes afterwards, the variable will be rounded to that
+precision in force at time of use.
+\begin{everbatim*}
+\xintdeffloatvar e:=2.7182818284590452353602874713526624977572470936999595749669676;%
+\xinttheexpr e\relax\newline % shows the recorded value
+\xintthefloatexpr e\relax\newline % output rounds
+\xintthefloatexpr 1+e\relax\newline % the rounding was done by addition (trust me...)
+\xintdeffloatvar e:=float(2.7182818284590452353602874713526624977572470936999595749669676);%
+\xinttheexpr e\relax\par % use of float forced immediate rounding
+\end{everbatim*}
+
+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;
+\xintthefloatexpr[16] e, e^1000, e^1000000\relax (e rounded to 24 digits first)\newline
+\xintDigits:=16;
+\xintthefloatexpr e, e^1000, e^1000000\relax (e rounded to 16 digits first)\par
+\end{everbatim*}
+
+With |\xintverbosetrue| the values of the assigned variables will be written
+to the log. For example like this (the line numbers here are artificial):
+
+\begin{everbatim}
+Package xintexpr Info: (on line 2875)
+ Variable "e" defined with value 2718281828459045235360287471352662497757247
+0936999595749669676[-61].
+Package xintexpr Info: (on line 2879)
+ Variable "e" defined with value 2718281828459045[-15].
+Package xintexpr Info: (on line 2886)
+ Variable "e_1" defined with value 9864101/3628800[0].
+Package xintexpr Info: (on line 2887)
+ Variable "e_2" defined with value 2718281801146385[-15].
+Package xintexpr Info: (on line 2889)
+ Variable "e_3" defined with value 6613313319248080001/2432902008176640000[0
+].
+Package xintexpr Info: (on line 2890)
+ Variable "e_4" defined with value 2718281828459046[-15].
+Package xintexpr Info: (on line 2892)
+ Variable "e" defined with value 2718281828459045235360287471352662497757247
+0936999595749669676[-61].
+\end{everbatim}
+
+
+\subsubsection{\csh{xintunassignvar}}
+\label{xintunassignvar}
+
+Variable declarations obey the current scope. To let a (multi-letter) name be
+unknown to (all parsers of) \xintexprname\CHANGED{1.3d} without waiting the
+end of the scope one issues \csa{xintunassignvar}\marg{variable}. Prior to
+|1.3d|, this only redefined the variable to represent the value \dtt{0}.
+
+In the special case of \csa{xintunassignvar}\marg{letter}, the effect is
+different,\IMPORTANT{} as it is synonymous with
+\csbxint{newdummy}\marg{letter}: the (catcode 11) \meta{letter} recovers or
+acquires meaning as a dummy variable in the current scope.
+\begin{everbatim*}
+\xintFor #1 in {e_1, e_2, e_3, e_4, e} \do {\xintunassignvar {#1}}
+% overwriting a dummy letter
+\xintdefvar i := 3;%
+\xinttheiiexpr add(i, i = 1..10)\relax\ ("i" has the fixed value 3)\newline
+\xintunassignvar{i}% back to normal
+\xinttheiiexpr add(i, i = 1..10)\relax\ ("i" is again a dummy variable)\par
+\end{everbatim*}
+
+Under \csbxint{globaldefstrue} regime the effect of \csa{xintunassignvar} is
+global.
+
+\subsubsection{\csh{xintnewdummy}}
+\label{xintnewdummy}
+
+Any catcode 11 character can serve as a dummy variable, via this declaration:
+\begin{everbatim}
+\xintnewdummy{<character>}
+\end{everbatim}
+For example with Xe\TeX\ or Lua\LaTeX\ the following works:
+\begin{everbatim}
+% use a Unicode engine
+\input xintexpr.sty
+\xintnewdummy ξ% or any other letter character !
+\xinttheexpr add(ξ, ξ=1..10)\relax
+\bye
+\end{everbatim}
+Under \csbxint{globaldefstrue} regime the effect of \csa{xintnewdummy} is
+global.
+
+\subsubsection{\csh{xintensuredummy}, \csh{xintrestorelettervar}}
+\label{xintensuredummy}
+\label{xintrestorelettervar}
+
+Use\NewWith{1.3e}
+\begin{everbatim}
+\xintensuredummy{<character>}
+...
+... code using the (catcode 11) character as a dummy variable
+...
+\xintrestorelettervar{<character>}
+\end{everbatim}
+if other parts need the letter as an assigned variable name. For example
+\xinttrigname 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\HOOKLOCALTOC#1#2#3{}
+\etocsetnexttocdepth{subsubsection}\localtableofcontents
+\let\HOOKLOCALTOC\empty
+
+\subsubsection{\csh{xintdeffunc}}
+\label{xintdeffunc}
+
+Since release |1.2c| it is possible to declare functions:
+\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)|.)
+
+
+
+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 variables used in the function signature are single letters
+ (lowercase or uppercase) which have \emph{not} been re-declared via
+ \csbxint{defvar} as assigned variables. The choice of the letters is
+ entirely up to the user and has nil influence on the actual function,
+ naturally.
+\item A function can have at most nine variables.
+\item The mechanism for functions shares a common code base with the one
+ implementing \csbxint{NewExpr}. This means it shares its features and also
+ its \hyperref[sssec:limitations]{limitations}. %
+
+ Most notably,\IMPORTANT{} the |1.3d| \csbxint{eval}, \csbxint{ieval},
+ \csbxint{floateval} can not be used inside the parsed
+ expression: only the lower level syntax
+ \csbxint{expr}|...\relax| et al. is accepted (and not
+ \csbxint{theexpr} et al.\CHANGED{1.3e} which are about the same as \csbxint{eval} et al.).
+ Prior to |1.3e| \csbxint{NewExpr} and \csbxint{deffunc} diverged on that
+ point, but their behaviour is now identical.
+\item In order to allow recursive constructs, a core mechanism is implemented
+ which inhibits immediate expansion in a new definition; think of
+ \csbxint{deffunc} as being
+ analogous to a |\protected\edef|. This means that another function
+ |bar(x,..)| whose definition uses |foo(17.5)| will only store that it should
+ at some point compute
+ |foo(17.5)|, in place of storing its actual value.
+\item If |foo(x)| definition is not recursive, then you should use
+ \csbxint{defefunc} rather. This is analogous to an |\edef| without the
+ |\protected|.\NewWith{1.3e} Then |bar(x,...)| (defined with
+ \csbxint{deffunc} or \csbxint{defefunc}) will store the actual
+ evaluation of |foo(17.5)|.
+\item If |foo(x)| definition does need recursivity and you want to use
+ efficiently |foo(17.5)| in another function definition, assign it to a
+ variable (see \csbxint{defvar}) and use that variable rather in the
+ definition of |bar()|. Notice that only the variable value, not its name,
+ gets stored, so the variable name is a temporary auxiliary. In the analogy
+ with TeX macros one can think of \csbxint{defvar} or \csbxint{eval} as
+ producing expansion like typesetting does, whereas \csbxint{deffunc} is like
+ a
+ |\protected\edef|, and \csbxint{defefunc} an |\edef| not making the defined
+ function |\protected|.
+\item A function declared via \csbxint{deffunc} remains 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 like this:\NewWith{1.3e}
+\begin{everbatim}
+\xintdeffloatfunc foo(x) := float(\xintexpr foo(x)\relax);
+\end{everbatim}
+ The \func{float} wrapper is in order for the float variant to produce an
+ already-rounded value, possibly speeding-up usage if used as input for other
+ functions. 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 |float(x)| above is not mandatory but recommended. The macro associated
+ to the user float function |bar(x)| may use many times its argument |x| and
+ it does not care to round it, because it basically expect an already rounded
+ value; 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.
+\item If the expression uses an \func{iterr}, \func{rseq}, or \func{rrseq}) it
+ must hide its |;| inside braces to let it not be confused with the ending
+ |;|.
+\item \csbxint{deffunc} tries to set the catcode of |;| before fetching the
+ expression as a delimited parameter, but this is too late if the whole thing
+ was already fetched as argument to some macro. On the other hand the
+ (reasonable) catcode of the |:| does not matter at all, actually this colon
+ before the equality sign is optional.
+\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
+|\xintverbosetrue|. Here it is:
+\begin{everbatim}
+ Function e for \xintexpr parser associated to \XINT_expr_userfunc_e with me
+aning macro:#1->\xintAdd {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xi
+ntDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\x
+intAdd {\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 main problem is that dummy variables in the defining expression are usable
+only to the extent that their values are numerical. For example
+%
+\centeredline{|\xintdeffunc f(x):=add(i^2,i=1..x);|}
+%
+ is not currently possible. See \autoref{sssec:limitations} and the next
+ subsection.
+
+% In this example one could use the alternative syntax with list
+% operations:%
+% %
+% \footnote{It turns out |`+`(seq(i^2, i=1..x))| would work here, but this isn't
+% always the case with |seq| constructs.}
+% %! par exemple \xintdeffunc g(a,b,c):=seq(x+a+b,x=1..c);
+% %! donne une erreur avec g(0,0,2). Mardi 08 mars 2016 à 09:12:43.
+% \begin{everbatim*}
+% \xintdeffunc f(x):=`+`([1..x]^2);\xinttheexpr seq(f(x), x=1..20)\relax
+% \end{everbatim*}
+
+% Side remark: as the |seq(f(x), x=1..10)| does many times the same
+% computations, an |rseq| here would be more efficient:\footnote{Note that
+% |omit| and |abort| are not usable in |add| or |mul| (currently).}
+% \begin{everbatim*}
+% \xinttheexpr rseq(1; (x>20)?{abort}{@+x^2}, x=2++)\relax
+% \end{everbatim*}
+
+On the other hand a construct like the following has no issue, as the values
+iterated over do not depend upon the function parameters:
+\begin{everbatim*}
+\xintdeffunc f(x):=iter(1{;} @*x/i+1, i=10..1);% one must hide the first semi-colon !
+\xinttheexpr e(1), f(1)\relax
+\end{everbatim*}
+
+
+Another problem is with trying to do |g(f(x))| where |g()| expects two
+arguments and |f()| was defined to output two comma separated values. This
+works fine numerically but not with a variable |x| inside the definition of
+another function.
+
+See \autoref{sssec:csv} for more about comma separated values in output and
+input.
+
+\subsubsection{\csh{xintdefiifunc}}
+\label{xintdefiifunc}
+
+With \csbxint{deffunc} the created function is known by the \csbxint{expr}
+parser only.
+ Cryptic error messages will signal failures of using with another parser a
+ function declared for one parser (particularly if the name is a single
+ letter, because the parser will have made an attempt to use the letter as a
+ dummy variable.)
+
+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}. See \csbxint{deffunc} for more information on this
+point.
+
+
+\subsubsection{Some examples of recursive definitions}
+\label{sssec:recursive}
+
+Since |1.3|, it is possible to make recursive definitions. Here
+are two examples:
+\begin{everbatim*}
+\xintdeffunc GCD(a,b):=if(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*}
+
+But there is already a built-in \func{gcd} (which
+accepts arbitrarily many arguments):
+\begin{everbatim*}
+\xinttheexpr gcd(385/102, 605/238)\relax
+\end{everbatim*}
+
+Since |1.3d| the built-in \func{gcd} accepts inputs being fractions and
+produces the positive generator of the corresponding fractional ideal. And
+loading of \xintgcdname is not needed for this function to be available.\NewWith{1.3d}
+
+Our second example is modular exponentiation:
+\begin{everbatim*}
+\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);
+\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| behaves
+the same), but zealous users will add the necessary code for negative
+exponents, after having defined another function for modular inverse!
+
+It is mandatory for such definitions to use the \func{if} function, and not
+the |(x)?{A}{B}| construct which much choose a branch. The parsing of the
+\func{if} function keeps the memory of the two alternative branches; to the
+contrary, the \emph{constructed} |powmod| function will expand \emph{only} the
+then relevant branch. This is of course absolutely needed for things such as
+the Euclide algorithm where it would be catastrophic to evaluate both branches
+as the first one involves a division by |b| and the algorithm stops only when
+|b| is actually zero.
+
+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...
+
+\subsubsection{\csh{xintdefefunc}}
+\label{xintdefefunc}
+
+Think of former described variant \csbxint{deffunc} as doing the same as this
+\csbxint{defefunc}\NewWith{1.3e} but with an extra protection added to the
+defined function. If you don't need recursivity, \csbxint{defefunc} is the
+better tool, as numerical evaluation involving it and arising in further
+definitions will be converted on the spot to actual values, rather than being
+delayed for expansion to actual use of the defined function in \csbxint{eval}
+or \csbxint{ieval}.
+
+\subsubsection{\csh{xintdeffloatefunc}}
+\label{xintdeffloatefunc}
+
+The ``unprotected'' variant of \csbxint{deffloatfunc}.\NewWith{1.3e}
+
+\subsubsection{\csh{xintdefiiefunc}}
+\label{xintdefiiefunc}
+
+The ``unprotected'' variant of \csbxint{defiifunc}.\NewWith{1.3e}
+
+
+\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*}
+
+% N.B.: we have declared in this section |f| and |g| as functions. They remain
+% usable as dummy variables, but tacit multiplication in front of parentheses is
+% dropped, in order for their function meanings to prevail.
+
+% \begin{everbatim*}
+% \xintdeffunc f(x):=x^2;
+% \xinttheexpr seq(f(f+f), f= 1..10)\relax\newline % f is used both as function and dummy variable
+% \xinttheexpr seq(f*(f+f), f= 1..10)\relax % f is used as dummy variable
+% \xintunassignexprfunc{f}\newline % drop meaning as function
+% \xinttheexpr seq(f(f+f), f= 1..10)\relax % f as dummy variable, tacit multiplication applies
+% \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}.\NewWith{1.3d}
+\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 {\xintSu
+b {\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}
+and the declaration |\xintdeffunc f(x):=iter(1{;} @*x/i+1, i=10..1);| generates:
+\begin{everbatim}
+ Function f for \xintexpr parser associated to \XINT_expr_userfunc_f with me
+aning macro:#1->\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xi
+ntAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\x
+intMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\
+xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {
+1}{#1}}{10/1[0]}}{1}}{#1}}{9/1[0]}}{1}}{#1}}{8/1[0]}}{1}}{#1}}{7/1[0]}}{1}}{#1}
+}{6/1[0]}}{1}}{#1}}{5/1[0]}}{1}}{#1}}{4/1[0]}}{1}}{#1}}{3/1[0]}}{1}}{#1}}{2/1[0
+]}}{1}}{#1}}{1/1[0]}}{1}
+\end{everbatim}
+
+Starting with |1.2d| the definitions made by \csbxint{NewExpr} have local
+scope, hence this is also the case with the definitions made by
+\csbxint{deffunc}. See also \csb{ifxintglobaldefs} conditional.
+
+\subsubsection{\csh{ifxintglobaldefs} conditional}
+\label{xintglobaldefstrue}
+\label{xintglobaldefsfalse}
+\label{ifxintglobaldefs}
+
+If true user defined variables (\csbxint{defvar}, ...) and functions
+(\csbxint{deffunc}, ...) for the expression parsers,\NewWith{1.3c} as well as
+macros obtained via \csbxint{NewExpr} et al have global scope. If false
+(default) they have local scope.
+
+\subsubsection{Functions expanding to comma separated values}
+\label{sssec:csv}
+
+It is possible to define functions which expand to comma-separated values, for
+example the declarations:
+\begin{everbatim*}
+\xintdeffunc f(x):= x, x^2, x^3, x^x;
+\xintdeffunc g(x):= x^[0..x];% x^[1, 2, 3, x] would be like f above.
+\end{everbatim*}
+will generate
+\begin{everbatim}
+ Function f for \xintexpr parser associated to \XINT_expr_userfunc_f with me
+aning macro:#1->#1,\xintPow {#1}{2},\xintPow {#1}{3},\xintPow {#1}{#1}
+
+ Function g for \xintexpr parser associated to \XINT_expr_userfunc_g with me
+aning macro:#1->\xintApply::csv {\xintPow {#1}}{\xintSeq::csv {0}{#1}}
+\end{everbatim}
+and we can check that they work:
+\begin{everbatim*}
+\xinttheexpr f(10)\relax; \xinttheexpr g(10)\relax
+\end{everbatim*}
+
+However please consider this as WIP. They are some known (or half-known,
+because the author gets a headache whenever he reconsiders the whole thing)
+thorny issues, mostly related to the fact that \xintexprname has no proper
+variable type for lists. See \autoref{ssec:lists}.
+
+Here is another aspect: the documentation of release |1.3c| included this paragraph:
+
+\begin{quote}
+ It is possible to define functions of variables which stand for lists (see
+ \autoref{ssec:lists}), or functions defining lists of comma separated items.
+ For example the scalar product and cross product of 3-dimensional vectors
+ can be defined this way:
+\end{quote}
+\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);
+\end{everbatim*}
+
+But it should be added promptly that due to absence to typed variables of type
+list (see \autoref{ssec:lists}), usage of the above is very subtle: although
+it is possible to define variables |U|, |V|, |W| expanding to three components
+each it is impossible to use them with |Det3(U, V, W)| because \csbxint{expr}
+will convert |U, V, W| to a comma separated list of \dtt{9} numbers, and
+|Det3| was defined as a function of only \dtt{3} things.
+
+The only way (currently) is to define |U|, |V|, |W| as \emph{functions}
+(possibly of no variable), then to define a new \emph{function} |Z = Det3(U, V,
+W)|, and finally to evaluate |Z| with no argument:
+\begin{everbatim*}
+\xintdeffunc V() := 1, 1, 1;
+\xintdeffunc W() := 1, 5, 25;
+\xintdeffunc Y() := 1, 10, 100;
+\xintdeffunc Z() := Det3(V(), W(), Y());
+% \xinteval{Det3(V(), W(), Y())} does NOT work, one must go via Z()
+\xinteval{Z()}
+\end{everbatim*}
+
+It is better for pure numerics to define the |Det3()| initially as a function
+of \dtt{9} variables. But the above works well if one really wants to work
+with variables:
+\begin{everbatim*}
+\xintdeffunc V(x) := 1, x, x^2;
+\xintdeffunc Z(x,y,z) := Det3(V(x), V(y), V(z));
+\xinteval{Z(1, 5, 10)}
+\end{everbatim*}
+
+This can be combined with usage of my other package
+\href{http://ctan.org/pkg/polexpr}{polexpr}. I thank Thomas \textsc{Söll} who
+explored precisely that during 2018.
+
+To tell the whole truth,\CHANGED{1.3e} until |1.3e| the above worked
+\emph{only} with at least one variable, the syntax with no variables had a
+bug.
+
+Cleaning up:
+\begin{everbatim*}
+\xintunassignexprfunc{g}
+\xintunassignexprfunc{V}
+\xintunassignexprfunc{W}
+\xintunassignexprfunc{Y}
+\xintunassignexprfunc{Z}
+\xintunassignexprfunc{dprod}\xintunassignexprfunc{cprod}\xintunassignexprfunc{Det3}
+\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;\xintthefloatexpr Rump(77617,33096)#\cr
+\xintiloop [8+1]
+\xintiloopindex &\relax\CR
+\ifnum\xintiloopindex<40 \repeat
+}
+\end{everbatim*}
+
+\subsubsection{\csh{xintNewFunction}}
+\label{xintNewFunction}
+
+The syntax is analogous to the one of \csbxint{NewExpr} but achieves something
+\emph{completely different} from
+\csbxint{NewExpr}/\csbxint{deffunc}. Here is an example:
+\begin{everbatim*}
+\xintNewFunction {foo}[3]{add(mul(x+i, i=#1..#2),x=1..#3)}
+\end{everbatim*}
+\begin{framed}
+ We now have a genuine function |foo( , , )| of three variables which we can
+ use fully in \emph{all three parsers}, be it with numerical arguments or
+ variables or whatever.
+\end{framed}
+\begin{everbatim*}
+\xinttheexpr seq(foo(0, 3, j), j= 1..10)\relax
+\end{everbatim*}
+See \autoref{ssec:PrimesIV} for some additional examples.
+
+This construct is only syntactic sugar to benefit from functional notation.
+Each time the created «function-macro» |foo()| will be encountered the
+corresponding expression 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).
+\begin{everbatim}
+ Function foo for the expression parsers is associated to \XINT_expr_macrofu
+nc_foo with meaning macro:#1#2#3->add(mul(x+i, i=\XINT_expr_wrapit {#1}..\XINT_
+expr_wrapit {#2}),x=1..\XINT_expr_wrapit {#3})
+\end{everbatim}
+Thus, this works with quite arbitrary constructs, contrarily to the mechanism
+of |\xintdeffunc|. It is not currently possible to define a |foo| function
+like the one above via |\xintdeffunc|.%
+%
+\footnote{Or rather, it turns out that no error is raised on making the
+ definition via \csbxint{deffunc} but the created supporting macro is only
+ garbage and raises errors on use.}
+
+One can declare a function |foo| with |[0]| arguments: it may be used
+as |foo()| or |foo(nil)| (prior to |1.3b| only the latter was accepted).\CHANGED{1.3b}
+
+\subsection{List operations}
+\label{ssec:lists}
+
+By \emph{list} we hereby mean simply comma-separated values, for example |3,
+-7, 1e5|. This section describes some syntax which allows to manipulate such
+lists, for example |[3, -7, 1e5][1]| extracts |-7| (we follow the Python
+convention of enumerating starting at zero.)
+
+In the context of dummy variables, lists can be used in substitutions:
+\begin{everbatim*}
+\xinttheiiexpr subs(`+`(L), L = 1, 3, 5, 7, 9)\relax\newline
+\end{everbatim*}
+and also the |rseq| and |iter| constructs allow |@| to refer to a list:
+\begin{everbatim*}
+\xinttheiiexpr iter(0, 1; ([@][1], [@][0]+[@][1]), i=1..10)\relax\newline
+\end{everbatim*}
+where each step constructs a new list with two entries.
+
+However, despite appearances there is not really internally a notion of a
+\emph{list type} and it is currently impossible to create,
+manipulate, or return on output a \emph{list of lists}. There is a special
+reserved variable |nil| which stands for the empty list.
+
+The syntax which is explained next includes in particular what are called
+\emph{list itemwise operators} such as:
+\begin{everbatim*}
+\xinttheiiexpr 37+[13,100,1000]\relax\newline
+\end{everbatim*}%
+This part of the syntax is considered provisory, for the reason that its
+presence might make more difficult some extensions in the future. On the other
+hand the Python-like slicing syntax should not change.
+
+
+\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*}
+\xinttheexpr 1.5+0.4..2.3+1.1\relax; \xinttheexpr 1.9..3.4\relax; \xinttheexpr 2..3\relax
+\end{everbatim*}
+
+ \item |a..[d]..b| allows to generate big integers, or also fractions, it
+ proceeds with step (non necessarily integral nor positive) |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*}
+\xinttheexpr 1.5..[1.01]..11.23\relax
+\end{everbatim*}
+
+ \item |[list][n]| extracts the |n+1|th element if |n>=0|. If
+ |n<0| it extracts from the tail. List items are numbered (since |1.2g|) as
+ in Python, the first element corresponding to |n=0|.
+ |len(list)| computes the number of items of the list.
+\begin{everbatim*}
+\xinttheiexpr \empty[0..10][6], len(0..10), [0..10][-1], [0..10][23*18-22*19]\relax\
+(and 23*18-22*19 has value \the\numexpr 23*18-22*19\relax).
+\end{everbatim*}
+
+See the next frame for why the example above has |\empty| token at start.
+
+As shown, it is perfectly legal to do operations in the index parameter, which
+will be handled by the parser as everything else. The same remark applies to
+the next items.
+
+ \item |[list][:n]| extracts the first |n| elements if |n>0|, or suppresses
+ the last \verb+|n|+ elements if |n<0|.
+\begin{everbatim*}
+\xinttheiiexpr [0..10][:6]\relax\ and \xinttheiiexpr [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*}
+\xinttheiiexpr [0..10][6:]\relax\ and \xinttheiiexpr [0..10][-6:]\relax
+\end{everbatim*}
+\item More generally, |[list][a:b]| works according to the Python ``slicing''
+ rules (inclusive of negative indices). Notice though that there is no
+ optional third argument for the step, which always defaults to |+1|.
+\begin{everbatim*}
+\xinttheiiexpr [1..20][6:13]\relax\ = \xinttheiiexpr [1..20][6-20:13-20]\relax
+\end{everbatim*}
+\item It is naturally possible to nest these things:
+\begin{everbatim*}
+\xinttheexpr [[1..50][13:37]][10:-10]\relax
+\end{everbatim*}
+\item itemwise operations either on the left or the right are possible:
+\begin{everbatim*}
+\xinttheiiexpr 123*[1..10]^2\relax
+\end{everbatim*}
+
+\begin{snugframed}
+ List operations are implemented using square brackets, but the |\xintiexpr|
+ and |\xintfloatexpr| parsers also check to see if an optional parameter
+ within brackets is specified before the start of the expression. To avoid the
+ resulting confusion if this |[| actually serves to delimit
+ comma separated values for list operations, one can either:\IMPORTANT{}
+ \begin{itemize}
+ \item insert something before the bracket such as |\empty| token,
+\begin{everbatim*}
+\xinttheiexpr \empty [1,3,6,99,100,200][2:4]\relax
+\end{everbatim*}
+ \item use parentheses:
+\begin{everbatim*}
+\xinttheiexpr ([1,3,6,99,100,200][2:4])\relax
+\end{everbatim*}
+ \end{itemize}
+
+
+ Notice though that |([1,3,6,99,100,200])[2:4]| would not work: it is
+ mandatory for |][| and |][:| not to be interspersed with parentheses. Spaces
+ are perfectly legal:
+\begin{everbatim*}
+\xinttheiexpr \empty[1..10 ] [ : 7 ]\relax
+\end{everbatim*}
+
+Similarly all the |+[|, |*[|, \dots and |]**|, |]/|, \dots operators admit
+spaces but nothing else between their constituent characters.
+\begin{everbatim*}
+\xinttheiexpr \empty [ 1 . . 1 0 ] * * 1 1 \relax
+\end{everbatim*}
+\end{snugframed}
+
+In an other vein, the parser will be confused by |1..[a,b,c][1]|, and one must
+write |1..([a,b,c][1])|. And things such as |[100,300,500,700][2]//11| or
+|[100,300,500,700][2]/11| are syntax errors and one must use parentheses, as
+in |([100,300,500,700][2])/11|.
+
+\end{itemize}
+
+
+
+\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 needs |\xintthe| prefix to be printed on the page, or be used in
+ macros (expanding their argument.) The |\the| \TeX\ primitive prefix would
+ not work here.
+\item (ctd.) As a synonym to |\xintthe\xintiiexpr| one can use |\xinttheiiexpr|,
+ or (since |1.2h|) |\thexintiiexpr|.
+\item (ctd.) One can embed a |\numexpr...\relax| (with its |\relax|!) inside an
+ |\xintiiexpr...\relax| without |\the| or |\number|, but the reverse situation
+ requires use of |\xintthe|.
+\item |\numexpr -(1)\relax| is illegal. But |\xintiiexpr -(1)\relax| is
+ perfectly legal and gives the expected result (what else ?).
+\item |\numexpr 2\cnta\relax| is illegal (with |\cnta| a |\count| register.) But
+ |\xintiiexpr 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.
+
+For example, here is the code employed
+on the title page to compute (expandably, of course!) the 1250th Fibonacci
+number:
+
+\begin{everbatim*}
+\catcode`_ 11
+\def\Fibonacci #1{% \Fibonacci{N} computes F(N) with F(0)=0, F(1)=1.
+ \expandafter\Fibonacci_a\expandafter
+ {\the\numexpr #1\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro 0\relax}}
+%
+\def\Fibonacci_a #1{%
+ \ifcase #1
+ \expandafter\Fibonacci_end_i
+ \or
+ \expandafter\Fibonacci_end_ii
+ \else
+ \ifodd #1
+ \expandafter\expandafter\expandafter\Fibonacci_b_ii
+ \else
+ \expandafter\expandafter\expandafter\Fibonacci_b_i
+ \fi
+ \fi {#1}%
+}% * signs are omitted from the next macros, tacit multiplications
+\def\Fibonacci_b_i #1#2#3{\expandafter\Fibonacci_a\expandafter
+ {\the\numexpr #1/2\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro sqr(#2)+sqr(#3)\expandafter\relax\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro (2#2-#3)#3\relax}%
+}% end of Fibonacci_b_i
+\def\Fibonacci_b_ii #1#2#3#4#5{\expandafter\Fibonacci_a\expandafter
+ {\the\numexpr (#1-1)/2\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro sqr(#2)+sqr(#3)\expandafter\relax\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro (2#2-#3)#3\expandafter\relax\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro #2#4+#3#5\expandafter\relax\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro #2#5+#3(#4-#5)\relax}%
+}% end of Fibonacci_b_ii
+% code as used on title page:
+%\def\Fibonacci_end_i #1#2#3#4#5{\xintthe#5}
+%\def\Fibonacci_end_ii #1#2#3#4#5{\xinttheiiexpr #2#5+#3(#4-#5)\relax}
+% new definitions:
+\def\Fibonacci_end_i #1#2#3#4#5{{#4}{#5}}% {F(N+1)}{F(N)} in \xintexpr format
+\def\Fibonacci_end_ii #1#2#3#4#5%
+ {\expandafter
+ {\romannumeral0\xintiiexpro #2#4+#3#5\expandafter\relax
+ \expandafter}\expandafter
+ {\romannumeral0\xintiiexpro #2#5+#3(#4-#5)\relax}}% idem.
+% \FibonacciN returns F(N) (in encapsulated format: needs \xintthe for printing)
+\def\FibonacciN {\expandafter\xint_secondoftwo\romannumeral-`0\Fibonacci }%
+\catcode`_ 8
+\end{everbatim*}
+
+
+The macro |\Fibonacci| produces not one specific value |F(N)| but a pair of
+successive values |{F(N)}{F(N+1)}| which can then serve as starting point of
+another routine devoted to compute a whole sequence |F(N), F(N+1),
+F(N+2),....|. Each of |F(N)| and |F(N+1)| is kept in the encapsulated internal
+\xintexprname format.
+
+|\FibonacciN| produces the single |F(N)|. It also keeps it in the private
+format; thus printing it will need the |\xintthe| prefix.
+
+\begingroup\footnotesize\sffamily\baselineskip 10pt
+Here a code snippet which
+checks the routine via a \string\message\ of the first $51$ 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 [0+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.
+
+Allright, so let's now give the code to generate |{F(N)}{F(N+1)}{F(N+2)}...|,
+using |\Fibonacci| for the first two and then using the standard recursion
+|F(N+2)=F(N+1)+F(N)|:
+
+\catcode`_ 11
+\def\FibonacciSeq #1#2{%#1=starting index, #2>#1=ending index
+ \expandafter\Fibonacci_Seq\expandafter
+ {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2-1}%
+}%
+\def\Fibonacci_Seq #1#2{%
+ \expandafter\Fibonacci_Seq_loop\expandafter
+ {\the\numexpr #1\expandafter}\romannumeral0\Fibonacci {#1}{#2}%
+}%
+\def\Fibonacci_Seq_loop #1#2#3#4{% standard Fibonacci recursion
+ {#3}\unless\ifnum #1<#4 \Fibonacci_Seq_end\fi
+ \expandafter\Fibonacci_Seq_loop\expandafter
+ {\the\numexpr #1+1\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro #2+#3\relax}{#2}{#4}%
+}%
+\def\Fibonacci_Seq_end\fi\expandafter\Fibonacci_Seq_loop\expandafter
+ #1\expandafter #2#3#4{\fi {#3}}%
+\catcode`_ 8
+
+\begingroup\footnotesize\baselineskip10pt
+\everb|@
+\catcode`_ 11
+\def\FibonacciSeq #1#2{%#1=starting index, #2>#1=ending index
+ \expandafter\Fibonacci_Seq\expandafter
+ {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2-1}%
+}%
+\def\Fibonacci_Seq #1#2{%
+ \expandafter\Fibonacci_Seq_loop\expandafter
+ {\the\numexpr #1\expandafter}\romannumeral0\Fibonacci {#1}{#2}%
+}%
+\def\Fibonacci_Seq_loop #1#2#3#4{% standard Fibonacci recursion
+ {#3}\unless\ifnum #1<#4 \Fibonacci_Seq_end\fi
+ \expandafter\Fibonacci_Seq_loop\expandafter
+ {\the\numexpr #1+1\expandafter}\expandafter
+ {\romannumeral0\xintiiexpro #2+#3\relax}{#2}{#4}%
+}%
+\def\Fibonacci_Seq_end\fi\expandafter\Fibonacci_Seq_loop\expandafter
+ #1\expandafter #2#3#4{\fi {#3}}%
+\catcode`_ 8
+|
+\endgroup
+
+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\footnotesize\baselineskip10pt
+\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 |;-)|.
+
+\section{The \xintname bundle}
+
+\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://mirror.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 \href{http://www.ctan.org/pkg/bigintcalc}{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
+ \href{http://ctan.org/pkg/bnumexpr}{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.}
+%
+\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{http://www.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{http://www.ctan.org/pkg/l3kernel}{l3fp} (exactly represented) floating
+ point numbers have their exponents limited to $\pm$\dtt{9999}.}
+%
+
+More directly related to the \xintname bundle 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
+ \href{http://www.ctan.org/pkg/apnum}{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{http://www.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}
+
+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;|}
+%
+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.
+
+
+
+
+
+
+
+\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 power
+function in the expression parsers accepts integer exponents and also
+half-integer exponents for float expressions.\footnote{Half-integer exponents
+ work inside expressions, but not via the \csbxint{FloatPower} macro.}
+A preliminary implementation of fractional powers is available see
+\xintlogname. Trigonometrical functions are available (\xinttrigname).
+
+
+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).
+
+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
+ \href{http://www.ctan.org/pkg/etoolbox}{etoolbox}%
+%
+\footnote{\url{http://www.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.
+
+ At |1.2o| many macros from \xintcorename/\xintname which
+ use \csbxint{Num} to parse their arguments got deprecated, see
+ \autoref{ssec:coredeprecated}, \autoref{ssec:xintdeprecated}, and
+ \autoref{ssec:xintdeprecatedNum}.
+
+ All these macros have now been removed at |1.3|.\CHANGEDf{1.3}
+
+\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{<space>\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 with |Float| in their names produce on output scientific
+format with |P=|\nobreak\csbxint{theDigits} digits, a lowercase |e| and an
+exponent |N|. The first digit is not zero, it is preceded by an optional minus
+sign and is followed by a dot and |P-1| digits. Trailing zeroes are not
+trimmed. There is one exceptional case:
+\begin{itemize}[nosep]
+\item if the value is mathematically zero, it is output as |0.e0|,
+ i.e. zeros after the decimal mark are removed and the exponent is always |0|.
+\end{itemize}
+Future versions of the package may modify this.
+\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 \xintname bundle 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...<unit>|. First the decimal is
+ \emph{rounded} to the nearest integral multiple of |1/65536|, say |X/65536|.
+ The |<unit>| is associated to a ratio |N/D|, which represents |<unit>/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|.
+
+ For more details refer to:\newline
+ \url{http://tex.stackexchange.com/questions/338297/why-pdf-file-cannot-be-reproduced/338510#338510}.
+\end{framed}
+
+
+\subsection{\csh{ifcase}, \csh{ifnum}, ... 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 \xintname bundle 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
+\href{http://www.ctan.org/pkg/etoolbox}{etoolbox}%
+%
+\footnote{\url{http://www.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{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{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. The user is asked to hit the RETURN key thrice, which
+will display additional information. In non-interactive
+|nonstopmode| the \TeX{} run goes on uninterrupted and the error data will be
+found in the compilation log.
+
+Here is an example interactive run:
+\begin{everbatim}
+! Undefined control sequence.
+<argument> \ ! /
+ DivisionByZero (hit <RET> thrice)
+l.11 \xintiiDivision{123}{0}
+
+?
+! Undefined control sequence.
+<argument> \ ! /
+ Division of 123 by 0
+l.11 \xintiiDivision{123}{0}
+
+?
+! Undefined control sequence.
+<argument> \ ! /
+ next: {0}{0}
+l.11 \xintiiDivision{123}{0}
+
+?
+[1] (./temptest.aux) )
+Output written on temptest.dvi (1 page, 216 bytes).
+Transcript written on temptest.log.
+\end{everbatim}
+
+This is an experimental feature, which is in preparation for next major
+release.%
+%
+\footnote{The related macros checking or resetting error flags are implemented
+ in embryonic form but no user interface is provided with |1.2l| release.}
+%
+For the good functioning of this the macro with the weird appearance
+{\catcode`/ 11 \catcode`! 11 \catcode32 11 |\ ! /|} (yes, this is a single
+control sequence) must be left undefined. I trust it will be |;-)|.%
+%
+\footnote{The implementation is cloned from \LaTeX3, the
+ {\catcode`/ 11 \catcode`! 11 \catcode32 11 |\ ! /|} was chosen for its
+ shortness.}
+
+Deprecated macros also generate an (expandable) error message. Just hit the
+|RETURN| key once to proceed.\IMPORTANT\ Most deprecated macros at |1.2o| are
+listed either in \autoref{ssec:coredeprecated} or
+\autoref{ssec:xintdeprecated} or \autoref{ssec:xintdeprecatedNum}. All
+were removed at |1.3|.\CHANGED{1.3}
+
+The expression parsers are at |1.2l| still using a slightly less evolved
+method which lets \TeX{} display an undefined control sequence name giving
+some indication of the underlying problem (we copied this method from the
+|bigintcalc| package). The name of the control sequence is the message.
+
+\begin{multicols}{2}\parskip0pt\relax
+\begin{everbatim}
+\xintError:ignored
+\xintError:removed
+\xintError:inserted
+\xintError:unknownfunction
+\xintError:we_are_doomed
+\xintError:missing_xintthe!
+\end{everbatim}
+\end{multicols}
+
+
+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 a non-terminated
+|\numexpr|:
+\begin{everbatim}
+\xinttheexpr 3 + \numexpr 5+4\relax followed by some LaTeX code...
+\end{everbatim}
+as the |\numexpr| will swallow the |\relax| whose presence is mandatory for
+|\xinttheexpr|, errors will inevitably 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.\footnote{not to mention the \LaTeX\ error messages used by
+ Emacs AUC\TeX\ mode also for Plain \TeX\ runs...}
+
+
+\subsection{Package namespace, catcodes}
+
+
+The bundle packages needs that the \csa{space} and \csa{empty} control
+sequences are pre-defined with the identical meanings as in Plain \TeX{} (or
+\LaTeX2e which has the same macros).
+
+Private macros of \xintkernelname, \xintcorename, \xinttoolsname,
+\xintname, \xintfracname, \xintexprname, \xintbinhexname, \xintgcdname,
+\xintseriesname, and \xintcfracname{} use one or more underscores |_| as
+private letter, to reduce the risk of getting overwritten. They almost
+all begin either with |\XINT_| or with |\xint_|, a handful of these
+private macros such as \csa{XINTsetupcatcodes}, \csa{XINTdigits} and
+those with names such as |\XINTinFloat...| or |\XINTinfloat...| do not
+have any underscore in their names (for obscure legacy reasons).
+
+\xintkernelname provides \hyperref[odef]{|\odef|}, \hyperref[oodef]{|\oodef|},
+\hyperref[fdef]{|\fdef|}: if macros with these names already exist
+\xinttoolsname will not overwrite them. The same meanings are independently
+available under the names |\xintodef|, |\xintoodef|, etc...
+
+Apart from |\thexintexpr|, |\thexintiexpr|, ...
+all other public macros from the \xintname bundle packages start with |\xint|.
+
+For the good functioning of the macros, standard catcodes are assumed for the
+minus sign, the forward slash, the square brackets, the letter `e'. These
+requirements are dropped inside an |\xintexpr|-ession: spaces are gobbled,
+catcodes mostly do not matter, the |e| of scientific notation may be |E| (on
+input) \dots{}
+
+If a character used in the |\xintexpr| syntax is made active,
+this will surely cause problems; prefixing it with |\string| is one option.
+There is \csbxint{exprSafeCatcodes} and \csbxint{exprRestoreCatcodes} to
+temporarily turn off potentially active characters.
+
+\begin{framed}
+ For advanced \TeX\ users. At loading time of the packages the
+ catcode configuration may be arbitrary as long as it satisfies the following
+ requirements: the percent is of category code comment character, the
+ backslash is of category code escape character, digits have category code
+ other and letters have category code letter. Nothing else is assumed.
+\end{framed}
+
+As pointed out in previous section the control sequence {\catcode`/ 11
+ \catcode`! 11 \catcode32 11 |\ ! /|} must be left undefined.
+
+\subsection{Origins of the package}
+\label{ssec:origins}
+
+|2013/03/28.| Package |bigintcalc| by \textsc{Heiko Oberdiek} already
+provides expandable arithmetic operations on ``big integers'',
+exceeding the \TeX{} limits (of $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 correspondance 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.
+
+
+\section{Some utilities from the \xinttoolsname package}\label{sec:sometoolsutils}
+
+This is a first overview. Many examples combining these utilities with the
+arithmetic macros of \xintname are to be found in \autoref{sec:tools}. See
+also \autoref{sec:examples}.
+
+\subsection{Assignments}\label{sec:assign}
+
+\xintAssign {357}{323}\to\tmpA\tmpB
+\xintAssign \xintBezout{357}{323}\to\tmpU\tmpV\tmpD
+
+It might not be necessary to maintain at all times complete expandability. A
+devoted syntax is provided to make these things more efficient, for example when
+using the \csbxint{iiDivision} macro which computes both quotient and remainder
+at
+the same time:
+%
+\leftedline{\csbxint{Assign}
+ |\xintiiDivision{\xintiiPow {2}{1000}}{\xintiiFac{100}}\A\B|}
+%
+give:
+\xintAssign\xintiiDivision{\xintiiPow {2}{1000}}{\xintiiFac{100}}\to\A\B
+|\meaning\A|\dtt{: \printnumber{\meaning\A}\relax} and
+|\meaning\B|\dtt{: \printnumber{\meaning\B}\relax}.
+%
+Another example (which uses \csbxint{Bezout} from the \xintgcdname package):
+%
+\leftedline{\csbxint{Assign}
+%
+ |\xintBezout{357}{323}\to\U\V\D|}
+%
+is equivalent to setting |\U| to
+\dtt{\tmpU}, |\V| to \dtt{\tmpV}, and |\D| to \dtt{\tmpD}. And indeed
+\dtt{$\tmpU\times\tmpA+\tmpV\times\tmpB=
+ \xintiiAdd{\xintiiMul\tmpU\tmpA}{\xintiiMul\tmpV\tmpB}$} is a Bézout Identity.
+
+Thus, what |\xintAssign| does is to first apply an
+\hyperref[ssec:expansions]{\fexpan sion} to what comes next; it then defines one
+after the other (using |\def|; an optional argument allows to modify the
+expansion type, see \autoref{xintAssign} for details), the macros found after
+|\to| to correspond to the successive braced contents (or single tokens) located
+prior to |\to|. In case the first token (after the
+optional parameter within brackets, \emph{cf.} the \csbxint{Assign} detailed
+document) is not an opening brace |{|, |\xintAssign| consider that there is
+ only one macro to define, and that its replacement text should be all that
+ follows until the |\to|.
+
+\xintAssign
+{3570902836026}{200467139463}\to\tmpA\tmpB
+\xintAssign
+\xintBezout{3570902836026}{200467139463}\to\tmpU\tmpV\tmpD
+
+\leftedline
+{\csbxint{Assign}|\xintBezout{3570902836026}{200467139463}\to\U\V\D|}
+\noindent
+gives then |\U| with meaning \dtt{\tmpU},
+ |\V| with meaning \dtt{\tmpV} and |\D| with meaning \dtt{\tmpD}.
+
+%
+In situations when one does not know in advance the number of items, one has
+\csbxint{AssignArray} or its synonym \csbxint{DigitsOf}:
+%
+\leftedline{\csbxint{DigitsOf}|\xintiiPow{2}{100}\to|\csa{DIGITS}}
+%
+This defines \csa{DIGITS} to be macro with one parameter, \csa{DIGITS}|{0}|
+gives the size |N| of the array and \csa{DIGITS}|{n}|, for |n| from |1| to |N|
+then gives the |n|th element of the array, here the |n|th digit of $2^{100}$,
+from the most significant to the least significant. As usual, the generated
+macro \csa{DIGITS} is completely expandable (in two steps). As it wouldn't make
+much sense to allow indices exceeding the \TeX{} bounds, the macros created by
+\csbxint{AssignArray} put their argument inside a \csa{numexpr}, so it is
+completely expanded and may be a count register, not necessarily prefixed by
+|\the| or |\number|. Consider the following code snippet:
+%
+\begin{everbatim*}
+% \newcount\cnta
+% \newcount\cntb
+\begingroup
+\xintDigitsOf\xintiiPow{2}{100}\to\DIGITS
+\cnta = 1
+\cntb = 0
+\loop
+\advance \cntb \xintiiSqr{\DIGITS{\cnta}}
+\ifnum \cnta < \DIGITS{0}
+\advance\cnta 1
+\repeat
+
+|2^{100}| (=\xintiiPow {2}{100}) has \DIGITS{0} digits and the sum of their squares is \the\cntb.
+These digits are, from the least to the most significant: \cnta = \DIGITS{0} \loop
+\DIGITS{\cnta}\ifnum \cnta > 1 \advance\cnta -1 , \repeat.\endgroup
+\end{everbatim*}
+
+Warning: \csbxint{Assign}, \csbxint{AssignArray} and \csbxint{DigitsOf}
+\emph{do not do any check} on whether the macros they define are already
+defined.
+
+
+\subsection{Utilities for expandable manipulations}\label{sec:utils}
+
+The package now has more utilities to deal expandably with `lists of things',
+which were treated un-expandably in the previous section with \csa{xintAssign}
+and \csa{xintAssignArray}: \csbxint{ReverseOrder} and \csbxint{Length} since the
+first release, \csbxint{Apply} and \csbxint{ListWithSep} since |1.04|,
+\csbxint{RevWithBraces}, \csbxint{CSVtoList}, \csbxint{NthElt} since |1.06|,
+\csbxint{ApplyUnbraced}, since |1.06b|, \csbxint{loop} and \csbxint{iloop} since
+|1.09g|.%
+%
+\footnote{All these utilities, as well as \csbxint{Assign},
+ \csbxint{AssignArray} and the \csbxint{For} loops are now available from the
+ \xinttoolsname package, independently of the big integers facilities of
+ \xintname.}
+
+As an example the following code uses only expandable operations:
+\begin{everbatim*}
+$2^{100}$ (=\xintiiPow {2}{100}) has \xintLen{\xintiiPow {2}{100}} digits and the sum of their
+squares is \xintiiSum{\xintApply {\xintiiSqr}{\xintiiPow {2}{100}}}. These digits are, from the
+least to the most significant: \xintListWithSep {, }{\xintRev{\xintiiPow {2}{100}}}. The thirteenth
+most significant digit is \xintNthElt{13}{\xintiiPow {2}{100}}. The seventh least significant one
+is \xintNthElt{7}{\xintRev{\xintiiPow {2}{100}}}.
+\end{everbatim*}
+
+It would be more efficient to do once and for all
+|\edef\z{\xintiiPow {2}{100}}|, and then use |\z| in place of
+ |\xintiiPow {2}{100}| everywhere as this would spare the CPU some repetitions.
+
+Expandably computing primes is done in \autoref{xintSeq}.
+
+\subsection{A new kind of for loop}
+
+As part of the \hyperref[sec:tools]{utilities} coming with the \xinttoolsname
+package, there is a new kind of for loop, \csbxint{For}. Check it out
+(\autoref{xintFor} and also in next section).
+
+\subsection{A new kind of expandable loop}
+
+Also included in \xinttoolsname, \csbxint{iloop} is an expandable loop giving
+access to an iteration index, without using count registers which would break
+expandability. Check it out (\autoref{xintiloop} and also in next section).
+
+
+
+\section {Additional examples using \xinttoolsname or \xintexprname or both}
+\label{sec:examples}
+
+Note: \xintexprname.sty automatically loads \xinttoolsname.sty.
+
+\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*}
+\let\IsPrime\undefined \let\SmallestFactor\undefined % clean up possible previous mess
+\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}
+
+This section is based on my \url{http://tex.stackexchange.com/a/165008} post.
+
+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
+
+\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);
+
+% See http://tex.stackexchange.com/a/165008 for macros written directly by a
+% human.
+
+% For comparison here are the underlying support macros defined by
+% \xintdefiifunc from the code above (since 1.3a): (with linebreaks added by
+% TeX when writing to the log)
+
+% Function powmod_a for \xintiiexpr parser associated to \XINT_iiexpr_userfun
+% c_powmod_a with meaning macro:#1#2#3->\xintiiifOne {#2}{\xintiiMod {#1}{#3}}{\x
+% intiiifNotZero {\xintiiOdd {#2}}{\xintiiMod {\xintiiMul {#1}{\xintiiSqr {\xintE
+% xpandArgs {XINT_iiexpr_userfunc_powmod_a}{{#1}{\xintiiDivFloor {#2}{2}}{#3}}}}}
+% {#3}}{\xintiiMod {\xintiiSqr {\xintExpandArgs {XINT_iiexpr_userfunc_powmod_a}{{
+% #1}{\xintiiDivFloor {#2}{2}}{#3}}}}{#3}}}
+
+% Function powmod for \xintiiexpr parser associated to \XINT_iiexpr_userfunc_
+% powmod with meaning macro:#1#2#3->\xintiiifNotZero {#2}{\xintExpandArgs {XINT_i
+% iexpr_userfunc_powmod_a}{{#1}{#2}{#3}}}{1}
+
+% II ------------------------------ Miller-Rabin compositeness witness
+
+% n=2^k m + 1 with m odd and k at least 1
+
+% Choose 1<x<n.
+% compute y=x^m modulo n
+% if equals 1 we can't say anything
+% if equals n-1 we can't say anything
+% else put j=1, and
+% compute repeatedly the square, incrementing j by 1 each time,
+% thus always we have y^{2^{j-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
+% <http://mathworld.wolfram.com/Rabin-MillerStrongPseudoprimeTest.html>
+% <http://mathworld.wolfram.com/StrongPseudoprime.html>
+
+% 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
+ {\IsVerySmallPrime{\xintthe#1}}% macro needs to be fed with #1 unlocked.
+ {(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
+\xinttheiiexpr
+ 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 \url{http://tex.stackexchange.com/a/273084}. The version here is like
+ |code 3| on \url{http://tex.stackexchange.com} (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).
+
+\unless\ifxetex % pour tester compilation de xint.dtx avec xetex qui n'a pas
+ % \pdfuniformdeviate
+\begin{everbatim*}
+% QuickSort expandably on comma separated values with random choice of pivots
+% ====> Requires availability of \pdfuniformdeviate <====
+% \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{\pdfuniformdeviate #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{000}\scantokens\expandafter{\meaning\z}\par
+\endgroup
+\end{everbatim*}
+\fi % fin de si pas xetex
+
+
+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
+\url{http://tex.stackexchange.com/a/273084} 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 \url{http://tex.stackexchange.com/a/142634/4686}. 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}}}% many \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|.
+
+\etocdepthtag.toc {macros}
+\addtocontents{toc}{\gdef\string\sectioncouleur{{joli}}}
+\addtocontents{toc}{\gdef\string\SKIPSECTIONINTERSPACE{\kern\smallskipamount}}
+\renewcommand{\etocaftertochook}{\addvspace{\bigskipamount}}
+
+\clearpage
+\def\n{|{N}|}
+\def\m{|{M}|}
+\def\x{|{x}|}
+\csname xintkernelnameUp\endcsname
+\section{Macros of the \xintkernelname package}
+\RaisedLabel{sec:kernel}
+
+\localtableofcontents
+
+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}
+
+\csa{oodef}|\controlsequence {<stuff>}| does
+\everb|@
+ \expandafter\expandafter\expandafter\def
+ \expandafter\expandafter\expandafter\controlsequence
+ \expandafter\expandafter\expandafter{<stuff>}
+|
+
+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
+|<stuff>|, and |\fdef| which expands fully |<stuff>| 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 \xintname bundle, when the
+result has a few dozens of digits. |\oodef| needs thousands of digits it seems
+to become competitive.
+
+
+\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}}
+
+\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}}}}
+
+\subsection{\csh{xintLastItem}}
+\label{xintLastItem}
+
+\csa{xintLastItem}\marg{list}\etype{n} returns the last item (unbraced) of its
+argument. 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{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}'s answer to \url{http://tex.stackexchange.com/questions/16189/repeat-command-n-times}.}
+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.}
+
+Note that expansion must be triggered by a |\romannumeral|.
+
+
+\subsection{\csh{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|.
+
+
+Note that expansion must be triggered by a |\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 a wrapper of engine
+|\pdfuniformdeviate| (or |\uniformdeviate|).%
+%
+\footnote{The |\uniformdeviate| primitive has been added to Xe\TeX\
+ and will be available with \TeX Live 2019 release.}
+The implementation is to be
+considered experimental for the time being.\NewWith{1.3b}%
+
+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 Random Number Generator works with an array of 55 28bits
+integers. To produce a « uniform » random integer in a given range
+\dtt{0..x-1} it produces next pseudo-random |y| (supposedly uniformly
+distributed, i.e. non-uniformity can be neglected) such that \dtt{$0\leq y <
+ 2^{28}$} and the output is the rounding of \dtt{$x*(y/2^{28})$}, with upper
+bound |x| remapped to |0|. This has following corollaries:
+\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}
+These observations are not to be construed as criticism of the engine
+primitive itself, which comes from MetaPost, as the code comments and more
+generally the whole of \emph{The Art of Computer Programming, Vol. 2} stresses
+that it should rather be seen as producing random fractions (the unit fraction
+being $2^{28}$). Using it as a generator for \emph{integers} is a bit of an
+abuse.
+
+The first goal of \csa{xintUniformDeviate} is to guarantee a better uniformity
+for the distribution of random integers in any given range |x|.
+
+\emph{If the probability to obtain a given |y| in |0..x-1| is
+ \verb$(1+e(y))/x$, the ``{relative non-uniformity}'' for that value |y| is
+ \verb$|e(y)|$.}
+
+The engine primitive guarantees only \dtt{$x/2^{28}$} relative non-uniformity, and
+\csa{xintUniformDeviate} (in its current implementation) improves this by
+a factor \dtt{|2^{28}=|\number"10000000}: the non-uniformity is guaranteed to
+be bounded by \dtt{$x/2^{56}$}.%
+%
+\expandafter\footnote\expandafter{\ifnum\value{footnote}=55 This «56» is proof
+ of existence of devil, no? \fi 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}|!}
+%
+With such a small non-uniformity, modulo phenomena as mentioned earlier are
+not observable in reasonable computing time.%
+%
+\footnote{The function \func{qraw} is used here not so much to speed up the
+ loop expansion, but in relation to \autoref{ssec:memory} to avoid too much
+ usage of |\csname...\endcsname| storage. Besides, if we had used |mod3|
+ function we would have needed |\xinttheiiexpr mod3(\pdfun...)\relax|
+ wrapping for each individual macro. So we decided rather to use a macro
+ |\ModThree|; of course we could have used |\numexpr|, with the technical
+ problem to expand only once |\pdfuniformdeviate|, which would have led to
+ some extra manoeuver, so ok for |\ModThree|.}
+%
+\begin{everbatim*}
+%\xintdefiifunc mod3(x):= x 'mod' 3;
+\xintNewIIExpr\ModThree[1]{#1 'mod' 3}
+
+\pdfsetrandomseed 87654321
+\xintdefiivar BadDigits:=qraw(%
+ \romannumeral\xintreplicate{503}{\ModThree{\pdfuniformdeviate "C000000},}%
+ \ModThree{\pdfuniformdeviate "C000000}%
+);% 504=503+1
+
+\pdfsetrandomseed 87654321
+\xintdefiivar GoodDigits:=qraw(%
+ \romannumeral\xintreplicate{503}{\ModThree{\xintUniformDeviate{"C000000}},}%
+ \ModThree{\xintUniformDeviate{"C000000}}%
+);% 504=503+1
+
+These 504 digits generated from \string\pdfuniformdeviate:
+\xinttheiiexpr BadDigits\relax\hfill\break
+contain these respective amounts of 0, 1, and 2:
+% (this is definitely not the fastest way to count, but it is fun - and expandable)
+\xinttheiiexpr iter(0,0,0;(i=0)?{[@][0]+1,[@][1],[@][2]}
+ {(i=1)?{[@][0],[@][1]+1,[@][2]}
+ {[@][0],[@][1],[@][2]+1}},
+ i=BadDigits)\relax\par
+
+These 504 digits generated from \string\xintUniformDeviate:
+\xinttheiiexpr GoodDigits\relax\hfill\break
+contain these respective amounts of 0, 1, and 2:
+\xinttheiiexpr iter(0,0,0;(i=0)?{[@][0]+1,[@][1],[@][2]}
+ {(i=1)?{[@][0],[@][1]+1,[@][2]}
+ {[@][0],[@][1],[@][2]+1}},
+ i=GoodDigits)\relax\par
+% % output to data file for double-check with python
+% \newwrite\out
+% \immediate\openout\out=\jobname.data
+% \immediate\write\out{Lbad=[\xinttheiiexpr BadDigits\relax]}
+% \immediate\write\out{Lgood=[\xinttheiiexpr GoodDigits\relax]}
+% \immediate\closeout\out
+\end{everbatim*}
+
+There is a second peculiarity of the engine RNG: two seeds sharing the same
+low |k| bits generate sequences of 28-bits integers which are identical modulo
+|2^k|! In particular after setting the seed, there are only 2 distinct
+sequences of parity bits for the integers generated by |\pdfuniformdeviate (2
+to the power 28)|...
+
+In order to mitigate, \csa{xintUniformDeviate} 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.
+
+\smallskip
+\emph{The description above summarizes parts of discussions held with Bruno Le
+ Floch in May 2018 on occasion of his LaTeX3 contributions related to this.}
+\par
+\smallskip
+
+\TeXnote
+currently 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 28bits integers, rather than one single
+28bits 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 to the tenth power:
+%
+\footnote{This is done on a |2.4GHz| processor. Hmm... or on a |2.8GHz| one,
+ I should add some automatic recognition to the build process...}
+%
+\begin{everbatim*}
+\pdfsetrandomseed 12345678
+\pdfresettimer\romannumeral\xintreplicate
+ {100}{\fdef\foo{\xintiiPow{\xintUniformDeviate{100000000}}{10}}}%
+\the\dimexpr\pdfelapsedtime sp\relax\space (with \string\xintUniformDeviate)\newline
+(last result: \foo)\newline
+\pdfsetrandomseed 12345678
+\pdfresettimer\romannumeral\xintreplicate
+ {100}{\fdef\foo{\xintiiPow{\pdfuniformdeviate 100000000}{10}}}%
+\the\dimexpr\pdfelapsedtime sp\relax\space (with \string\pdfuniformdeviate)\newline
+(last result: \foo)\par
+\end{everbatim*}
+
+\TeXnote
+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
+\csa{xintUniformDeviate}|{100000000}|, but via a direct optimized call made
+possibly by the range being a power of 10.
+
+\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
+
+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}
+
+Most removed macros listed in \autoref{ssec:coredeprecated} were by design
+applying \csbxint{Num} to their inputs. Typically these macros had a single
+|i| in their names, for example \csa{xintiAdd} was such a companion to
+\csa{xintiiAdd}. \xintfracname redefined \csbxint{Num} to be the macro
+accepting general fractional input and truncating it to an integer. Hence a
+macro such as \csa{xintiAdd} was compatible with the output format of
+\xintfracname macros, contrarily to \csbxint{iiAdd} which handles only strict
+integer format for its inputs. Of course, \xintfracname defined also its own
+\csbxint{Add} which did the addition of its arguments without truncating them
+to integers... but whose output format is the |A/B[N]| format explained in
+\autoref{ssec:outputs}, hence even if representing a small integer it can not
+be used directly in a \TeX\ context such as |\ifnum|, contrarily to
+\csa{xintiAdd} or to \csbxint{iiAdd}.
+
+\begin{framed}
+ This situation was the result of some early-on design
+ decisions which now appear misguided and impede further development. Hence,
+ at |1.2o| it has been decided to deprecate \emph{all} such |i|-macros. And
+ they got removed from the package at |1.3|.\CHANGEDf{1.3}
+\end{framed}
+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.%
+%
+\footnote{Regarding \csbxint{FDg} and \csbxint{LDg}, this is a breaking change
+ because formerly they used \csbxint{Num}.}
+
+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}.
+
+\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 \xintname bundle (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 |N<M|.
+
+At |1.2l| this macro was moved from package \xintname to \xintcorename.
+
+\subsection{\csh{xintiiSub}}\label{xintiiSub}
+
+|\xintiiSub|\n\m\etype{ff} computes the difference |N-M|.
+
+\subsection{\csh{xintiiMul}}\label{xintiiMul}
+
+|\xintiiMul|\n\m\etype{ff} computes the product of two (big) integers.
+
+\subsection{\csh{xintiiSqr}}\label{xintiiSqr}
+
+|\xintiiSqr|\n\etype{f} produces the square.
+
+\subsection{\csh{xintiiPow}}\label{xintiiPow}
+
+|\xintiiPow|\n\x\etype{f\numx} computes |N^x|. For |x=0|, this is 1. For |N=0|
+and |x<0|, or if \verb+|N|>1+ 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.
+
+\begin{framed}
+ Indeed, the maximal power of $2$ which \xintname is able to compute
+ explicitely is |2^(2^17)=2^131072| which has \dtt{39457} digits. This
+ exceeds the maximal size on input for the \xintcorename multiplication, hence
+ any |2^N| with a higher |N| will fail. On the other hand |2^(2^16)| has
+ \dtt{19729} digits, thus it can be squared once to obtain |2^(2^17)| or
+ multiplied by anything smaller, thus all exponents up to and including |2^17|
+ are allowed (because the power operation works by squaring things and making
+ products).
+\end{framed}
+
+% Side remark: after all it does pay to think! I almost melted my CPU trying by
+% dichotomy to pin-point the exact maximal allowable |N| for |\xintiiPow 2{N}|
+% before finally making the reasoning above. Indeed, each such computation with
+% |N>130000| activates the fan of my laptop and results in so warm a keyboard
+% that I can hardly go on working on it! And it takes about 12 minutes for each
+% |\xintiiPow2{N}| with such |N|'s of the order of $130000$ (a.t.t.o.w.).
+
+\subsection{\csh{xintiiFac}}\label{xintiiFac}
+
+|\xintiiFac|\x\etype{\numx} computes the factorial.
+
+\begin{framed}
+ The (theoretically) allowable range is $0\leqslant x\leqslant10000$.
+
+ However the maximal possible computation depends on the values of some memory
+ parameters of the |tex| executable: with the current default settings of
+ TeXLive 2015, the maximal computable factorial (a.t.t.o.w. 2015/10/06) turns
+ out to be $5971!$ which has $19956$ digits.%\footnotemark
+\end{framed}
+
+
+
+The |factorial| function, or equivalently |!| as post-fix operator is
+available in \csbxint{iiexpr}, \csbxint{expr}:
+\begin{everbatim*}
+\printnumber{\xinttheiiexpr 200!\relax}\par
+\end{everbatim*}
+See also \csbxint{FloatFac} from package \xintfracname for the float variant,
+used in \csbxint{floatexpr}.
+
+
+
+\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.
+
+\subsection{Removed macros}\label{ssec:coredeprecated}
+
+These macros were deprecated at |1.2o| and removed at |1.3|.\CHANGED{1.3}
+|\xintiiFDg| (renamed to \csbxint{FDg}),
+|\xintiiLDg| (renamed to \csbxint{LDg}),
+|\xintiOpp|,
+|\xintiAbs|,
+|\xintiAdd|,
+|\xintCmp| (it gets defined by \xintfracname, so deprecation will usually not be
+seen; the macro with this name from former \xintcorename should have been
+called |\xintiCmp| actually),
+|\xintSgn| (it also gets its proper definition from \xintfracname),
+|\xintiSub|,
+|\xintiMul|,
+|\xintiDivision|,
+|\xintiQuo|,
+|\xintiRem|,
+|\xintiDivRound|,
+|\xintiDivTrunc|,
+|\xintiMod|,
+|\xintiSqr|,
+|\xintiPow|,
+|\xintiFac|.
+
+
+\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}
+
+This package loads automatically \xintcorename (and \xintkernelname) hence
+all macros described in \autoref{sec:core} are still available.
+
+\etocsetnexttocdepth{subsubsection}
+\localtableofcontents
+
+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{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 «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 «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|.\CHANGED{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{xintiiGCD}}
+
+This is the same as the \csbxint{iiGCD} from package \xintgcdname.
+
+\subsection{\csh{xintiiLCM}}
+
+This is the same as the \csbxint{iiLCM} from package \xintgcdname.
+
+\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^{-|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{xintiiGxstorEq}
+
+|\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{A<B}\marg{A=B}\marg{A>B}\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{A<B}\marg{not(A<B)}\etype{ffnn}
+checks if $A<B$ and executes the corresponding branch.
+
+\subsection{\csh{xintiiifOdd}}\label{xintiiifOdd}
+
+\csa{xintiiifOdd}\marg{A}\marg{A odd}\marg{A even}\etype{fnn} checks if $A$ is
+and odd integer and executes the corresponding branch.
+
+\subsection{\csh{xintiiSum}}\label{xintiiSum}
+
+\csa{xintiiSum}\marg{braced things}\etype{{\lowast f}} after expanding its
+argument expects to find a sequence of tokens (or braced material). Each is
+\fexpan ded, and the sum of all these numbers is returned.
+\begin{everbatim*}
+\xintiiSum{{123}{-98763450}{\xintiiFac{7}}{\xintiiMul{3347}{591}}}\newline
+\xintiiSum{1234567890}\newline
+\xintiiSum{1234}\newline
+\xintiiSum{}
+\end{everbatim*}
+
+A sum with only one term returns that
+number: |\xintiiSum {{-1234}}|\dtt{=\xintiiSum {{-1234}}}.
+Attention that |\xintiiSum {-1234}| is not legal input and would make the
+\TeX{} run fail.
+
+\subsection{\csh{xintiiPrd}}\label{xintiiPrd}
+
+\csa{xintiiPrd}\marg{braced things}\etype{{\lowast f}} after expanding its
+argument expects to find a sequence of (of braced items or unbraced
+single tokens). Each is
+expanded (with the usual meaning), and the product of all these numbers is
+returned.
+\begin{everbatim*}
+\xintiiPrd{{-9876}{\xintiiFac{7}}{\xintiiMul{3347}{591}}}\newline
+\xintiiPrd{123456789123456789}\newline
+\xintiiPrd {1234}\newline
+\xintiiPrd{}
+\end{everbatim*}
+
+Attention that |\xintiiPrd {-1234}| is not legal input and would make the \TeX{}
+compilation fail.
+\begin{everbatim*}
+$2^{200}3^{100}7^{100}=\printnumber
+ {\xintiiPrd {{\xintiiPow {2}{200}}{\xintiiPow {3}{100}}{\xintiiPow {7}{100}}}}$
+\end{everbatim*}
+
+With \xintexprname, the syntax is the natural one:
+\begin{everbatim*}
+$2^{200}3^{100}7^{100}=\printnumber{\xinttheiiexpr 2^200 * 3^100 * 7^100\relax}$
+\end{everbatim*}
+
+\subsection{\csh{xintiiSquareRoot}}
+\label{xintiiSquareRoot}
+
+|\xintiiSquareRoot|\n\etype{f} returns two braced integers |{M}{d}| which
+satisfy |d>0| 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{|N|}$ is $|M|-\frac{|d|}{|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 |x<y| the macro
+evaluates to \dtt{\xintiiBinomial{1}{-1}}.
+
+
+%\begin{framed}
+ The allowable range is $0\leqslant x\leqslant99999999$.
+%\end{framed}
+ % Thus the maximal computable value is ${9999 \choose 5000}$ which turns out
+ % to have \dtt{3008} digits.
+ But this theoretical range includes binomial coefficients with 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.
+
+%
+It turns out that ${65000 \choose 32500}$ has \dtt{19565} digits and
+${64000 \choose 32000}$ has \dtt{19264} digits. The latter can be evaluated
+(this takes a long long time) but presumably not the former (I didn't try).
+Reasonable feasible evaluations are with binomial coefficients not exceeding
+about one thousand digits.
+
+
+%
+The |binomial| function is available in the \xintexprname parsers.
+\begin{everbatim*}
+\xinttheiiexpr seq(binomial(100,i), i=47..53)\relax
+\end{everbatim*}
+
+See \csbxint{FloatBinomial} from package \xintfracname for the float variant,
+used in \csbxint{floatexpr}.
+
+
+In order to
+evaluate binomial coefficients ${x \choose y}$ with $x>99999999$, 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 $a<j\leqslant b$, hence in particular if $a\geqslant b$ the
+ product is empty and the macro evaluates to |1|.
+
+ Only for $0\leqslant a\leqslant b$ is the behaviour to be considered
+ stable. For $a>b$ 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 «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 «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{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{Removed macros (they require \xintfracname)}\label{ssec:xintdeprecated}
+
+These macros now require \xintfracname. They have been removed from \xintname
+at |1.3|.\CHANGED{1.3}
+|\xintEq|,
+|\xintNeq|,
+|\xintGeq|,
+|\xintGt|,
+|\xintLt|,
+|\xintGtorEq|,
+|\xintLtorEq|,
+|\xintIsZero|,
+|\xintIsNotZero|,
+|\xintIsOne|,
+|\xintOdd|,
+|\xintEven|,
+|\xintifSgn|,
+|\xintifCmp|,
+|\xintifEq|,
+|\xintifGt|,
+|\xintifLt|,
+|\xintifZero|,
+|\xintifNotZero|,
+|\xintifOne|,
+|\xintifOdd|.
+
+With the exception of |\xintNeq| which was renamed to |\xintNotEq|, the above
+listed macros all belong to \xintfracname.
+
+\subsection{Removed macros (they used \csh{xintNum})}\label{ssec:xintdeprecatedNum}
+
+These macros filtered their arguments via \csbxint{Num}. They got deprecated
+at |1.2o| and removed at |1.3|:\CHANGED{1.3}
+|\xintMON|,
+|\xintMMON|,
+|\xintiMax|,
+|\xintiMin|,
+|\xintiMaxof|,
+|\xintiMinof|,
+|\xintiSquareRoot|,
+|\xintiSqrt|,
+|\xintiSqrtR|,
+|\xintiBinomial|,
+|\xintiPFactorial|.
+
+\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}
+
+\subsection{(WIP) \csh{xintRandomDigits}}\label{xintRandomDigits}
+
+|\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.\NewWith{1.3b}
+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*}
+\pdfsetrandomseed 271828182
+\xintRandomDigits{92}
+\end{everbatim*}
+
+\TeXnote the digits are produced eight by eight by the same method which would
+result from \csbxint{UniformDeviate}|{100000000}| but with less overhead.
+
+% \subsection{\csh{\xintOneRandomDigit}}\label{xintOneRandomDigit}
+
+\subsection{(WIP) \csh{xintXRandomDigits}}\label{xintXRandomDigits}
+
+|\xintXRandomDigits{N}|\retype{\numx} expands under exhaustive expansion
+(|\edef|, |\write|, |\csname| ...) to |N| random decimal
+digits. The argument must be non-negative.\NewWith{1.3b}
+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].
+<inserted text> 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).
+
+\TeXnote the digits are produced eight by eight by the same method which would
+result from \csbxint{UniformDeviate}|{100000000}| but with less overhead.
+
+\subsection{(WIP) \csh{xintiiRandRange}}\label{xintiiRandRange}
+
+|\xintiiRandRange{A}|\etype{f} expands to a random (big) integer |N|
+such that |0<=N<A|. It is a supporting macro for \func{randrange}. As with
+Python's function of the same name, it is an error if |A<=0|.\NewWith{1.3b}
+\begin{everbatim*}
+\pdfsetrandomseed 271828314
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\newline
+\xintiiRandRange{\xintNum{1e40}}\newline
+\pdfsetrandomseed 271828314
+\xinttheiiexpr randrange(num(1e40))\relax\newline % bare 1e40 not understood by \xintiiexpr
+\pdfsetrandomseed 271828314
+\xinttheexpr randrange(1e40)\relax
+\end{everbatim*}
+
+Of course, keeping in mind that the set of seeds is of cardinality |2^{28}|,
+randomness is a bit illusory here say with |A=10^N|, |N>8|, 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 fourty digits as random numbers, and this
+makes the previous section about usage of \csbxint{XRandomDigits} to generate
+millions of digits a bit comical...
+
+\TeXnote the digits are produced eight by eight by the same method which would
+result from \csbxint{UniformDeviate}|{100000000}| but with less overhead.
+
+\subsection{(WIP) \csh{xintiiRandRangeAtoB}}\label{xintiiRandRangeAtoB}
+
+|\xintiiRandRangeAtoB{A}{B}|\etype{ff} expands to a random (big) integer |N|
+such that |A<=N<B|. It is a supporting macro for \func{randrange}. As with
+Python's function of the same name, it is an error if |B<=A|.\NewWith{1.3b}
+\begin{everbatim*}
+\pdfsetrandomseed 271828314
+12345678911111111111111111111\newline
+\xintiiRandRangeAtoB{12345678911111111111111111111}{12345678922222222222222222222}\newline
+\pdfsetrandomseed 271828314
+\def\test{%
+\xinttheiiexpr randrange(12345678911111111111111111111,12345678922222222222222222222)\relax}%
+\romannumeral\xintreplicate{10}{\test\newline}%
+12345678922222222222222222222
+\end{everbatim*}
+
+\TeXnote the digits are produced eight by eight by the same method which would
+result from \csbxint{UniformDeviate}|{100000000}| but with less overhead.
+
+\clearpage
+\let\xintnameUp\undefined
+\csname xintfracnameUp\endcsname
+\def\n{|{N}|}
+\def\m{|{M}|}
+\def\x{|{x}|}
+\section{Macros of the \xintfracname package}
+\RaisedLabel{sec:frac}
+
+First version of this package was in release |1.03| (|2013/04/14|) of the
+\xintname bundle.
+
+At release |1.3| (|2018/02/28|) the behaviour of \csbxint{Add} (and of
+\csbxint{Sub}) was modified:\CHANGED{1.3} when adding |a/b| and |c/d| they
+will use always the least common multiple of the denominators. This helps
+limit the build-up of denominators, but the author still hesitates if the
+fraction should be reduced to smallest terms. The current method allows (for
+example when multiplying two polynomials) to keep a well-predictable
+denominator among various terms, even though some may be reducible.
+
+\localtableofcontents
+
+\xintfracname loads automatically \xintcorename and \xintname and inherits
+their macro definitions. Only these two are redefined:
+\hyperref[xintNumFrac]{\string\xintNum} and
+\hyperref[xintLenFrac]{\string\xintLen}. As explained in \autoref{ssec:inputs}
+and \autoref{ssec:outputs} the interchange format for the \xintfracname
+macros, i.e. |A/B[N]|, is not understood by the |ii|-named macros of
+\xintcorename/\xintname which expect the so-called strict integer format.
+Hence, to use such an |ii|-macro with an output from an \xintfracname macro,
+an extra \csbxint{Num} wrapper is required. But macros already defined by
+\xintfracname cover most use cases hence this should be a rarely needed.
+
+In the macro descriptions, the variable |f|\ntype{\Ff} and the margin
+indicator stand for the \xintfracname input format for integers, scientific
+numbers, and fractions as described in \autoref{ssec:inputs}.
+
+As in the \hyperref[sec:xint]{xint.sty} documentation, |x|\ntype{\numx} stands
+for something which internally will be handled in a \csa{numexpr}. It may thus
+be an expression as understood by \csa{numexpr} but its evaluation and
+intermediate steps must obey the \TeX\ bound.
+
+The output format for most macros is the |A/B[N]| format but naturally the
+float macros use the scientific notation on output. And some macros are
+special, for example \csbxint{Trunc} produces decimal numbers, \csbxint{Irr}
+produces an |A/B| with no |[N]|, \csbxint{iTrunc} and \csbxint{iRound} produce
+integers without trailing |[N]| either, etc\dots
+
+|1.3a| belatedly adds documentation for some macros such as
+\csbxint{DivFloor} which had been defined long ago, but did not make it to the
+user manual for various reasons, one being that it is thought few users will
+use directly the \xintfracname macros, the \csbxint{expr} interface being more
+convenient. For complete documentation refer to |sourcexint.pdf|.
+
+\subsection{\csh{xintNum}}\label{xintNumFrac}
+
+The original \csbxint{Num} \etype{\Ff} from \xintname is made a synonym to
+\csbxint{TTrunc} (whose description is to be found farther in this section).
+
+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{xintNumerator}}\label{xintNumerator}
+
+The input data\etype{\Ff} is parsed as if by \csbxint{Raw} into |A/B[N]|
+format and
+the macro outputs |A| 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]|
+format and
+the macro outputs |B| 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*}
+
+This macro is used internally by various other constructs; its implementation
+was redone entirely at |1.3a|, and it got faster on long inputs.
+
+\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.\NewWith{1.3}
+(|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{xintDecToString}}\label{xintDecToString}
+
+This is\etype{\Ff} a macro tailored for printing decimal numbers. It does not
+trim trailing zeros, use |\xintDecToString{\xintREZ{<foo>}}| for that.
+\NewWith{1.3}
+\begin{everbatim*}
+\xintDecToString {123456789e5}\newline
+\xintDecToString {123456789e-5}\newline
+\xintDecToString {12345e-10}\newline
+\xintDecToString {12345e-10/123}\par % just leave denominator as is
+\end{everbatim*}
+Consider it an unstable macro, what it does exactly is yet to be decided. It
+is a backport from \href{http://ctan.org/pkg/polexpr}{polexpr}'s
+|\PolDecToString|, which has now been made an alias to it.
+
+\subsection{\csh{xintTrunc}}\label{xintTrunc}
+
+\csa{xintTrunc}|{x}{f}|\etype{\numx\Ff} returns the integral part, a dot
+(standing for the decimal mark), and
+then the first |x| digits of the decimal expansion of the fraction |f|, except
+when the fraction is (or evaluates to) zero, then it simply prints \dtt{0}
+(with no dot).
+
+\begin{framed}
+ The argument |x| must be non-negative, the behaviour is currently undefined
+ when |x<0| and will provoke errors.
+\end{framed}
+
+Except when the input is (or evaluates to) exactly zero, the output contains
+exactly |x| digits after the decimal mark, thus the output may be
+\dtt{0.00...0} or \dtt{-0.00...0}, indicating that the original fraction was
+positive, respectively negative.
+
+\begin{framed}
+ \textbf{Warning:} \emph{it is not yet decided is this 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).
+
+ If \xintfracname distinguished zero, positive zero, and
+ negative zero 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}
+\begin{everbatim*}
+\xintTrunc {16}{-803.2028/20905.298}\newline
+\xintTrunc {20}{-803.2028/20905.298}\newline
+\xintTrunc {10}{\xintPow {-11}{-11}}\newline
+\xintTrunc {12}{\xintPow {-11}{-11}}\newline
+\xintTrunc {50}{\xintPow {-11}{-11}}\newline
+\xintTrunc {12}{\xintAdd {-1/3}{3/9}}\par
+\end{everbatim*}
+The digits printed are exact up to and including the last one.
+
+
+\subsection{\csh{xintXTrunc}}\label{xintXTrunc}
+
+
+\csa{xintXTrunc}|{x}{f}|\retype{\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 |-1<frac(f)<=0| and if |f>0| 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 |x| digits precision after the decimal
+point. The argument |x| should be non-negative. Only when |f| evaluates exactly
+to zero does \csa{xintRound} return |0| without decimal point. When |f| is not
+zero, its sign is given in the output, also when the digits printed are all
+zero.
+\begin{everbatim*}
+\xintRound {16}{-803.2028/20905.298}\newline
+\xintRound {20}{-803.2028/20905.298}\newline
+\xintRound {10}{\xintPow {-11}{-11}}\newline
+\xintRound {12}{\xintPow {-11}{-11}}\newline
+\xintRound {12}{\xintAdd {-1/3}{3/9}}\par
+\end{everbatim*}
+
+\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.
+\begin{everbatim*}
+\xintiTrunc {16}{-803.2028/20905.298}\newline
+\xintiTrunc {10}{\xintPow {-11}{-11}}\newline
+\xintiTrunc {12}{\xintPow {-11}{-11}}\par
+\end{everbatim*}
+
+In particular \csa{xintiTrunc}|{0}{f}|'s output is in strict integer format
+contrarily to \csa{xintTrunc}|{0}{f}| which produces an output with a decimal
+mark, except if |f| turns out to be zero.
+
+\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.
+\begin{everbatim*}
+\xintiRound {16}{-803.2028/20905.298}\newline
+\xintiRound {10}{\xintPow {-11}{-11}}\par
+\end{everbatim*}
+
+In particular \csa{xintiRound}|{0}{f}|'s output is in strict integer format
+contrarily to \csa{xintRound}|{0}{f}| which produces an output with a decimal
+mark, except if |f| turns out to be zero.
+
+\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 |F<G|, |F=G|, |F>G|.
+
+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{xintGxstorEq}
+
+|\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 f<g}\marg{if f=g}\marg{if
+ f>g}\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<g$ and in that case executes the |YES| branch.
+
+\subsection{\csh{xintifInt}}\label{xintifInt}
+
+\csa{xintifInt}|{f}{YES branch}{NO branch}|\etype{\Ff nn} expandably chooses
+the |YES| branch if |f| reveals itself after expansion and simplification to
+be an integer.
+
+\subsection{\csh{xintSgn}}\label{xintSgn}
+
+The sign of a fraction.\etype{\Ff}
+
+\subsection{\csh{xintOpp}}\label{xintOpp}
+
+The opposite of a fraction.\etype{\Ff}
+Note that |\xintOpp {3}| produces \dtt{\xintOpp
+ {3}} whereas |\xintiiOpp {3}| produces \dtt{\xintiiOpp {3}}.
+
+\subsection{\csh{xintAbs}}\label{xintAbs}
+
+The absolute value\etype{\Ff}. Note that |\xintAbs {-2}|\dtt{=\xintAbs {-2}}
+where |\xintiiAbs {-2}| outputs \dtt{=\xintiiAbs {-2}}.
+
+\subsection{\csh{xintAdd}}\label{xintAdd}
+
+Computes the addition\etype{\Ff\Ff} of two fractions.
+
+Since |1.3| always uses the least common multiple of the
+denominators.\CHANGED{1.3}
+
+\subsection{\csh{xintSub}}\label{xintSub}
+
+Computes the difference\etype{\Ff\Ff} of two fractions (|\xintSub{F}{G}|
+computes |F-G|).
+
+Since |1.3| always uses the least common multiple of the
+denominators.\CHANGED{1.3}
+
+\subsection{\csh{xintMul}}\label{xintMul}
+
+Computes the product\etype{\Ff\Ff} of two fractions.
+
+Output is not reduced to smallest terms.
+
+\subsection{\csh{xintDiv}}\label{xintDiv}
+
+Computes the quotient \etype{\Ff\Ff} of two fractions.
+(|\xintDiv{F}{G}| computes |F/G|).
+
+Output is not reduced to smallest terms.
+
+\subsection{\csh{xintDivFloor}}
+\label{xintDivFloor}
+
+Computes the quotient \etype{\Ff\Ff} of two arguments then apply floor
+function to get an integer (in strict format). This macro was defined at |1.1|
+(but was left not documented until |1.3a|...) and changed at |1.2p|, formerly
+it appended |/1[0]| to output.
+\begin{everbatim*}
+\xintDivFloor{-170/3}{23/2}
+\end{everbatim*}
+
+\subsection{\csh{xintMod}}
+\label{xintMod}
+
+Computes the remainder associated to the floored division\etype{\Ff\Ff}
+\csbxint{DivFloor}. Prior to |1.2p| the meaning was the one of
+\csbxint{ModTrunc}. Was left undocumented until |1.3a|.
+\begin{everbatim*}
+\xintMod{-170/3}{23/2}
+\end{everbatim*}
+
+Modified at |1.3| to use a l.c.m. for the denominator of the result.
+\CHANGED{1.3}
+
+\subsection{\csh{xintDivMod}}
+\label{xintDivMod}
+
+Computes both the floored division and the remainder\etype{\Ff\Ff}
+\csbxint{DivFloor}. New at |1.2p| and documented at |1.3a|.
+\begin{everbatim*}
+\oodef\foo{\xintDivMod{-170/3}{23/2}}\meaning\foo
+\end{everbatim*}
+
+\subsection{\csh{xintDivTrunc}}
+\label{xintDivTrunc}
+
+Computes the quotient \etype{\Ff\Ff} of two arguments then
+truncates to an integer (in strict format).
+\begin{everbatim*}
+\xintDivTrunc{-170/3}{23/2}
+\end{everbatim*}
+
+\subsection{\csh{xintModTrunc}}
+\label{xintModTrunc}
+
+Computes the remainder\etype{\Ff\Ff} associated with the truncated division of
+two arguments. Prior to |1.2p| it was named \csbxint{Mod}, but the latter then
+got associated with floored division.
+\begin{everbatim*}
+\xintModTrunc{-170/3}{23/2}
+\end{everbatim*}
+
+Modified at |1.3| to use a l.c.m. for the denominator of the result.
+\CHANGED{1.3}
+
+\subsection{\csh{xintDivRound}}
+\label{xintDivRound}
+
+Computes the quotient \etype{\Ff\Ff} of the two arguments then rounds to an
+integer (in strict format).
+\begin{everbatim*}
+\xintDivRound{-170/3}{23/2}
+\end{everbatim*}
+
+\subsection{\csh{xintSqr}}\label{xintSqr}
+
+Computes the square\etype{\Ff} of one fraction.
+
+\subsection{\csh{xintPow}}\label{xintPow}
+
+\csa{xintPow}{|{f}{x}|}:\etype{\Ff\Numf} computes |f^x| with |f| a fraction and
+|x| possibly also, but |x| will first get truncated to a (positive or negative)
+integer.
+
+The exponent |x| must obey the TeX-bound, but this limit is theoretical, as
+\TeX's memory or expansion settings get saturated quite earlier: it is
+explained in the documentation of \csbxint{iiPow} that the maximal power of
+$2$ computable by \xintname is |2^131072| which has \dtt{39457} digits.
+Actually, the pratical range is even smaller due to execution times.
+
+The output will always be in the form |A/B[n]| (even if the exponent
+vanishes: |\xintPow {2/3}{0}|\dtt{=\xintPow{2/3}{0}}).
+
+
+Within an \csbxint{iiexpr}|..\relax| the infix operator |^| is mapped to
+\csa{xintiiPow}; within an \csbxint{expr}-ession it is mapped to
+\csa{xintPow}.
+
+\subsection{\csh{xintFac}}\label{xintFac}
+
+This is a convenience variant of \csbxint{iiFac} which applies \csbxint{Num}
+to its argument\etype{\Numf}. Notice however that the output will have a trailing
+|[0]| according to the \xintfracname format for integers.
+
+
+\subsection{\csh{xintBinomial}}\label{xintBinomial}
+
+This is a convenience variant of \csbxint{iiBinomial} which applies
+\csbxint{Num} to its arguments\etype{\Numf\Numf}. Notice however that the
+output will have a trailing |[0]| according to the \xintfracname format for
+integers.
+
+
+\subsection{\csh{xintPFactorial}}\label{xintPFactorial}
+
+This is a convenience variant of \csbxint{iiPFactorial} which applies
+\csbxint{Num} to its arguments\etype{\Numf\Numf}. Notice however that the
+output will have a trailing |[0]| according to the \xintfracname format for
+integers.
+
+
+\subsection{\csh{xintMax}}\label{xintMax}
+
+The maximum of two fractions.\etype{\Ff\Ff} Beware that |\xintMax {2}{3}|
+produces \dtt{\xintMax {2}{3}}. The original, for use with
+integers only with no need of normalization, is available as \csbxint{iiMax}:
+|\xintiiMax {2}{3}=|\dtt{\xintiiMax {2}{3}}.\etype{ff}
+
+\begin{everbatim*}
+\xintMax {2.5}{7.2}
+\end{everbatim*}
+
+\subsection{\csh{xintMin}}\label{xintMin}
+
+The minimum of two fractions.\etype{\Ff\Ff} Beware that |\xintMin {2}{3}|
+produces \dtt{\xintMin {2}{3}}. The original, for use with
+integers only with no need of normalization, is available as \csbxint{iiMin}:
+|\xintiiMin {2}{3}=|\dtt{\xintiiMin {2}{3}}.\etype{ff}
+
+\begin{everbatim*}
+\xintMin {2.5}{7.2}
+\end{everbatim*}
+
+\subsection{\csh{xintMaxof}}\label{xintMaxof}
+
+The maximum of any number of fractions, each within braces, and the whole
+thing within braces. \etype{f{$\to$}{\lowast\Ff}}
+
+\begin{everbatim*}
+\xintMaxof {{1.23}{1.2299}{1.2301}} and \xintMaxof {{-1.23}{-1.2299}{-1.2301}}
+\end{everbatim*}
+
+\subsection{\csh{xintMinof}}\label{xintMinof}
+
+The minimum of any number of fractions, each within braces, and the whole
+thing within braces. \etype{f{$\to$}{\lowast\Ff}}
+
+\begin{everbatim*}
+\xintMinof {{1.23}{1.2299}{1.2301}} and \xintMinof {{-1.23}{-1.2299}{-1.2301}}
+\end{everbatim*}
+
+\subsection{\csh{xintSum}}\label{xintSum}
+
+This\etype{f{$\to$}{\lowast\Ff}} computes the sum of fractions. The output
+will now always be in the form |A/B[n]|. The original, for big integers only
+(in strict format), is available as \csa{xintiiSum}.
+
+\begin{everbatim*}
+\xintSum {{1282/2196921}{-281710/291927}{4028/28612}}
+\end{everbatim*}
+
+No simplification attempted.
+
+\subsection{\csh{xintPrd}}\label{xintPrd}
+
+TThis\etype{f{$\to$}{\lowast\Ff}} computes the product of fractions. The output
+will now always be in the form |A/B[n]|. The original, for big integers only
+(in strict format), is available as \csa{xintiiPrd}.
+
+\begin{everbatim*}
+\xintPrd {{1282/2196921}{-281710/291927}{4028/28612}}
+\end{everbatim*}
+
+No simplification attempted.
+
+\begin{everbatim*}
+$\xintIsOne {21921379213/21921379213}\neq\xintIsOne {1.00000000000000000000000000000001}$
+\end{everbatim*}
+
+\subsection{\csh{xintDigits}, \csh{xinttheDigits}}
+\label{xintDigits}
+\label{xinttheDigits}
+
+The syntax |\xintDigits := D;| (where spaces do not matter) assigns the
+value of |D| to the number of digits to be used by floating point
+operations. The default is |16|. The maximal value is |32767|. The macro
+|\xinttheDigits|\etype{} serves to print the current value.
+
+\subsection{\csh{xintFloat}}\label{xintFloat}
+
+
+The macro |\xintFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} has an optional
+argument |P| which replaces the current value of |\xinttheDigits|. The
+fraction |f| is then printed in scientific notation with a rounding to |P| digits.
+
+That is, on output: the first digit is from |1| to |9|, it is possibly
+prefixed by a minus sign and is followed by a dot and |P-1| digits, then a
+lower case |e| and an exponent |N|. The trailing zeroes are not trimmed.
+
+\begin{framed}
+ There is currently one exceptional case: the zero value, which gets output
+ as \dtt{\xintFloat{0}}. It is yet to be decided what the final policy will be.
+\end{framed}
+
+Starting with |1.2k|, when the input is a fraction |AeN/BeM|
+the output always is the \emph{correct rounding} to |P| digits. Formerly, this
+was guaranteed only when |A| and |B| had at most |P+2| digits, or when |B| was
+|1| and |A| was arbitrary, but in other cases it was only guaranteed that the
+difference between the original fraction and the rounding was at most
+\dtt{0.6} unit in the last place (of the output), hence the output could
+differ in the last digit (and earlier ones in case of chains of zeros or
+nines) from the correct rounding.
+
+Also: for releases |1.2j| and earlier, in the special case when
+|A/B| ended up being rounded up to the next power of ten, the output was with
+a mantissa of the shape |10.0...0eN|. However, this worked only for |B=1| or
+when both |A| and |B| had at most |P+2| digits, because the detection of the
+rounding-up to next power of ten was done not on original |A/B| but on an
+approximation |A'/B'|, and it could happen that |A'/B'| was itself being
+rounded \emph{down} to a power of ten which however was a rounding \emph{up}
+of original |A/B|. With the |1.2j| refactoring which achieves correct rounding
+in all cases, it was decided not to add to the code the extra overhead of
+detecting with 100\% fiability the rounding up to next power of ten (such
+overhead would necessitate alterations of the algorithm and as a result we
+would end up with a slightly less efficient one; it would make sense in a
+model where inputs have their intrinsic precisions which is obeyed by the
+implementation of the basic operations, but currently the design decision for
+the floating point macros is that when the target precision is |P| the inputs
+are rounded first to |P| digits before further processing.)
+\begin{everbatim*}
+{\def\x{99999999999999994999999999999999/99999999999999999999999999999999}%
+\xintFor #1 in {13, 14, 15, 16, 17, 18, 19, 47, 48, 49, 50, 79, 80, 81}
+\do{#1: \xintFloat[#1]{\x}\xintifForLast{\par}{\newline}}}%
+\end{everbatim*}
+As an aside, which is illustrated by the above, rounding is not
+transitive in the number of kept digits.
+\begin{everbatim*}
+{\def\x{137893789173289739179317/13890138013801398}%
+\xintFor* #1 in {\xintSeq{4}{20}}
+\do{#1: \xintFloat[#1]{\x}\newline}}%
+\xintFloat{5/9999999999999999}\newline
+\xintFloat[32]{5/9999999999999999}\newline
+\xintFloat[48]{5/9999999999999999}\par
+\end{everbatim*}
+
+
+
+\subsection{\csh{xintPFloat}}\label{xintPFloat}
+
+The macro |\xintPFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} is like
+\csbxint{Float} but ``pretty-prints'' the output. Its behaviour has changed
+with release |1.2f|\IMPORTANT{}: there is only one simplification rule now
+which is that decimal notation (with possibly needed extra zeros) is used in
+place of scientific notation when the exponent would end up being between
+\dtt{-5} and \dtt{5} inclusive.
+
+If the input vanishes the output will be \dtt{\xintPFloat{0}} with a a decimal
+mark.%
+%
+\footnote{Currently there are no subnormal numbers, and no underflow
+ because the exponent is only limited by the maximal \TeX\ number; thus
+ underflow situations would manifest themselves via low-level arithmetic
+ overflow errors.}
+
+\csbxint{thefloatexpr} applies this macro to its output (or each of
+its outputs, if comma separated).
+
+Currently trailing zeros are not trimmed.
+
+\begin{everbatim*}
+\begingroup\def\test #1{#1${}\to{}$\xintPFloat{#1}}%
+\string\xintDigits\ at \xinttheDigits
+\begin{itemize}[nosep]
+\item \test {0}
+\item \test {1.23456789e-7}
+\item \test {1.23456789e-6}
+\item \test {1.23456789e-5}
+\item \test {1.23456789e-4}
+\item \test {1.23456789e-3}
+\item \test {1.23456789e-2}
+\item \test {1.23456789e-1}
+\item \test {1.23456789e0}
+\item \test {1.23456789e1}
+\item \test {1.23456789e2}
+\item \test {1.23456789e3}
+\item \test {1.23456789e4}
+\item \test {1.23456789e5}
+\item \test {1.23456789e6}
+\item \test {1.23456789e7}
+\end{itemize}
+\endgroup
+\end{everbatim*}
+
+
+\subsection{\csh{xintFloatE}}\label{xintFloatE}
+
+|\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*}
+
+\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 obviously much needed that the author improves its algorithms to avoid
+ going through the exact |2P| or |2P-1| digits before
+ throwing to the waste-bin half of those digits !
+
+ % \xintname initially was purely an \emph{exact} arbitrary precision
+ % arithmetic machine, and the introduction of floating point numbers was an
+ % after-thought. I got it working in release |1.07 (2013/05/25)| and never had
+ % time to come back to it.
+\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 places 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 [8]{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 must simplify to a (possibly big) 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 places to give
+|f'|. The output |Z| is then such that the exact |f'^g| differs from
+|Z| by an absolute error less than |0.52 ulp(Z)|.
+
+This is the macro which is used for the |^| (or |**|) infix operators in
+|\xintthefloatexpr...\relax|. In this context (but not directly with the
+macro,) half-integer exponents are allowed. This is handled via an integer power
+followed by a square-root extraction. The exponent is first rounded to nearest
+integer or half-integer so that the computation never raises errors (except
+naturally for negative exponent and zero |f|.) The |0.52 ulp(Z)| bound applies
+with half-integer exponents too.
+
+
+Notice that this is a bound on the distance from |f'^g| to |Z|, as |f| always
+gets rounded to |P| or \csbxint{theDigits} digits. 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;\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;\np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}}\newline
+\np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}\newline
+{\xintDigits:=27;\np{\xintthefloatexpr (1+1e-8)^(12^16)\relax}}\newline
+{\xintDigits:=48;\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{|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, as
+the Stirling formula cannot be used for lack so far of |exp/log|.
+
+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<y| the
+macro evaluates to \dtt{\xintFloatBinomial{1}{-1}}.
+The exact theoretical value differs from the calculated one |Y| by an absolute
+error strictly less than |0.6 ulp(Y)|.
+
+\begin{everbatim*}
+${3000\choose 1500}\approx{}$\xintFloatBinomial [24]{3000}{1500}
+\end{everbatim*}
+
+% \begin{everbatim*}
+% ${9999\choose 5000}\approx{}$\xintFloatBinomial [24]{9999}{5000}
+% \end{everbatim*}
+
+% 2015/11/28
+% 7.95895131766219474168799e3007
+% aparté: (testé avec Maple 16, 2015/11/28)
+% > 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;
+
+\subsection{\csh{xintFrac}}\label{xintFrac}
+
+This is a \LaTeX{} only macro,\etype{\Ff} to be used in math mode only. It
+will print a fraction, internally represented as something equivalent to
+|A/B[n]| as |\frac {A}{B}10^n|. The power of ten is omitted when |n=0|, the
+denominator is omitted when it has value one, the number being separated from
+the power of ten by a |\cdot|. |$\xintFrac {178.000/25600000}$| gives $\xintFrac
+{178.000/25600000}$, |$\xintFrac {178.000/1}$| gives $\xintFrac {178.000/1}$,
+|$\xintFrac {3.5/5.7}$| gives $\xintFrac {3.5/5.7}$, and |$\xintFrac {\xintNum
+ {\xintiiFac{10}/|\allowbreak|\xintiiSqr{\xintiiFac {5}}}}$| gives $\xintFrac
+{\xintNum {\xintiiFac{10}/\xintiiSqr{\xintiiFac {5}}}}$. As shown by the examples,
+simplification of the input (apart from removing the decimal points and moving
+the minus sign to the numerator) is not done automatically and must be the
+result of macros such as |\xintIrr|, |\xintREZ|, or |\xintNum| (for fractions
+being in fact integers.)
+
+\subsection{\csh{xintSignedFrac}}\label{xintSignedFrac}
+
+
+This is as \csbxint{Frac}\etype{\Ff} except that a negative fraction has the
+sign put in front, not in the numerator.
+\begin{everbatim*}
+\[\xintFrac{-355/113}=\xintSignedFrac {-355/113}\]
+\end{everbatim*}
+
+\subsection{\csh{xintFwOver}}\label{xintFwOver}
+
+This does the same as \csa{xintFrac}\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). |$\xintFwOver {178.000/25600000}$|
+gives $\xintFwOver {178.000/25600000}$, |$\xintFwOver {178.000/1}$| gives
+$\xintFwOver {178.000/1}$, |$\xintFwOver {3.5/5.7}$| gives $\xintFwOver
+{3.5/5.7}$, and |$\xintFwOver {\xintNum {\xintiiFac{10}/\xintiiSqr{\xintiiFac
+ {5}}}}$| gives $\xintFwOver {\xintNum {\xintiiFac{10}/\xintiiSqr{\xintiiFac
+ {5}}}}$.
+
+\subsection{\csh{xintSignedFwOver}}\label{xintSignedFwOver}
+
+This is as \csbxint{FwOver}\etype{\Ff} except that a negative fraction has the
+sign put in front, not in the numerator.
+\begin{everbatim*}
+\[\xintFwOver{-355/113}=\xintSignedFwOver {-355/113}\]
+\end{everbatim*}
+
+\subsection{\csh{xintLen}}\label{xintLenFrac}
+
+The original \csbxint{Len} macro\etype{\Ff} 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).
+
+\clearpage
+\let\xintfracnameUp\undefined
+\csname xintexprnameUp\endcsname
+\def\n{|{N}|}
+\def\m{|{M}|}
+\def\x{|{x}|}
+\section{Macros of the \xintexprname package}%
+\RaisedLabel{sec:expr}
+
+\localtableofcontents
+
+The \xintexprname package was first released with version |1.07|
+(|2013/05/25|) of the \xintname bundle. It was substantially enhanced with
+release |1.1| from |2014/10/28|.
+
+The package loads automatically \xintfracname and \xinttoolsname.
+\begin{itemize}
+\item |1.3d| adds \csbxint{eval}, \csbxint{ieval}, \csbxint{iieval},
+ \csbxint{floateval}.\NewWith{1.3d}
+\item for the \func{gcd} and \func{lcm} functions, it is NOT necessary anymore
+ to
+ load package \xintgcdname. And they now work not only with integers:\NewWith{1.3d}
+\begin{everbatim*}
+\xinttheiiexpr lcm (2^5*7*13^10*17^5,2^3*13^15*19^3,7^3*13*23^2)\relax\newline
+\end{everbatim*}%
+but also with fractions:\IMPORTANT
+\begin{everbatim*}
+\xinttheexpr lcm(7/300, 11/150, 13/60), gcd(7/300, 11/150, 13/60)\relax\par
+\end{everbatim*}
+\item for allowing hexadecimal (uppercase letters only) input, it is \emph{necessary}
+ to load package \xintbinhexname.\IMPORTANT
+ \begin{everbatim*}
+\xinttheexpr "A*"B*"C*"D*"D*"F, "FF.FF, reduce("FF.FFF + 16^-3)\relax
+\end{everbatim*}
+\end{itemize}
+
+Please refer to \autoref{sec:xintexprsyntax} for a more detailed description
+of some syntax elements.
+
+\subsection{The \csh{xintexpr} expressions}
+\label{xintexpr}
+\label{xinttheexpr}
+\label{thexintexpr}
+\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).
+Like a |\numexpr| expression, it is not printable as is, nor can it be directly
+employed as argument to the other package macros. For this one must use one
+of the three equivalent forms:
+\begin{itemize}
+\item \csb{thexintexpr}\meta{expandable\_expression}|\relax|\etype{x}, or
+\item \csb{xinttheexpr}\meta{expandable\_expression}|\relax|\etype{x}, or
+\item \csb{xintthe}|\xintexpr|\meta{expandable\_expression}|\relax|.\etype{x}
+\end{itemize}
+
+The computations are done \emph{exactly}, and with no simplification of the
+result. See \csbxint{floatexpr} for a similar parser which rounds each
+operation inside the expression to \csbxint{theDigits} digits of precision.
+
+As an alternative and equivalent syntax to
+\begin{everbatim}
+\xintexpr round(<expression>, D)\relax
+\end{everbatim}
+there is\footnote{For truncation rather than rounding, one uses
+|\xintexpr trunc(<expression>, D)\relax|.}
+\begin{everbatim}
+\xintiexpr [D] <expression> \relax
+\end{everbatim}
+The parameter |D| must be zero or positive.\footnote{|D=0|
+ corresponds to using |round(<expression>)| not |round(<expression>,0)| which
+ would leave a trailing dot. Same for |trunc|. There is also function |float|
+ for floating point rounding to \csbxint{theDigits} or the given number of
+ significant digits as second argument.} Perhaps some future version will
+give a meaning to using a negative |D|.\footnote{Thanks to KT for this
+ suggestion. Sorry for the delay in implementing it... matter of formatting
+ the output and corresponding choice of user interface are still in need of
+ some additional thinking.}
+
+\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 the other package macros,
+ or more generally to macros which expand their arguments, one must use the
+ |\xinttheexpr...\relax| or |\xintthe\xintexpr...\relax| forms.
+ \item similarly,
+ printing the result itself must be done with these forms.
+ \item one should not use |\xinttheexpr...\relax| as a sub-constituent of an
+ |\xintexpr...\relax| 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}
+
+See \autoref{sec:xintexprsyntax} for the primary information on built-in
+operators and functions. This section now adds some complementary information.
+
+
+\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. For
+ example, the French language in |Babel| system, for pdf\LaTeX, activates |!|,
+ |?|, |;| and |:|. Turn off the activity before expressions using such characters.
+
+ Alternatively the macro \csbxint{exprSafeCatcodes} resets all
+ characters potentially needed by \csbxint{expr} to their standard catcodes
+ and \csbxint{exprRestoreCatcodes} restores the former status.
+
+\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 an internal private format.
+ 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|. Same as |\xintexpr| with the final
+ result converted to $1$ if it is not zero.
+
+\item See also
+ \csbxint{ifboolexpr} (\autoref{xintifboolexpr}) and the
+ \func{bool} and \func{togl} functions
+ in \autoref{sec:expr}. Here is an example:
+\catcode`| 12 %
+\begin{everbatim*}
+\xintNewBoolExpr \AssertionA[3]{ #1 && (#2||#3) }
+\xintNewBoolExpr \AssertionB[3]{ #1 || (#2&&#3) }
+\xintNewBoolExpr \AssertionC[3]{ xor(#1,#2,#3) }
+{\centering\normalcolor\xintFor #1 in {0,1} \do {%
+ \xintFor #2 in {0,1} \do {%
+ \xintFor #3 in {0,1} \do {%
+ #1 AND (#2 OR #3) is \textcolor[named]{OrangeRed}{\AssertionA {#1}{#2}{#3}}\hfil
+ #1 OR (#2 AND #3) is \textcolor[named]{OrangeRed}{\AssertionB {#1}{#2}{#3}}\hfil
+ #1 XOR #2 XOR #3 is \textcolor[named]{OrangeRed}{\AssertionC {#1}{#2}{#3}}\\}}}}
+\end{everbatim*}\catcode`| 13
+
+ This example used for efficiency \csbxint{NewBoolExpr}. See also the
+ \autoref{xintNewExpr}.
+
+\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;| 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, if not thousands, of digits.
+ %
+\begin{everbatim*}
+\xintDigits:=48;\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 once 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}
+
+Active characters may (and will) break the functioning of \csbxint{expr}.
+Inside an expression one may prefix, for example a |:| with |\string|. Or, for
+a more radical way, there is \csbxint{exprSafeCatcodes}. This is a
+non-expandable step as it changes catcodes.
+
+\subsubsection{\csh{xintexprSafeCatcodes}}
+\label{xintexprSafeCatcodes}
+
+This macro sets the catcodes of many characters to safe values. 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.
+
+Also \csbxint{defvar}, \csbxint{deffunc}, ..., use it before fetching their
+semi-colon delimited arguments, so they can be used (also in the document
+body) for example with Babel+French which makes the semi-colon active in the
+(\LaTeX) document body.\CHANGED{1.3c}
+
+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.
+
+But \csbxint{deffunc}, \csbxint{defvar} and variants need the (catcode other)
+semi-colon as delimiter. Thus make sure the semi-colon has its normal catcode
+when using \csbxint{deffunc} inside some macro definition.
+
+The macros \csbxint{deffunc} and variants ignore completely the colon in |:=|
+(which furthermore is optional) so it can have any (reasonable) frozen catcode.
+
+The macros \csbxint{defvar} and variants are also compatible with any
+reasonable frozen catcode of the colon |:| in |:=|, and the colon presence is
+only optional.\NewWith{1.3c}
+
+\begin{framed}
+ It is important to ALWAYS shortly let \csbxint{exprSafeCatcodes} be followed
+ by \csbxint{exprRestoreCatcodes}.\IMPORTANTf{} If one uses twice
+ \csbxint{exprSafeCatcodes} then the next \csbxint{exprRestoreCatcodes} will
+ restore the ancien catcode regime at time of the first one.
+\end{framed}
+
+\subsubsection{\csh{xintexprRestoreCatcodes}}
+\label{xintexprRestoreCatcodes}
+
+Restores the catcodes to the earlier state. More precisely,
+\csbxint{exprSafeCatcodes} sets a toggle (with local scope). If the toggle is
+set already it does not restore the current catcodes. The next
+\csa{xintexprRestoreCatcodes} unsets the toggle.\CHANGED{1.3c}
+So, in case of nesting, the
+catcodes are restored to what they were when the \emph{first} un-paired
+\csbxint{exprSafeCatcodes} got executed.
+
+\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: (unbraced) digits, binary operators, minus and plus signs as
+prefixes, dot as decimal mark, parentheses, may be indifferently of catcode
+letter or other or subscript or superscript, ..., it doesn't matter.%
+%
+\footnote{Furthermore, although \csbxint{expr} uses \csa{string}, it is
+ escape-char agnostic. It should work with any \csa{escapechar} setting
+ including -1.}
+
+The characters |+|, |-|, |*|, |/|, |^|, |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|,
+|=|, |(|, |)|, |"|, |[|, |]|, |;|, the dot and the comma should not be active if
+in the expression, as everything is expanded along the way. If one of them is
+active, it should be prefixed with |\string|.
+
+The exclamation mark |!| should have its standard catcode: with catcode letter
+it is used internally and hence will confuse the parsers if it comes from the
+expression.
+
+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''.
+
+A macro with arguments will expand and grab its arguments before the
+parser may get a chance to see them, so the situation with catcodes and spaces
+is not the same within such macro arguments.
+
+
+
+\subsection{Expandability, \csh{xintexpro}}
+
+As is the case with all other package macros |\xintexpr| \fexpan ds (in two
+steps) to its final (non-printable) 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.
+
+Starting with |1.09j|, an |\xintexpr..\relax| can be inserted without
+|\xintthe| prefix inside an |\edef|, or a |\write|. It expands to a private
+more compact representation (five tokens) than |\xinttheexpr| or
+|\xintthe\xintexpr|.
+
+The material between |\xintexpr| and |\relax| should contain only expandable
+material.
+
+The once expanded |\xintexpr| is |\romannumeral0\xintexpro|.\CHANGED{1.3d}
+\centeredline{ATTENTION! Prior to |1.3d| the |\xintexpro| macro was named
+ |\xinteval|.}
+But \csbxint{eval} is now something else. And there
+is similarly |\xintiexpro| (formerly |\xintieval|), |\xintiiexpro| (formerly
+|\xintiieval|), and |\xintfloatexpro| (formerly |\xintfloateval|). For an
+example see \autoref{ssec:fibonacci}.
+
+An expression can only be legally finished by a |\relax| token, which
+will be absorbed.
+
+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 surrounding ``environment'' is the
+|\xintiiexpr| one.
+
+\subsection{Memory considerations}
+\label{ssec:memory}
+
+The parser creates an undefined control sequence for each intermediate
+computation evaluation: addition, subtraction, etc\dots Thus, a moderately sized
+expression might create 10, or 20 such control sequences. On my \TeX{}
+installation, the memory available for such things is of circa \np{200000}
+multi-letter control words. So this means that a document containing hundreds,
+perhaps even thousands of expressions will compile with no problem.
+
+Besides the hash table, also \TeX{} main memory is impacted. Thus, if
+\xintexprname is used for computing plots%
+%
+\footnote{this is not very probable as so far \xintname does not include
+ a mathematical library with floating point calculations, but provides
+ only the basic operations of algebra.}%
+%
+, this may cause a problem. In my testing and with current |TL2015| memory
+settings, I ran into problems after doing about \emph{ten thousand}
+evaluations (for example |(#1+#2)*#3-#1*#3-#2*#3)|) each with number having
+\emph{hundreds} of digits. Typical error message can be:
+\begin{everbatim}
+./testaleatoires.tex:243: TeX capacity exceeded, sorry [pool size=6134970].
+<argument> ...19140037877484848545931233090884903
+\end{everbatim}
+
+There is a (partial) solution.%
+%
+\footnote{which convinced me that I could stick with the parser
+ implementation despite its potential impact on the hash-table and
+ other parts of \TeX{}'s memory.}
+
+A document can possibly do tens of thousands of evaluations only if some
+identical formulae are being used repeatedly, with varying arguments (from
+previous computations possibly) or coming from data being fetched from a file.
+Most certainly, there will be a a few dozens formulae at most, but they will
+be used again and again with varying inputs.
+
+With the \csbxint{NewExpr} macro, it is possible to convert once and
+for all an expression containing parameters into an expandable macro
+with parameters. Only this initial definition of this macro actually
+activates the \csbxint{expr} parser and will (very moderately) impact
+the hash-table: once this unique parsing is done, a macro with
+parameters is produced which is built-up recursively from the
+\csbxint{Add}, \csbxint{Mul}, etc... macros, exactly as it would be
+necessary to do without the facilities of the \xintexprname package.
+
+Notice that since |1.2c| the \csbxint{deffunc} construct allows an alternative
+to \csa{xintNewExpr} whose syntax uses arbitrary letters rather than macro
+parameters |#1|, |#2|, ..., |#9|. The declared function must still be used
+inside an expression, but its use will need only as many |\csname|'s as were
+needed for the function arguments plus one more for encapsulating the function
+result.
+
+\subsection{\csh{xintiexpr}, \csh{xinttheiexpr}}
+\label{xintiexpr}\label{xinttheiexpr}\label{thexintiexpr}
+
+Equivalent\etype{x} to doing |\xintexpr round(...)\relax| (more precisely,
+|round| is applied to each one of the evaluated values, if the expression was
+comma separated). Thus, only the \emph{final result value} is rounded to an
+integer. Half integers are rounded towards $+\infty$ for positive numbers and
+towards $-\infty$ for negative ones.
+
+An optional parameter |d>0| within brackets, immediately after |\xintiexpr|
+is allowed: it instructs the expression to do its final rounding to the
+nearest value with that many digits after the decimal mark, \emph{i.e.},
+|\xintiexpr [d] <expression>\relax| is equivalent (in case of a single
+expression) to |\xintexpr round(<expression>, d)\relax|.
+
+|\xintiexpr [0] ...| is the same as |\xintiexpr ...|.\footnote{Incidentally
+ using |round(...,0)| in place of |round(...)| in |\xintexpr| would leave a
+ trailing dot in the produced value.}
+
+If truncation rather than rounding is needed use (in case of a single
+expression, naturally) |\xintexpr trunc(...)\relax| for truncation to an
+integer or |\xintexpr trunc(...,d)\relax| for truncation to a decimal number
+with |d>0| digits after the decimal mark.
+
+Perhaps in the future some meaning will be given to using negative value for
+the optional parameter |d|.\footnote{Thanks to KT for this suggestion.}
+
+|\thexintiexpr| is synonym to |\xinttheiexpr|.
+
+\subsection{\csh{xintiiexpr}, \csh{xinttheiiexpr}}
+\label{xintiiexpr}\label{xinttheiiexpr}\label{thexintiiexpr}
+
+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 |round|, |trunc|, |floor|, |ceil| functions are still available, and are
+about the only places where fractions can be used, but |/| within, if not
+somehow hidden will be executed as integer rounded division. To avoid this one
+can wrap the input in \dtt{qfrac}: this means however that none of the normal
+expression parsing will be executed on the argument.
+
+To understand the illustrative examples, recall that |round| and |trunc| have
+a second (non negative) optional argument. In a normal \csbxint{expr}-essions,
+|round| and |trunc| are mapped to \csbxint{Round} and \csbxint{Trunc}, in
+\csbxint{iiexpr}-essions, they are mapped to \csbxint{iRound} and
+\csbxint{iTrunc}.
+
+
+\begin{everbatim*}
+\xinttheiiexpr 5/3, round(5/3,3), trunc(5/3,3), trunc(\xintDiv {5}{3},3),
+trunc(\xintRaw {5/3},3)\relax{} are problematic, but
+%
+\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*}
+
+On the other hand decimal numbers and scientific numbers can be used directly
+as arguments to the |num|, |round|, or any function producing an integer.
+
+\begin{framed}
+ Scientific numbers will be
+ represented with as many zeroes as necessary, thus one does not want to
+ insert \dtt{num(1e100000)} for example in an \csa{xintiiexpr}ession !
+\end{framed}
+
+%
+\begin{everbatim*}
+\xinttheiiexpr num(13.4567e3)+num(10000123e-3)\relax % should (num truncates) compute 13456+10000
+\end{everbatim*}
+%
+
+The |reduce| function is not available and will raise un 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
+
+\noindent The next example requires the |round|, and one could not put the |+| inside it:
+
+\xinttheiiexpr round(\xintFloatSqrt [20]{2},19)+round(\xintFloatSqrt [20]{3},19)\relax
+
+(the second argument of |round| and |trunc| tells how many digits from after the
+decimal mark one should keep.)
+\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).
+
+
+|\thexintiiexpr| is synonym to |\xinttheiiexpr|.
+
+\subsection{\csh{xintboolexpr},
+ \csh{xinttheboolexpr}}
+\label{xintboolexpr}\label{xinttheboolexpr}\label{thexintboolexpr}
+
+
+Equivalent\etype{x} to doing |\xintexpr ...\relax| and returning $1$ if the
+result does not vanish, and $0$ is the result is zero. As |\xintexpr|, this
+can be used on comma separated lists of expressions, and will return a
+comma separated list of $0$'s and $1$'s.
+
+|\thexintboolexpr| is synonym to |\xinttheboolexpr|.
+
+There is slight 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}\label{thexintfloatexpr}
+
+\csbxint{floatexpr}|...\relax|\etype{x} is exactly like |\xintexpr...\relax|
+but with the four binary operations and the power function are mapped to
+\csa{xintFloatAdd}, \csa{xintFloatSub}, \csa{xintFloatMul}, \csa{xintFloatDiv}
+and \csa{xintFloatPower}, respectively.\footnote{Since |1.2f| the \string^
+ handles half-integer exponents, contrarily to \csa{xintFloatPower}.}
+
+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 is allowed:
+\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, rounding
+ the value).\NewWith{1.3e} 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.
+
+|\thexintfloatexpr| is synonym to |\xintthefloatexpr|.
+
+|\xintDigits:=36;|\xintDigits:=36;
+%
+\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.
+
+\subsection{\csh{xinteval}, \csh{xintieval}, \csh{xintiieval},
+ \csh{xintfloateval}}
+\label{xinteval}\label{xintieval}\label{xintiieval}\label{xintfloateval}
+
+\begin{framed}
+ Prior to |1.3d|,\NewWithf{1.3d} these macros existed but with a different meaning: they
+ arose in the once-expanded \csbxint{expr}, etc..., i.e. one had:
+\begin{everbatim}
+\def\xintexpr{\romannumeral0\xinteval}
+\end{everbatim}
+ The\IMPORTANTf\ old macros were renamed into \csa{xintexpro}, etc..., in order to free
+ their names for new meanings, more alike what one finds in
+ other math packages.
+\end{framed}
+
+\csbxint{eval}\etype{x} is an \fexpan dable macro which is basically defined
+like this:
+\begin{everbatim}
+\def\xinteval#1{\romannumeral-`0\xinttheexpr#1\relax}
+\end{everbatim}
+thus expands in two steps (its exact definition differs from the one given
+above in order to achieve a slight optimization).
+\begin{everbatim*}
+\xinteval{add(x^2, x = 100..110), add(x^3, x = 100..110)}
+\end{everbatim*}
+
+\csbxint{ieval}\etype{x} is similarly related to \csbxint{theiexpr}. Its optional
+argument must be located inside the braces:
+\begin{everbatim*}
+\xintieval{[7] 355/113}
+\end{everbatim*}
+
+\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}. Its optional
+argument must be located inside the braces:
+\begin{everbatim*}
+\xintfloateval{[7] 355/113}
+\end{everbatim*}
+
+When negative it tells how many digits to remove from the prevailing precision
+(\csbxint{theDigits}):\NewWith{1.3e}
+\begin{everbatim*}
+\xintfloateval{[-2] 355/113} has \xinttheDigits\ minus 2 digits.
+\end{everbatim*}
+
+These macros are useful when one uses some extra wrapper doing some parsing of
+its input, like the |\num| macro of
+\href{http://ctan.org/pkg/siunitx}{siunitx}, which would choke on some of the
+syntax elements allowed inside \csb{xintexpr}|...\relax| (for example
+brackets).
+As shown in the above examples, these macros, like the underlying parsers
+accept arbitrarily many comma separated expressions.
+
+
+\subsection{Using an expression parser within another one}
+
+This was already illustrated before. In the following:
+\begin{everbatim*}
+\xintthefloatexpr \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*}
+\xintthefloatexpr 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*}
+\xinttheiiexpr round(\xintfloatexpr 3.14^10\relax)\relax % or trunc
+\end{everbatim*}
+
+
+\subsection{The \csh{xintthecoords} macro}
+\label{xintthecoords}
+
+It converts a comma separated list into the format for list of coordinates as
+expected by the |TikZ| |coordinates| syntax.%
+%
+\footnote{The implementation had to work around the
+problem that |TikZ| seemingly allows only a maximal number of about one
+hundred expansion steps for the list to be entirely produced.}%
+%
+\begin{everbatim*}
+\begin{figure}[htbp]
+\centering\begin{tikzpicture}[scale=10]\xintDigits:=8;
+ \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 what is next into (x1, y1) (x2, y2)... format)
+ \xintfloatexpr seq((x^2-1,mul(x-t,t=-1+[0..4]/2)),x=-1.2..[0.1]..+1.2) \relax };
+\end{tikzpicture}
+\caption{Coordinates with \cs{xintthecoords}.}
+\end{figure}
+\end{everbatim*}
+
+% Notice: if x goes no take exactly value 1 or -1, the origin appears slightly
+% off the curve, not MY fault!!!
+
+As examplified above, \csbxint{thecoords} is to be used followed immediately
+by either \csbxint{floatexpr} or \csbxint{iexpr} or \csbxint{iiexpr}. See
+\url{https://tex.stackexchange.com/a/447290} for another example.
+
+As |TikZ| will not understand the |A/B[N]| format which is used on output by
+|\xintexpr|, |\xintthecoords\xintexpr| has no use inside a |TikZ| picture but
+may have other usages; the reason for the spaces in output is to allow if
+necessary to print on the page for examination and give \TeX\ a change to
+establish line-breaks.
+
+\begin{everbatim*}
+\edef\x{\xintthecoords \xintexpr rrseq(1/2,1/3; @1+@2, x=1..20)\relax }
+\meaning\x +++
+\end{everbatim*}
+
+\subsection{\csh{xintifboolexpr}, \csh{xintifboolfloatexpr}, \csh{xintifbooliiexpr}}
+\label{xintifboolexpr}
+\label{xintifboolfloatexpr}
+\label{xintifbooliiexpr}
+
+\csh{xintifboolexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does
+\csbxint{theexpr}<expr>|\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.
+
+\csh{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.
+
+\csh{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}
+
+\csh{xintifsgnexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates
+the \csbxint{expr}ession and chooses the branch corresponding to its sign.
+
+\csh{xintifsgnfloatexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates
+the \csbxint{floatexpr}ession and chooses the branch corresponding to its sign.
+
+\csh{xintifsgniiexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates
+the \csbxint{iiexpr}ession and chooses the branch corresponding to its sign.\NewWith{1.3d}
+
+The expression argument must be a single one, comma separated sub-expressions
+will cause low-level errors.
+
+\subsection{The \csh{xintNewExpr} macro}
+\label{xintNewExpr}
+
+The 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 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 use of \csbxint{NewExpr} circumvents the impact of the |\xintexpr|
+ parsers on \TeX's memory: it is useful if one has a formula which has to be
+ re-evaluated thousands of times with distinct inputs each with dozens, or
+ hundreds of digits.
+
+ A ``formula'' created by |\xintNewExpr| is thus a macro whose parameters are
+ given to a possibly very complicated combination of the various macros of
+ \xintname and \xintfracname. Consequently, one can not use at all any infix
+ notation in the inputs, but only the formats which are recognized by the
+ \xintfracname macros.
+
+ This is thus quite different from a macro with parameters which one would
+ have defined via a simple |\def| or |\newcommand| as for example:
+ %
+ \leftedline{|\newcommand\myformula [1]{\xinttheexpr (#1)^3\relax}|}
+ %
+ Such a macro |\myformula|, if it was used tens of thousands of times with
+ various big inputs would end up populating large parts of \TeX's memory. It
+ would thus be better for such use cases to go for:
+ %
+ \leftedline{|\xintNewExpr\myformula [1]{#1^3\relax}|}
+ %
+ Here naturally the situation is over-simplified and it would be even simpler
+ to go directly for the use of the macro |\xintPow| or |\xintPower|.
+
+
+|\xintNewExpr| tries to do as many evaluations as are possible at the time the
+macro parameters are still parameters. Let's see a few examples. For this I
+will use |\meaning| which reveals the contents of a macro.
+
+\begin{enumerate}
+\item the examples use a mysterious |\fixmeaning| macro, which is there to get
+ in the display |\romannumeral`^^@| rather than the frankly cabalistic
+ |\romannumeral``| which made the admiration of the readers of the
+ documentation dated |2015/10/19| (the second |`| stood for an ascii code
+ zero token as per |T1| encoded |newtxtt| font). Thus the true meaning is
+ ``fixed'' to display something different which is how the macro could be
+ defined in a standard |tex| source file (modulo, as one can see in example,
+ the use of characters such as |:| as letters in control sequence names).
+ Prior to |1.2a|, the meaning would have started with a more mundane
+ |\romannumeral-`0|, but I decided at the time of releasing |1.2a| to imitate
+ the serious guys and switch for the more hacky yet |\romannumeral`^^@|
+ everywhere in the source code (not only in the macros produced by
+ \csbxint{NewExpr}), or to be more precise for an equivalent as the caret has
+ catcode letter in \xintname's source code, and I had to use another
+ character.
+\item the meaning reveals the use of some private macros from the \xintname
+ bundle, which should not be directly used. If the things look a bit
+ complicated, it is because they have to cater for many possibilities.
+\item the point of showing the meaning is also to see what has already been
+ evaluated in the construction of the macros.
+\end{enumerate}
+
+\begin{everbatim*}
+\xintNewIIExpr\FA [1]{13*25*78*#1+2826*292}\fixmeaning\FA
+\end{everbatim*}
+\smallskip
+
+\begin{everbatim*}
+\xintNewIExpr\FA [2]{(3/5*9/7*13/11*#1-#2)*3^7}
+\printnumber{\fixmeaning\FA}
+\end{everbatim*}
+
+\smallskip
+
+\begin{everbatim*}
+% an example with optional parameter
+\xintNewIExpr\FA [3]{[24] (#1+#2)/(#1-#2)^#3}
+\printnumber{\fixmeaning\FA}
+\end{everbatim*}
+
+\smallskip
+
+\begin{everbatim*}
+\xintNewFloatExpr\FA [2]{[12] 3.1415^3*#1-#2^5}
+\printnumber{\fixmeaning\FA}
+\end{everbatim*}
+
+\smallskip
+
+\begin{everbatim*}
+\xintNewExpr\DET[9]{ #1*#5*#9+#2*#6*#7+#3*#4*#8-#1*#6*#8-#2*#4*#9-#3*#5*#7 }
+\printnumber{\fixmeaning\DET}
+\end{everbatim*}
+
+\unless\ifxetex
+Notice that since |1.2c| it is perhaps more natural to do:
+\begin{everbatim*}
+% attention that «ad» would try to use non-existent variable "ad"
+\xintdeffunc det2(a, b, c, d) := a*d - b*c ;
+% This is impossible because we must use single letters :
+% \xintdeffunc det3(x_11, x_12, x_13, x_21, x_22, x_23, x_31, x_32, x_33) :=
+% x_11 * det2 (x_22, x_23, x_32, x_33) + x_21 * det2 (x_32, x_33, x_12, x_13)
+% + x_31 * det2 (x_12, x_13, x_22, x_23);
+\xintdeffunc det3 (a, b, c, u, v, w, x, y, z) := a*v*z + b*w*x + c*u*y - b*u*z - c*v*x - a*w*y ;
+\xinttheexpr det3 (1,1,1,1,2,4,1,3,9), det3 (1,10,100,1,100,10000,1,1000,1000000),
+ 90*900*990, reduce(det3 (1,1/2,1/3,1/2,1/3,1/4,1/3,1/4,1/5))\relax\newline
+\xintdeffunc det3bis (a, b, c, u, v, w, x, y, z) :=
+ a*det2(v,w,y,z)-b*det2(u,w,x,z)+c*det2(u,v,x,y);
+\pdfsetrandomseed 123456789 % xint.pdf should be predictable from xint.dtx !
+\xinttheexpr subs(subs(subs(subs(subs(subs(subs(subs(subs(
+% we use one extra pair of parentheses to hide the commas from the subs
+ (a, b, c, u, v, w, x, y, z, det3 (a, b, c, u, v, w, x, y, z),
+ det3bis (a, b, c, u, v, w, x, y, z)),
+ z=\pdfuniformdeviate 1000), y=\pdfuniformdeviate 1000), x=\pdfuniformdeviate 1000),
+ w=\pdfuniformdeviate 1000), v=\pdfuniformdeviate 1000), u=\pdfuniformdeviate 1000),
+ c=\pdfuniformdeviate 1000), b=\pdfuniformdeviate 1000), a=\pdfuniformdeviate 1000)\relax
+\end{everbatim*}
+
+
+The last computation with its nine nested |subs| can be coded more
+economically (and efficiently), exploiting the fact that a single dummy
+variable can expand to a whole list:
+\begin{everbatim*}
+\pdfsetrandomseed 123456789 % xint.pdf should be predictable from xint.dtx !
+\xinttheexpr subs((L, det3(L), det3bis(L)), % parentheses used to hide the inner commas
+ L=\pdfuniformdeviate 1000, \pdfuniformdeviate 1000, \pdfuniformdeviate 1000,
+ \pdfuniformdeviate 1000, \pdfuniformdeviate 1000, \pdfuniformdeviate 1000,
+ \pdfuniformdeviate 1000, \pdfuniformdeviate 1000, \pdfuniformdeviate 1000)\relax
+\end{everbatim*}
+\fi % de pas de xetex
+
+With |\xintverbosetrue| we will find in the log:
+
+\begin{everbatim}
+ Function det3 for \xintexpr parser associated to \XINT_expr_userfunc_det3 w
+ith meaning macro:#1#2#3#4#5#6#7#8#9->\xintSub {\xintSub {\xintSub {\xintAdd {\
+xintAdd {\xintMul {\xintMul {#1}{#5}}{#9}}{\xintMul {\xintMul {#2}{#6}}{#7}}}{\
+xintMul {\xintMul {#3}{#4}}{#8}}}{\xintMul {\xintMul {#2}{#4}}{#9}}}{\xintMul {
+\xintMul {#3}{#5}}{#7}}}{\xintMul {\xintMul {#1}{#6}}{#8}}
+
+ Function det3bis for \xintexpr parser associated to \XINT_expr_userfunc_det
+3bis with meaning macro:#1#2#3#4#5#6#7#8#9->\xintAdd {\xintSub {\xintMul {#1}{\
+xintExpandArgs {XINT_expr_userfunc_det2}{{#5}{#6}{#8}{#9}}}}{\xintMul {#2}{\xin
+tExpandArgs {XINT_expr_userfunc_det2}{{#4}{#6}{#7}{#9}}}}}{\xintMul {#3}{\xintE
+xpandArgs {XINT_expr_userfunc_det2}{{#4}{#5}{#7}{#8}}}}
+\end{everbatim}
+
+
+
+\medskip
+Lists, including Python-like selectors, are compatible with
+\csa{xintNewExpr}:%
+%
+\footnote{The |\empty| token is optional here, but it would
+ be needed in case of \csbxint{NewFloatExpr} or \csbxint{NewIExpr}.}
+%
+\begin{everbatim*}
+\xintNewExpr\Foo[5]{\empty[#1..[#2]..#3][#4:#5]}
+\begin{itemize}[nosep]
+\item |\Foo{1}{3}{90}{20}{30}|->\Foo{1}{3}{90}{20}{30}
+\item |\Foo{1}{3}{90}{-40}{-15}|->\Foo{1}{3}{90}{-40}{-15}
+\item |\Foo{1.234}{-0.123}{-10}{3}{7}|->\Foo{1.234}{-0.123}{-10}{3}{7}
+\end{itemize}
+\fdef\test {\Foo {0}{10}{100}{3}{6}}\meaning\test +++
+\end{everbatim*}
+
+In this last example the macro |\Foo| will not be able to handle an empty |#4|
+or |#5|: this is only possible in an expression, because the parser identifies
+|][:| or |:]| and handles them appropriately. During the construction of |\Foo|
+the parser will find |][#4:| and not |][:|.
+
+\begin{framed}
+ The \csbxint{deffunc}, \csbxint{defiifunc}, \csbxint{deffloatfunc}
+ declarators added to \xintexprname since release |1.2c| are based on the
+ same underlying mechanism as \csa{xintNewExpr}, \csa{xintNewIIExpr}, ... The
+ discussion that follows applies to them too.
+\end{framed}
+
+\subsubsection {Conditional operators and \csh{NewExpr}}
+\label{sssec:cond}
+
+The |?| and |??| conditional operators cannot be parsed by |\xintNewExpr| when
+they contain macro parameters |#1|,\dots, |#9| within their scope. However
+replacing them with the functions |if| and, respectively |ifsgn|, the parsing
+should succeed. And the created macro will \emph{not evaluate the branches to
+ be skipped}, thus behaving exactly like |?| and |??| would have in the
+|\xintexpr|.
+
+\begin{everbatim*}
+\xintNewExpr\Formula [3]{ if((#1>#2) && (#2>#3), sqrt(#1-#2)*sqrt(#2-#3), #1^2+#3/#2) }%
+\printnumber{\fixmeaning\Formula }
+\end{everbatim*}
+
+This formula (with its |\xintiiifNotZero|) will gobble the false branch without
+evaluating it when used with given arguments.
+
+Remark: the meaning above reveals some of the private macros used by the
+package. They are not for direct use.
+
+Another example
+
+\begin{everbatim*}
+\xintNewExpr\myformula[3]{ ifsgn(#1,#2/#3,#2-#3,#2*#3) }%
+\fixmeaning\myformula
+\end{everbatim*}
+
+Again, this macro gobbles the false branches, as would have the operator |??|
+inside an |\xintexpr|-ession.
+
+\subsubsection{External macros and \csh{xintNewExpr}; the protect function}
+\label{sssec:protect}
+
+For macros within such a created \xintname-formula macro, there
+are two cases:
+\begin{itemize}
+\item the macro does not involve the numbered parameters in its arguments: it
+ may then be left as is, and will be evaluated once during the construction of
+ the formula,
+\item it does involve at least one of the macro parameters as argument. Then:
+ \begin{snugframed}
+ the whole thing (macro + argument) should be |protect|-ed, not in the
+ \LaTeX{} sense (!), but in the following way: |protect(\macro {#1})|.\IMPORTANT
+ \end{snugframed}
+\end{itemize}
+
+Here is a silly example illustrating the general principle: the macros here have
+equivalent functional forms which are more convenient; but some of the more
+obscure package macros of \xintname dealing with integers do not have functions
+pre-defined to be in correspondance with them, use this mechanism could be
+applied to them.
+
+\begin{everbatim*}
+\xintNewExpr\formulaA[2]{protect(\xintRound{#1}{#2}) - protect(\xintTrunc{#1}{#2})}%
+\printnumber{\fixmeaning\formulaA}
+
+\xintNewIIExpr\formulaB [3]{rem(#1,quo(protect(\the\numexpr #2\relax),#3))}%
+\noindent\printnumber{\fixmeaning\formulaB }
+\end{everbatim*}
+
+Only macros involving the |#1|, |#2|, etc\dots should be protected in this
+way; the |+|, |*|, etc\dots symbols, the functions from the \csbxint{expr}
+syntax, none should ever be included in a protected string.
+
+
+\subsubsection{Limitations of \csh{NewExpr} and \csh{deffunc}}
+\label{sssec:limitations}
+
+\csbxint{NewExpr} will pre-evaluate everything as long as it does not contain
+the macro parameters |#1|, |#2|, ... and the special measures to take when
+these are inside branches to |?| and |??| (replace these operators by |if| and
+|ifsgn|) or as arguments to macros external to \xintexprname (use |protect|)
+were discussed in \autoref{sssec:cond} and \autoref{sssec:protect}.
+
+The main remaining limitation is that expressions with dummy variables are
+compatible with \csa{xintNewExpr} only to the extent that the iterated-over
+list of values does not depend on the macro parameters |#1|, |#2|, ... For
+example, this works:
+\begin{everbatim*}
+\xintNewExpr \FA [2] {reduce(add((t+#1)/(t+#2), t=0..5))}
+\FA {1}{1}, \FA {1}{2}, \FA {2}{3}
+\end{everbatim*}
+but the |5| can not be abstracted into a third argument |#3|.
+
+There are no restriction on using macro parameters |#1|, |#2|, ... with list
+constructs. For example, this works:
+\begin{everbatim*}
+\xintNewIExpr \FB [3] {[4] `+`([1/3..[#1/3]..#2]*#3)}
+\begin{itemize}[nosep]
+\item \FB {1}{10/3}{100} % (1/3+2/3+...+10/3)*100
+\item \FB {5}{5}{20} % (1/3+6/3+11/3)*20
+\item \FB {3}{4}{1} % (1/3+4/3+7/3+10/3)*1
+\end{itemize}
+\end{everbatim*}
+
+Some simple expressions with |add| or |mul| can be also expressed with |`+`|
+and |`*`| and list operations. But there is no hope for |seq|, |iter|, etc...
+if the |#1|, |#2|, ... are used inside the list argument:
+|seq(x(x+#1)(x+#2),x=1..#3)| is currently not compatible with
+\csa{xintNewExpr}. But |seq(x(x+#1)(x+#2), x=1..10)| has no problem.
+
+All the preceeding applies identically for \csbxint{deffunc}, \csbxint{defiifunc},
+\csbxint{deffloatfunc} which share the same routines as \csa{xintNewExpr},
+\csa{xintNewIIExpr}, ..., replacing the |#1|, |#2|, ... in the discussion by
+the letters used as function arguments.
+
+Here is a final syntax restriction: it is possible to use sub-expressions only if they use
+\csa{xintexpr}, those with \csa{xinttheexpr}, or \csbxint{eval} are illegal.
+\begin{everbatim*}
+\xintNewExpr \FC [4] {#1+\xintexpr #2*#3\relax + #4}
+\printnumber{\fixmeaning\FC}
+\end{everbatim*}\newline
+works, but
+\begin{everbatim}
+\xintNewExpr \FD [1] {#1+\xinttheexpr 1\relax}
+\end{everbatim}
+or
+\begin{everbatim}
+\xintNewExpr \FD [1] {#1+\xinteval{1}}
+\end{everbatim}
+do not.
+
+Prior to |1.3e| it would have been possible to do\CHANGED{1.3e}
+\begin{everbatim}
+\xintdeffunc FD(t) := t + \xinttheexpr 1\relax ;
+\end{everbatim}
+and even
+\begin{everbatim}
+\xintdeffunc FE(t,u) := t + \xinttheexpr u\relax ;
+\end{everbatim}
+They are now illegal, but fortunately
+\begin{everbatim*}
+\xintdeffunc FD(t) := t + \xintexpr 1\relax ;
+\end{everbatim*}
+and even for example
+\begin{everbatim*}
+\xintdeffunc FE(t,u) := \xintfloatexpr t + u\relax ;
+\end{everbatim*}
+do work. The latter would not have worked formerly. It now does, see
+\xinttrigname for use case.
+
+Anyway, one should never use |\xinttheexpr| for sub-expressions but only
+|\xintexpr|, so these restrictions on the \csbxint{NewExpr} and
+\csbxint{deffunc} syntax have no importance. However since the package
+provides the high level \csbxint{eval} et al., it may trap some users. But if
+they read the documentation they will have been warned.
+
+\subsection{\csh{xintNewFloatExpr}}\label{xintNewFloatExpr}
+
+This is exactly like \csbxint{NewExpr} except that the created formulas are
+set-up to use |\xintthefloatexpr|. Careful though that the |[...]| list syntax
+if first thing in the expression will be confused by the parser with the
+optional rounding argument |[N]| of \csbxint{floatexpr} (cf.
+\autoref{ssec:lists}.) Use an |\empty| token:
+\begin{everbatim*}
+\xintNewFloatExpr\F[1]{\empty[divmod(11.7,#1)][1]}
+% this is a bit silly example, done only to check that it works
+\F{1.35}
+\end{everbatim*}
+
+The numbers hard-wired in the original expression are evaluated using the
+prevailing |\xintDigits| precision at time of creation; the rest of the
+formula will be evaluated using the precision valid at the time of use.
+\begin{everbatim*}
+\xintNewFloatExpr \f [1] {sqrt(#1)}
+\f {2} (with \xinttheDigits{} digits of precision).
+
+{\xintDigits := 32;\f {2} (with \xinttheDigits{} digits of precision).}
+
+\xintNewFloatExpr \f [1] {sqrt(#1)*sqrt(2)}
+\f {2} (with \xinttheDigits {} digits of precision).
+
+\xintDigits := 32;\f {2} (?? we thought we had a higher precision.)
+
+\xintNewFloatExpr \f [1] {sqrt(#1)*sqrt(2)}
+\f {2} (with \xinttheDigits {} digits of precision)
+
+\xintDigits := 16;% back to default
+\end{everbatim*}
+
+The |sqrt(2)| in the first |sqrt(#1)*sqrt(2)| NewFloatExpression was computed
+with only \dtt{\xinttheDigits} digits of precision. In the second one, the
+|sqrt(2)| gets pre-evaluated with \dtt{32} digits of precision.
+
+\subsection{\csh{xintNewIExpr}}\label{xintNewIExpr}
+
+Like \csbxint{NewExpr} but using |\xinttheiexpr|. As |\xintiexpr| admits an
+optional rounding argument |[N]| the same caveat when square brackets come
+first in the expression as in the discussion of \csbxint{NewFloatExpr}
+applies.
+
+
+\subsection{\csh{xintNewIIExpr}}\label{xintNewIIExpr}
+
+Like \csbxint{NewExpr} but using |\xinttheiiexpr|.
+
+\subsection{\csh{xintNewBoolExpr}}\label{xintNewBoolExpr}
+
+Like \csbxint{NewExpr} but using |\xinttheboolexpr|.
+
+\xintDigits:= 16;
+
+\subsection{The \cshnolabel{xintdefvar}, \cshnolabel{xintdefiivar}, \cshnolabel{xintdeffloatvar} macros}
+
+See \autoref{xintdefvar} for their documentation.
+
+\subsection{The \cshnolabel{xintdeffunc}, \cshnolabel{xintdefiifunc}, \cshnolabel{xintdeffloatfunc} macros}
+
+See \autoref{xintdeffunc} for their documentation.
+
+\subsection{The \cshnolabel{xintNewFunction} macro}
+
+See \autoref{xintNewFunction} for its documentation.
+
+\subsection{Technicalities}
+
+As already mentioned \csa{xintNewExpr}|\myformula[n]| does not check the prior
+existence of a macro |\myformula|. And the number of parameters |n| given as
+mandatory argument within square brackets should be (at least) equal
+to the number of parameters in the expression.
+
+Obviously I should mention that \csa{xintNewExpr} itself can not be used in an
+expansion-only context, as it creates a macro.
+
+The |\escapechar| setting may be arbitrary when using |\xintexpr|.
+
+The format of the output of
+|\xintexpr|\meta{stuff}|\relax| is a |!| (with catcode 11) followed by various things:
+\begin{everbatim*}
+\edef\f {\xintexpr 1.23^10\relax }\meaning\f
+\end{everbatim*}
+
+\begin{framed}
+ Note that |\xintexpr| expands in an |\edef|, contrarily
+ to |\numexpr| which is non-expandable, if not prefixed by |\the|, |\number|,
+ or |\romannumeral| or in some other context where \TeX{} is building a number. See
+ \autoref{ssec:fibonacci} for some illustration.
+\end{framed}
+
+I decided to put all intermediate results (from each evaluation of an infix
+operators, or of a parenthesized subpart of the expression, or from application
+of the minus as prefix, or of the exclamation sign as postfix, or any
+encountered braced material) inside |\csname...\endcsname|, as this can be done
+expandably and encapsulates an arbitrarily long fraction in a single token (left
+with undefined meaning), thus providing tremendous relief to the programmer in
+his/her expansion control.
+
+\begin{framed}
+ As the |\xintexpr| computations corresponding to functions and infix
+ or postfix operators are done inside |\csname...\endcsname|, the
+ \fexpan dability could possibly be dropped and one could imagine
+ implementing the basic operations with expandable but not \fexpan
+ dable macros (as \csbxint{XTrunc}.) I have not investigated that
+ possibility.
+\end{framed}
+
+Syntax errors in the input such as using a one-argument function with two
+arguments will generate low-level \TeX{} processing unrecoverable errors, with
+cryptic accompanying message.
+
+Some other problems will give rise to `error messages' macros giving some
+indication on the location and nature of the problem. Mainly, an attempt has
+been made to handle gracefully missing or extraneous parentheses.
+
+However, this mechanism is completely inoperant for parentheses involved in
+the syntax of the |seq|, |add|, |mul|, |subs|, |rseq| and |rrseq| functions,
+and missing parentheses may cause the parser to fetch tokens beyond the ending
+|\relax| necessarily ending up in cryptic low-level \TeX-errors.
+
+Note that the |,<letter>=| part must be visible, it can not arise from
+expansion (the equal sign does not have to be an equal sign, it can be any
+token and will be gobbled).\IMPORTANT{} However for |iter|, |iterr|, |rseq|,
+|rrseq|, the initial values delimited by a |;| are parsed in the normal way,
+and in particular may be braced or arise from expansion. This is useful as the
+|;| may be hidden from \csa{xintdeffunc} as |{;}| for example. Again, this
+remark does \emph{not} apply to the comma |,| which precedes the |<letter>=|
+part. The comma will be fetched by delimited macros and must be there. Nesting
+is handled by checking (again using suitable delimited macros) that
+parentheses are suitably balanced.
+
+
+Note that |\relax| is \emph{mandatory} (contrarily to the situation for |\numexpr|).
+
+\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{http://www.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
+\let\xintexprnameUp\undefined
+\csname xinttrignameUp\endcsname
+\def\n{|{N}|}
+\def\m{|{M}|}
+\def\x{|{x}|}
+\section{Macros of the \xinttrigname package}
+\RaisedLabel{sec:trig}
+
+\localtableofcontents
+
+This package provides trigonometric functions for use with \xintexprname.
+The sole macro is \csbxint{reloadxinttrig}.
+
+This package was first included in release |1.3e| (|2019/04/01|) of
+\xintexprname. It is automatically loaded by \xintexprname.
+
+\textbf{Acknowledgements} I finally decided to release some such functions
+under friendly pressure of Jürgen \textsc{Gilg} and Thomas \textsc{Söll}, let
+them both be thanked here.
+
+\subsection{\csh{xintreloadxinttrig}}\label{xintreloadxinttrig}
+
+\begin{framed}
+ After modifying \csbxint{Digits},\IMPORTANTf{} one must issue
+ \csbxint{reloadxinttrig} to let the package re-configure itself.
+\end{framed}
+
+The library is pre-configured to be able to handle a precision of up to about
+\fbox{\dtt{60}} digits (make this \dtt{59} at most for the inverse functions).
+But absence of guard digits (whether in the used hard-coded constants or in
+passing over values from one auxiliary function to the next) due to high level
+(user) interface used for the programming means that the produced values are
+definitely expected to be wrong in the last digit or last two digits. I should
+actually give some estimate of the actual maximal error in |ulps| unit, but I
+have not done the complete analysis for lack of time.
+
+Final computation results should thus probably be printed via
+\csbxint{floateval}|{[-2]....}| in order to strip off (with rounding) the last
+two digits, if one does not like seeing those non-meaningful figures in the
+last one or two positions (I don't say those last two figures are
+\emph{systematically} off). For example, to achieve \dtt{16} digits of
+precision one should work with a precision of 18 digits (being careful to have
+issued \csbxint{reloadxinttrig}) and round results using
+\csbxint{floateval}|{[-2]....}|.
+
+Another approach is to use \csbxint{ieval}|{[D]...}| for conversion to
+a fixed point format.
+
+In future, lower level coding will probably replace the high-level interface,
+or at least the macros produced by the high-level interface will be hacked
+into to tell the float macros to work at a somewhat elevated precision.
+
+\subsection{Constants}
+
+They are the correct rounding to \csbxint{Digits} precision of the
+mathematically exact ones. Their values get incorporated into the
+trigonometrical functions at the time of their definitions during loading or
+reloading of the package. They are left free to use, or modified, or
+\csbxint{unassignvar}'d, as this will have no impact whatsoever on the
+functions.
+
+\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$
+\vardesc{invfact2} this is $1/2!$
+\vardesc{invfact3} this is $1/3!$
+\item[\dots]
+\vardesc{invfact44} this is $1/44!$
+\end{description}
+
+For a (very) slight optimization of usage, it is recommended to convert them
+to macro form, for example:
+\begin{everbatim*}
+\edef\oneDegree{\xintfloatexpr oneDegree\relax}
+\xintfloateval{sin(37\oneDegree)}\newline
+\xintfloateval{sind(37)}\newline
+\end{everbatim*}
+By the way, the above value differs by |1ulp| from correct rounding of exact
+one (which looks \dtt{...520482}79917...), see \autoref{ssec:trignotes}.
+
+\subsection{Functions}
+
+\subsubsection{Direct trigonometry}
+
+With the variable in radians:
+
+\begin{description}
+\funcdesc{sin} sine
+\funcdesc{cos} cosine
+\funcdesc{tan} tangent
+\funcdesc{cot} cotangent
+\funcdesc{sec} secant
+\funcdesc{csc} cosecant
+\end{description}
+
+With the variable in degrees:
+
+\begin{description}
+\funcdesc{sind} sine
+\funcdesc{cosd} cosine
+\funcdesc{tand} tangent
+\funcdesc{cotd} cotangent
+\funcdesc{secd} secant
+\funcdesc{cscd} cosecant
+\end{description}
+
+Only available with the variable in radians:
+\begin{description}
+\funcdesc{tg} tangent
+\funcdesc{cotg} cotangent
+\funcdesc{sinc} cardinal sine $\sinc(x) = \sin(x)/x$
+\end{description}
+
+\subsubsection{Inverse trigonometry}
+
+With the value in radians:
+
+\begin{description}
+\funcdesc{asin} arcsine
+\funcdesc{acos} arccosine
+\funcdesc{atan} arctangent
+\funcdesc[x, y]{Arg} the main branch of the argument of the complex number
+|x+iy|, from $-\pi$ (excluded) to $\pi$ (included). Inherent rounding of
+output makes
+-\var{Pi} 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} a possible return value.
+\funcdesc[y, x]{atan2} it 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} it is |Arg(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
+\xinttrigname functions are already defined for the two units, I felt this was
+not really needed. It is a oneliner to add them:
+\begin{everbatim}
+\xintdeffloatefunc radians(x) := x * oneDegree;
+\xintdeffloatefunc degrees(x) := x * oneRadian;
+\xintdefefunc radians(x) := x * oneDegree;
+\xintdefefunc degrees(x) := x * oneRadian;
+\end{everbatim}
+
+The variants for \csbxint{expr} above do an exact multiplication, I did not
+add a \func{float} wrapper to force rounding as anyhow the trigonometrical
+functions will do this initial rounding of their arguments. But if you define
+a variable for multiple later use using such a |degrees()| function, it would
+be better to add a \func{float} wrapper in the variable definition so the
+rounding is already done: rounding an already rounded value is unavoidable
+overhead but proceeds faster as it is quicly realized the input actually needs
+no rounding.
+
+Notice however that the conversion factors above are without guard digits. One
+can do this:
+\begin{everbatim}
+\xintdeffloatefunc radians(x) := float(\xintexpr x * oneDegreewithmoredigits\relax);
+\xintdeffloatefunc degrees(x) := float(\xintexpr x * oneRadianwithmoredigits\relax);
+\end{everbatim}
+But recall that |x| will normally already be a rounded value, so this is
+perhaps a bit complex for not much ado. Probably better to work overall with
+an elevated precision and print final results at a lower precision.
+
+\subsection{Important implementation notes}
+\label{ssec:trignotes}
+
+\begin{itemize}
+\item The package is almost entirely implemented using the high level user
+ interface of \xintexprname, see \autoref{sec:xintexprsyntax} for
+ \csbxint{deffloatefunc} and \csbxint{deffloatvar}, the main two exceptions
+ are:
+ \begin{enumerate}[nolistsep]
+ \item the range reduction for the |sind()| and |cosd()| functions which
+ required for optimized efficiency the coding at some more core level.
+ \item a change at core level was done to \csbxint{deffunc} in order to
+ facilitate the transfer of the defined functions from the float parser to
+ the exact parser. See \autoref{sssec:limitations}, the source code
+ comments in |sourcexint.pdf| and the discussion of \csbxint{deffunc} for
+ details. The \csbxint{defefunc} added at |1.3e| was also motivated by this
+ context.
+ \end{enumerate}
+ To avoid problems if the package is reloaded at a time the user has
+ used some letter variables as assigned variables, I added
+ \csbxint{ensuredummy} and \csbxint{restorelettervar}.
+\item It is not possible from this interface to (easily) let the computation
+ proceed with a temporarily elevated precision (``guard digits''). Expect
+ thus some errors in the last places; basically one should use the optional
+ rounding argument of either \csbxint{floateval} or \csbxint{ieval} to reduce
+ the number of digits of printed values by about two digits, if one
+ hopes to get correct rounding (most of the time).
+\item Currently, \xintname is lacking some dedicated internal representation
+ of floats which means that most operations re-parse the digit tokens of their
+ arguments to count them\dots\ this does not contribute to efficiency (you
+ can load the module under |\xintverbosetrue| regime and see how the nested
+ macros look like and get an idea of how many times some rather silly
+ re-counting of mantissa lengths will get done!)
+\item One should not overwrite some function names which are employed as
+ auxiliaries: |sin_aux|, |cos_aux|, |sin_|, |cos_|, |sind_|, |cosd_|,
+ |asin_l|\dots others\dots |asin_a|, |asind_a|, |atan_a|, |atand_a|,
+ |atan_b|, |atand_b|. If you redefine any one of them, you break the
+ whole thing.
+\item Floats with large exponents are integers and are multiple of \dtt{1000};
+ hence modulo \dtt{360} all such ``angles'' are multiple of \dtt{40} degrees.
+ Needless to say that considering usage of the sine and cosine functions
+ with such large float numbers is meaningless.
+\item Regarding such a big float angle in radians, \xinttrigname converts
+ it to degrees by multiplication by (pre-rounded) $180/\pi$, then it does
+ range reduction modulo $360$ and goes back to radians in the appropriate
+ octants and use the series (roughly said). Thus |cos()| and |sin()| will be
+ evaluated as if at some of the finitely many rounded multiples of (exact)
+ $2\pi/9$. When the unit in the last place of the original input was for
+ example \dtt{1e9} it is clear that the final result means nothing at all;
+ this intrinsic problem is not one of conversion from radians to degrees: the
+ unit in the last place interval extends above possibly astronomical numbers of
+ intervals of length $2\pi$. This is an in-built inadequacy of (large)
+ floating point numbers for trigonometrical evaluations; the argument should
+ be treated then 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
+ programming complication of deciding how to make the transition. Too lazy
+ for that.
+\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}
+
+\clearpage
+\let\xinttrignameUp\undefined
+\csname xintlognameUp\endcsname
+\def\n{|{N}|}
+\def\m{|{M}|}
+\def\x{|{x}|}
+
+\section{Macros of the \xintlogname package}
+\RaisedLabel{sec:log}
+
+\localtableofcontents
+
+This package provides logarithms, exponentials and fractional powers for use
+with \xintexprname.
+
+This package was first included in release |1.3e| (|2019/04/01|) of
+\xintexprname. It is automatically loaded by \xintexprname.
+
+Currently it is a wrapper to import package
+\href{http://www.ctan.org/pkg/poormanlog}{poormanlog} which computes with
+\dtt{8} or \dtt{9} digits of precision, adding the \func{log}, \func{exp}, and
+\func{pow} function to the \func{log10} and \func{pow10} provided by the package.
+
+\subsection{\csh{poormanloghack}}
+\label{ssec:poormanloghack}
+
+\begin{description}
+\item[\string\poormanloghack\string{**\string}] use it to let the |**| operator be remapped to the
+ \func{pow} function.
+\item[\string\poormanloghack\string{\string^\string}] use it to let the |^| operator be remapped to the
+ \func{pow} function.
+\end{description}
+If used, they obey \TeX\ scoping as usual.
+\begin{everbatim*}
+\begingroup
+\poormanloghack{**}\xintfloateval{[8]1.234**5.678}\newline
+\poormanloghack{^}\xintfloateval{[8]1.234^5.678}\par
+\endgroup
+% ** and ^ now do not accept fractional exponents: only half-integer ones and
+% only in \xintfloateval, not \xinteval.
+\end{everbatim*}
+
+Notice that in \csbxint{floateval} those (equivalent) operators already
+natively handle half-integer exponents. Once remapped to the \func{pow}
+function they will become less precise than the original ones for half-integer
+and integer exponents.
+
+\subsection{Functions}
+
+All those functions achieve only about \dtt{8} or \dtt{9} digits of precision.
+Notice in particular that the digits beyond the ninth printed by \func{log}
+have no significance (here we suppose |1<x<10|), but I did not add the
+rounding overhead as it is expected anyhow that the final result will be
+appropriately rounded. Notice however that \func{log10} should be seen as
+going from floating point to fixed point (in the sense of the number of
+fractional digits) and \func{pow10} from fixed point to floating point.
+
+\begin{description}
+\funcdesc{log10} logarithm in base 10
+\funcdesc{pow10} fractional powers of 10
+\funcdesc{log} natural logarithm via |log10(x)*2.3025850923| formula; only the
+first 8 or 9 digits of the output are significant...
+\funcdesc{exp} exponential function via |pow10(x*0.434294481903)| formula
+\funcdesc[x, y]{pow} computes $x^y$ via the formula |pow10(y*log10(x))|
+\end{description}
+
+\begin{everbatim*}
+\xintfloateval{[9] log(2), exp(1), pow(2,0.5)}
+\end{everbatim*}
+Notice that the last digit of |log(2)| is not the correctly rounded one... I
+did say 9 \textbf{or} 8 digits or precision... The documentation of
+\href{http://www.ctan.org/pkg/poormanlog}{poormanlog} mentions an error of up
+to 2 units in the ninth digit when computing |log10(x)| for |1<x<10| and
+|10^x| for |0<x<1|.
+
+\clearpage
+\let\xintlognameUp\undefined
+\csname xintbinhexnameUp\endcsname
+\def\n{|{N}|}
+\def\m{|{M}|}
+\def\x{|{x}|}
+\section{Macros of the \xintbinhexname package}
+\RaisedLabel{sec:binhex}
+
+\localtableofcontents
+
+This package provides expandable conversions of (big) integers to
+and from binary and hexadecimal.
+
+First version of this package was in the |1.08| (|2013/06/07|) release of
+\xintname. Its routines remained un-modified until their complete rewrite at
+release |1.2m| (|2017/07/31|). The new macros are faster, using techniques
+from the |1.2| (|2015/10/10|) release of \xintcorename. But the inputs are now
+limited to a few thousand digits, whereas the |1.08| could handle (slowly...)
+tens of thousands of digits.
+
+\autoref{tab:binhexsizes} recapitulates the maximal allowed sizes (they got
+increased at |1.2n|):
+for macro |\xintFooToBar| in the first column, the value in the second column
+is the maximal |N| such that |\edef\X{\xintFooToBar{<N digits>}}| does not
+raise an error with standard \TeX\ memory parameters (input stack
+size=\dtt{5000}, expansion depth=\dtt{10000}, parameter stack
+size=\dtt{10000}). The tests were done with TL2017 and |etex|. Nested calls
+will allow slightly lesser values only. The third column gives the
+corresponding maximal size of output. The fourth column gives the \TeX\
+parameter cited in the error message when trying with |N+1| digits.
+
+\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<{!}>{\E{19}}c<{!}r}
+ \hline
+ &Max\ length\ of\ input&->\ length\ of\ output&Limiting factor\\
+ \csbxint{DecToHex}&6014&4995&input stack size=5000\\
+ \csbxint{DecToBin}&6014&19979&input stack size=5000\\
+ \csbxint{HexToDec}&8298&9992&input stack size=5000\\
+ \csbxint{BinToDec}&19988&6017&input stack size=5000\\
+ \csbxint{BinToHex}&19988&4997&input stack size=5000\\
+ \csbxint{HexToBin}&4996&19984&input stack size=5000\\
+ \csbxint{CHexToBin}&4997&19988&input stack size=5000\\
+ \hline
+\end{tabular}
+\caption{Maximal sizes of inputs (at \texttt{1.2n}) for \xintbinhexname macros}\label{tab:binhexsizes}
+\end{table}
+
+Roughly, base |10| numbers are limited to \dtt{6000} digits, hexadecimal
+numbers to (almost) \dtt{5000} digits, and binary numbers to (almost)
+\dtt{20000} digits. With the surprising exception of \csbxint{HexToDec} which
+allows almost \dtt{8300} hexadecimal digits on input.
+
+The argument is first \fexpan ded.
+It may optionally have a unique leading minus sign (a plus sign is not
+allowed), and leading zeroes.
+
+An input (possibly signed) with no leading zeroes is guaranteed to give an
+output without leading zero, with the sole, deliberate, exception of
+\csbxint{CHexToBin}: from |N| hexadecimal digits it produces |4N| binary
+digits, hence possibly with up to three leading zeroes (if the
+input had none.)
+
+Inputs with leading zeroes usually produce outputs with an unspecified,
+case-dependent, number of leading zeroes (\csbxint{BinToHex} always uses the
+minimal number of hexadecimal digits needed to represent the binary digits,
+inclusive of leading zeroes if present.)
+
+The macros converting from binary or decimal are robust against
+non terminated inputs like |\the\numexpr 2+3| or |\the\mathcode`\-|. The macro
+\csbxint{HexToDec} also but not \csbxint{HexToBin} and \csbxint{CHexToBin}
+(anyway there are no primitive in (e)-\TeX\ to my knowledge which will
+generate hexadecimal digits and may force expansion of next token).
+
+Hexadecimal digits |A..F| must be in uppercase. Category code for them on
+input may be \emph{letter} or \emph{other}. On output they are of category
+code \emph{letter}, and in uppercase.
+
+Low-level unrecoverable errors will happen if for example a supposedly binary
+input contains other digits than |0| and |1|. Inputs can not start with a
+|0b|, |0x|, |#x|, |"| or similar prefix: only digits/letters according to the
+binary, decimal, or hexadecimal notation.
+
+
+With this package loaded additionally to \xintexprname, hexadecimal input is
+possible in expressions: simply by using the prefix |"|. Such hexadecimal
+numbers may have a fractional part. Lowercase hexadecimal letters are
+currently \emph{not} recognized as such in expressions.
+Currently the |p| postfix notation from standard programming languages
+standing for an extra
+power of two multiplicand is not implemented.
+
+% \clearpage
+
+\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{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{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{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{xintBinToHex}}\label{xintBinToHex}
+
+Converts from binary to hexadecimal.\etype{f} The input is first zero-filled
+to |4N| binary digits, hence 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{xintHexToBin}}\label{xintHexToBin}
+
+Converts from hexadecimal to binary. Up to three leading zeroes of the 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*}
+This zero-fills to 4N digits the input, hence gives here a leading zero in output:
+\xintBinToHex{0001111}\newline
+Chaining, we end up with 4N-3 digits, as three binary zeroes are trimmed:
+\xintHexToBin{\xintBinToHex{0001111}}\newline
+But this will always reproduce the initial input zero-filled to length 4N:
+\xintCHexToBin{\xintBinToHex{0001111}}\par
+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
+\end{everbatim*}
+\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
+
+This package was included in the original release |1.0| (|2013/03/28|) of the
+\xintname bundle.
+
+Since release |1.09a| the macros filter their inputs through the \csbxint{Num}
+macro, so one can use count registers, or fractions as long as they reduce to
+integers.
+
+Since release |1.1|, the two ``|typeset|'' macros require the explicit
+loading by the user of package \xinttoolsname.
+
+At |1.3d| macros \csbxint{iiGCD} and \csbxint{iiLCM} are copied over to
+\xintname, hence \func{gcd} and \func{lcm} functions in \csbxint{iiexpr} are
+available simply from loading \xintexprname, \xintgcdname is not
+needed.\NewWith{1.3d}
+
+
+%% \clearpage
+
+\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}}}
+
+With release |1.3d|, this macro is also available from loading
+\xintname\NewWith{1.3d}, hence also with \xintexprname, as it used by the
+\func{gcd} function in \csbxint{iiexpr}, hence removes a dependency of
+\xintexprname on \xintgcdname.
+
+\subsection{\csh{xintGCD}}\label{xintGCD}
+
+\csa{xintGCD} uses \csbxint{Num} overhead to make its arguments into strict
+integers\etype{\Numf\Numf} first. With \xintfracname loaded this conversion
+means truncation to integers.
+
+\subsection{\csh{xintGCDof}}\label{xintGCDof}
+
+\csa{xintGCDof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast\Numf}} computes the greatest common divisor of all
+integers |a|, |b|, \dots{} The list argument
+may be a macro, it is \fexpan ded first and must contain at least one item.
+
+\subsection{\csh{xintiiLCM}}\label{xintiiLCM}
+
+|\xintiiLCM|\n\m\etype{ff} computes the least common multiple of integers. It
+is positive, except if one |N| or |M| vanishes, in which case the macro
+returns zero.
+%
+\leftedline{\csa{xintiiLCM}|{10000}{1113}|\dtt{=\xintiiLCM{10000}{1113}}}
+%
+\leftedline{|\xintiiLCM{123456789012345}{9876543210321}=|\dtt
+ {\xintiiLCM{123456789012345}{9876543210321}}}
+
+With release |1.3d|, this macro is also available from loading
+\xintname\NewWith{1.3d}, hence also with \xintexprname, as it used by the
+\func{lcm} function in \csbxint{iiexpr}, hence removes a dependency of
+\xintexprname on \xintgcdname.
+
+\subsection{\csh{xintLCM}}\label{xintLCM}
+
+\csa{xintLCM} uses \csbxint{Num} overhead to make its arguments into strict
+integers\etype{\Numf\Numf} first. With \xintfracname loaded this conversion
+means truncation to integers.
+
+\subsection{\csh{xintLCMof}}\label{xintLCMof}
+
+\csa{xintLCMof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast\Numf}} computes the least
+common multiple of all integers |a|, |b|, \dots{} The list argument may be a
+macro, it is \fexpan ded first and must contain at least one item.
+
+\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.
+
+\emph{Usage of this macro requires the user to load} \xinttoolsname.\IMPORTANT
+
+\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.
+
+\emph{Usage of this macro requires the user to load} \xinttoolsname.\IMPORTANT
+
+\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
+
+This package was first released with version |1.03| (|2013/04/14|) of the
+\xintname bundle.
+
+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} = \xintFrac\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|:
+\[\xintFrac\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}=\xintFrac\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=
+ \xintFrac\z=\xintFrac{\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=\xintFrac{\z}=\xintFrac{\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 |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
+ =\xintFrac{\xintIrr{\xintPowerSeries {0}{20}{\geom}{\f}}}
+ =\xintFrac{\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}
+ = \xintFrac {\xintIrr {\xintPowerSeries {1}{20}{\coefflog}{\f}}}\]
+\[ \log 2 \approx \sum_{n=1}^{50} \frac1{n\cdot 2^n}
+ = \xintFrac {\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}
+= \xintFrac{\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 |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
+
+\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}
+\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\xintFrac{\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{|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 $|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'<D| of digits. Maybe for the next
+release.
+
+\subsection{\csh{xintFloatPowerSeries}}\label{xintFloatPowerSeries}
+
+
+\noindent\csa{xintFloatPowerSeries}|[P]{A}{B}{\coeff}{f}|%
+\ntype{{\upshape[\numx]}\numx\numx}
+ computes
+$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot |f|^{\,\text{|n|}}$
+with a floating point
+precision given by the optional parameter |P| or by the current setting of
+|\xintDigits|.\etype{\Ff\Ff}
+
+In the current, preliminary, version, no attempt has been made to try to
+guarantee to the final result the precision |P|. Rather, |P| is used for all
+intermediate floating point evaluations. So
+rounding errors will make some of the last printed digits invalid. The
+operations done are first the evaluation of |f^A| using \csa{xintFloatPow}, then
+each successive power is obtained from this first one by multiplication by |f|
+using \csa{xintFloatMul}, then again with \csa{xintFloatMul} this is multiplied
+with |\coeff{n}|, and the sum is done adding one term at a time with
+\csa{xintFloatAdd}. To sum up, this is just the naive transformation of
+\csa{xintFxPtPowerSeries} from fixed point to floating point.
+
+\def\coefflog #1{\the\numexpr\ifodd#1 1\else-1\fi\relax/#1[0]}%
+
+\everb+@
+\def\coefflog #1{\the\numexpr\ifodd#1 1\else-1\fi\relax/#1[0]}%
+\xintFloatPowerSeries [8]{1}{30}{\coefflog}{-1/2[0]}
++
+
+%
+\leftedline{\dtt{\xintFloatPowerSeries [8]{1}{30}{\coefflog}{-1/2[0]}}}
+
+\subsection{\csh{xintFloatPowerSeriesX}}\label{xintFloatPowerSeriesX}
+
+
+\noindent\csa{xintFloatPowerSeriesX}|[P]{A}{B}{\coeff}{f}|%
+\ntype{{\upshape[\numx]}\numx\numx}
+is like
+\csa{xintFloatPowerSeries} with the difference that |f| is
+expanded once\etype{\Ff\Ff}
+and for all at the start of the computation, thus allowing
+efficient chaining of such series evaluations.
+\def\coefflog #1{\the\numexpr\ifodd#1 1\else-1\fi\relax/#1[0]}%
+
+\everb+@
+\def\coeffexp #1{1/\xintiiFac {#1}[0]}% 1/n! (exact, not float)
+\def\coefflog #1{\the\numexpr\ifodd#1 1\else-1\fi\relax/#1[0]}%
+\xintFloatPowerSeriesX [8]{0}{30}{\coeffexp}
+ {\xintFloatPowerSeries [8]{1}{30}{\coefflog}{-1/2[0]}}
++
+
+%
+\leftedline{\dtt{\xintFloatPowerSeriesX [8]{0}{30}{\coeffexp}
+ {\xintFloatPowerSeries [8]{1}{30}{\coefflog}{-1/2[0]}}}}
+
+\subsection{Computing \texorpdfstring{$\log 2$}{log(2)} and \texorpdfstring{$\pi$}{pi}}\label{ssec:Machin}
+
+In this final section, the use of \csbxint{FxPtPowerSeries} (and
+\csbxint{PowerSeries}) will be
+illustrated on the (expandable... why make things simple when it is so easy to
+make them difficult!) computations of the first digits of the decimal expansion
+of the familiar constants $\log 2$ and $\pi$.
+
+Let us start with $\log 2$. We will get it from this formula (which is
+left as an exercise): %
+%
+\leftedline{\dtt{log(2)=-2\,log(1-13/256)-%
+ 5\,log(1-1/9)}}
+%
+The number of terms to be kept in the log series, for a desired
+precision of |10^{-D}| was roughly estimated without much theoretical
+analysis. Computing exactly the partial sums with \csa{xintPowerSeries}
+and then printing the truncated values, from |D=0| up to |D=100| showed
+that it worked in terms of quality of the approximation. Because of
+possible strings of zeroes or nines in the exact decimal expansion (in
+the present case of $\log 2$, strings of zeroes around the fourtieth and
+the sixtieth decimals), this
+does not mean though that all digits printed were always exact. In
+the end one always end up having to compute at some higher level of
+desired precision to validate the earlier result.
+
+Then we tried with \csa{xintFxPtPowerSeries}: this is worthwile only for
+|D|'s at least 50, as the exact evaluations are faster (with these
+short-length |f|'s) for a lower
+number of digits. And as expected the degradation in the quality of
+approximation was in this range of the order of two or three digits.
+This meant roughly that the 3+1=4 ending digits were wrong. Again, we ended
+up having to compute with five more digits and compare with the earlier
+value to validate it. We use truncation rather than rounding because our
+goal is not to obtain the correct rounded decimal expansion but the
+correct exact truncated one.
+
+% 693147180559945309417232121458176568075500134360255254120680009493
+
+\begin{everbatim*}
+\def\coefflog #1{1/#1[0]}% 1/n
+\def\xa {13/256[0]}% we will compute log(1-13/256)
+\def\xb {1/9[0]}% we will compute log(1-1/9)
+\def\LogTwo #1%
+% get log(2)=-2log(1-13/256)- 5log(1-1/9)
+{% we want to use \printnumber, hence need something expanding in two steps
+ % only, so we use here the \romannumeral0 method
+ \romannumeral0\expandafter\LogTwoDoIt \expandafter
+ % Nb Terms for 1/9:
+ {\the\numexpr #1*150/143\expandafter}\expandafter
+ % Nb Terms for 13/256:
+ {\the\numexpr #1*100/129\expandafter}\expandafter
+ % We print #1 digits, but we know the ending ones are garbage
+ {\the\numexpr #1\relax}% allows #1 to be a count register
+}%
+\def\LogTwoDoIt #1#2#3%
+% #1=nb of terms for 1/9, #2=nb of terms for 13/256,
+{% #3=nb of digits for computations, also used for printing
+ \xinttrunc {#3} % lowercase form to stop the \romannumeral0 expansion!
+ {\xintAdd
+ {\xintMul {2}{\xintFxPtPowerSeries {1}{#2}{\coefflog}{\xa}{#3}}}
+ {\xintMul {5}{\xintFxPtPowerSeries {1}{#1}{\coefflog}{\xb}{#3}}}%
+ }%
+}%
+\noindent $\log 2 \approx \LogTwo {60}\dots$\endgraf
+\noindent\phantom{$\log 2$}${}\approx{}$\printnumber{\LogTwo {65}}\dots\endgraf
+\noindent\phantom{$\log 2$}${}\approx{}$\printnumber{\LogTwo {70}}\dots\endgraf
+\end{everbatim*}
+
+Here is the code doing an exact evaluation of the partial sums. We have
+added a |+1| to the number of digits for estimating the number of terms
+to keep from the log series: we experimented that this gets exactly the
+first |D| digits, for all values from |D=0| to |D=100|, except in one
+case (|D=40|) where the last digit is wrong. For values of |D|
+higher than |100| it is more efficient to use the code using
+\csa{xintFxPtPowerSeries}.
+\everb|@
+\def\LogTwo #1% get log(2)=-2log(1-13/256)- 5log(1-1/9)
+{%
+ \romannumeral0\expandafter\LogTwoDoIt \expandafter
+ {\the\numexpr (#1+1)*150/143\expandafter}\expandafter
+ {\the\numexpr (#1+1)*100/129\expandafter}\expandafter
+ {\the\numexpr #1\relax}%
+}%
+\def\LogTwoDoIt #1#2#3%
+{% #3=nb of digits for truncating an EXACT partial sum
+ \xinttrunc {#3}
+ {\xintAdd
+ {\xintMul {2}{\xintPowerSeries {1}{#2}{\coefflog}{\xa}}}
+ {\xintMul {5}{\xintPowerSeries {1}{#1}{\coefflog}{\xb}}}%
+ }%
+}%
+|
+
+Let us turn now to Pi, computed with the Machin formula (but see also the
+approach via the \hyperlink{BrentSalamin}{Brent-Salamin algorithm} with
+\csa{xintfloatexpr}) Again the numbers of terms to keep in the two |arctg|
+series were roughly estimated, and some experimentations showed that removing
+the last three digits was enough (at least for |D=0-100| range). And the
+algorithm does print the correct digits when used with |D=1000| (to be
+convinced of that one needs to run it for |D=1000| and again, say for
+|D=1010|.) A theoretical analysis could help confirm that this algorithm
+always gets better than |10^{-D}| precision, but again, strings of zeroes or
+nines encountered in the decimal expansion may falsify the ending digits,
+nines may be zeroes (and the last non-nine one should be increased) and zeroes
+may be nine (and the last non-zero one should be decreased).
+
+\hypertarget{MachinCode}{}
+\begin{everbatim*}
+\def\coeffarctg #1{\the\numexpr\ifodd#1 -1\else1\fi\relax/%
+ \the\numexpr 2*#1+1\relax [0]}%
+%\def\coeffarctg #1{\romannumeral0\xintmon{#1}/\the\numexpr 2*#1+1\relax }%
+\def\xa {1/25[0]}% 1/5^2, the [0] for faster parsing
+\def\xb {1/57121[0]}% 1/239^2, the [0] for faster parsing
+\def\Machin #1{% #1 may be a count register, \Machin {\mycount} is allowed
+ \romannumeral0\expandafter\MachinA \expandafter
+ % number of terms for arctg(1/5):
+ {\the\numexpr (#1+3)*5/7\expandafter}\expandafter
+ % number of terms for arctg(1/239):
+ {\the\numexpr (#1+3)*10/45\expandafter}\expandafter
+ % do the computations with 3 additional digits:
+ {\the\numexpr #1+3\expandafter}\expandafter
+ % allow #1 to be a count register:
+ {\the\numexpr #1\relax }}%
+\def\MachinA #1#2#3#4%
+{\xinttrunc {#4}
+ {\xintSub
+ {\xintMul {16/5}{\xintFxPtPowerSeries {0}{#1}{\coeffarctg}{\xa}{#3}}}
+ {\xintMul{4/239}{\xintFxPtPowerSeries {0}{#2}{\coeffarctg}{\xb}{#3}}}%
+ }}%
+\begin{framed}
+ \[ \pi = \Machin {60}\dots \]
+\end{framed}
+\end{everbatim*}
+
+Here is a variant|\MachinBis|,
+which evaluates the partial sums \emph{exactly} using
+\csa{xintPowerSeries}, before their final truncation. No need for a
+``|+3|'' then.
+\begin{everbatim*}
+\def\MachinBis #1{% #1 may be a count register,
+% the final result will be truncated to #1 digits post decimal point
+ \romannumeral0\expandafter\MachinBisA \expandafter
+ % number of terms for arctg(1/5):
+ {\the\numexpr #1*5/7\expandafter}\expandafter
+ % number of terms for arctg(1/239):
+ {\the\numexpr #1*10/45\expandafter}\expandafter
+ % allow #1 to be a count register:
+ {\the\numexpr #1\relax }}%
+\def\MachinBisA #1#2#3%
+{\xinttrunc {#3} %
+ {\xintSub
+ {\xintMul {16/5}{\xintPowerSeries {0}{#1}{\coeffarctg}{\xa}}}
+ {\xintMul{4/239}{\xintPowerSeries {0}{#2}{\coeffarctg}{\xb}}}%
+}}%
+\end{everbatim*}
+
+Let us use this variant for a loop showing the build-up of digits:
+\begin{everbatim*}
+\begin{multicols}{2}
+ \cnta 0 % previously declared \count register
+ \loop \noindent
+ \centeredline{\dtt{\MachinBis{\cnta}}}%
+ \ifnum\cnta < 30
+ \advance\cnta 1 \repeat
+\end{multicols}
+\end{everbatim*}
+
+\hypertarget{Machin1000}{}
+%
+You want more digits and have some time? compile this copy of the
+\hyperlink{MachinCode}{|\Machin|} with |etex| (or |pdftex|):
+%
+\everb|@
+% Compile with e-TeX extensions enabled (etex, pdftex, ...)
+\input xintfrac.sty
+\input xintseries.sty
+% pi = 16 Arctg(1/5) - 4 Arctg(1/239) (John Machin's formula)
+\def\coeffarctg #1{\the\numexpr\ifodd#1 -1\else1\fi\relax/%
+ \the\numexpr 2*#1+1\relax [0]}%
+\def\xa {1/25[0]}%
+\def\xb {1/57121[0]}%
+\def\Machin #1{%
+ \romannumeral0\expandafter\MachinA \expandafter
+ {\the\numexpr (#1+3)*5/7\expandafter}\expandafter
+ {\the\numexpr (#1+3)*10/45\expandafter}\expandafter
+ {\the\numexpr #1+3\expandafter}\expandafter
+ {\the\numexpr #1\relax }}%
+\def\MachinA #1#2#3#4%
+{\xinttrunc {#4}
+ {\xintSub
+ {\xintMul {16/5}{\xintFxPtPowerSeries {0}{#1}{\coeffarctg}{\xa}{#3}}}
+ {\xintMul {4/239}{\xintFxPtPowerSeries {0}{#2}{\coeffarctg}{\xb}{#3}}}%
+}}%
+\pdfresettimer
+\fdef\Z {\Machin {1000}}
+\odef\W {\the\pdfelapsedtime}
+\message{\Z}
+\message{computed in \xintRound {2}{\W/65536} seconds.}
+\bye
+|
+
+This will log the first 1000 digits of $\pi$ after the decimal point. On my
+laptop (a 2012 model) this took about $5.05$ seconds last time I tried.%
+%
+\footnote{With \texttt{1.09i} and earlier \xintname, this used to be \dtt{42}
+ seconds; starting with \texttt{1.09j}, and prior to \texttt{1.2}, it was
+ \dtt{16} seconds (this was probably due to a more efficient division with
+ denominators at most $9999$). The |1.2| \xintcorename achieves a further
+ gain at \dtt{5.6} seconds.}
+%
+\footnote{With |\xintDigits:=1001;|, the non-optimized implementation with the
+ |iter| of \xintexprname fame using the
+ \hyperlink{BrentSalamin}{Brent-Salamin algorithm}, took, last time I tried
+ (1.2i), about \dtt{7} seconds on my laptop (the last two digits were wrong,
+ which is ok as they serve as guard digits), and for obtaining about
+ \dtt{500} digits, it was about \dtt{1.7}s. This is not bad, taking into
+ account that the syntax is almost free rolling speech, contrarily to the
+ code above for the Machin formula computation; we would like to use the
+ quadratically convergent Brent-Salamin algorithm for more digits, but with
+ such computations with numbers of one thousand digits we are beyond the
+ border of the reasonable range for \xintname. Innocent people not knowing
+ what it means to compute with \TeX, and with the extra constraint of
+ expandability will wonder why this is at least thousands of times slower
+ than with any other language (with a little Python program using the
+ |Decimal| library, I timed the Brent-Salamin algorithm to \dtt{4.4ms} for
+ about |1000| digits and \dtt{1.14ms} for |500| digits.) I will just say that
+ for example digits are represented and manipulated via their ascii-code !
+ all computations must convert from ascii-code to cpu words; furthermore
+ nothing can be stored away. And there is no memory storage with |O(1)| time
+ access... if expandability is to be verified.}
+%
+
+
+As mentioned in the
+introduction, the file \href{http://www.ctan.org/pkg/pi}{pi.tex} by \textsc{D.
+ Roegel} shows that orders of magnitude faster computations are possible within
+\TeX{}, but recall our constraints of complete expandability and be merciful,
+please.
+
+\textbf{Why truncating rather than rounding?} One of our main competitors
+on the market of scientific computing, a canadian product (not
+encumbered with expandability constraints, and having barely ever heard
+of \TeX{} ;-), prints numbers rounded in the last digit. Why didn't we
+follow suit in the macros \csa{xintFxPtPowerSeries} and
+\csa{xintFxPtPowerSeriesX}? To round at |D| digits, and excluding a
+rewrite or cloning of the division algorithm which anyhow would add to
+it some overhead in its final steps, \xintfracname needs to truncate at
+|D+1|, then round. And rounding loses information! So, with more time
+spent, we obtain a worst result than the one truncated at |D+1| (one
+could imagine that additions and so on, done with only |D| digits, cost
+less; true, but this is a negligeable effect per summand compared to the
+additional cost for this term of having been truncated at |D+1| then
+rounded). Rounding is the way to go when setting up algorithms to
+evaluate functions destined to be composed one after the other: exact
+algebraic operations with many summands and an |f| variable which is a
+fraction are costly and create an even bigger fraction; replacing |f|
+with a reasonable rounding, and rounding the result, is necessary to
+allow arbitrary chaining.
+
+But, for the
+computation of a single constant, we are really interested in the exact
+decimal expansion, so we truncate and compute more terms until the
+earlier result gets validated. Finally if we do want the rounding we can
+always do it on a value computed with |D+1| truncation.
+
+\clearpage
+\let\xintseriesnameUp\undefined
+\csname xintcfracnameUp\endcsname
+\def\n{|{N}|}
+\def\m{|{M}|}
+\def\x{|{x}|}
+\section{Macros of the \xintcfracname package}
+\RaisedLabel{sec:cfrac}
+
+\localtableofcontents
+
+First version of this package was included in release |1.04| (|2013/04/25|) of the
+\xintname bundle. It was kept almost unchanged until |1.09m| of |2014/02/26|
+which brought some new macros: \csbxint{FtoC}, \csbxint{CtoF}, \csbxint{CtoCv},
+dealing with sequences of braced partial quotients rather than comma separated
+ones, \csbxint{FGtoC} which is to produce ``guaranteed'' coefficients of some
+real number known approximately, and \csbxint{GGCFrac} for displaying arbitrary
+material as a continued fraction; also, some changes to existing macros:
+\csbxint{FtoCs} and \csbxint{CntoCs} insert spaces after the commas,
+\csbxint{CstoF} and \csbxint{CstoCv} authorize spaces in the input also before
+the commas.
+
+Note: \csbxint{CstoF} and \csbxint{CstoCv} create a partial dependency on
+\xinttoolsname (its \csbxint{CSVtoList}.)
+
+This section contains:
+\begin{enumerate}
+\item an \hyperref[ssec:cfracoverview]{overview} of the package functionalities,
+\item a description of each one of the package macros,
+\item further illustration of their use via the study of the
+ \hyperref[ssec:e-convergents]{convergents of $e$}.
+\end{enumerate}
+
+\subsection{Package overview}\label{ssec:cfracoverview}
+
+The package computes partial quotients and convergents of a fraction, or
+conversely start from coefficients and obtain the corresponding fraction; three
+macros \csbxint {CFrac}, \csbxint {GCFrac} and \csbxint {GGCFrac} are
+for typesetting (the first two assume that the coefficients are numeric
+quantities acceptable by the \xintfracname \csbxint{Frac} macro, the
+last one will display arbitrary material), the others
+can be nested (if applicable) or see their outputs further processed by other
+macros from the \xintname bundle, particularly the macros of \xinttoolsname
+dealing with sequences of braced items or comma separated lists.
+
+A \emph{simple} continued fraction has coefficients
+|[c0,c1,...,cN]| (usually called partial quotients, but I
+dislike this entrenched terminology), where |c0| is a positive or
+negative integer and the others are positive integers.
+
+Typesetting is usually done via the |amsmath| macro |\cfrac|:
+\begin{everbatim*}
+\[ c_0 + \cfrac{1}{c_1+\cfrac1{c_2+\cfrac1{c_3+\cfrac1{\ddots}}}}\]
+\end{everbatim*}
+
+Here is a concrete example:
+\begin{everbatim*}
+\[ \xintFrac {208341/66317}=\xintCFrac {208341/66317}\]%
+\end{everbatim*}
+But it is the macro \csbxint{CFrac} which did all the work of \emph{computing}
+the continued fraction \emph{and} using |\cfrac| from |amsmath| to typeset
+it.
+
+A \emph{generalized} continued fraction has the same structure but the
+numerators are not restricted to be $1$, and numbers used in the continued
+fraction may be arbitrary, also fractions, irrationals, complex,
+indeterminates.%
+%
+\footnote{\xintcfracname may be used with indeterminates,
+ for basic conversions from one inline format to another, but not for
+ actual computations. See \csbxint{GGCFrac}.}
+%
+The \emph{centered} continued fraction is an
+example:
+\begin{everbatim*}
+\[ \xintFrac {915286/188421}=\xintGCFrac {5+-1/7+1/39+-1/53+-1/13}
+ =\xintCFrac {915286/188421}\]
+\end{everbatim*}
+
+The macro \csbxint{GCFrac}, contrarily to
+\csbxint{CFrac}, does not compute anything, it just typesets starting from a
+generalized continued fraction in inline format, which in this example
+was input literally. We also used \csa{xintCFrac}
+for comparison of the two types of continued fractions.
+
+To let \TeX{} compute the centered continued fraction of |f| there is
+\csbxint{FtoCC}:
+\begin{everbatim*}
+\[\xintFrac {915286/188421}\to\xintFtoCC {915286/188421}\]
+\end{everbatim*}
+The package macros are expandable and may be nested (naturally \csa{xintCFrac}
+and \csa{xintGCFrac} must be at the top level, as they deal with typesetting).
+\begin{everbatim*}
+\[\xintGCFrac {\xintFtoCC{915286/188421}}\]
+\end{everbatim*}
+
+The `inline' format expected on input by \csbxint{GCFrac} is
+%
+\leftedline{$a_0+b_0/a_1+b_1/a_2+b_2/a_3+\cdots+b_{n-2}/a_{n-1}+b_{n-1}/a_n$}
+%
+Fractions among the coefficients are allowed but they must be enclosed
+within braces. Signed integers may be left without braces (but the |+|
+signs are mandatory). No spaces are allowed around the plus and fraction
+symbols. The coefficients may themselves be macros, as long as these
+macros are \fexpan dable.
+\begin{everbatim*}
+\[ \xintFrac{\xintGCtoF {1+-1/57+\xintPow {-3}{7}/\xintiiQuo {132}{25}}}
+ = \xintGCFrac {1+-1/57+\xintPow {-3}{7}/\xintiiQuo {132}{25}}\]
+\end{everbatim*}
+To compute the actual fraction one has \csbxint{GCtoF}:
+\begin{everbatim*}
+\[\xintFrac{\xintGCtoF {1+-1/57+\xintPow {-3}{7}/\xintiiQuo {132}{25}}}\]
+\end{everbatim*}
+For non-numeric input there is \csbxint{GGCFrac}.
+\begin{everbatim*}
+\[\xintGGCFrac {a_0+b_0/a_1+b_1/a_2+b_2/\ddots+\ddots/a_{n-1}+b_{n-1}/a_n}\]
+\end{everbatim*}
+For regular continued fractions, there is a simpler comma separated format:
+\begin{everbatim*}
+\[-7,6,19,1,33\to\xintFrac{\xintCstoF{-7,6,19,1,33}}=\xintCFrac{\xintCstoF{-7,6,19,1,33}}\]
+\end{everbatim*}
+The macro \csbxint{FtoCs} produces from a fraction |f| the comma separated
+list of its coefficients.
+\begin{everbatim*}
+\[\xintFrac{1084483/398959}=[\xintFtoCs{1084483/398959}]\]
+\end{everbatim*}
+If one prefers other separators, one can use the two arguments macros
+\csbxint{FtoCx} whose first argument is the separator (which may consist of more
+than one token) which is to be used.
+\begin{everbatim*}
+\[\xintFrac{2721/1001}=\xintFtoCx {+1/(}{2721/1001})\cdots)\]
+\end{everbatim*}
+This allows under Plain \TeX{} with |amstex| to obtain the same effect
+as with \LaTeX{}+|\amsmath|+\csbxint{CFrac}:
+%
+\leftedline{|$$\xintFwOver{2721/1001}=\xintFtoCx {+\cfrac1\\ }{2721/1001}\endcfrac$$|}
+
+As a shortcut to \csa{xintFtoCx} with separator |1+/|, there is
+\csbxint{FtoGC}:
+\begin{everbatim*}
+2721/1001=\xintFtoGC {2721/1001}
+\end{everbatim*}
+Let us compare in that case with the output of \csbxint{FtoCC}:
+\begin{everbatim*}
+2721/1001=\xintFtoCC {2721/1001}
+\end{everbatim*}
+To obtain the coefficients as a sequence of braced numbers, there is
+\csbxint{FtoC} (this is a shortcut for |\xintFtoCx {}|). This list
+(sequence) may then be manipulated using the various macros of \xinttoolsname
+such as the non-expandable macro \csbxint{AssignArray} or the expandable
+\csbxint{Apply} and \csbxint{ListWithSep}.
+
+Conversely to go from such a sequence of braced coefficients to the
+corresponding fraction there is \csbxint{CtoF}.
+
+The `|\printnumber|' (\autoref{ssec:printnumber}) macro which we use in this
+document to print long numbers can also be useful on long continued fractions.
+%
+\begin{everbatim*}
+\printnumber{\xintFtoCC {35037018906350720204351049/244241737886197404558180}}
+\end{everbatim*}
+%
+If we apply \csbxint{GCtoF} to this generalized continued fraction, we
+discover that the original fraction was reducible:
+%
+\leftedline{|\xintGCtoF
+ {143+1/2+...+-1/9}|\dtt{=\xintGCtoF{143+1/2+1/5+-1/4+-1/4+-1/4+-1/3+1/2+1/2+1/6+-1/22+1/2+1/10+-1/5+-1/11+-1/3+1/4+-1/2+1/2+1/4+-1/2+1/23+1/3+1/8+-1/6+-1/9}}}
+
+\def\mymacro #1{$\xintFrac{#1}=[\xintFtoCs{#1}]$\vtop to 6pt{}}
+
+\begingroup
+\catcode`^\active
+\def^#1^{\hbox{#1}}%
+
+When a generalized continued fraction is built with integers, and
+numerators are only |1|'s or |-1|'s, the produced fraction is
+irreducible. And if we compute it again with the last sub-fraction
+omitted we get another irreducible fraction related to the bigger one by
+a Bézout identity. Doing this here we get:
+%
+\leftedline{|\xintGCtoF {143+1/2+...+-1/6}|\dtt{=\xintGCtoF{143+1/2+1/5+-1/4+-1/4+-1/4+-1/3+1/2+1/2+1/6+-1/22+1/2+1/10+-1/5+-1/11+-1/3+1/4+-1/2+1/2+1/4+-1/2+1/23+1/3+1/8+-1/6}}}
+and indeed:
+\[\begin{vmatrix}
+ ^2897319801297630107^ & ^328124887710626729^\\
+ ^20197107104701740^ & ^2287346221788023^
+ \end{vmatrix} = \mbox{\dtt{\xintiiSub {\xintiiMul {2897319801297630107}{2287346221788023}}{\xintiiMul{20197107104701740}{328124887710626729}}}}\]
+
+\endgroup
+
+The various fractions obtained from the truncation of a continued fraction to
+its initial terms are called the convergents. The macros of \xintcfracname
+such as \csbxint{FtoCv}, \csbxint{FtoCCv}, and others which compute such
+convergents, return them as a list of braced items, with no separator (as does
+\csbxint {FtoC} for the partial quotients). Here is an example:
+
+\begin{everbatim*}
+\[\xintFrac{915286/188421}\to
+ \xintListWithSep{,}{\xintApply\xintFrac{\xintFtoCv{915286/188421}}}\]
+\end{everbatim*}
+\begin{everbatim*}
+\[\xintFrac{915286/188421}\to
+ \xintListWithSep{,}{\xintApply\xintFrac{\xintFtoCCv{915286/188421}}}\]
+\end{everbatim*}
+%
+We thus see that the `centered convergents' obtained with \csbxint{FtoCCv} are
+among the fuller list of convergents as returned by \csbxint{FtoCv}.
+
+Here is a more complicated use of \csa{xintApply}
+and \csa{xintListWithSep}. We first define a macro which will be applied to each
+convergent:%
+%
+\leftedline{|\newcommand{\mymacro}[1]{$\xintFrac{#1}=[\xintFtoCs{#1}]$\vtop to 6pt{}}|}
+%
+Next, we use the following code:
+%
+\leftedline{|$\xintFrac{49171/18089}\to{}$|}
+%
+\leftedline{|\xintListWithSep {,
+ }{\xintApply{\mymacro}{\xintFtoCv{49171/18089}}}|}
+It produces:\par
+\noindent$ \xintFrac{49171/18089}\to {}$\xintListWithSep {,
+ }{\xintApply{\mymacro}{\xintFtoCv{49171/18089}}}.
+
+The macro \csbxint{CntoF} allows to specify the coefficients as a function given
+by a one-parameter macro. The produced values do not have to be integers.
+\begin{everbatim*}
+\def\cn #1{\xintiiPow {2}{#1}}% 2^n
+ \[\xintFrac{\xintCntoF {6}{\cn}}=\xintCFrac [l]{\xintCntoF {6}{\cn}}\]
+\end{everbatim*}
+
+Notice the use of the optional argument |[l]| to \csa{xintCFrac}. Other
+possibilities are |[r]| and (default) |[c]|.
+\begin{everbatim*}
+\def\cn #1{\xintPow {2}{-#1}}%
+ \[\xintFrac{\xintCntoF {6}{\cn}}=\xintGCFrac [r]{\xintCntoGC {6}{\cn}}=
+ [\xintFtoCs {\xintCntoF {6}{\cn}}]\]
+\end{everbatim*}
+We used \csbxint{CntoGC} as we wanted to display also the continued fraction and
+not only the fraction returned by \csa{xintCntoF}.
+
+There are also \csbxint{GCntoF} and \csbxint{GCntoGC} which allow the same for
+generalized fractions. An initial portion of a generalized continued
+fraction for $\pi$ is obtained like this
+\begin{everbatim*}
+\def\an #1{\the\numexpr 2*#1+1\relax }%
+\def\bn #1{\the\numexpr (#1+1)*(#1+1)\relax }%
+\[\xintFrac{\xintDiv {4}{\xintGCntoF {5}{\an}{\bn}}} =
+ \cfrac{4}{\xintGCFrac{\xintGCntoGC {5}{\an}{\bn}}} =
+ \xintTrunc {10}{\xintDiv {4}{\xintGCntoF {5}{\an}{\bn}}}\dots\]
+\end{everbatim*}
+
+We see that the quality of approximation is not fantastic compared to the simple
+continued fraction of $\pi$ with about as many terms:
+\begin{everbatim*}
+\[\xintFrac{\xintCstoF{3,7,15,1,292,1,1}}=
+ \xintGCFrac{3+1/7+1/15+1/1+1/292+1/1+1/1}=
+ \xintTrunc{10}{\xintCstoF{3,7,15,1,292,1,1}}\dots\]
+\end{everbatim*}
+
+When studying the continued fraction of some real number, there is always
+some doubt about how many terms are valid, when computed starting from some
+approximation. If $f\leqslant x\leqslant g$ and $f, g$ both have the
+same first $K$ partial quotients, then $x$ also has the same first $K$ quotients
+and convergents. The macro \csbxint{FGtoC} outputs as a sequence of braced items
+the common partial quotients of its two arguments. We can thus use it to produce
+a sure list of valid convergents of $\pi$ for example, starting from some proven
+lower and upper bound:
+\begin{everbatim*}
+$$\pi\to [\xintListWithSep{,}
+ {\xintFGtoC {3.14159265358979323}{3.14159265358979324}}, \dots]$$
+\noindent$\pi\to\xintListWithSep{,\allowbreak\;}
+ {\xintApply{\xintFrac}
+ {\xintCtoCv{\xintFGtoC {3.14159265358979323}{3.14159265358979324}}}}, \dots$
+\end{everbatim*}
+
+
+\subsection{\csh{xintCFrac}}\label{xintCFrac}
+
+\csa{xintCFrac}|{f}|\ntype{\Ff} is a math-mode only, \LaTeX{} with |amsmath|
+only, macro which first computes then displays with the help of |\cfrac| the
+simple continued fraction corresponding to the given fraction. It admits an
+optional argument which may be |[l]|, |[r]| or (the default) |[c]| to specify
+the location of the one's in the numerators of the sub-fractions. Each
+coefficient is typeset using the \csbxint{Frac} macro from the \xintfracname
+package. This macro is \fexpan dable in the sense that it prepares expandably
+the whole expression with the multiple |\cfrac|'s, but it is not completely
+expandable naturally as |\cfrac| isn't.
+
+\subsection{\csh{xintGCFrac}}\label{xintGCFrac}
+
+\csa{xintGCFrac}|{a+b/c+d/e+f/g+h/...+x/y}|\ntype{f} uses similarly |\cfrac|
+to prepare the typesetting with the |amsmath| |\cfrac| (\LaTeX{}) of a
+generalized continued fraction given in inline format (or as macro which
+will \fexpan d to it). It admits the
+same optional argument as \csa{xintCFrac}. Plain \TeX{} with |amstex|
+users, see \csbxint{GCtoGCx}.
+\begin{everbatim*}
+\[\xintGCFrac {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}\]
+\end{everbatim*}
+This is mostly a typesetting macro, although it does provoke the
+expansion of the coefficients. See \csbxint{GCtoF} if you are impatient
+to see this specific fraction computed.
+
+It admits an optional argument within square brackets which may be
+either |[l]|, |[c]| or |[r]|. Default is |[c]| (numerators are centered).
+
+Numerators and denominators are made arguments to the \csbxint{Frac}
+macro. This allows them to be themselves fractions or anything \fexpan
+dable giving numbers or fractions, but also means however that they can
+not be arbitrary material, they can not contain color changing macros
+for example. One of the reasons is that \csa{xintGCFrac} tries to
+determine the signs of the numerators and chooses accordingly to use
+$+$ or $-$.
+
+\subsection{\csh{xintGGCFrac}}\label{xintGGCFrac}
+
+\csa{xintGGCFrac}|{a+b/c+d/e+f/g+h/...+x/y}|\ntype{f} is a clone of
+\csbxint{GCFrac}, hence again \LaTeX{} specific with package
+|amsmath|.
+It does not assume the coefficients to be numbers as understood by
+\xintfracname. The macro can be used for displaying arbitrary content as
+a continued fraction with |\cfrac|, using only plus signs though. Note
+though that it will first \fexpan d its argument, which may be thus be
+one of the \xintcfracname macros producing a (general) continued
+fraction in inline format, see \csbxint{FtoCx} for an example. If this
+expansion is not wished, it is enough to start the argument with a
+space.
+\begin{everbatim*}
+\[\xintGGCFrac {1+q/1+q^2/1+q^3/1+q^4/1+q^5/\ddots}\]
+\end{everbatim*}
+
+\subsection{\csh{xintGCtoGCx}}\label{xintGCtoGCx}
+%{\small New with release |1.05|.\par}
+
+\csa{xintGCtoGCx}|{sepa}{sepb}{a+b/c+d/e+f/...+x/y}|\etype{nnf} returns the list
+of the coefficients of the generalized continued fraction of |f|, each one
+within a pair of braces, and separated with the help of |sepa| and |sepb|. Thus
+%
+\leftedline{|\xintGCtoGCx :;{1+2/3+4/5+6/7}| gives \xintGCtoGCx
+ :;{1+2/3+4/5+6/7}}
+%
+The following can be used byt Plain \TeX{}+|amstex| users to obtain an
+output similar as the ones produced by \csbxint{GCFrac} and
+\csbxint{GGCFrac}:\par
+\everb|@
+$$\xintGCtoGCx {+\cfrac}{\\}{a+b/...}\endcfrac$$
+$$\xintGCtoGCx {+\cfrac\xintFwOver}{\\\xintFwOver}{a+b/...}\endcfrac$$
+|
+
+\subsection{\csh{xintFtoC}}\label{xintFtoC}
+
+\csa{xintFtoC}|{f}|\etype{\Ff} computes the
+coefficients of the simple continued fraction of |f| and returns them as a list
+(sequence) of braced items.
+
+\begin{everbatim*}
+\fdef\test{\xintFtoC{-5262046/89233}}\texttt{\meaning\test}
+\end{everbatim*}
+
+\subsection{\csh{xintFtoCs}}\label{xintFtoCs}
+
+\csa{xintFtoCs}|{f}|\etype{\Ff} returns the comma separated list of the
+coefficients of the simple continued fraction of |f|. Notice that starting with
+|1.09m| a space follows each comma (mainly for usage in text mode, as in math
+mode spaces are produced in the typeset output by \TeX{} itself).
+\begin{everbatim*}
+\[ \xintSignedFrac{-5262046/89233} \to [\xintFtoCs{-5262046/89233}]\]
+\end{everbatim*}
+
+\subsection{\csh{xintFtoCx}}\label{xintFtoCx}
+
+\csa{xintFtoCx}|{sep}{f}|\etype{n\Ff} returns the list of the
+coefficients of the simple continued fraction of |f| separated with the
+help of |sep|, which may be anything (and is kept unexpanded). For
+example, with Plain \TeX{} and |amstex|,
+%
+\leftedline{|$$\xintFtoCx {+\cfrac1\\ }{-5262046/89233}\endcfrac$$|}
+%
+will display the continued fraction using
+|\cfrac|. Each coefficient is inside a brace pair \hbox{|{ }|}, allowing
+a macro to end the separator and fetch it as argument,
+for example, again with Plain \TeX{} and |amstex|:
+\everb|@
+ \def\highlight #1{\ifnum #1>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 |f<x<g| or |f>x>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*}
+\[\xintFrac{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.
+
+\emph{Usage of this macro requires the user to load} \xinttoolsname.\IMPORTANT
+
+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}=
+ \xintSignedFrac{\xintCstoF {-1,3,-5,7,-9,11,-13}}=\xintSignedFrac{\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}}=\xintFrac{\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*}
+\[ \xintFrac{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}} =
+\xintFrac{\xintGCtoF {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}} =
+\xintFrac{\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}} =
+ \xintFrac{\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.
+
+\emph{Usage of this macro requires the user to load} \xinttoolsname.\IMPORTANT
+
+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\xintFrac{\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\xintFrac
+ {\xintGCtoCv{3+{-2}/{7/2}+{3/4}/12+{-56}/3}}}\]
+\[\xintListWithSep{,}{\xintApply\xintFrac{\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\xintFrac{\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\xintFrac{\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}} =
+ \xintFrac{\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*}
+\[ \xintFrac{\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\xintFrac {\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}}=\xintSignedFrac{\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=
+ \xintFrac{\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$.
+
+\clearpage
+\let\xintcfracnameUp\undefined
+\csname xinttoolsnameUp\endcsname
+\def\n{|{N}|}
+\def\m{|{M}|}
+\def\x{|{x}|}
+\section{Macros of the \xinttoolsname package}
+
+\RaisedLabel{sec:tools}
+
+\localtableofcontents
+
+These utilities used to be provided within the \xintname package; since |1.09g|
+(|2013/11/22|) they have been moved to an independently usable package
+\xinttoolsname, which has none of the \xintname facilities regarding big
+numbers. Whenever relevant release |1.09h| has made the macros |\long| so they
+accept |\par| tokens on input.
+
+The completely expandable utilities (up to \csbxint{iloop}) are documented
+first, then the non expandable utilities.
+
+A brief overview is in \autoref{sec:sometoolsutils} and \autoref{sec:examples}
+has more examples of use of macros of this package.
+
+\subsection{\csh{xintRevWithBraces}}\label{xintRevWithBraces}
+
+%{\small New in release |1.06|.\par}
+
+\edef\X{\xintRevWithBraces{12345}}
+\edef\y{\xintRevWithBraces\X}
+\expandafter\def\expandafter\w\expandafter
+ {\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}}
+
+%
+\csa{xintRevWithBraces}\marg{list}\etype{f} first does the \fexpan sion of its
+argument then it reverses the order of the tokens, or braced material, it
+encounters, maintaining existing braces and adding a brace pair around each
+naked token encountered. Space tokens (in-between top level braces or naked
+tokens) are gobbled. This macro is mainly thought out for use on a \meta{list}
+of such braced material; with such a list as argument the \fexpan sion will only
+hit against the first opening brace, hence do nothing, and the braced stuff may
+thus be macros one does not want to expand.
+%
+\leftedline{|\edef\x{\xintRevWithBraces{12345}}|}
+%
+\leftedline{|\meaning\x:|\dtt{\meaning\X}}
+%
+\leftedline{|\edef\y{\xintRevWithBraces\x}|}
+%
+\leftedline{|\meaning\y:|\dtt{\meaning\y}}
+%
+The examples above could be defined with |\edef|'s because the braced material
+did not contain macros. Alternatively:
+%
+\leftedline{|\expandafter\def\expandafter\w\expandafter|}
+%
+\leftedline{|{\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}}|}
+%
+\leftedline{|\meaning\w:|\dtt{\meaning\w}}
+%
+The macro \csa{xintReverseWithBracesNoExpand}\etype{n} does the same job
+without the initial expansion of its argument.
+
+
+\subsection{\csh{xintZapFirstSpaces}, \csh{xintZapLastSpaces}, \csh{xintZapSpaces}, \csh{xintZapSpacesB}}
+\label{xintZapFirstSpaces}
+\label{xintZapLastSpaces}
+\label{xintZapSpaces}
+\label{xintZapSpacesB}
+%{\small New with release |1.09f|.\par}
+
+\csa{xintZapFirstSpaces}\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} spaces.
+
+This macro will be mostly of interest to programmers who will know what I will
+now be talking about. \emph{The essential points, naturally, are the complete
+ expandability and the fact that no brace removal nor any other alteration is
+ done to the input.}
+
+\TeX's input scanner already converts consecutive blanks into single space
+tokens, but |\xintZapFirstSpaces| handles successfully also inputs with
+consecutive multiple space tokens.
+However, it is assumed that \meta{stuff} does not contain (except inside braced
+sub-material) space tokens of character code distinct from $32$.
+
+It expands in two steps, and if the goal is to apply it to the
+expansion text of |\x| to define |\y|, then one can do:
+|\odef\y{\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}|
+(one can also define a wrapper macro to |\xintZapFirstSpaces| in order to
+expand once the argument first, but \xinttoolsname not being a programming
+layer, it provides no «Generate Variants» facilities).
+
+Other use case: inside a macro which received a parameter |#1|, one can do
+|\oodef\x{\xintZapFirstSpaces {#1}}|, or, if |#1|, after leading spaces have
+been stripped can accept |\edef| expansion, one can do
+|\edef\x{\xintZapFirstSpaces{#1}}|.
+
+\begingroup
+\def\x { \a { \X } { \b \Y } }
+%
+\leftedline{|\xintZapFirstSpaces { \a { \X } { \b \Y } }->|%
+\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 |<spaces>{braced}<spaces>|. 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 ``|<opt. spaces>{}<opt.
+spaces>|'' 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{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.
+
+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<test>...\repeat|\retype{} 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 \url{http://tex.stackexchange.com/a/143035/4686} 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<test> ... \repeat|\retype{} 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 <afterloop>.etc.. etc... \repeat|}
+%
+The reason is that one may wish to use the then current value of
+|\xintiloopindex| in |<afterloop>| 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 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 <opt sign><digits>\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 <opt sign><digits>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
+
+\ifnum\NoSourceCode=1
+\bigskip
+\begin{framed}
+ \small This documentation has been compiled without the source code,
+ which is available in the separate file:
+ %
+ \centeredline{|sourcexint.pdf|,}
+ %
+ which will open in a PDF viewer via |texdoc sourcexint.pdf|.
+
+ To produce a single file including both the user documentation and the
+ source code:
+ \begin{itemize}
+ \item run |etex| on |xint.dtx| to generate |xint.tex| among other files,
+ \item edit |xint.tex| to set the |\NoSourceCode| toggle within it to |0|,
+ \item run |make clean| and then |make xint.pdf|.
+ \end{itemize}
+ This will need |latexmk|; if not available you will need in replacement of
+ the last step to execute manually |latex| on |xint.tex| (thrice)
+ then |dvipdfmx|.
+\end{framed}
+\fi
+
+\ifnum\dosourcexint=1
++fi
++catcode`\ 0
+\catcode0 15 % retour à la normale, peu importe
+\catcode`\+ 12
+\etocignoredepthtags
+\etocsetnexttocdepth{section}
+\tableofcontents
+\makeatletter
+\@gobble\fi
+\StopEventually{\end{document}\endinput}
+\ifnum\dosourcexint=1
+\renewcommand{\etocaftertochook}{\addvspace{\bigskipamount}}
+\etocsettocstyle {}{}
+\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 !!!
+\else
+\clearpage
+\fi
+
+\makeatletter
+
+\def\MARGEPAGENO{1.25em}
+\etocsettocdepth{subsubsection}% 2015/09/15
+
+\etocdepthtag.toc {implementation}
+\addtocontents{toc}{\gdef\string\sectioncouleur{[named]{RoyalPurple}}}
+
+\def\storedlinecounts {}
+\def\StoreCodelineNo #1{\edef\storedlinecounts{%
+ \unexpanded\expandafter{\storedlinecounts}%
+ {{#1}{\the\c@CodelineNo}}}\c@CodelineNo\z@ }
+
+% \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.
+
+%
+% Actually, I should not at all rely on the doc class, I should do it all by
+% myself. As I don't use at all \DocInput (which caused me loads of problems
+% back then when I was trying to get a workflow satisfying my views on how
+% .dtx files should be structured), there is not much rationale for using the
+% doc class.
+
+\def\macrocode{\macro@code
+ \frenchspacing \@vobeyspaces
+ \makestarlowast
+ \xmacro@code }
+
+\def\macro@font {\ttbfamily }% slashed 0
+
+% \lverb
+% ======
+
+% Définition de \lverb
+% Has become more complicated for 1.2l
+\catcode`_ 11
+{\catcode32\active%
+\gdef\myobeyspaces{\catcode32\active\def {\leavevmode\kern\fontcharwd\font`X}}}
+\def\lverbpercent {\catcode32\active\lverbpercent_a}%
+\def\lverbpercent_a #1{%
+ \if\XINT_sptoken\detokenize{#1}\xint_dothis{\catcode32 10 }\fi
+ \if-\detokenize{#1}\xint_dothis{\par #1}\fi
+ \if(\detokenize{#1}\xint_dothis{\par\bgroup\myobeyspaces\obeylines}\fi
+ \if:\detokenize{#1}\xint_dothis{}\fi
+ \if)\detokenize{#1}\xint_dothis{\egroup\everypar{\hskip-\parindent\everypar{}}}\fi
+ \if!\detokenize{#1}\xint_dothis{\lverbpercent}\fi
+ \ifx#1\lverbpercent\xint_dothis{\catcode32 10 \par #1}\fi
+ \xint_orthat{\catcode32 10 #1}%
+}
+\catcode`_ 8
+\long\def\lverb {%
+ \relax\par\smallskip%\noindent\null
+ \begingroup
+ \bgroup
+ \aftergroup\@@par \aftergroup\endgroup \aftergroup\medskip
+ \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}%
+ \MicroFont % sera donc en couleur.
+ \@lverb
+}
+
+\def\@lverb #1{\catcode`#1\active
+ \lccode`\~`#1\lowercase{\let~\egroup}}%
+
+\def\MicroFont {%\ttzfamily
+ \color[named]{Purple}\makestarlowast }
+
+% privatecodecomments
+% ===================
+\newenvironment{privatecodecomments}
+ {\par \textbf{\textcolor{red}{COMMENTAIRES PRIVÉS.}}\par
+ \begingroup\lccode`\~`\%\lowercase{\endgroup\let~\lverbpercent}%
+ \catcode`\%\active}
+ {\par \textbf{\textcolor{red}{FIN DES COMMENTAIRES PRIVÉS.}}\par}
+
+% \changed
+% ========
+
+\def\changed#1#2{%
+ \par\smallskip\noindent
+ \textbf{#1\if\relax\detokenize{#2}\relax\else\space(#2)\fi.}%
+% \hangindent\leftmarginii
+ \hangindent\parindent
+}
+
+% Hyperlinks
+% ==========
+
+% renew some definitions (new labels, prefixed with src-)
+
+% hyperlink and slash
+\DeclareRobustCommand\csbxint[1]
+ {\hyperref[\detokenize{src-xint#1}]%
+ {{\char92\mbox{xint}\-\endlinechar-1
+ \makestarlowast \catcode`_ 12 \catcode`^ 12
+ \scantokens\expandafter{\detokenize{#1}}}}}
+
+\DeclareRobustCommand\csbXINT[1]
+ {\hyperref[\detokenize{src-XINT#1}]%
+ {{\char92\mbox{XINT}\-\endlinechar-1
+ \makestarlowast \catcode`_ 12 \catcode`^ 12
+ \scantokens\expandafter{\detokenize{#1}}}}}
+
+\DeclareRobustCommand\csb [1]
+ {\hyperref[\detokenize{src-#1}]%
+ {{\char92 \endlinechar-1
+ \makestarlowast \catcode`_ 12 \catcode`^ 12
+ \scantokens\expandafter{\detokenize{#1}}}}}
+
+% hyperlink and no slash
+\DeclareRobustCommand\csbn[1]
+ {\hyperref[\detokenize{src-#1}]%
+ {{\endlinechar-1
+ \makestarlowast \catcode`_ 12 \catcode`^ 12
+ \scantokens\expandafter{\detokenize{#1}}}}}
+
+% HACK OF \@sect
+% ==============
+% goal is to add labels but without having to modify currently
+% existing mark-up in sources. But KOMA annoyingly makes an extra
+% step needed. 2018/06/11
+\let\original@sect\@sect
+\def\@sect#1#2#3#4#5#6[#7]#8{\original@sect{#1}{#2}{#3}{#4}{#5}{#6}[{#7}]%
+ {\begingroup
+ %not possible because of KOMA wrappers
+ %\def\csh##1{\csa{##1}\label{\detokenize{src-##1}}}%
+ \let\csh\cshintitle
+ \let\cshn\cshnintitle
+ #8%
+ \endgroup}%
+}%
+\def\cshintitle#1{\csa{#1}%
+ \label{\detokenize{src-#1}}%
+ %\expandafter\DescribeMacro\csname#1\endcsname
+ }
+% \csan: no backslash
+\def\cshnintitle#1{\csan{#1}\label{\detokenize{src-#1}}}
+
+%% END OF MACRO DEFINITIONS FOR SOURCEXINT
+
+\def\xintImpRunningHeader{{\catcode`,12\relax
+ \DOCxintfrontpage,
+ \xintkernelnameimp,
+ \xinttoolsnameimp,
+ \xintcorenameimp,
+ \xintnameimp,
+ \xintbinhexnameimp,
+ \xintgcdnameimp,
+ \xintfracnameimp,
+ \xintseriesnameimp,
+ \xintcfracnameimp,
+ \xintexprnameimp,
+ \xinttrignameimp, \xintlognameimp}}
+\markboth{\makebox[0pt]{\xintImpRunningHeader}}{\makebox[0pt]{\xintImpRunningHeader}}
+
+\makeatother
+
+\section{Introduction to the implementation (recent changes)}
+
+This is \expandafter|\xintbndlversion| of \expandafter|\xintbndldate|.
+
+Please refer to |CHANGES.pdf| or |CHANGES.html|.\centeredline{Internet:
+ \url{http://mirrors.ctan.org/macros/generic/xint/CHANGES.html}}
+We keep here only a brief timeline of the most important changes.
+
+At |1.3e| the indices which were added at |1.3c| got removed: their inclusion
+caused extra time in the build of |sourcexint.pdf|, larger file size, and the
+macros created using |\csname...\endcsname| were not indexed, of course the
+indexing of functions would have needed systematic extra mark-up. Besides
+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 when one searches something.
+
+\begin{itemize}
+\item Release |1.3e| of |2019/04/01|: \xinttrignameimp, \xintlognameimp,
+ \csbxint{defefunc} ``non-protected'' variant of \csbxint{deffunc}. Indices
+ removed from |sourcexint.pdf|.
+\item Release |1.3d| of |2019/01/06|: bugfix 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,
+ |sourcexint.pdf| with indices of macros. 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|: bugfix release (|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.
+\end{itemize}
+
+Some parts of the code still date back to the initial release, and
+ at that time I was learning my trade in expandable TeX macro programming.
+ At some point in the future, I will have to re-examine the older parts of
+ the code.
+
+Warning: pay attention when looking at the code to the catcode configuration
+as found in \csbXINT{_setcatcodes}. Additional temporary configuration is used
+at some locations. For example |!| is of catcode letter in \xintexprnameimp
+and there are locations with funny catcodes e.g. using some letters with the
+math shift catcode.
+
+\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</dtx>\relax
+%\let<*xintkernel>\gardesinactifs
+%</dtx>^^A--------------------------------------------------------
+%<*xintkernel>^^A-------------------------------------------------
+%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*-
+% \clearpage\csname xintkernelnameUp\endcsname
+% \section {Package \xintkernelnameimp implementation}
+% \RaisedLabel{sec:kernelimp}
+%
+% \localtableofcontents
+%
+% 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}.
+%
+% \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{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+ \catcode13=5 % ^^M
+ \endlinechar=13 %
+ \catcode123=1 % {
+ \catcode125=2 % }
+ \catcode35=6 % #
+ \catcode44=12 % ,
+ \catcode45=12 % -
+ \catcode46=12 % .
+ \catcode58=12 % :
+ \catcode95=11 % _
+ \expandafter
+ \ifx\csname PackageInfo\endcsname\relax
+ \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}%
+ \else
+ \def\y#1#2{\PackageInfo{#1}{#2}}%
+ \fi
+ \let\z\relax
+ \expandafter
+ \ifx\csname numexpr\endcsname\relax
+ \y{xintkernel}{\numexpr not available, aborting input}%
+ \def\z{\endgroup\endinput}%
+ \else
+ \expandafter
+ \ifx\csname XINTsetupcatcodes\endcsname\relax
+ \else
+ \y{xintkernel}{I was already loaded, aborting input}%
+ \def\z{\endgroup\endinput}%
+ \fi
+ \fi
+ \ifx\z\relax\else\expandafter\z\fi%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_setcatcodes}, \csh{XINT_storecatcodes},
+% \csh{XINT_restorecatcodes_endinput}}
+% \begin{macrocode}
+ \def\PrepareCatcodes
+ {%
+ \endgroup
+ \def\XINT_restorecatcodes
+ {% takes care of all, to allow more economical code in modules
+ \catcode0=\the\catcode0 %
+ \catcode59=\the\catcode59 % ; xintexpr
+ \catcode126=\the\catcode126 % ~ xintexpr
+ \catcode39=\the\catcode39 % ' xintexpr
+ \catcode34=\the\catcode34 % " xintbinhex, and xintexpr
+ \catcode63=\the\catcode63 % ? xintexpr
+ \catcode124=\the\catcode124 % | xintexpr
+ \catcode38=\the\catcode38 % & xintexpr
+ \catcode64=\the\catcode64 % @ xintexpr
+ \catcode33=\the\catcode33 % ! xintexpr
+ \catcode93=\the\catcode93 % ] -, xintfrac, xintseries, xintcfrac
+ \catcode91=\the\catcode91 % [ -, xintfrac, xintseries, xintcfrac
+ \catcode36=\the\catcode36 % $ xintgcd only
+ \catcode94=\the\catcode94 % ^
+ \catcode96=\the\catcode96 % `
+ \catcode47=\the\catcode47 % /
+ \catcode41=\the\catcode41 % )
+ \catcode40=\the\catcode40 % (
+ \catcode42=\the\catcode42 % *
+ \catcode43=\the\catcode43 % +
+ \catcode62=\the\catcode62 % >
+ \catcode60=\the\catcode60 % <
+ \catcode58=\the\catcode58 % :
+ \catcode46=\the\catcode46 % .
+ \catcode45=\the\catcode45 % -
+ \catcode44=\the\catcode44 % ,
+ \catcode35=\the\catcode35 % #
+ \catcode95=\the\catcode95 % _
+ \catcode125=\the\catcode125 % }
+ \catcode123=\the\catcode123 % {
+ \endlinechar=\the\endlinechar
+ \catcode13=\the\catcode13 % ^^M
+ \catcode32=\the\catcode32 %
+ \catcode61=\the\catcode61\relax % =
+ }%
+ \edef\XINT_restorecatcodes_endinput
+ {%
+ \XINT_restorecatcodes\noexpand\endinput %
+ }%
+ \def\XINT_setcatcodes
+ {%
+ \catcode61=12 % =
+ \catcode32=10 % space
+ \catcode13=5 % ^^M
+ \endlinechar=13 %
+ \catcode123=1 % {
+ \catcode125=2 % }
+ \catcode95=11 % _ LETTER
+ \catcode35=6 % #
+ \catcode44=12 % ,
+ \catcode45=12 % -
+ \catcode46=12 % .
+ \catcode58=11 % : LETTER
+ \catcode60=12 % <
+ \catcode62=12 % >
+ \catcode43=12 % +
+ \catcode42=12 % *
+ \catcode40=12 % (
+ \catcode41=12 % )
+ \catcode47=12 % /
+ \catcode96=12 % `
+ \catcode94=11 % ^ LETTER
+ \catcode36=3 % $
+ \catcode91=12 % [
+ \catcode93=12 % ]
+ \catcode33=12 % ! (xintexpr.sty will use catcode 11)
+ \catcode64=11 % @ LETTER
+ \catcode38=7 % & for \romannumeral`&&@ trick.
+ \catcode124=12 % |
+ \catcode63=11 % ? LETTER
+ \catcode34=12 % "
+ \catcode39=12 % '
+ \catcode126=3 % ~ MATH
+ \catcode59=12 % ;
+ \catcode0=12 % for \romannumeral`&&@ trick
+ }%
+ \XINT_setcatcodes
+ }%
+\PrepareCatcodes
+% \end{macrocode}
+% Other modules could possibly be loaded under a different catcode regime.
+% \begin{macrocode}
+\def\XINTsetupcatcodes {% for use by other modules
+ \edef\XINT_restorecatcodes_endinput
+ {%
+ \XINT_restorecatcodes\noexpand\endinput %
+ }%
+ \XINT_setcatcodes
+}%
+% \end{macrocode}
+% \subsection{Package identification}
+%
+% Inspired from \textsc{Heiko Oberdiek}'s packages. Modified in |1.09b| to allow
+% re-use in the other modules. Also I assume now that if |\ProvidesPackage|
+% exists it then does define |\ver@<pkgname>.sty|, code of |HO| for some reason
+% escaping me (compatibility with LaTeX 2.09 or other things ??) seems to set
+% extra precautions.
+%
+% |1.09c| uses e-\TeX{} |\ifdefined|.
+% \begin{macrocode}
+\ifdefined\ProvidesPackage
+ \let\XINT_providespackage\relax
+\else
+ \def\XINT_providespackage #1#2[#3]%
+ {\immediate\write-1{Package: #2 #3}%
+ \expandafter\xdef\csname ver@#2.sty\endcsname{#3}}%
+\fi
+\XINT_providespackage
+\ProvidesPackage {xintkernel}%
+ [2019/04/05 1.3e 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_xii 12
+\chardef\xint_c_xiv 14
+\chardef\xint_c_xvi 16
+\chardef\xint_c_xviii 18
+\chardef\xint_c_xxii 22
+\chardef\xint_c_ii^v 32
+\chardef\xint_c_ii^vi 64
+\chardef\xint_c_ii^vii 128
+\mathchardef\xint_c_ii^viii 256
+\mathchardef\xint_c_ii^xii 4096
+\mathchardef\xint_c_x^iv 10000
+% \end{macrocode}
+% \subsection{(WIP) \csh{xint_texuniformdeviate} and needed counts}
+% \begin{macrocode}
+\ifdefined\pdfuniformdeviate \let\xint_texuniformdeviate\pdfuniformdeviate\fi
+\ifdefined\uniformdeviate \let\xint_texuniformdeviate\uniformdeviate \fi
+\ifx\xint_texuniformdeviate\relax\let\xint_texuniformdeviate\xint_undefined\fi
+\ifdefined\xint_texuniformdeviate
+ \csname newcount\endcsname\xint_c_ii^xiv
+ \xint_c_ii^xiv 16384 % "4000, 2**14
+ \csname newcount\endcsname\xint_c_ii^xxi
+ \xint_c_ii^xxi 2097152 % "200000, 2**21
+\fi
+% \end{macrocode}
+% \subsection{Token management utilities}
+% \changed{1.3b}{}
+% |\xint_gobandstop_...| macros because this is handy for
+% \csbxint{RandomDigits}.
+% \begin{macrocode}
+\def\XINT_tmpa { }%
+\ifx\XINT_tmpa\space\else
+ \immediate\write-1{Package xintkernel Warning: ATTENTION!}%
+ \immediate\write-1{\string\space\XINT_tmpa macro does not have its normal
+ meaning.}%
+ \immediate\write-1{\XINT_tmpa\XINT_tmpa\XINT_tmpa\XINT_tmpa
+ All kinds of catastrophes will ensue!!!!}%
+\fi
+\def\XINT_tmpb {}%
+\ifx\XINT_tmpb\empty\else
+ \immediate\write-1{Package xintkernel Warning: ATTENTION!}%
+ \immediate\write-1{\string\empty\XINT_tmpa macro does not have its normal
+ meaning.}%
+ \immediate\write-1{\XINT_tmpa\XINT_tmpa\XINT_tmpa\XINT_tmpa
+ All kinds of catastrophes will ensue!!!!}%
+\fi
+\let\XINT_tmpa\relax \let\XINT_tmpb\relax
+\ifdefined\space\else\def\space { }\fi
+\ifdefined\empty\else\def\empty {}\fi
+\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{}%
+\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{ }%
+\long\def\xint_firstofone #1{#1}%
+\long\def\xint_firstoftwo #1#2{#1}%
+\long\def\xint_secondoftwo #1#2{#2}%
+\let\xint_stop_aftergobble\xint_gob_andstop_i
+\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}
+% \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:{}%
+\def\xint_bracedstopper{\xint:}%
+\long\def\xint_gob_til_exclam #1!{}%
+\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}{}
+% |\xint_Bye| for \csbxint{DSRr} and \csbxint{Round}. Also |\xint_stop_afterbye|.
+% \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:
+% \lverb|
+%( \if..\xint_dothis{..}\fi
+%: \if..\xint_dothis{..}\fi
+%: \if..\xint_dothis{..}\fi
+%: ...more such...
+%: \xint_orthat{...}
+%) |
+% 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 utility zaps leading, intermediate, trailing, spaces in
+% completely expanding context (|\edef|, |\csname...\endcsname|).
+% \centeredline{Usage: |\xint_zapspaces foo<space>\xint_gobble_i|}
+%
+% Will remove some brace pairs (but not spaces inside them). By the way 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|.
+%
+% 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|.
+%
+% This is not really robust as it may switch the expansion order of macros,
+% and the |\xint_zapspaces| token might end up being fetched up by a macro.
+% But it is enough for our purposes, for example:
+% \centeredline{|\the\numexpr\xint_zapspaces 1 2 \xint_gobble_i\relax|}
+% expands to |12|, not to |12\relax|.
+%
+% \changed{1.2e}{} |\xint_zapspaces_o|. Expansion of |#1| should not gobble a
+% space!
+%
+% \changed{1.2i}{} made |\long|.
+% \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{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.
+% \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{1.2i}{2016/12/10}
+% Output empty if input empty. One level
+% of braces removed in output. Does not expand its argument.
+% \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{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}}
+% \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|.
+% \begin{macrocode}
+\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}}
+% \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}...|}
+%
+% \begin{macrocode}
+\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{(WIP) \csh{xintUniformDeviate}}
+% \changed{1.3b}{} See user manual for related information.
+% \begin{macrocode}
+\ifdefined\xint_texuniformdeviate
+ \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%
+ -\xint_texuniformdeviate\xint_c_ii^vii%
+ -\xint_c_ii^vii*\xint_texuniformdeviate\xint_c_ii^vii%
+ -\xint_c_ii^xiv*\xint_texuniformdeviate\xint_c_ii^vii%
+ -\xint_c_ii^xxi*\xint_texuniformdeviate\xint_c_ii^vii%
+ +\xint_texuniformdeviate#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}%
+}%
+{%
+ \def\xintUniformDeviate#1%
+ {%
+ \the\numexpr
+ \XINT_expandableerror{No uniformdeviate at engine level, returning 0.}%
+ 0\relax
+ }%
+}%
+% \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 LuaTeX in particular.
+%
+% \changed{1.3e}{} set the |\newlinechar|.
+% \begin{macrocode}
+\def\xintMessage #1#2#3{%
+ \edef\XINT_newlinechar{\the\newlinechar}%
+ \newlinechar10
+ \immediate\write128{Package #1 #2: (on line \the\inputlineno)}%
+ \immediate\write128{\space\space\space\space#3}%
+ \newlinechar\XINT_newlinechar\space
+}%
+\newif\ifxintverbose
+% \end{macrocode}
+% \subsection{\csh{ifxintglobaldefs}, \csh{XINT_global}}\label{src-xintglobaldefstrue}
+% \changed{1.3c}{}
+% \begin{macrocode}
+\newif\ifxintglobaldefs
+\def\XINT_global{\ifxintglobaldefs\global\fi}%
+% \end{macrocode}
+% \subsection{(WIP) Expandable error message}
+% \changed{1.2l}{} but really belongs to next major release beyond |1.3|.
+%
+% This is copied over from l3kernel code. I am using |\ ! /| control sequence
+% though, which must be left undefined. |\xintError:| would be 6 letters more
+% already.
+% \begin{macrocode}
+\def\XINT_expandableerror #1#2{%
+ \def\XINT_expandableerror ##1{%
+ \expandafter\expandafter\expandafter
+ \XINT_expandableerror_continue\xint_firstofone{#2#1##1#1}}%
+ \def\XINT_expandableerror_continue ##1#1##2#1{##1}%
+}%
+\begingroup\lccode`$ 32 \catcode`/ 11 \catcode`! 11 \catcode32 11 % $
+% \end{macrocode}
+% \begin{macrocode}
+\lowercase{\endgroup\XINT_expandableerror$\ ! /\let\ ! /\xint_undefined}% $
+\XINT_restorecatcodes_endinput%
+% \end{macrocode}
+% \StoreCodelineNo {xintkernel}
+% \cleardoublepage\let\xintkernelnameUp\undefined
+%\gardesactifs
+%\let</xintkernel>\relax
+%\let<*xinttools>\gardesinactifs
+%</xintkernel>^^A-------------------------------------------------
+%<*xinttools>^^A--------------------------------------------------
+%^^A -*- coding: utf-8; mode: doctex; -*-
+% \clearpage\csname xinttoolsnameUp\endcsname
+% \section{Package \xinttoolsnameimp implementation}
+% \RaisedLabel{sec:toolsimp}
+%
+% \localtableofcontents
+%
+% Release |1.09g| of |2013/11/22| splits off |xinttools.sty| from |xint.sty|.
+% Starting with |1.1|, \xinttoolsnameimp ceases being loaded automatically by
+% \xintnameimp.
+%
+% \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{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+ \catcode13=5 % ^^M
+ \endlinechar=13 %
+ \catcode123=1 % {
+ \catcode125=2 % }
+ \catcode64=11 % @
+ \catcode35=6 % #
+ \catcode44=12 % ,
+ \catcode45=12 % -
+ \catcode46=12 % .
+ \catcode58=12 % :
+ \let\z\endgroup
+ \expandafter\let\expandafter\x\csname ver@xinttools.sty\endcsname
+ \expandafter\let\expandafter\w\csname ver@xintkernel.sty\endcsname
+ \expandafter
+ \ifx\csname PackageInfo\endcsname\relax
+ \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}%
+ \else
+ \def\y#1#2{\PackageInfo{#1}{#2}}%
+ \fi
+ \expandafter
+ \ifx\csname numexpr\endcsname\relax
+ \y{xinttools}{\numexpr not available, aborting input}%
+ \aftergroup\endinput
+ \else
+ \ifx\x\relax % plain-TeX, first loading of xinttools.sty
+ \ifx\w\relax % but xintkernel.sty not yet loaded.
+ \def\z{\endgroup\input xintkernel.sty\relax}%
+ \fi
+ \else
+ \def\empty {}%
+ \ifx\x\empty % LaTeX, first loading,
+ % variable is initialized, but \ProvidesPackage not yet seen
+ \ifx\w\relax % xintkernel.sty not yet loaded.
+ \def\z{\endgroup\RequirePackage{xintkernel}}%
+ \fi
+ \else
+ \aftergroup\endinput % xinttools already loaded.
+ \fi
+ \fi
+ \fi
+\z%
+\XINTsetupcatcodes% defined in xintkernel.sty
+% \end{macrocode}
+% \subsection{Package identification}
+% \begin{macrocode}
+\XINT_providespackage
+\ProvidesPackage{xinttools}%
+ [2019/04/05 1.3e Expandable and non-expandable utilities (JFB)]%
+% \end{macrocode}
+% \lverb|\XINT_toks is used in macros such as \xintFor. It is not used
+% elsewhere in the xint bundle.|
+% \begin{macrocode}
+\newtoks\XINT_toks
+\xint_firstofone{\let\XINT_sptoken= } %<- space here!
+% \end{macrocode}
+% \subsection{\csh{xintgodef}, \csh{xintgoodef}, \csh{xintgfdef}}
+% \lverb|1.09i. For use in \xintAssign.|
+% \begin{macrocode}
+\def\xintgodef {\global\xintodef }%
+\def\xintgoodef {\global\xintoodef }%
+\def\xintgfdef {\global\xintfdef }%
+% \end{macrocode}
+% \subsection{\csh{xintRevWithBraces}}
+% \lverb|New with 1.06. Makes the expansion of its argument and then reverses
+% the resulting tokens or braced tokens, adding a pair of braces to each (thus,
+% maintaining it when it was already there.) The reason for
+% \xint:, here and in other locations, is in case #1 expands to nothing,
+% the \romannumeral-`0 must be stopped|
+% \begin{macrocode}
+\def\xintRevWithBraces {\romannumeral0\xintrevwithbraces }%
+\def\xintRevWithBracesNoExpand {\romannumeral0\xintrevwithbracesnoexpand }%
+\long\def\xintrevwithbraces #1%
+{%
+ \expandafter\XINT_revwbr_loop\expandafter{\expandafter}%
+ \romannumeral`&&@#1\xint:\xint:\xint:\xint:%
+ \xint:\xint:\xint:\xint:\xint_bye
+}%
+\long\def\xintrevwithbracesnoexpand #1%
+{%
+ \XINT_revwbr_loop {}%
+ #1\xint:\xint:\xint:\xint:%
+ \xint:\xint:\xint:\xint:\xint_bye
+}%
+\long\def\XINT_revwbr_loop #1#2#3#4#5#6#7#8#9%
+{%
+ \xint_gob_til_xint: #9\XINT_revwbr_finish_a\xint:%
+ \XINT_revwbr_loop {{#9}{#8}{#7}{#6}{#5}{#4}{#3}{#2}#1}%
+}%
+\long\def\XINT_revwbr_finish_a\xint:\XINT_revwbr_loop #1#2\xint_bye
+{%
+ \XINT_revwbr_finish_b #2\R\R\R\R\R\R\R\Z #1%
+}%
+\def\XINT_revwbr_finish_b #1#2#3#4#5#6#7#8\Z
+{%
+ \xint_gob_til_R
+ #1\XINT_revwbr_finish_c \xint_gobble_viii
+ #2\XINT_revwbr_finish_c \xint_gobble_vii
+ #3\XINT_revwbr_finish_c \xint_gobble_vi
+ #4\XINT_revwbr_finish_c \xint_gobble_v
+ #5\XINT_revwbr_finish_c \xint_gobble_iv
+ #6\XINT_revwbr_finish_c \xint_gobble_iii
+ #7\XINT_revwbr_finish_c \xint_gobble_ii
+ \R\XINT_revwbr_finish_c \xint_gobble_i\Z
+}%
+% \end{macrocode}
+% \lverb|1.1c revisited this old code and improved upon the earlier endings.|
+% \begin{macrocode}
+\def\XINT_revwbr_finish_c#1{%
+\def\XINT_revwbr_finish_c##1##2\Z{\expandafter#1##1}%
+}\XINT_revwbr_finish_c{ }%
+% \end{macrocode}
+% \subsection{\csh{xintZapFirstSpaces}}
+% \lverb|1.09f, written [2013/11/01]. Modified (2014/10/21) for release 1.1 to
+% correct the bug in case of an empty argument, or argument containing only
+% spaces, which had been forgotten in first version. New version is simpler than
+% the initial one. This macro does NOT expand its argument.|
+% \begin{macrocode}
+\def\xintZapFirstSpaces {\romannumeral0\xintzapfirstspaces }%
+\def\xintzapfirstspaces#1{\long
+\def\xintzapfirstspaces ##1{\XINT_zapbsp_a #1##1\xint:#1#1\xint:}%
+}\xintzapfirstspaces{ }%
+% \end{macrocode}
+% \lverb|If the original #1 started with a space, the grabbed #1 is empty. Thus
+% _again? will see #1=\xint_bye, and hand over control to _again which will loop
+% back into \XINT_zapbsp_a, with one initial space less. If the original #1 did
+% not start with a space, or was empty, then the #1 below will be a <sptoken>,
+% then an extract of the original #1, not empty and not starting with a space,
+% which contains what was up to the first <sp><sp> present in original #1, or,
+% if none preexisted, <sptoken> and all of #1 (possibly empty) plus an ending
+% \xint:. The added initial space will stop later the \romannumeral0. No
+% brace stripping is possible. Control is handed over to \XINT_zapbsp_b which
+% strips out the ending \xint:<sp><sp>\xint:|
+% \begin{macrocode}
+\def\XINT_zapbsp_a#1{\long\def\XINT_zapbsp_a ##1#1#1{%
+ \XINT_zapbsp_again?##1\xint_bye\XINT_zapbsp_b ##1#1#1}%
+}\XINT_zapbsp_a{ }%
+\long\def\XINT_zapbsp_again? #1{\xint_bye #1\XINT_zapbsp_again }%
+\xint_firstofone{\def\XINT_zapbsp_again\XINT_zapbsp_b} {\XINT_zapbsp_a }%
+\long\def\XINT_zapbsp_b #1\xint:#2\xint:{#1}%
+% \end{macrocode}
+% \subsection{\csh{xintZapLastSpaces}}
+% \lverb+1.09f, written [2013/11/01]. +
+% \begin{macrocode}
+\def\xintZapLastSpaces {\romannumeral0\xintzaplastspaces }%
+\def\xintzaplastspaces#1{\long
+\def\xintzaplastspaces ##1{\XINT_zapesp_a {}\empty##1#1#1\xint_bye\xint:}%
+}\xintzaplastspaces{ }%
+% \end{macrocode}
+% \lverb|The \empty from \xintzaplastspaces is to prevent brace removal in the
+% #2 below. The \expandafter chain removes it.|
+% \begin{macrocode}
+\xint_firstofone {\long\def\XINT_zapesp_a #1#2 } %<- second space here
+ {\expandafter\XINT_zapesp_b\expandafter{#2}{#1}}%
+% \end{macrocode}
+% \lverb|Notice again an \empty added here. This is in preparation for possibly looping
+% back to \XINT_zapesp_a. If the initial #1 had no <sp><sp>, the stuff however
+% will not loop, because #3 will already be <some spaces>\xint_bye. Notice
+% that this macro fetches all way to the ending \xint:. This looks not
+% very efficient, but how often do we have to strip ending spaces from
+% something which also has inner stretches of _multiple_ space tokens ?;-). |
+% \begin{macrocode}
+\long\def\XINT_zapesp_b #1#2#3\xint:%
+ {\XINT_zapesp_end? #3\XINT_zapesp_e {#2#1}\empty #3\xint:}%
+% \end{macrocode}
+% \lverb|When we have been over all possible <sp><sp> things, we reach the
+% ending space tokens, and #3 will be a bunch of spaces (possibly none)
+% followed by \xint_bye. So the #1 in _end? will be \xint_bye. In all other cases
+% #1 can not be \xint_bye (assuming naturally this token does nor arise in
+% original input), hence control falls back to \XINT_zapesp_e which will loop back
+% to \XINT_zapesp_a.|
+% \begin{macrocode}
+\long\def\XINT_zapesp_end? #1{\xint_bye #1\XINT_zapesp_end }%
+% \end{macrocode}
+% \lverb|We are done. The #1 here has accumulated all the previous material,
+% and is stripped of its ending spaces, if any.|
+% \begin{macrocode}
+\long\def\XINT_zapesp_end\XINT_zapesp_e #1#2\xint:{ #1}%
+% \end{macrocode}
+% \lverb|We haven't yet reached the end, so we need to re-inject two space
+% tokens after what we have gotten so far. Then we loop.|
+% \begin{macrocode}
+\def\XINT_zapesp_e#1{%
+\long\def\XINT_zapesp_e ##1{\XINT_zapesp_a {##1#1#1}}%
+}\XINT_zapesp_e{ }%
+% \end{macrocode}
+% \subsection{\csh{xintZapSpaces}}
+% \lverb+1.09f, written [2013/11/01]. Modified for 1.1, 2014/10/21 as it has the
+% same bug as \xintZapFirstSpaces. We in effect do first \xintZapFirstSpaces,
+% then \xintZapLastSpaces.+
+% \begin{macrocode}
+\def\xintZapSpaces {\romannumeral0\xintzapspaces }%
+\def\xintzapspaces#1{%
+\long\def\xintzapspaces ##1% like \xintZapFirstSpaces.
+ {\XINT_zapsp_a #1##1\xint:#1#1\xint:}%
+}\xintzapspaces{ }%
+\def\XINT_zapsp_a#1{%
+\long\def\XINT_zapsp_a ##1#1#1%
+ {\XINT_zapsp_again?##1\xint_bye\XINT_zapsp_b##1#1#1}%
+}\XINT_zapsp_a{ }%
+\long\def\XINT_zapsp_again? #1{\xint_bye #1\XINT_zapsp_again }%
+\xint_firstofone{\def\XINT_zapsp_again\XINT_zapsp_b} {\XINT_zapsp_a }%
+\xint_firstofone{\def\XINT_zapsp_b} {\XINT_zapsp_c }%
+\def\XINT_zapsp_c#1{%
+\long\def\XINT_zapsp_c ##1\xint:##2\xint:%
+ {\XINT_zapesp_a{}\empty ##1#1#1\xint_bye\xint:}%
+}\XINT_zapsp_c{ }%
+% \end{macrocode}
+% \subsection{\csh{xintZapSpacesB}}
+% \lverb+1.09f, written [2013/11/01]. Strips up to one pair of braces (but then
+% does not strip spaces inside).+
+% \begin{macrocode}
+\def\xintZapSpacesB {\romannumeral0\xintzapspacesb }%
+\long\def\xintzapspacesb #1{\XINT_zapspb_one? #1\xint:\xint:%
+ \xint_bye\xintzapspaces {#1}}%
+\long\def\XINT_zapspb_one? #1#2%
+ {\xint_gob_til_xint: #1\XINT_zapspb_onlyspaces\xint:%
+ \xint_gob_til_xint: #2\XINT_zapspb_bracedorone\xint:%
+ \xint_bye {#1}}%
+\def\XINT_zapspb_onlyspaces\xint:%
+ \xint_gob_til_xint:\xint:\XINT_zapspb_bracedorone\xint:%
+ \xint_bye #1\xint_bye\xintzapspaces #2{ }%
+\long\def\XINT_zapspb_bracedorone\xint:%
+ \xint_bye #1\xint:\xint_bye\xintzapspaces #2{ #1}%
+% \end{macrocode}
+% \subsection{\csh{xintCSVtoList}, \csh{xintCSVtoListNonStripped}}
+% \lverb|\xintCSVtoList transforms a,b,..,z into {a}{b}...{z}. The comma
+% separated list may be a macro which is first f-expanded. First included in
+% release 1.06. Here, use of \Z (and \R) perfectly safe.
+%
+% [2013/11/02]: Starting with 1.09f, automatically filters items with
+% \xintZapSpacesB to strip away all spaces around commas, and spaces at the start
+% and end of the list. The original is kept as \xintCSVtoListNonStripped, and is
+% faster. But ... it doesn't strip spaces.
+%
+% ATTENTION: if the input is empty the output contains one item (empty, of
+% course). This means an \xintFor loop always executes at least once the
+% iteration, contrarily to \xintFor*.|
+% \begin{macrocode}
+\def\xintCSVtoList {\romannumeral0\xintcsvtolist }%
+\long\def\xintcsvtolist #1{\expandafter\xintApply
+ \expandafter\xintzapspacesb
+ \expandafter{\romannumeral0\xintcsvtolistnonstripped{#1}}}%
+\def\xintCSVtoListNoExpand {\romannumeral0\xintcsvtolistnoexpand }%
+\long\def\xintcsvtolistnoexpand #1{\expandafter\xintApply
+ \expandafter\xintzapspacesb
+ \expandafter{\romannumeral0\xintcsvtolistnonstrippednoexpand{#1}}}%
+\def\xintCSVtoListNonStripped {\romannumeral0\xintcsvtolistnonstripped }%
+\def\xintCSVtoListNonStrippedNoExpand
+ {\romannumeral0\xintcsvtolistnonstrippednoexpand }%
+\long\def\xintcsvtolistnonstripped #1%
+{%
+ \expandafter\XINT_csvtol_loop_a\expandafter
+ {\expandafter}\romannumeral`&&@#1%
+ ,\xint_bye,\xint_bye,\xint_bye,\xint_bye
+ ,\xint_bye,\xint_bye,\xint_bye,\xint_bye,\Z
+}%
+\long\def\xintcsvtolistnonstrippednoexpand #1%
+{%
+ \XINT_csvtol_loop_a
+ {}#1,\xint_bye,\xint_bye,\xint_bye,\xint_bye
+ ,\xint_bye,\xint_bye,\xint_bye,\xint_bye,\Z
+}%
+\long\def\XINT_csvtol_loop_a #1#2,#3,#4,#5,#6,#7,#8,#9,%
+{%
+ \xint_bye #9\XINT_csvtol_finish_a\xint_bye
+ \XINT_csvtol_loop_b {#1}{{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}}%
+}%
+\long\def\XINT_csvtol_loop_b #1#2{\XINT_csvtol_loop_a {#1#2}}%
+\long\def\XINT_csvtol_finish_a\xint_bye\XINT_csvtol_loop_b #1#2#3\Z
+{%
+ \XINT_csvtol_finish_b #3\R,\R,\R,\R,\R,\R,\R,\Z #2{#1}%
+}%
+% \end{macrocode}
+% \lverb|1.1c revisits this old code and improves upon the earlier endings.
+% But as the _d.. macros have already nine parameters, I needed the
+% \expandafter and \xint_gob_til_Z in finish_b (compare \XINT_keep_endb, or
+% also \XINT_RQ_end_b).|
+% \begin{macrocode}
+\def\XINT_csvtol_finish_b #1,#2,#3,#4,#5,#6,#7,#8\Z
+{%
+ \xint_gob_til_R
+ #1\expandafter\XINT_csvtol_finish_dviii\xint_gob_til_Z
+ #2\expandafter\XINT_csvtol_finish_dvii \xint_gob_til_Z
+ #3\expandafter\XINT_csvtol_finish_dvi \xint_gob_til_Z
+ #4\expandafter\XINT_csvtol_finish_dv \xint_gob_til_Z
+ #5\expandafter\XINT_csvtol_finish_div \xint_gob_til_Z
+ #6\expandafter\XINT_csvtol_finish_diii \xint_gob_til_Z
+ #7\expandafter\XINT_csvtol_finish_dii \xint_gob_til_Z
+ \R\XINT_csvtol_finish_di \Z
+}%
+\long\def\XINT_csvtol_finish_dviii #1#2#3#4#5#6#7#8#9{ #9}%
+\long\def\XINT_csvtol_finish_dvii #1#2#3#4#5#6#7#8#9{ #9{#1}}%
+\long\def\XINT_csvtol_finish_dvi #1#2#3#4#5#6#7#8#9{ #9{#1}{#2}}%
+\long\def\XINT_csvtol_finish_dv #1#2#3#4#5#6#7#8#9{ #9{#1}{#2}{#3}}%
+\long\def\XINT_csvtol_finish_div #1#2#3#4#5#6#7#8#9{ #9{#1}{#2}{#3}{#4}}%
+\long\def\XINT_csvtol_finish_diii #1#2#3#4#5#6#7#8#9{ #9{#1}{#2}{#3}{#4}{#5}}%
+\long\def\XINT_csvtol_finish_dii #1#2#3#4#5#6#7#8#9%
+ { #9{#1}{#2}{#3}{#4}{#5}{#6}}%
+\long\def\XINT_csvtol_finish_di\Z #1#2#3#4#5#6#7#8#9%
+ { #9{#1}{#2}{#3}{#4}{#5}{#6}{#7}}%
+% \end{macrocode}
+% \subsection{\csh{xintListWithSep}}
+% \lverb|1.04.
+% \xintListWithSep {\sep}{{a}{b}...{z}} returns a \sep b \sep ....\sep z. It
+% f-expands its second argument. The 'sep' may be \par's: the macro
+% \xintlistwithsep etc... are all declared long. 'sep' does not have to be a
+% single token. It is not expanded. The "list" argument may be empty.
+%
+% \xintListWithSepNoExpand does not f-expand its second argument.
+%
+% This venerable macro from 1.04 remained unchanged for a long time and was
+% finally refactored at 1.2p for increased speed. Tests done with a list of
+% identical {\x} items and a sep of \z demonstrated a speed increase of about:
+%( - 3x for 30 items,
+%: - 4.5x for 100 items,
+%: - 7.5x--8x for 1000 items.
+%) |
+% \begin{macrocode}
+\def\xintListWithSep {\romannumeral0\xintlistwithsep }%
+\def\xintListWithSepNoExpand {\romannumeral0\xintlistwithsepnoexpand }%
+\long\def\xintlistwithsep #1#2%
+ {\expandafter\XINT_lws\expandafter {\romannumeral`&&@#2}{#1}}%
+\long\def\xintlistwithsepnoexpand #1#2%
+{%
+ \XINT_lws_loop_a {#1}#2{\xint_bye\XINT_lws_e_vi}%
+ {\xint_bye\XINT_lws_e_v}{\xint_bye\XINT_lws_e_iv}%
+ {\xint_bye\XINT_lws_e_iii}{\xint_bye\XINT_lws_e_ii}%
+ {\xint_bye\XINT_lws_e_i}{\xint_bye\XINT_lws_e}%
+ {\xint_bye\expandafter\space}\xint_bye
+}%
+\long\def\XINT_lws #1#2%
+{%
+ \XINT_lws_loop_a {#2}#1{\xint_bye\XINT_lws_e_vi}%
+ {\xint_bye\XINT_lws_e_v}{\xint_bye\XINT_lws_e_iv}%
+ {\xint_bye\XINT_lws_e_iii}{\xint_bye\XINT_lws_e_ii}%
+ {\xint_bye\XINT_lws_e_i}{\xint_bye\XINT_lws_e}%
+ {\xint_bye\expandafter\space}\xint_bye
+}%
+\long\def\XINT_lws_loop_a #1#2#3#4#5#6#7#8#9%
+{%
+ \xint_bye #9\xint_bye
+ \XINT_lws_loop_b {#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}%
+}%
+\long\def\XINT_lws_loop_b #1#2#3#4#5#6#7#8#9%
+{%
+ \XINT_lws_loop_a {#1}{#2#1#3#1#4#1#5#1#6#1#7#1#8#1#9}%
+}%
+\long\def\XINT_lws_e_vi\xint_bye\XINT_lws_loop_b #1#2#3#4#5#6#7#8#9\xint_bye
+ { #2#1#3#1#4#1#5#1#6#1#7#1#8}%
+\long\def\XINT_lws_e_v\xint_bye\XINT_lws_loop_b #1#2#3#4#5#6#7#8\xint_bye
+ { #2#1#3#1#4#1#5#1#6#1#7}%
+\long\def\XINT_lws_e_iv\xint_bye\XINT_lws_loop_b #1#2#3#4#5#6#7\xint_bye
+ { #2#1#3#1#4#1#5#1#6}%
+\long\def\XINT_lws_e_iii\xint_bye\XINT_lws_loop_b #1#2#3#4#5#6\xint_bye
+ { #2#1#3#1#4#1#5}%
+\long\def\XINT_lws_e_ii\xint_bye\XINT_lws_loop_b #1#2#3#4#5\xint_bye
+ { #2#1#3#1#4}%
+\long\def\XINT_lws_e_i\xint_bye\XINT_lws_loop_b #1#2#3#4\xint_bye
+ { #2#1#3}%
+\long\def\XINT_lws_e\xint_bye\XINT_lws_loop_b #1#2#3\xint_bye
+ { #2}%
+% \end{macrocode}
+% \subsection{\csh{xintNthElt}}
+% \lverb?First included in release 1.06. Last refactored in 1.2j.
+%
+% \xintNthElt {i}{List} returns the i th item from List (one pair of braces
+% removed). The list is first f-expanded. The \xintNthEltNoExpand does no
+% expansion of its second argument. Both variants expand i inside \numexpr.
+%
+% With i = 0, the number of items is returned using \xintLength but with the
+% List argument f-expanded first.
+%
+% Negative values return the |i|th element from the end.
+%
+% When i is out of range, an empty value is returned.
+% ?
+% \begin{macrocode}
+\def\xintNthElt {\romannumeral0\xintnthelt }%
+\def\xintNthEltNoExpand {\romannumeral0\xintntheltnoexpand }%
+\long\def\xintnthelt #1#2{\expandafter\XINT_nthelt_a\the\numexpr #1\expandafter.%
+ \expandafter{\romannumeral`&&@#2}}%
+\def\xintntheltnoexpand #1{\expandafter\XINT_nthelt_a\the\numexpr #1.}%
+\def\XINT_nthelt_a #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_nthelt_zero
+ 0#1\XINT_nthelt_neg
+ 0-{\XINT_nthelt_pos #1}%
+ \krof
+}%
+\def\XINT_nthelt_zero #1.{\xintlength }%
+\long\def\XINT_nthelt_neg #1.#2%
+{%
+ \expandafter\XINT_nthelt_neg_a\the\numexpr\xint_c_i+\XINT_length_loop
+ #2\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
+ -#1.#2\xint_bye
+}%
+\def\XINT_nthelt_neg_a #1%
+{%
+ \xint_UDzerominusfork
+ #1-\xint_stop_afterbye
+ 0#1\xint_stop_afterbye
+ 0-{}%
+ \krof
+ \expandafter\XINT_nthelt_neg_b
+ \romannumeral\expandafter\XINT_gobble\the\numexpr-\xint_c_i+#1%
+}%
+\long\def\XINT_nthelt_neg_b #1#2\xint_bye{ #1}%
+\long\def\XINT_nthelt_pos #1.#2%
+{%
+ \expandafter\XINT_nthelt_pos_done
+ \romannumeral0\expandafter\XINT_trim_loop\the\numexpr#1-\xint_c_x.%
+ #2\xint:\xint:\xint:\xint:\xint:%
+ \xint:\xint:\xint:\xint:\xint:%
+ \xint_bye
+}%
+\def\XINT_nthelt_pos_done #1{%
+\long\def\XINT_nthelt_pos_done ##1##2\xint_bye{%
+ \xint_gob_til_xint:##1\expandafter#1\xint_gobble_ii\xint:#1##1}%
+}\XINT_nthelt_pos_done{ }%
+% \end{macrocode}
+% \subsection{\csh{xintKeep}}
+% \lverb@&
+%
+% First included in release 1.09m.
+%
+% \xintKeep{i}{L} f-expands its second argument L. It then grabs the first i
+% items from L and discards the rest.
+%
+% ATTENTION: **each such kept item is returned inside a brace pair**
+% Use \xintKeepUnbraced to avoid that.
+%
+% For i equal or larger to the number N of items in (expanded) L, the full L
+% is returned (with braced items). For i=0, the macro returns an empty output.
+% For i<0, the macro discards the first N-|i| items. No brace pairs added to
+% the remaining items. For i is less or equal to -N, the full L is returned
+% (with no braces added.)
+%
+% \xintKeepNoExpand does not expand the L argument.
+%
+%
+%
+% Prior to 1.2i the code proceeded along a loop with no pre-computation of
+% the length of L, for the i>0 case. The faster 1.2i version takes advantage
+% of novel \xintLengthUpTo from xintkernel.sty.
+% @
+% \begin{macrocode}
+\def\xintKeep {\romannumeral0\xintkeep }%
+\def\xintKeepNoExpand {\romannumeral0\xintkeepnoexpand }%
+\long\def\xintkeep #1#2{\expandafter\XINT_keep_a\the\numexpr #1\expandafter.%
+ \expandafter{\romannumeral`&&@#2}}%
+\def\xintkeepnoexpand #1{\expandafter\XINT_keep_a\the\numexpr #1.}%
+\def\XINT_keep_a #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_keep_keepnone
+ 0#1\XINT_keep_neg
+ 0-{\XINT_keep_pos #1}%
+ \krof
+}%
+\long\def\XINT_keep_keepnone .#1{ }%
+\long\def\XINT_keep_neg #1.#2%
+{%
+ \expandafter\XINT_keep_neg_a\the\numexpr
+ #1-\numexpr\XINT_length_loop
+ #2\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.#2%
+}%
+\def\XINT_keep_neg_a #1%
+{%
+ \xint_UDsignfork
+ #1{\expandafter\space\romannumeral\XINT_gobble}%
+ -\XINT_keep_keepall
+ \krof
+}%
+\def\XINT_keep_keepall #1.{ }%
+\long\def\XINT_keep_pos #1.#2%
+{%
+ \expandafter\XINT_keep_loop
+ \the\numexpr#1-\XINT_lengthupto_loop
+ #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.%
+ -\xint_c_viii.{}#2\xint_bye%
+}%
+\def\XINT_keep_loop #1#2.%
+{%
+ \xint_gob_til_minus#1\XINT_keep_loop_end-%
+ \expandafter\XINT_keep_loop
+ \the\numexpr#1#2-\xint_c_viii\expandafter.\XINT_keep_loop_pickeight
+}%
+\long\def\XINT_keep_loop_pickeight
+ #1#2#3#4#5#6#7#8#9{{#1{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}}}%
+\def\XINT_keep_loop_end-\expandafter\XINT_keep_loop
+ \the\numexpr-#1-\xint_c_viii\expandafter.\XINT_keep_loop_pickeight
+ {\csname XINT_keep_end#1\endcsname}%
+\long\expandafter\def\csname XINT_keep_end1\endcsname
+ #1#2#3#4#5#6#7#8#9\xint_bye { #1{#2}{#3}{#4}{#5}{#6}{#7}{#8}}%
+\long\expandafter\def\csname XINT_keep_end2\endcsname
+ #1#2#3#4#5#6#7#8\xint_bye { #1{#2}{#3}{#4}{#5}{#6}{#7}}%
+\long\expandafter\def\csname XINT_keep_end3\endcsname
+ #1#2#3#4#5#6#7\xint_bye { #1{#2}{#3}{#4}{#5}{#6}}%
+\long\expandafter\def\csname XINT_keep_end4\endcsname
+ #1#2#3#4#5#6\xint_bye { #1{#2}{#3}{#4}{#5}}%
+\long\expandafter\def\csname XINT_keep_end5\endcsname
+ #1#2#3#4#5\xint_bye { #1{#2}{#3}{#4}}%
+\long\expandafter\def\csname XINT_keep_end6\endcsname
+ #1#2#3#4\xint_bye { #1{#2}{#3}}%
+\long\expandafter\def\csname XINT_keep_end7\endcsname
+ #1#2#3\xint_bye { #1{#2}}%
+\long\expandafter\def\csname XINT_keep_end8\endcsname
+ #1#2\xint_bye { #1}%
+% \end{macrocode}
+% \subsection{\csh{xintKeepUnbraced}}
+% \lverb?1.2a. Same as \xintKeep but will *not* add (or maintain) brace pairs
+% around the kept items when length(L)>i>0.
+%
+% The name may cause a mis-understanding: for i<0, (i.e. keeping only
+% trailing items), there is no brace removal at all happening.
+%
+% Modified for 1.2i like \xintKeep.
+% ?
+% \begin{macrocode}
+\def\xintKeepUnbraced {\romannumeral0\xintkeepunbraced }%
+\def\xintKeepUnbracedNoExpand {\romannumeral0\xintkeepunbracednoexpand }%
+\long\def\xintkeepunbraced #1#2%
+ {\expandafter\XINT_keepunbr_a\the\numexpr #1\expandafter.%
+ \expandafter{\romannumeral`&&@#2}}%
+\def\xintkeepunbracednoexpand #1%
+ {\expandafter\XINT_keepunbr_a\the\numexpr #1.}%
+\def\XINT_keepunbr_a #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_keep_keepnone
+ 0#1\XINT_keep_neg
+ 0-{\XINT_keepunbr_pos #1}%
+ \krof
+}%
+\long\def\XINT_keepunbr_pos #1.#2%
+{%
+ \expandafter\XINT_keepunbr_loop
+ \the\numexpr#1-\XINT_lengthupto_loop
+ #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.%
+ -\xint_c_viii.{}#2\xint_bye%
+}%
+\def\XINT_keepunbr_loop #1#2.%
+{%
+ \xint_gob_til_minus#1\XINT_keepunbr_loop_end-%
+ \expandafter\XINT_keepunbr_loop
+ \the\numexpr#1#2-\xint_c_viii\expandafter.\XINT_keepunbr_loop_pickeight
+}%
+\long\def\XINT_keepunbr_loop_pickeight
+ #1#2#3#4#5#6#7#8#9{{#1#2#3#4#5#6#7#8#9}}%
+\def\XINT_keepunbr_loop_end-\expandafter\XINT_keepunbr_loop
+ \the\numexpr-#1-\xint_c_viii\expandafter.\XINT_keepunbr_loop_pickeight
+ {\csname XINT_keepunbr_end#1\endcsname}%
+\long\expandafter\def\csname XINT_keepunbr_end1\endcsname
+ #1#2#3#4#5#6#7#8#9\xint_bye { #1#2#3#4#5#6#7#8}%
+\long\expandafter\def\csname XINT_keepunbr_end2\endcsname
+ #1#2#3#4#5#6#7#8\xint_bye { #1#2#3#4#5#6#7}%
+\long\expandafter\def\csname XINT_keepunbr_end3\endcsname
+ #1#2#3#4#5#6#7\xint_bye { #1#2#3#4#5#6}%
+\long\expandafter\def\csname XINT_keepunbr_end4\endcsname
+ #1#2#3#4#5#6\xint_bye { #1#2#3#4#5}%
+\long\expandafter\def\csname XINT_keepunbr_end5\endcsname
+ #1#2#3#4#5\xint_bye { #1#2#3#4}%
+\long\expandafter\def\csname XINT_keepunbr_end6\endcsname
+ #1#2#3#4\xint_bye { #1#2#3}%
+\long\expandafter\def\csname XINT_keepunbr_end7\endcsname
+ #1#2#3\xint_bye { #1#2}%
+\long\expandafter\def\csname XINT_keepunbr_end8\endcsname
+ #1#2\xint_bye { #1}%
+% \end{macrocode}
+% \subsection{\csh{xintTrim}}
+% \lverb?&
+%
+% First included in release 1.09m.
+%
+% \xintTrim{i}{L} f-expands its second argument L. It then removes the first i
+% items from L and keeps the rest. For i equal or larger to the number N of
+% items in (expanded) L, the macro returns an empty output. For i=0, the
+% original (expanded) L is returned. For i<0, the macro proceeds from the
+% tail. It thus removes the last |i| items, i.e. it keeps the first N-|i|
+% items. For |i|>= N, the empty list is returned.
+%
+% \xintTrimNoExpand does not expand the L argument.
+%
+% Speed improvements with 1.2i for i<0 branch (which hands over to
+% \xintKeep). Speed improvements with 1.2j for i>0 branch which gobbles items
+% nine by nine despite not knowing in advance if it will go too far.
+% ?
+% \begin{macrocode}
+\def\xintTrim {\romannumeral0\xinttrim }%
+\def\xintTrimNoExpand {\romannumeral0\xinttrimnoexpand }%
+\long\def\xinttrim #1#2{\expandafter\XINT_trim_a\the\numexpr #1\expandafter.%
+ \expandafter{\romannumeral`&&@#2}}%
+\def\xinttrimnoexpand #1{\expandafter\XINT_trim_a\the\numexpr #1.}%
+\def\XINT_trim_a #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_trim_trimnone
+ 0#1\XINT_trim_neg
+ 0-{\XINT_trim_pos #1}%
+ \krof
+}%
+\long\def\XINT_trim_trimnone .#1{ #1}%
+\long\def\XINT_trim_neg #1.#2%
+{%
+ \expandafter\XINT_trim_neg_a\the\numexpr
+ #1-\numexpr\XINT_length_loop
+ #2\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
+ .{}#2\xint_bye
+}%
+\def\XINT_trim_neg_a #1%
+{%
+ \xint_UDsignfork
+ #1{\expandafter\XINT_keep_loop\the\numexpr-\xint_c_viii+}%
+ -\XINT_trim_trimall
+ \krof
+}%
+\def\XINT_trim_trimall#1{%
+\def\XINT_trim_trimall {\expandafter#1\xint_bye}%
+}\XINT_trim_trimall{ }%
+% \end{macrocode}
+% \lverb|This branch doesn't pre-evaluate the length of the list argument.
+% Redone again for 1.2j, manages to trim nine by nine. Some non optimal
+% looking aspect of the code is for allowing sharing with \xintNthElt.|
+% \begin{macrocode}
+\long\def\XINT_trim_pos #1.#2%
+{%
+ \expandafter\XINT_trim_pos_done\expandafter\space
+ \romannumeral0\expandafter\XINT_trim_loop\the\numexpr#1-\xint_c_ix.%
+ #2\xint:\xint:\xint:\xint:\xint:%
+ \xint:\xint:\xint:\xint:\xint:%
+ \xint_bye
+}%
+\def\XINT_trim_loop #1#2.%
+{%
+ \xint_gob_til_minus#1\XINT_trim_finish-%
+ \expandafter\XINT_trim_loop\the\numexpr#1#2\XINT_trim_loop_trimnine
+}%
+\long\def\XINT_trim_loop_trimnine #1#2#3#4#5#6#7#8#9%
+{%
+ \xint_gob_til_xint: #9\XINT_trim_toofew\xint:-\xint_c_ix.%
+}%
+\def\XINT_trim_toofew\xint:{*\xint_c_}%
+\def\XINT_trim_finish#1{%
+\def\XINT_trim_finish-%
+ \expandafter\XINT_trim_loop\the\numexpr-##1\XINT_trim_loop_trimnine
+{%
+ \expandafter\expandafter\expandafter#1%
+ \csname xint_gobble_\romannumeral\numexpr\xint_c_ix-##1\endcsname
+}}\XINT_trim_finish{ }%
+\long\def\XINT_trim_pos_done #1\xint:#2\xint_bye {#1}%
+% \end{macrocode}
+% \subsection{\csh{xintTrimUnbraced}}
+% \lverb?1.2a. Modified in 1.2i like \xintTrim?
+% \begin{macrocode}
+\def\xintTrimUnbraced {\romannumeral0\xinttrimunbraced }%
+\def\xintTrimUnbracedNoExpand {\romannumeral0\xinttrimunbracednoexpand }%
+\long\def\xinttrimunbraced #1#2%
+ {\expandafter\XINT_trimunbr_a\the\numexpr #1\expandafter.%
+ \expandafter{\romannumeral`&&@#2}}%
+\def\xinttrimunbracednoexpand #1%
+ {\expandafter\XINT_trimunbr_a\the\numexpr #1.}%
+\def\XINT_trimunbr_a #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_trim_trimnone
+ 0#1\XINT_trimunbr_neg
+ 0-{\XINT_trim_pos #1}%
+ \krof
+}%
+\long\def\XINT_trimunbr_neg #1.#2%
+{%
+ \expandafter\XINT_trimunbr_neg_a\the\numexpr
+ #1-\numexpr\XINT_length_loop
+ #2\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
+ .{}#2\xint_bye
+}%
+\def\XINT_trimunbr_neg_a #1%
+{%
+ \xint_UDsignfork
+ #1{\expandafter\XINT_keepunbr_loop\the\numexpr-\xint_c_viii+}%
+ -\XINT_trim_trimall
+ \krof
+}%
+% \end{macrocode}
+% \subsection{\csh{xintApply}}
+% \lverb|\xintApply {\macro}{{a}{b}...{z}} returns {\macro{a}}...{\macro{b}}
+% where each instance of \macro is f-expanded. The list itself is first
+% f-expanded and may thus be a macro. Introduced with release 1.04.|
+% \begin{macrocode}
+\def\xintApply {\romannumeral0\xintapply }%
+\def\xintApplyNoExpand {\romannumeral0\xintapplynoexpand }%
+\long\def\xintapply #1#2%
+{%
+ \expandafter\XINT_apply\expandafter {\romannumeral`&&@#2}%
+ {#1}%
+}%
+\long\def\XINT_apply #1#2{\XINT_apply_loop_a {}{#2}#1\xint_bye }%
+\long\def\xintapplynoexpand #1#2{\XINT_apply_loop_a {}{#1}#2\xint_bye }%
+\long\def\XINT_apply_loop_a #1#2#3%
+{%
+ \xint_bye #3\XINT_apply_end\xint_bye
+ \expandafter
+ \XINT_apply_loop_b
+ \expandafter {\romannumeral`&&@#2{#3}}{#1}{#2}%
+}%
+\long\def\XINT_apply_loop_b #1#2{\XINT_apply_loop_a {#2{#1}}}%
+\long\def\XINT_apply_end\xint_bye\expandafter\XINT_apply_loop_b
+ \expandafter #1#2#3{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintApplyUnbraced}}
+% \lverb|\xintApplyUnbraced {\macro}{{a}{b}...{z}} returns \macro{a}...\macro{z}
+% where each instance of \macro is f-expanded using \romannumeral-`0. The second
+% argument may be a macro as it is itself also f-expanded. No braces
+% are added: this allows for example a non-expandable \def in \macro, without
+% having to do \gdef. Introduced with release 1.06b.|
+% \begin{macrocode}
+\def\xintApplyUnbraced {\romannumeral0\xintapplyunbraced }%
+\def\xintApplyUnbracedNoExpand {\romannumeral0\xintapplyunbracednoexpand }%
+\long\def\xintapplyunbraced #1#2%
+{%
+ \expandafter\XINT_applyunbr\expandafter {\romannumeral`&&@#2}%
+ {#1}%
+}%
+\long\def\XINT_applyunbr #1#2{\XINT_applyunbr_loop_a {}{#2}#1\xint_bye }%
+\long\def\xintapplyunbracednoexpand #1#2%
+ {\XINT_applyunbr_loop_a {}{#1}#2\xint_bye }%
+\long\def\XINT_applyunbr_loop_a #1#2#3%
+{%
+ \xint_bye #3\XINT_applyunbr_end\xint_bye
+ \expandafter\XINT_applyunbr_loop_b
+ \expandafter {\romannumeral`&&@#2{#3}}{#1}{#2}%
+}%
+\long\def\XINT_applyunbr_loop_b #1#2{\XINT_applyunbr_loop_a {#2#1}}%
+\long\def\XINT_applyunbr_end\xint_bye\expandafter\XINT_applyunbr_loop_b
+ \expandafter #1#2#3{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintSeq}}
+% \lverb|1.09c. Without the optional argument puts stress on the input stack,
+% should not be used to generated thousands of terms then.|
+% \begin{macrocode}
+\def\xintSeq {\romannumeral0\xintseq }%
+\def\xintseq #1{\XINT_seq_chkopt #1\xint_bye }%
+\def\XINT_seq_chkopt #1%
+{%
+ \ifx [#1\expandafter\XINT_seq_opt
+ \else\expandafter\XINT_seq_noopt
+ \fi #1%
+}%
+\def\XINT_seq_noopt #1\xint_bye #2%
+{%
+ \expandafter\XINT_seq\expandafter
+ {\the\numexpr#1\expandafter}\expandafter{\the\numexpr #2}%
+}%
+\def\XINT_seq #1#2%
+{%
+ \ifcase\ifnum #1=#2 0\else\ifnum #2>#1 1\else -1\fi\fi\space
+ \expandafter\xint_stop_atfirstoftwo
+ \or
+ \expandafter\XINT_seq_p
+ \else
+ \expandafter\XINT_seq_n
+ \fi
+ {#2}{#1}%
+}%
+\def\XINT_seq_p #1#2%
+{%
+ \ifnum #1>#2
+ \expandafter\expandafter\expandafter\XINT_seq_p
+ \else
+ \expandafter\XINT_seq_e
+ \fi
+ \expandafter{\the\numexpr #1-\xint_c_i}{#2}{#1}%
+}%
+\def\XINT_seq_n #1#2%
+{%
+ \ifnum #1<#2
+ \expandafter\expandafter\expandafter\XINT_seq_n
+ \else
+ \expandafter\XINT_seq_e
+ \fi
+ \expandafter{\the\numexpr #1+\xint_c_i}{#2}{#1}%
+}%
+\def\XINT_seq_e #1#2#3{ }%
+\def\XINT_seq_opt [\xint_bye #1]#2#3%
+{%
+ \expandafter\XINT_seqo\expandafter
+ {\the\numexpr #2\expandafter}\expandafter
+ {\the\numexpr #3\expandafter}\expandafter
+ {\the\numexpr #1}%
+}%
+\def\XINT_seqo #1#2%
+{%
+ \ifcase\ifnum #1=#2 0\else\ifnum #2>#1 1\else -1\fi\fi\space
+ \expandafter\XINT_seqo_a
+ \or
+ \expandafter\XINT_seqo_pa
+ \else
+ \expandafter\XINT_seqo_na
+ \fi
+ {#1}{#2}%
+}%
+\def\XINT_seqo_a #1#2#3{ {#1}}%
+\def\XINT_seqo_o #1#2#3#4{ #4}%
+\def\XINT_seqo_pa #1#2#3%
+{%
+ \ifcase\ifnum #3=\xint_c_ 0\else\ifnum #3>\xint_c_ 1\else -1\fi\fi\space
+ \expandafter\XINT_seqo_o
+ \or
+ \expandafter\XINT_seqo_pb
+ \else
+ \xint_afterfi{\expandafter\space\xint_gobble_iv}%
+ \fi
+ {#1}{#2}{#3}{{#1}}%
+}%
+\def\XINT_seqo_pb #1#2#3%
+{%
+ \expandafter\XINT_seqo_pc\expandafter{\the\numexpr #1+#3}{#2}{#3}%
+}%
+\def\XINT_seqo_pc #1#2%
+{%
+ \ifnum #1>#2
+ \expandafter\XINT_seqo_o
+ \else
+ \expandafter\XINT_seqo_pd
+ \fi
+ {#1}{#2}%
+}%
+\def\XINT_seqo_pd #1#2#3#4{\XINT_seqo_pb {#1}{#2}{#3}{#4{#1}}}%
+\def\XINT_seqo_na #1#2#3%
+{%
+ \ifcase\ifnum #3=\xint_c_ 0\else\ifnum #3>\xint_c_ 1\else -1\fi\fi\space
+ \expandafter\XINT_seqo_o
+ \or
+ \xint_afterfi{\expandafter\space\xint_gobble_iv}%
+ \else
+ \expandafter\XINT_seqo_nb
+ \fi
+ {#1}{#2}{#3}{{#1}}%
+}%
+\def\XINT_seqo_nb #1#2#3%
+{%
+ \expandafter\XINT_seqo_nc\expandafter{\the\numexpr #1+#3}{#2}{#3}%
+}%
+\def\XINT_seqo_nc #1#2%
+{%
+ \ifnum #1<#2
+ \expandafter\XINT_seqo_o
+ \else
+ \expandafter\XINT_seqo_nd
+ \fi
+ {#1}{#2}%
+}%
+\def\XINT_seqo_nd #1#2#3#4{\XINT_seqo_nb {#1}{#2}{#3}{#4{#1}}}%
+% \end{macrocode}
+%\subsection{\csh{xintloop}, \csh{xintbreakloop}, \csh{xintbreakloopanddo},
+% \csh{xintloopskiptonext}}
+% \lverb|1.09g [2013/11/22]. Made long with 1.09h.|
+% \begin{macrocode}
+\long\def\xintloop #1#2\repeat {#1#2\xintloop_again\fi\xint_gobble_i {#1#2}}%
+\long\def\xintloop_again\fi\xint_gobble_i #1{\fi
+ #1\xintloop_again\fi\xint_gobble_i {#1}}%
+\long\def\xintbreakloop #1\xintloop_again\fi\xint_gobble_i #2{}%
+\long\def\xintbreakloopanddo #1#2\xintloop_again\fi\xint_gobble_i #3{#1}%
+\long\def\xintloopskiptonext #1\xintloop_again\fi\xint_gobble_i #2{%
+ #2\xintloop_again\fi\xint_gobble_i {#2}}%
+% \end{macrocode}
+% \subsection{\csh{xintiloop},
+% \csh{xintiloopindex},
+% \csh{xintbracediloopindex},
+% \csh{xintouteriloopindex},
+% \csh{xintbracedouteriloopindex},
+% \csh{xintbreakiloop},
+% \csh{xintbreakiloopanddo},
+% \csh{xintiloopskiptonext},
+% \csh{xintiloopskipandredo}}
+% \lverb|1.09g [2013/11/22]. Made long with 1.09h.
+%
+% «braced» variants added (2018/04/24) for 1.3b.|
+% \begin{macrocode}
+\def\xintiloop [#1+#2]{%
+ \expandafter\xintiloop_a\the\numexpr #1\expandafter.\the\numexpr #2.}%
+\long\def\xintiloop_a #1.#2.#3#4\repeat{%
+ #3#4\xintiloop_again\fi\xint_gobble_iii {#1}{#2}{#3#4}}%
+\def\xintiloop_again\fi\xint_gobble_iii #1#2{%
+ \fi\expandafter\xintiloop_again_b\the\numexpr#1+#2.#2.}%
+\long\def\xintiloop_again_b #1.#2.#3{%
+ #3\xintiloop_again\fi\xint_gobble_iii {#1}{#2}{#3}}%
+\long\def\xintbreakiloop #1\xintiloop_again\fi\xint_gobble_iii #2#3#4{}%
+\long\def\xintbreakiloopanddo
+ #1.#2\xintiloop_again\fi\xint_gobble_iii #3#4#5{#1}%
+\long\def\xintiloopindex #1\xintiloop_again\fi\xint_gobble_iii #2%
+ {#2#1\xintiloop_again\fi\xint_gobble_iii {#2}}%
+\long\def\xintbracediloopindex #1\xintiloop_again\fi\xint_gobble_iii #2%
+ {{#2}#1\xintiloop_again\fi\xint_gobble_iii {#2}}%
+\long\def\xintouteriloopindex #1\xintiloop_again
+ #2\xintiloop_again\fi\xint_gobble_iii #3%
+ {#3#1\xintiloop_again #2\xintiloop_again\fi\xint_gobble_iii {#3}}%
+\long\def\xintbracedouteriloopindex #1\xintiloop_again
+ #2\xintiloop_again\fi\xint_gobble_iii #3%
+ {{#3}#1\xintiloop_again #2\xintiloop_again\fi\xint_gobble_iii {#3}}%
+\long\def\xintiloopskiptonext #1\xintiloop_again\fi\xint_gobble_iii #2#3{%
+ \expandafter\xintiloop_again_b \the\numexpr#2+#3.#3.}%
+\long\def\xintiloopskipandredo #1\xintiloop_again\fi\xint_gobble_iii #2#3#4{%
+ #4\xintiloop_again\fi\xint_gobble_iii {#2}{#3}{#4}}%
+% \end{macrocode}
+% \subsection{\csh{XINT_xflet}}
+% \lverb|1.09e [2013/10/29]: we f-expand unbraced tokens and swallow arising
+% space tokens until the dust settles.|
+% \begin{macrocode}
+\def\XINT_xflet #1%
+{%
+ \def\XINT_xflet_macro {#1}\XINT_xflet_zapsp
+}%
+\def\XINT_xflet_zapsp
+{%
+ \expandafter\futurelet\expandafter\XINT_token
+ \expandafter\XINT_xflet_sp?\romannumeral`&&@%
+}%
+\def\XINT_xflet_sp?
+{%
+ \ifx\XINT_token\XINT_sptoken
+ \expandafter\XINT_xflet_zapsp
+ \else\expandafter\XINT_xflet_zapspB
+ \fi
+}%
+\def\XINT_xflet_zapspB
+{%
+ \expandafter\futurelet\expandafter\XINT_tokenB
+ \expandafter\XINT_xflet_spB?\romannumeral`&&@%
+}%
+\def\XINT_xflet_spB?
+{%
+ \ifx\XINT_tokenB\XINT_sptoken
+ \expandafter\XINT_xflet_zapspB
+ \else\expandafter\XINT_xflet_eq?
+ \fi
+}%
+\def\XINT_xflet_eq?
+{%
+ \ifx\XINT_token\XINT_tokenB
+ \expandafter\XINT_xflet_macro
+ \else\expandafter\XINT_xflet_zapsp
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintApplyInline}}
+% \lverb|1.09a: \xintApplyInline\macro{{a}{b}...{z}} has the same effect as
+% executing \macro{a} and then applying again \xintApplyInline to the shortened
+% list {{b}...{z}} until nothing is left. This is a non-expandable command
+% which will result in quicker code than using \xintApplyUnbraced. It f-expands
+% its second (list) argument first, which may thus be encapsulated in a macro.
+%
+% Rewritten in 1.09c. Nota bene: uses catcode 3 Z as privated list terminator.|
+% \begin{macrocode}
+\catcode`Z 3
+\long\def\xintApplyInline #1#2%
+{%
+ \long\expandafter\def\expandafter\XINT_inline_macro
+ \expandafter ##\expandafter 1\expandafter {#1{##1}}%
+ \XINT_xflet\XINT_inline_b #2Z% this Z has catcode 3
+}%
+\def\XINT_inline_b
+{%
+ \ifx\XINT_token Z\expandafter\xint_gobble_i
+ \else\expandafter\XINT_inline_d\fi
+}%
+\long\def\XINT_inline_d #1%
+{%
+ \long\def\XINT_item{{#1}}\XINT_xflet\XINT_inline_e
+}%
+\def\XINT_inline_e
+{%
+ \ifx\XINT_token Z\expandafter\XINT_inline_w
+ \else\expandafter\XINT_inline_f\fi
+}%
+\def\XINT_inline_f
+{%
+ \expandafter\XINT_inline_g\expandafter{\XINT_inline_macro {##1}}%
+}%
+\long\def\XINT_inline_g #1%
+{%
+ \expandafter\XINT_inline_macro\XINT_item
+ \long\def\XINT_inline_macro ##1{#1}\XINT_inline_d
+}%
+\def\XINT_inline_w #1%
+{%
+ \expandafter\XINT_inline_macro\XINT_item
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFor}, \csh{xintFor*}, \csh{xintBreakFor}, \csh{xintBreakForAndDo}}
+% \lverb|1.09c [2013/10/09]: a new kind of loop which uses macro parameters
+% #1, #2, #3, #4 rather than macros; while not expandable it survives executing
+% code closing groups, like what happens in an alignment with the $& character.
+% When inserted in a macro for later use, the # character must be doubled.
+%
+% The non-star variant works on a csv list, which it expands once, the
+% star variant works on a token list, which it (repeatedly) f-expands.
+%
+% 1.09e adds \XINT_forever with \xintintegers, \xintdimensions, \xintrationals
+% and \xintBreakFor, \xintBreakForAndDo, \xintifForFirst, \xintifForLast. On
+% this occasion \xint_firstoftwo and \xint_secondoftwo are made long.
+%
+% 1.09f: rewrites large parts of \xintFor code in order to filter the comma
+% separated list via \xintCSVtoList which gets rid of spaces. The #1 in
+% \XINT_for_forever? has an initial space token which serves two purposes:
+% preventing brace stripping, and stopping the expansion made by \xintcsvtolist.
+% If the \XINT_forever branch is taken, the added space will not be a problem
+% there.
+%
+% 1.09f rewrites (2013/11/03) the code which now allows all macro parameters
+% from #1 to #9 in \xintFor, \xintFor*, and \XINT_forever.
+% 1.2i: slightly more robust \xintifForFirst/Last in case of nesting.
+% |
+% \begin{macrocode}
+\def\XINT_tmpa #1#2{\ifnum #2<#1 \xint_afterfi {{#########2}}\fi}%
+\def\XINT_tmpb #1#2{\ifnum #1<#2 \xint_afterfi {{#########2}}\fi}%
+\def\XINT_tmpc #1%
+{%
+ \expandafter\edef \csname XINT_for_left#1\endcsname
+ {\xintApplyUnbraced {\XINT_tmpa #1}{123456789}}%
+ \expandafter\edef \csname XINT_for_right#1\endcsname
+ {\xintApplyUnbraced {\XINT_tmpb #1}{123456789}}%
+}%
+\xintApplyInline \XINT_tmpc {123456789}%
+\long\def\xintBreakFor #1Z{}%
+\long\def\xintBreakForAndDo #1#2Z{#1}%
+\def\xintFor {\let\xintifForFirst\xint_firstoftwo
+ \let\xintifForLast\xint_secondoftwo
+ \futurelet\XINT_token\XINT_for_ifstar }%
+\def\XINT_for_ifstar {\ifx\XINT_token*\expandafter\XINT_forx
+ \else\expandafter\XINT_for \fi }%
+\catcode`U 3 % with numexpr
+\catcode`V 3 % with xintfrac.sty (xint.sty not enough)
+\catcode`D 3 % with dimexpr
+\def\XINT_flet_zapsp
+{%
+ \futurelet\XINT_token\XINT_flet_sp?
+}%
+\def\XINT_flet_sp?
+{%
+ \ifx\XINT_token\XINT_sptoken
+ \xint_afterfi{\expandafter\XINT_flet_zapsp\romannumeral0}%
+ \else\expandafter\XINT_flet_macro
+ \fi
+}%
+\long\def\XINT_for #1#2in#3#4#5%
+{%
+ \expandafter\XINT_toks\expandafter
+ {\expandafter\XINT_for_d\the\numexpr #2\relax {#5}}%
+ \def\XINT_flet_macro {\expandafter\XINT_for_forever?\space}%
+ \expandafter\XINT_flet_zapsp #3Z%
+}%
+\def\XINT_for_forever? #1Z%
+{%
+ \ifx\XINT_token U\XINT_to_forever\fi
+ \ifx\XINT_token V\XINT_to_forever\fi
+ \ifx\XINT_token D\XINT_to_forever\fi
+ \expandafter\the\expandafter\XINT_toks\romannumeral0\xintcsvtolist {#1}Z%
+}%
+\def\XINT_to_forever\fi #1\xintcsvtolist #2{\fi \XINT_forever #2}%
+\long\def\XINT_forx *#1#2in#3#4#5%
+{%
+ \expandafter\XINT_toks\expandafter
+ {\expandafter\XINT_forx_d\the\numexpr #2\relax {#5}}%
+ \XINT_xflet\XINT_forx_forever? #3Z%
+}%
+\def\XINT_forx_forever?
+{%
+ \ifx\XINT_token U\XINT_to_forxever\fi
+ \ifx\XINT_token V\XINT_to_forxever\fi
+ \ifx\XINT_token D\XINT_to_forxever\fi
+ \XINT_forx_empty?
+}%
+\def\XINT_to_forxever\fi #1\XINT_forx_empty? {\fi \XINT_forever }%
+\catcode`U 11
+\catcode`D 11
+\catcode`V 11
+\def\XINT_forx_empty?
+{%
+ \ifx\XINT_token Z\expandafter\xintBreakFor\fi
+ \the\XINT_toks
+}%
+\long\def\XINT_for_d #1#2#3%
+{%
+ \long\def\XINT_y ##1##2##3##4##5##6##7##8##9{#2}%
+ \XINT_toks {{#3}}%
+ \long\edef\XINT_x {\noexpand\XINT_y \csname XINT_for_left#1\endcsname
+ \the\XINT_toks \csname XINT_for_right#1\endcsname }%
+ \XINT_toks {\XINT_x\let\xintifForFirst\xint_secondoftwo
+ \let\xintifForLast\xint_secondoftwo\XINT_for_d #1{#2}}%
+ \futurelet\XINT_token\XINT_for_last?
+}%
+\long\def\XINT_forx_d #1#2#3%
+{%
+ \long\def\XINT_y ##1##2##3##4##5##6##7##8##9{#2}%
+ \XINT_toks {{#3}}%
+ \long\edef\XINT_x {\noexpand\XINT_y \csname XINT_for_left#1\endcsname
+ \the\XINT_toks \csname XINT_for_right#1\endcsname }%
+ \XINT_toks {\XINT_x\let\xintifForFirst\xint_secondoftwo
+ \let\xintifForLast\xint_secondoftwo\XINT_forx_d #1{#2}}%
+ \XINT_xflet\XINT_for_last?
+}%
+\def\XINT_for_last?
+{%
+ \ifx\XINT_token Z\expandafter\XINT_for_last?yes\fi
+ \the\XINT_toks
+}%
+\def\XINT_for_last?yes
+{%
+ \let\xintifForLast\xint_firstoftwo
+ \xintBreakForAndDo{\XINT_x\xint_gobble_i Z}%
+}%
+% \end{macrocode}
+% \subsection{\csh{XINT_forever}, \csh{xintintegers}, \csh{xintdimensions}, \csh{xintrationals}}
+% \lverb|New with 1.09e. But this used inadvertently \xintiadd/\xintimul which
+% have the unnecessary \xintnum overhead. Changed in 1.09f to use
+% \xintiiadd/\xintiimul which do not have this overhead. Also 1.09f uses
+% \xintZapSpacesB for the \xintrationals case to get rid of leading and ending
+% spaces in the #4 and #5 delimited parameters of \XINT_forever_opt_a
+% (for \xintintegers and \xintdimensions this is not necessary, due to the use
+% of \numexpr resp. \dimexpr in \XINT_?expr_Ua, resp.\XINT_?expr_Da).|
+% \begin{macrocode}
+\catcode`U 3
+\catcode`D 3
+\catcode`V 3
+\let\xintegers U%
+\let\xintintegers U%
+\let\xintdimensions D%
+\let\xintrationals V%
+\def\XINT_forever #1%
+{%
+ \expandafter\XINT_forever_a
+ \csname XINT_?expr_\ifx#1UU\else\ifx#1DD\else V\fi\fi a\expandafter\endcsname
+ \csname XINT_?expr_\ifx#1UU\else\ifx#1DD\else V\fi\fi i\expandafter\endcsname
+ \csname XINT_?expr_\ifx#1UU\else\ifx#1DD\else V\fi\fi \endcsname
+}%
+\catcode`U 11
+\catcode`D 11
+\catcode`V 11
+\def\XINT_?expr_Ua #1#2%
+ {\expandafter{\expandafter\numexpr\the\numexpr #1\expandafter\relax
+ \expandafter\relax\expandafter}%
+ \expandafter{\the\numexpr #2}}%
+\def\XINT_?expr_Da #1#2%
+ {\expandafter{\expandafter\dimexpr\number\dimexpr #1\expandafter\relax
+ \expandafter s\expandafter p\expandafter\relax\expandafter}%
+ \expandafter{\number\dimexpr #2}}%
+\catcode`Z 11
+\def\XINT_?expr_Va #1#2%
+{%
+ \expandafter\XINT_?expr_Vb\expandafter
+ {\romannumeral`&&@\xintrawwithzeros{\xintZapSpacesB{#2}}}%
+ {\romannumeral`&&@\xintrawwithzeros{\xintZapSpacesB{#1}}}%
+}%
+\catcode`Z 3
+\def\XINT_?expr_Vb #1#2{\expandafter\XINT_?expr_Vc #2.#1.}%
+\def\XINT_?expr_Vc #1/#2.#3/#4.%
+{%
+ \xintifEq {#2}{#4}%
+ {\XINT_?expr_Vf {#3}{#1}{#2}}%
+ {\expandafter\XINT_?expr_Vd\expandafter
+ {\romannumeral0\xintiimul {#2}{#4}}%
+ {\romannumeral0\xintiimul {#1}{#4}}%
+ {\romannumeral0\xintiimul {#2}{#3}}%
+ }%
+}%
+\def\XINT_?expr_Vd #1#2#3{\expandafter\XINT_?expr_Ve\expandafter {#2}{#3}{#1}}%
+\def\XINT_?expr_Ve #1#2{\expandafter\XINT_?expr_Vf\expandafter {#2}{#1}}%
+\def\XINT_?expr_Vf #1#2#3{{#2/#3}{{0}{#1}{#2}{#3}}}%
+\def\XINT_?expr_Ui {{\numexpr 1\relax}{1}}%
+\def\XINT_?expr_Di {{\dimexpr 0pt\relax}{65536}}%
+\def\XINT_?expr_Vi {{1/1}{0111}}%
+\def\XINT_?expr_U #1#2%
+ {\expandafter{\expandafter\numexpr\the\numexpr #1+#2\relax\relax}{#2}}%
+\def\XINT_?expr_D #1#2%
+ {\expandafter{\expandafter\dimexpr\the\numexpr #1+#2\relax sp\relax}{#2}}%
+\def\XINT_?expr_V #1#2{\XINT_?expr_Vx #2}%
+\def\XINT_?expr_Vx #1#2%
+{%
+ \expandafter\XINT_?expr_Vy\expandafter
+ {\romannumeral0\xintiiadd {#1}{#2}}{#2}%
+}%
+\def\XINT_?expr_Vy #1#2#3#4%
+{%
+ \expandafter{\romannumeral0\xintiiadd {#3}{#1}/#4}{{#1}{#2}{#3}{#4}}%
+}%
+\def\XINT_forever_a #1#2#3#4%
+{%
+ \ifx #4[\expandafter\XINT_forever_opt_a
+ \else\expandafter\XINT_forever_b
+ \fi #1#2#3#4%
+}%
+\def\XINT_forever_b #1#2#3Z{\expandafter\XINT_forever_c\the\XINT_toks #2#3}%
+\long\def\XINT_forever_c #1#2#3#4#5%
+ {\expandafter\XINT_forever_d\expandafter #2#4#5{#3}Z}%
+\def\XINT_forever_opt_a #1#2#3[#4+#5]#6Z%
+{%
+ \expandafter\expandafter\expandafter
+ \XINT_forever_opt_c\expandafter\the\expandafter\XINT_toks
+ \romannumeral`&&@#1{#4}{#5}#3%
+}%
+\long\def\XINT_forever_opt_c #1#2#3#4#5#6{\XINT_forever_d #2{#4}{#5}#6{#3}Z}%
+\long\def\XINT_forever_d #1#2#3#4#5%
+{%
+ \long\def\XINT_y ##1##2##3##4##5##6##7##8##9{#5}%
+ \XINT_toks {{#2}}%
+ \long\edef\XINT_x {\noexpand\XINT_y \csname XINT_for_left#1\endcsname
+ \the\XINT_toks \csname XINT_for_right#1\endcsname }%
+ \XINT_x
+ \let\xintifForFirst\xint_secondoftwo
+ \let\xintifForLast\xint_secondoftwo
+ \expandafter\XINT_forever_d\expandafter #1\romannumeral`&&@#4{#2}{#3}#4{#5}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintForpair}, \csh{xintForthree}, \csh{xintForfour}}
+% \lverb|1.09c.
+%
+% [2013/11/02] 1.09f \xintForpair delegate to \xintCSVtoList and its
+% \xintZapSpacesB the handling of spaces. Does not share code with \xintFor
+% anymore.
+%
+% [2013/11/03] 1.09f: \xintForpair extended to accept #1#2, #2#3 etc... up to
+% #8#9, \xintForthree, #1#2#3 up to #7#8#9, \xintForfour id.
+%
+% 1.2i: slightly more robust \xintifForFirst/Last in case of nesting.
+% |
+% \begin{macrocode}
+\catcode`j 3
+\long\def\xintForpair #1#2#3in#4#5#6%
+{%
+ \let\xintifForFirst\xint_firstoftwo
+ \let\xintifForLast\xint_secondoftwo
+ \XINT_toks {\XINT_forpair_d #2{#6}}%
+ \expandafter\the\expandafter\XINT_toks #4jZ%
+}%
+\long\def\XINT_forpair_d #1#2#3(#4)#5%
+{%
+ \long\def\XINT_y ##1##2##3##4##5##6##7##8##9{#2}%
+ \XINT_toks \expandafter{\romannumeral0\xintcsvtolist{ #4}}%
+ \long\edef\XINT_x {\noexpand\XINT_y \csname XINT_for_left#1\endcsname
+ \the\XINT_toks \csname XINT_for_right\the\numexpr#1+\xint_c_i\endcsname}%
+ \ifx #5j\expandafter\XINT_for_last?yes\fi
+ \XINT_x
+ \let\xintifForFirst\xint_secondoftwo
+ \let\xintifForLast\xint_secondoftwo
+ \XINT_forpair_d #1{#2}%
+}%
+\long\def\xintForthree #1#2#3in#4#5#6%
+{%
+ \let\xintifForFirst\xint_firstoftwo
+ \let\xintifForLast\xint_secondoftwo
+ \XINT_toks {\XINT_forthree_d #2{#6}}%
+ \expandafter\the\expandafter\XINT_toks #4jZ%
+}%
+\long\def\XINT_forthree_d #1#2#3(#4)#5%
+{%
+ \long\def\XINT_y ##1##2##3##4##5##6##7##8##9{#2}%
+ \XINT_toks \expandafter{\romannumeral0\xintcsvtolist{ #4}}%
+ \long\edef\XINT_x {\noexpand\XINT_y \csname XINT_for_left#1\endcsname
+ \the\XINT_toks \csname XINT_for_right\the\numexpr#1+\xint_c_ii\endcsname}%
+ \ifx #5j\expandafter\XINT_for_last?yes\fi
+ \XINT_x
+ \let\xintifForFirst\xint_secondoftwo
+ \let\xintifForLast\xint_secondoftwo
+ \XINT_forthree_d #1{#2}%
+}%
+\long\def\xintForfour #1#2#3in#4#5#6%
+{%
+ \let\xintifForFirst\xint_firstoftwo
+ \let\xintifForLast\xint_secondoftwo
+ \XINT_toks {\XINT_forfour_d #2{#6}}%
+ \expandafter\the\expandafter\XINT_toks #4jZ%
+}%
+\long\def\XINT_forfour_d #1#2#3(#4)#5%
+{%
+ \long\def\XINT_y ##1##2##3##4##5##6##7##8##9{#2}%
+ \XINT_toks \expandafter{\romannumeral0\xintcsvtolist{ #4}}%
+ \long\edef\XINT_x {\noexpand\XINT_y \csname XINT_for_left#1\endcsname
+ \the\XINT_toks \csname XINT_for_right\the\numexpr#1+\xint_c_iii\endcsname}%
+ \ifx #5j\expandafter\XINT_for_last?yes\fi
+ \XINT_x
+ \let\xintifForFirst\xint_secondoftwo
+ \let\xintifForLast\xint_secondoftwo
+ \XINT_forfour_d #1{#2}%
+}%
+\catcode`Z 11
+\catcode`j 11
+% \end{macrocode}
+% \subsection{\csh{xintAssign}, \csh{xintAssignArray}, \csh{xintDigitsOf}}
+% \lverb|\xintAssign {a}{b}..{z}\to\A\B...\Z resp. \xintAssignArray
+% {a}{b}..{z}\to\U.
+%
+% \xintDigitsOf=\xintAssignArray.
+%
+% 1.1c 2015/09/12 has (belatedly) corrected some "features" of
+% \xintAssign which didn't like the case of a space right before the "\to", or
+% the case with the first token not an opening brace and the subsequent
+% material containing brace groups. The new code handles gracefully these
+% situations.|
+% \begin{macrocode}
+\def\xintAssign{\def\XINT_flet_macro {\XINT_assign_fork}\XINT_flet_zapsp }%
+\def\XINT_assign_fork
+{%
+ \let\XINT_assign_def\def
+ \ifx\XINT_token[\expandafter\XINT_assign_opt
+ \else\expandafter\XINT_assign_a
+ \fi
+}%
+\def\XINT_assign_opt [#1]%
+{%
+ \ifcsname #1def\endcsname
+ \expandafter\let\expandafter\XINT_assign_def \csname #1def\endcsname
+ \else
+ \expandafter\let\expandafter\XINT_assign_def \csname xint#1def\endcsname
+ \fi
+ \XINT_assign_a
+}%
+\long\def\XINT_assign_a #1\to
+{%
+ \def\XINT_flet_macro{\XINT_assign_b}%
+ \expandafter\XINT_flet_zapsp\romannumeral`&&@#1\xint:\to
+}%
+\long\def\XINT_assign_b
+{%
+ \ifx\XINT_token\bgroup
+ \expandafter\XINT_assign_c
+ \else\expandafter\XINT_assign_f
+ \fi
+}%
+\long\def\XINT_assign_f #1\xint:\to #2%
+{%
+ \XINT_assign_def #2{#1}%
+}%
+\long\def\XINT_assign_c #1%
+{%
+ \def\xint_temp {#1}%
+ \ifx\xint_temp\xint_bracedstopper
+ \expandafter\XINT_assign_e
+ \else
+ \expandafter\XINT_assign_d
+ \fi
+}%
+\long\def\XINT_assign_d #1\to #2%
+{%
+ \expandafter\XINT_assign_def\expandafter #2\expandafter{\xint_temp}%
+ \XINT_assign_c #1\to
+}%
+\def\XINT_assign_e #1\to {}%
+\def\xintRelaxArray #1%
+{%
+ \edef\XINT_restoreescapechar {\escapechar\the\escapechar\relax}%
+ \escapechar -1
+ \expandafter\def\expandafter\xint_arrayname\expandafter {\string #1}%
+ \XINT_restoreescapechar
+ \xintiloop [\csname\xint_arrayname 0\endcsname+-1]
+ \global
+ \expandafter\let\csname\xint_arrayname\xintiloopindex\endcsname\relax
+ \ifnum \xintiloopindex > \xint_c_
+ \repeat
+ \global\expandafter\let\csname\xint_arrayname 00\endcsname\relax
+ \global\let #1\relax
+}%
+\def\xintAssignArray{\def\XINT_flet_macro {\XINT_assignarray_fork}%
+ \XINT_flet_zapsp }%
+\def\XINT_assignarray_fork
+{%
+ \let\XINT_assignarray_def\def
+ \ifx\XINT_token[\expandafter\XINT_assignarray_opt
+ \else\expandafter\XINT_assignarray
+ \fi
+}%
+\def\XINT_assignarray_opt [#1]%
+{%
+ \ifcsname #1def\endcsname
+ \expandafter\let\expandafter\XINT_assignarray_def \csname #1def\endcsname
+ \else
+ \expandafter\let\expandafter\XINT_assignarray_def
+ \csname xint#1def\endcsname
+ \fi
+ \XINT_assignarray
+}%
+\long\def\XINT_assignarray #1\to #2%
+{%
+ \edef\XINT_restoreescapechar {\escapechar\the\escapechar\relax }%
+ \escapechar -1
+ \expandafter\def\expandafter\xint_arrayname\expandafter {\string #2}%
+ \XINT_restoreescapechar
+ \def\xint_itemcount {0}%
+ \expandafter\XINT_assignarray_loop \romannumeral`&&@#1\xint:
+ \csname\xint_arrayname 00\expandafter\endcsname
+ \csname\xint_arrayname 0\expandafter\endcsname
+ \expandafter {\xint_arrayname}#2%
+}%
+\long\def\XINT_assignarray_loop #1%
+{%
+ \def\xint_temp {#1}%
+ \ifx\xint_temp\xint_bracedstopper
+ \expandafter\def\csname\xint_arrayname 0\expandafter\endcsname
+ \expandafter{\the\numexpr\xint_itemcount}%
+ \expandafter\expandafter\expandafter\XINT_assignarray_end
+ \else
+ \expandafter\def\expandafter\xint_itemcount\expandafter
+ {\the\numexpr\xint_itemcount+\xint_c_i}%
+ \expandafter\XINT_assignarray_def
+ \csname\xint_arrayname\xint_itemcount\expandafter\endcsname
+ \expandafter{\xint_temp }%
+ \expandafter\XINT_assignarray_loop
+ \fi
+}%
+\def\XINT_assignarray_end #1#2#3#4%
+{%
+ \def #4##1%
+ {%
+ \romannumeral0\expandafter #1\expandafter{\the\numexpr ##1}%
+ }%
+ \def #1##1%
+ {%
+ \ifnum ##1<\xint_c_
+ \xint_afterfi{\XINT_expandableerror{Array index negative: 0 > ##1} }%
+ \else
+ \xint_afterfi {%
+ \ifnum ##1>#2
+ \xint_afterfi
+ {\XINT_expandableerror{Array index beyond range: ##1 > #2} }%
+ \else\xint_afterfi
+ {\expandafter\expandafter\expandafter\space\csname #3##1\endcsname}%
+ \fi}%
+ \fi
+ }%
+}%
+\let\xintDigitsOf\xintAssignArray
+% \end{macrocode}
+% \subsection{\csh{xintExpandArgs}}
+% \lverb|1.3a. Added for the needs of user defined functions for the
+% expression parsers. Should I re-code it to gain a bit in argument grabbing?
+% Must be f-expandable.|
+% \begin{macrocode}
+\def\xintExpandArgs#1#2{\csname #1\expandafter\endcsname
+ \romannumeral0\xintapply\xint_firstofone{#2}}%
+% \end{macrocode}
+%\subsection{CSV (non user documented) variants of Length, Keep, Trim, NthElt, Reverse}
+%
+% These routines are for use by |\xintListSel:x:csv| and |\xintListSel:f:csv|
+% from \xintexprnameimp, and also for the |reversed| and |len| functions.
+% Refactored for |1.2j| release, following |1.2i| updates to |\xintKeep|,
+% |\xintTrim|, ...
+%
+% These macros will remain undocumented in the user manual:
+%
+% -- they exist primarily for internal use by the \xintexprnameimp parsers,
+% hence don't have to be general purpose; for example, they a priori need to
+% handle only catcode 12 tokens (not true in |\xintNewExpr|, though)
+% hence they are not really worried about
+% controlling brace stripping (nevertheless |1.2j| has paid some secondary
+% attention to it, see below.) They are not worried about normalizing leading
+% spaces either, because none will be encountered when the macros are used as
+% auxiliaries to the expression parsers.
+%
+% -- crucial design elements may change in future:
+%
+% 1. whether the handled lists must have or not have a final comma. Currently,
+% the model is the one of comma separated lists with **no** final comma. But
+% this means that there can not be a distinction of principle between a truly
+% empty list and a list which contains one item which turns out to be empty.
+% More importantly it makes the coding more complicated as it is needed to
+% distinguish the empty list from the single-item list, both lacking commas.
+%
+% For the internal use of \xintexprnameimp, it would be ok to require all list
+% items to be terminated by a comma, and this would bring quite some
+% simplications here, but as initially I started with non-terminated lists, I
+% have left it this way in the |1.2j| refactoring.
+%
+% 2. the way to represent the empty list. I was tempted for matter of
+% optimization and synchronization with \xintexprnameimp context to require
+% the empty list to be always represented by a space token and to not let the
+% macros admit a completely empty input. But there were complications so for
+% the time being |1.2j| does accept truly empty output (it is not
+% distinguished from an input equal to a space token) and produces empty
+% output for empty list. This means that the status of the «nil» object for
+% the \xintexprnameimp parsers is not completely clarified (currently it is
+% represented by a space token).
+%
+% The original Python slicing code in \xintexprnameimp |1.1| used
+% |\xintCSVtoList| and |\xintListWithSep{,}| to convert back and forth to
+% token lists and apply |\xintKeep/\xintTrim|. Release |1.2g| switched to
+% devoted f-expandable macros added to \xinttoolsnameimp. Release |1.2j|
+% refactored all these macros as a follow-up to |1.2i| improvements to
+% |\xintKeep/\xintTrim|. They were made |\long| on this occasion and
+% auxiliary |\xintLengthUpTo:f:csv| was added.
+%
+% Leading spaces in items are currently maintained as is by the |1.2j|
+% macros, even by |\xintNthEltPy:f:csv|, with the exception of the first item,
+% as the list is f-expanded. Perhaps |\xintNthEltPy:f:csv| should remove a
+% leading space if present in the picked item; anyway, there are no spaces
+% for the lists handled internally by the Python slicer of \xintexprnameimp,
+% except the «nil» object currently represented by exactly one space.
+%
+% Kept items (with no leading spaces; but first item special as it will have
+% lost a leading space due to f-expansion) will lose a brace pair under
+% |\xintKeep:f:csv| if the first argument was positive and strictly less than
+% the length of the list. This differs of course from |\xintKeep| (which
+% always braces items it outputs when used with positive first argument) and
+% also from |\xintKeepUnbraced| in the case when the whole list is kept.
+% Actually the case of singleton list is special, and brace removal will
+% happen then.
+%
+% This behaviour was otherwise for releases earlier than |1.2j| and may
+% change again.
+%
+% Directly usable names are provided, but these macros (and the behaviour as
+% described above) are to be considered \emph{unstable} for the time being.
+%
+% \subsubsection{\csh{xintLength:f:csv}}
+% \lverb|1.2g. Redone for 1.2j. Contrarily to \xintLength from xintkernel.sty,
+% this one expands its argument.|
+% \begin{macrocode}
+\def\xintLength:f:csv {\romannumeral0\xintlength:f:csv}%
+\def\xintlength:f:csv #1%
+{\long\def\xintlength:f:csv ##1{%
+ \expandafter#1\the\numexpr\expandafter\XINT_length:f:csv_a
+ \romannumeral`&&@##1\xint:,\xint:,\xint:,\xint:,%
+ \xint:,\xint:,\xint:,\xint:,\xint:,%
+ \xint_c_ix,\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_bye
+ \relax
+}}\xintlength:f:csv { }%
+% \end{macrocode}
+% \lverb|Must first check if empty list.|
+% \begin{macrocode}
+\long\def\XINT_length:f:csv_a #1%
+{%
+ \xint_gob_til_xint: #1\xint_c_\xint_bye\xint:%
+ \XINT_length:f:csv_loop #1%
+}%
+\long\def\XINT_length:f:csv_loop #1,#2,#3,#4,#5,#6,#7,#8,#9,%
+{%
+ \xint_gob_til_xint: #9\XINT_length:f:csv_finish\xint:%
+ \xint_c_ix+\XINT_length:f:csv_loop
+}%
+\def\XINT_length:f:csv_finish\xint:\xint_c_ix+\XINT_length:f:csv_loop
+ #1,#2,#3,#4,#5,#6,#7,#8,#9,{#9\xint_bye}%
+% \end{macrocode}
+% \subsubsection{\csh{xintLengthUpTo:f:csv}}
+% \lverb|1.2j. \xintLengthUpTo:f:csv{N}{comma-list}. No ending comma. Returns
+% -0 if length>N, else returns difference N-length. **N must be non-negative!!**
+%
+% Attention to the dot after \xint_bye for the loop interface.|
+% \begin{macrocode}
+\def\xintLengthUpTo:f:csv {\romannumeral0\xintlengthupto:f:csv}%
+\long\def\xintlengthupto:f:csv #1#2%
+{%
+ \expandafter\XINT_lengthupto:f:csv_a
+ \the\numexpr#1\expandafter.%
+ \romannumeral`&&@#2\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_bye.%
+}%
+% \end{macrocode}
+% \lverb|Must first recognize if empty list. If this is the case, return N.|
+% \begin{macrocode}
+\long\def\XINT_lengthupto:f:csv_a #1.#2%
+{%
+ \xint_gob_til_xint: #2\XINT_lengthupto:f:csv_empty\xint:%
+ \XINT_lengthupto:f:csv_loop_b #1.#2%
+}%
+\def\XINT_lengthupto:f:csv_empty\xint:%
+ \XINT_lengthupto:f:csv_loop_b #1.#2\xint_bye.{ #1}%
+\def\XINT_lengthupto:f:csv_loop_a #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_lengthupto:f:csv_gt
+ -\XINT_lengthupto:f:csv_loop_b
+ \krof #1%
+}%
+\long\def\XINT_lengthupto:f:csv_gt #1\xint_bye.{-0}%
+\long\def\XINT_lengthupto:f:csv_loop_b #1.#2,#3,#4,#5,#6,#7,#8,#9,%
+{%
+ \xint_gob_til_xint: #9\XINT_lengthupto:f:csv_finish_a\xint:%
+ \expandafter\XINT_lengthupto:f:csv_loop_a\the\numexpr #1-\xint_c_viii.%
+}%
+\def\XINT_lengthupto:f:csv_finish_a\xint:
+ \expandafter\XINT_lengthupto:f:csv_loop_a
+ \the\numexpr #1-\xint_c_viii.#2,#3,#4,#5,#6,#7,#8,#9,%
+{%
+ \expandafter\XINT_lengthupto:f:csv_finish_b\the\numexpr #1-#9\xint_bye
+}%
+\def\XINT_lengthupto:f:csv_finish_b #1#2.%
+{%
+ \xint_UDsignfork
+ #1{-0}%
+ -{ #1#2}%
+ \krof
+}%
+% \end{macrocode}
+%\subsubsection{\csh{xintKeep:f:csv}}
+% \lverb|1.2g 2016/03/17. Redone for 1.2j with use of \xintLengthUpTo:f:csv.
+% Same code skeleton as \xintKeep but handling comma separated but non
+% terminated lists has complications. The \xintKeep in case of a negative #1
+% uses \xintgobble, we don't have that for comma delimited items, hence we do
+% a special loop here (this style of loop is surely competitive with
+% xintgobble for a few dozens items and even more). The loop knows before
+% starting that it will not go too far.
+%
+%|
+% \begin{macrocode}
+\def\xintKeep:f:csv {\romannumeral0\xintkeep:f:csv }%
+\long\def\xintkeep:f:csv #1#2%
+{%
+ \expandafter\xint_stop_aftergobble
+ \romannumeral0\expandafter\XINT_keep:f:csv_a
+ \the\numexpr #1\expandafter.\expandafter{\romannumeral`&&@#2}%
+}%
+\def\XINT_keep:f:csv_a #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_keep:f:csv_keepnone
+ 0#1\XINT_keep:f:csv_neg
+ 0-{\XINT_keep:f:csv_pos #1}%
+ \krof
+}%
+\long\def\XINT_keep:f:csv_keepnone .#1{,}%
+\long\def\XINT_keep:f:csv_neg #1.#2%
+{%
+ \expandafter\XINT_keep:f:csv_neg_done\expandafter,%
+ \romannumeral0%
+ \expandafter\XINT_keep:f:csv_neg_a\the\numexpr
+ #1-\numexpr\XINT_length:f:csv_a
+ #2\xint:,\xint:,\xint:,\xint:,%
+ \xint:,\xint:,\xint:,\xint:,\xint:,%
+ \xint_c_ix,\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_bye
+ .#2\xint_bye
+}%
+\def\XINT_keep:f:csv_neg_a #1%
+{%
+ \xint_UDsignfork
+ #1{\expandafter\XINT_keep:f:csv_trimloop\the\numexpr-\xint_c_ix+}%
+ -\XINT_keep:f:csv_keepall
+ \krof
+}%
+\def\XINT_keep:f:csv_keepall #1.{ }%
+\long\def\XINT_keep:f:csv_neg_done #1\xint_bye{#1}%
+\def\XINT_keep:f:csv_trimloop #1#2.%
+{%
+ \xint_gob_til_minus#1\XINT_keep:f:csv_trimloop_finish-%
+ \expandafter\XINT_keep:f:csv_trimloop
+ \the\numexpr#1#2-\xint_c_ix\expandafter.\XINT_keep:f:csv_trimloop_trimnine
+}%
+\long\def\XINT_keep:f:csv_trimloop_trimnine #1,#2,#3,#4,#5,#6,#7,#8,#9,{}%
+\def\XINT_keep:f:csv_trimloop_finish-%
+ \expandafter\XINT_keep:f:csv_trimloop
+ \the\numexpr-#1-\xint_c_ix\expandafter.\XINT_keep:f:csv_trimloop_trimnine
+ {\csname XINT_trim:f:csv_finish#1\endcsname}%
+\long\def\XINT_keep:f:csv_pos #1.#2%
+{%
+ \expandafter\XINT_keep:f:csv_pos_fork
+ \romannumeral0\XINT_lengthupto:f:csv_a
+ #1.#2\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_bye.%
+ .#1.{}#2\xint_bye%
+}%
+\def\XINT_keep:f:csv_pos_fork #1#2.%
+{%
+ \xint_UDsignfork
+ #1{\expandafter\XINT_keep:f:csv_loop\the\numexpr-\xint_c_viii+}%
+ -\XINT_keep:f:csv_pos_keepall
+ \krof
+}%
+\long\def\XINT_keep:f:csv_pos_keepall #1.#2#3\xint_bye{,#3}%
+\def\XINT_keep:f:csv_loop #1#2.%
+{%
+ \xint_gob_til_minus#1\XINT_keep:f:csv_loop_end-%
+ \expandafter\XINT_keep:f:csv_loop
+ \the\numexpr#1#2-\xint_c_viii\expandafter.\XINT_keep:f:csv_loop_pickeight
+}%
+\long\def\XINT_keep:f:csv_loop_pickeight
+ #1#2,#3,#4,#5,#6,#7,#8,#9,{{#1,#2,#3,#4,#5,#6,#7,#8,#9}}%
+\def\XINT_keep:f:csv_loop_end-\expandafter\XINT_keep:f:csv_loop
+ \the\numexpr-#1-\xint_c_viii\expandafter.\XINT_keep:f:csv_loop_pickeight
+ {\csname XINT_keep:f:csv_end#1\endcsname}%
+\long\expandafter\def\csname XINT_keep:f:csv_end1\endcsname
+ #1#2,#3,#4,#5,#6,#7,#8,#9\xint_bye {#1,#2,#3,#4,#5,#6,#7,#8}%
+\long\expandafter\def\csname XINT_keep:f:csv_end2\endcsname
+ #1#2,#3,#4,#5,#6,#7,#8\xint_bye {#1,#2,#3,#4,#5,#6,#7}%
+\long\expandafter\def\csname XINT_keep:f:csv_end3\endcsname
+ #1#2,#3,#4,#5,#6,#7\xint_bye {#1,#2,#3,#4,#5,#6}%
+\long\expandafter\def\csname XINT_keep:f:csv_end4\endcsname
+ #1#2,#3,#4,#5,#6\xint_bye {#1,#2,#3,#4,#5}%
+\long\expandafter\def\csname XINT_keep:f:csv_end5\endcsname
+ #1#2,#3,#4,#5\xint_bye {#1,#2,#3,#4}%
+\long\expandafter\def\csname XINT_keep:f:csv_end6\endcsname
+ #1#2,#3,#4\xint_bye {#1,#2,#3}%
+\long\expandafter\def\csname XINT_keep:f:csv_end7\endcsname
+ #1#2,#3\xint_bye {#1,#2}%
+\long\expandafter\def\csname XINT_keep:f:csv_end8\endcsname
+ #1#2\xint_bye {#1}%
+% \end{macrocode}
+%\subsubsection{\csh{xintTrim:f:csv}}
+% \lverb|1.2g 2016/03/17. Redone for 1.2j 2016/12/20 on the basis of new
+% \xintTrim.|
+% \begin{macrocode}
+\def\xintTrim:f:csv {\romannumeral0\xinttrim:f:csv }%
+\long\def\xinttrim:f:csv #1#2%
+{%
+ \expandafter\xint_stop_aftergobble
+ \romannumeral0\expandafter\XINT_trim:f:csv_a
+ \the\numexpr #1\expandafter.\expandafter{\romannumeral`&&@#2}%
+}%
+\def\XINT_trim:f:csv_a #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_trim:f:csv_trimnone
+ 0#1\XINT_trim:f:csv_neg
+ 0-{\XINT_trim:f:csv_pos #1}%
+ \krof
+}%
+\long\def\XINT_trim:f:csv_trimnone .#1{,#1}%
+\long\def\XINT_trim:f:csv_neg #1.#2%
+{%
+ \expandafter\XINT_trim:f:csv_neg_a\the\numexpr
+ #1-\numexpr\XINT_length:f:csv_a
+ #2\xint:,\xint:,\xint:,\xint:,%
+ \xint:,\xint:,\xint:,\xint:,\xint:,%
+ \xint_c_ix,\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_bye
+ .{}#2\xint_bye
+}%
+\def\XINT_trim:f:csv_neg_a #1%
+{%
+ \xint_UDsignfork
+ #1{\expandafter\XINT_keep:f:csv_loop\the\numexpr-\xint_c_viii+}%
+ -\XINT_trim:f:csv_trimall
+ \krof
+}%
+\def\XINT_trim:f:csv_trimall {\expandafter,\xint_bye}%
+\long\def\XINT_trim:f:csv_pos #1.#2%
+{%
+ \expandafter\XINT_trim:f:csv_pos_done\expandafter,%
+ \romannumeral0%
+ \expandafter\XINT_trim:f:csv_loop\the\numexpr#1-\xint_c_ix.%
+ #2\xint:,\xint:,\xint:,\xint:,\xint:,%
+ \xint:,\xint:,\xint:,\xint:,\xint:\xint_bye
+}%
+\def\XINT_trim:f:csv_loop #1#2.%
+{%
+ \xint_gob_til_minus#1\XINT_trim:f:csv_finish-%
+ \expandafter\XINT_trim:f:csv_loop\the\numexpr#1#2\XINT_trim:f:csv_loop_trimnine
+}%
+\long\def\XINT_trim:f:csv_loop_trimnine #1,#2,#3,#4,#5,#6,#7,#8,#9,%
+{%
+ \xint_gob_til_xint: #9\XINT_trim:f:csv_toofew\xint:-\xint_c_ix.%
+}%
+\def\XINT_trim:f:csv_toofew\xint:{*\xint_c_}%
+\def\XINT_trim:f:csv_finish-%
+ \expandafter\XINT_trim:f:csv_loop\the\numexpr-#1\XINT_trim:f:csv_loop_trimnine
+{%
+ \csname XINT_trim:f:csv_finish#1\endcsname
+}%
+\long\expandafter\def\csname XINT_trim:f:csv_finish1\endcsname
+ #1,#2,#3,#4,#5,#6,#7,#8,{ }%
+\long\expandafter\def\csname XINT_trim:f:csv_finish2\endcsname
+ #1,#2,#3,#4,#5,#6,#7,{ }%
+\long\expandafter\def\csname XINT_trim:f:csv_finish3\endcsname
+ #1,#2,#3,#4,#5,#6,{ }%
+\long\expandafter\def\csname XINT_trim:f:csv_finish4\endcsname
+ #1,#2,#3,#4,#5,{ }%
+\long\expandafter\def\csname XINT_trim:f:csv_finish5\endcsname
+ #1,#2,#3,#4,{ }%
+\long\expandafter\def\csname XINT_trim:f:csv_finish6\endcsname
+ #1,#2,#3,{ }%
+\long\expandafter\def\csname XINT_trim:f:csv_finish7\endcsname
+ #1,#2,{ }%
+\long\expandafter\def\csname XINT_trim:f:csv_finish8\endcsname
+ #1,{ }%
+\expandafter\let\csname XINT_trim:f:csv_finish9\endcsname\space
+\long\def\XINT_trim:f:csv_pos_done #1\xint:#2\xint_bye{#1}%
+% \end{macrocode}
+% \subsubsection{\csh{xintNthEltPy:f:csv}}
+% \lverb|Counts like Python starting at zero. Last refactored with 1.2j.
+% Attention, makes currently no effort at removing leading spaces in the
+% picked item.|
+% \begin{macrocode}
+\def\xintNthEltPy:f:csv {\romannumeral0\xintntheltpy:f:csv }%
+\long\def\xintntheltpy:f:csv #1#2%
+{%
+ \expandafter\XINT_nthelt:f:csv_a
+ \the\numexpr #1\expandafter.\expandafter{\romannumeral`&&@#2}%
+}%
+\def\XINT_nthelt:f:csv_a #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_nthelt:f:csv_neg
+ -\XINT_nthelt:f:csv_pos
+ \krof #1%
+}%
+\long\def\XINT_nthelt:f:csv_neg -#1.#2%
+{%
+ \expandafter\XINT_nthelt:f:csv_neg_fork
+ \the\numexpr\XINT_length:f:csv_a
+ #2\xint:,\xint:,\xint:,\xint:,%
+ \xint:,\xint:,\xint:,\xint:,\xint:,%
+ \xint_c_ix,\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_bye
+ -#1.#2,\xint_bye
+}%
+\def\XINT_nthelt:f:csv_neg_fork #1%
+{%
+ \if#1-\expandafter\xint_stop_afterbye\fi
+ \expandafter\XINT_nthelt:f:csv_neg_done
+ \romannumeral0%
+ \expandafter\XINT_keep:f:csv_trimloop\the\numexpr-\xint_c_ix+#1%
+}%
+\long\def\XINT_nthelt:f:csv_neg_done#1,#2\xint_bye{ #1}%
+\long\def\XINT_nthelt:f:csv_pos #1.#2%
+{%
+ \expandafter\XINT_nthelt:f:csv_pos_done
+ \romannumeral0%
+ \expandafter\XINT_trim:f:csv_loop\the\numexpr#1-\xint_c_ix.%
+ #2\xint:,\xint:,\xint:,\xint:,\xint:,%
+ \xint:,\xint:,\xint:,\xint:,\xint:,\xint_bye
+}%
+\def\XINT_nthelt:f:csv_pos_done #1{%
+\long\def\XINT_nthelt:f:csv_pos_done ##1,##2\xint_bye{%
+ \xint_gob_til_xint:##1\XINT_nthelt:f:csv_pos_cleanup\xint:#1##1}%
+}\XINT_nthelt:f:csv_pos_done{ }%
+% \end{macrocode}
+% \lverb|This strange thing is in case the picked item was the last one, hence
+% there was an ending \xint: (we could not put a comma earlier for
+% matters of not confusing empty list with a singleton list), and we do this
+% here to activate brace-stripping of item as all other items may be
+% brace-stripped if picked. This is done for coherence. Of course, in the
+% context of the xintexpr.sty parsers, there are no braces in list items...|
+% \begin{macrocode}
+\xint_firstofone{\long\def\XINT_nthelt:f:csv_pos_cleanup\xint:} %
+ #1\xint:{ #1}%
+% \end{macrocode}
+% \subsubsection{\csh{xintReverse:f:csv}}
+% \lverb|1.2g. Contrarily to \xintReverseOrder from xintkernel.sty, this
+% one expands its argument. Handles empty list too. 2016/03/17.
+% Made \long for 1.2j.|
+% \begin{macrocode}
+\def\xintReverse:f:csv {\romannumeral0\xintreverse:f:csv }%
+\long\def\xintreverse:f:csv #1%
+{%
+ \expandafter\XINT_reverse:f:csv_loop
+ \expandafter{\expandafter}\romannumeral`&&@#1,%
+ \xint:,%
+ \xint_bye,\xint_bye,\xint_bye,\xint_bye,%
+ \xint_bye,\xint_bye,\xint_bye,\xint_bye,%
+ \xint:
+}%
+\long\def\XINT_reverse:f:csv_loop #1#2,#3,#4,#5,#6,#7,#8,#9,%
+{%
+ \xint_bye #9\XINT_reverse:f:csv_cleanup\xint_bye
+ \XINT_reverse:f:csv_loop {,#9,#8,#7,#6,#5,#4,#3,#2#1}%
+}%
+\long\def\XINT_reverse:f:csv_cleanup\xint_bye\XINT_reverse:f:csv_loop #1#2\xint:
+{%
+ \XINT_reverse:f:csv_finish #1%
+}%
+\long\def\XINT_reverse:f:csv_finish #1\xint:,{ }%
+% \end{macrocode}
+% \subsubsection{\csh{xintFirstItem:f:csv}}
+% \lverb|Added with 1.2k for use by first() in
+% \xintexpr-essions, and some amount of compatibility with \xintNewExpr.|
+% \begin{macrocode}
+\def\xintFirstItem:f:csv {\romannumeral0\xintfirstitem:f:csv}%
+\long\def\xintfirstitem:f:csv #1%
+{%
+ \expandafter\XINT_first:f:csv_a\romannumeral`&&@#1,\xint_bye
+}%
+\long\def\XINT_first:f:csv_a #1,#2\xint_bye{ #1}%
+% \end{macrocode}
+% \subsubsection{\csh{xintLastItem:f:csv}}
+% \lverb|Added with 1.2k, based on and sharing code with xintkernel's
+% \xintLastItem from 1.2i. Output empty if input empty. f-expands its argument
+% (hence first item, if not protected.) For use by last() in
+% \xintexpr-essions with to some extent \xintNewExpr compatibility.|
+% \begin{macrocode}
+\def\xintLastItem:f:csv {\romannumeral0\xintlastitem:f:csv}%
+\long\def\xintlastitem:f:csv #1%
+{%
+ \expandafter\XINT_last:f:csv_loop\expandafter{\expandafter}\expandafter.%
+ \romannumeral`&&@#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:f:csv_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:f:csv_loop {#9}.%
+}%
+% \end{macrocode}
+% \subsubsection{Public names for the undocumented csv macros:
+% \csh{xintCSVLength}, \csh{xintCSVKeep}, \csh{xintCSVTrim},
+% \csh{xintCSVNthEltPy}, \csh{xintCSVReverse},
+% \csh{xintCSVFirstItem}, \csh{xintCSVLastItem}}
+%
+% \lverb|Completely unstable macros: currently they expand the list argument
+% and want no final comma. But for matters of xintexpr.sty I could as well
+% decide to require a final comma, and then I could simplify implementation
+% but of course this would break the macros if used with current
+% functionalities.|
+% \begin{macrocode}
+\let\xintCSVLength \xintLength:f:csv
+\let\xintCSVKeep \xintKeep:f:csv
+\let\xintCSVTrim \xintTrim:f:csv
+\let\xintCSVNthEltPy \xintNthEltPy:f:csv
+\let\xintCSVReverse \xintReverse:f:csv
+\let\xintCSVFirstItem\xintFirstItem:f:csv
+\let\xintCSVLastItem \xintLastItem:f:csv
+\let\XINT_tmpa\relax \let\XINT_tmpb\relax \let\XINT_tmpc\relax
+\XINT_restorecatcodes_endinput%
+% \end{macrocode}
+% \StoreCodelineNo {xinttools}
+% \cleardoublepage\let\xinttoolsnameUp\undefined
+%\gardesactifs
+%\let</xinttools>\relax
+%\let<*xintcore>\gardesinactifs
+%</xinttools>^^A--------------------------------------------------
+%<*xintcore>^^A---------------------------------------------------
+%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*-
+% \clearpage\csname xintcorenameUp\endcsname
+% \section{Package \xintcorenameimp implementation}
+% \RaisedLabel{sec:coreimp}
+%
+% \localtableofcontents
+%
+% Got split off from \xintnameimp with release |1.1|.
+%
+% The core arithmetic routines have been entirely rewritten for release
+% |1.2|. The |1.2i| and |1.2l| brought again some improvements.
+%
+% The commenting continues (\xintdocdate) to be very sparse: actually it got
+% worse than ever with release |1.2|. I will possibly add comments at a
+% later date, but for the time being the new routines are not commented at
+% all.
+%
+% |1.3| removes all macros which were deprecated at |1.2o|.
+%
+% \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{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+ \catcode13=5 % ^^M
+ \endlinechar=13 %
+ \catcode123=1 % {
+ \catcode125=2 % }
+ \catcode64=11 % @
+ \catcode35=6 % #
+ \catcode44=12 % ,
+ \catcode45=12 % -
+ \catcode46=12 % .
+ \catcode58=12 % :
+ \let\z\endgroup
+ \expandafter\let\expandafter\x\csname ver@xintcore.sty\endcsname
+ \expandafter\let\expandafter\w\csname ver@xintkernel.sty\endcsname
+ \expandafter
+ \ifx\csname PackageInfo\endcsname\relax
+ \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}%
+ \else
+ \def\y#1#2{\PackageInfo{#1}{#2}}%
+ \fi
+ \expandafter
+ \ifx\csname numexpr\endcsname\relax
+ \y{xintcore}{\numexpr not available, aborting input}%
+ \aftergroup\endinput
+ \else
+ \ifx\x\relax % plain-TeX, first loading of xintcore.sty
+ \ifx\w\relax % but xintkernel.sty not yet loaded.
+ \def\z{\endgroup\input xintkernel.sty\relax}%
+ \fi
+ \else
+ \def\empty {}%
+ \ifx\x\empty % LaTeX, first loading,
+ % variable is initialized, but \ProvidesPackage not yet seen
+ \ifx\w\relax % xintkernel.sty not yet loaded.
+ \def\z{\endgroup\RequirePackage{xintkernel}}%
+ \fi
+ \else
+ \aftergroup\endinput % xintkernel already loaded.
+ \fi
+ \fi
+ \fi
+\z%
+\XINTsetupcatcodes% defined in xintkernel.sty
+% \end{macrocode}
+% \subsection{Package identification}
+% \begin{macrocode}
+\XINT_providespackage
+\ProvidesPackage{xintcore}%
+ [2019/04/05 1.3e Expandable arithmetic on big integers (JFB)]%
+% \end{macrocode}
+% \subsection{(WIP!) Error conditions and exceptions}
+% \lverb|As per the Mike Cowlishaw/IBM's General Decimal Arithmetic Specification
+%
+% http://speleotrove.com/decimal/decarith.html
+%
+% and the Python3 implementation in its Decimal module.
+%
+% Clamped, ConversionSyntax, DivisionByZero, DivisionImpossible,
+% DivisionUndefined, Inexact, InsufficientStorage, InvalidContext,
+% InvalidOperation, Overflow, Inexact, Rounded, Subnormal,
+% Underflow.
+%
+% X3.274 rajoute LostDigits
+%
+% Python rajoute FloatOperation (et n'inclut pas InsufficientStorage)
+%
+% quote de decarith.pdf:
+% The Clamped, Inexact, Rounded, and Subnormal conditions can coincide with
+% each other or with other conditions. In these cases then any trap enabled
+% for another condition takes precedence over (is handled before) all of
+% these, any Subnormal trap takes precedence over Inexact, any Inexact trap
+% takes precedence over Rounded, and any Rounded trap takes precedence over
+% Clamped.
+%
+% WORK IN PROGRESS ! (1.2l, 2017/07/26)
+%
+% I follow the Python terminology: a trapped signal means it raises an
+% exception which for us means an expandable error message with some possible
+% user interaction. In this WIP
+% state, the interaction is commented out. A non-trapped signal or condition
+% would activate a (presumably silent) handler.
+%
+% Here, no signal-raising condition is "ignored" and all are "trapped" which
+% means that error handlers are never activated, thus left in garbage state in
+% the code.
+%
+% Various conditions can raise the same signal.
+%
+% Only signals, not conditions, raise Flags.
+%
+% If a signal is ignored it does not raise a Flag, but it activates the signal
+% handler (by default now no signal is ignored.)
+%
+% If a signal is not ignored it raises a Flag and then if it is not trapped it
+% activates the handler of the _condition_.
+%
+% If trapped (which is default now) an «exception» is raised, which means an
+% expandable error message (I copied over the LaTeX3 code for expandable error
+% messages, basically)
+% interrupts the TeX run. In future, user input could
+% be solicited, but currently this is commented out.
+%
+% For now macros to reset flags are done but without public interface nor
+% documentation.
+%
+% Only four conditions are currently possibly encountered:
+%- InvalidOperation
+%- DivisionByZero
+%- DivisionUndefined (which signals InvalidOperation)
+%- Underflow
+%
+% I did it quickly, anyhow this will become more palpable when some of the
+% Decimal Specification is actually implemented. The plan is to first do the
+% X3.274 norm, then more complete implementation will follow... perhaps...
+% |
+% \begin{macrocode}
+\csname XINT_Clamped_istrapped\endcsname
+\csname XINT_ConversionSyntax_istrapped\endcsname
+\csname XINT_DivisionByZero_istrapped\endcsname
+\csname XINT_DivisionImpossible_istrapped\endcsname
+\csname XINT_DivisionUndefined_istrapped\endcsname
+\csname XINT_InvalidOperation_istrapped\endcsname
+\csname XINT_Overflow_istrapped\endcsname
+\csname XINT_Underflow_istrapped\endcsname
+\catcode`- 11
+\def\XINT_ConversionSyntax-signal {{InvalidOperation}}%
+\let\XINT_DivisionImpossible-signal\XINT_ConversionSyntax-signal
+\let\XINT_DivisionUndefined-signal \XINT_ConversionSyntax-signal
+\let\XINT_InvalidContext-signal \XINT_ConversionSyntax-signal
+\catcode`- 12
+\def\XINT_signalcondition #1{\expandafter\XINT_signalcondition_a
+ \romannumeral0\ifcsname XINT_#1-signal\endcsname
+ \xint_dothis{\csname XINT_#1-signal\endcsname}%
+ \fi\xint_orthat{{#1}}{#1}}%
+\def\XINT_signalcondition_a #1#2#3#4#5{% copied over from Python Decimal module
+% #1=signal, #2=condition, #3=explanation for user,
+% #4=context for error handlers, #5=used
+ \ifcsname XINT_#1_isignoredflag\endcsname
+ \xint_dothis{\csname XINT_#1.handler\endcsname {#4}}%
+ \fi
+ \expandafter\xint_gobble_i\csname XINT_#1Flag_ON\endcsname
+ \unless\ifcsname XINT_#1_istrapped\endcsname
+ \xint_dothis{\csname XINT_#2.handler\endcsname {#4}}%
+ \fi
+ \xint_orthat{%
+ % the flag raised is named after the signal #1, but we show condition #2
+ \XINT_expandableerror{#2 (hit <RET> thrice)}%
+ \XINT_expandableerror{#3}%
+ \XINT_expandableerror{next: #5}%
+ % not for X3.274
+ %\XINT_expandableerror{<RET>, or I\xintUse{...}<RET>, or I\xintCTRLC<RET>}%
+ \xint_stop_atfirstofone{#5}%
+ }%
+}%
+%% \let\xintUse\xint_stop_atfirstofthree % defined in xint.sty
+\def\XINT_ifFlagRaised #1{%
+ \ifcsname XINT_#1Flag_ON\endcsname
+ \expandafter\xint_firstoftwo
+ \else
+ \expandafter\xint_secondoftwo
+ \fi}%
+\def\XINT_resetFlag #1%
+ {\expandafter\let\csname XINT_#1Flag_ON\endcsname\XINT_undefined}%
+\def\XINT_resetFlags {% WIP
+ \XINT_resetFlag{InvalidOperation}% also from DivisionUndefined
+ \XINT_resetFlag{DivisionByZero}%
+ \XINT_resetFlag{Underflow}% (\xintiiPow with negative exponent)
+ \XINT_resetFlag{Overflow}% not encountered so far in xint code 1.2l
+ % .. others ..
+}%
+\def\XINT_RaiseFlag #1{\expandafter\xint_gobble_i\csname XINT_#1Flag_ON\endcsname}%
+% \end{macrocode}
+% NOT IMPLEMENTED! WORK IN PROGRESS! (ALL SIGNALS TRAPPED, NO HANDLERS USED)
+% \begin{macrocode}
+\catcode`. 11
+\let\XINT_Clamped.handler\xint_firstofone % WIP
+\def\XINT_InvalidOperation.handler#1{_NaN}% WIP
+\def\XINT_ConversionSyntax.handler#1{_NaN}% WIP
+\def\XINT_DivisionByZero.handler#1{_SignedInfinity(#1)}% WIP
+\def\XINT_DivisionImpossible.handler#1{_NaN}% WIP
+\def\XINT_DivisionUndefined.handler#1{_NaN}% WIP
+\let\XINT_Inexact.handler\xint_firstofone % WIP
+\def\XINT_InvalidContext.handler#1{_NaN}% WIP
+\let\XINT_Rounded.handler\xint_firstofone % WIP
+\let\XINT_Subnormal.handler\xint_firstofone% WIP
+\def\XINT_Overflow.handler#1{_NaN}% WIP
+\def\XINT_Underflow.handler#1{_NaN}% WIP
+\catcode`. 12
+% \end{macrocode}
+% \subsection{Counts for holding needed constants}
+% \begin{macrocode}
+\ifdefined\m@ne\let\xint_c_mone\m@ne
+ \else\csname newcount\endcsname\xint_c_mone \xint_c_mone -1 \fi
+\ifdefined\xint_c_x^viii\else
+\csname newcount\endcsname\xint_c_x^viii \xint_c_x^viii 100000000
+\fi
+\ifdefined\xint_c_x^ix\else
+\csname newcount\endcsname\xint_c_x^ix \xint_c_x^ix 1000000000
+\fi
+\newcount\xint_c_x^viii_mone \xint_c_x^viii_mone 99999999
+\newcount\xint_c_xii_e_viii \xint_c_xii_e_viii 1200000000
+\newcount\xint_c_xi_e_viii_mone \xint_c_xi_e_viii_mone 1099999999
+% \end{macrocode}
+% \subsection*{Routines handling integers as lists of token digits}
+% \addcontentsline{toc}{subsection}{Routines handling integers as lists of token digits}
+% \lverb|&
+% Routines handling big integers which are lists of digit tokens with no
+% special additional structure.
+%
+% Some
+% routines do not accept non properly terminated inputs like "\the\numexpr1",
+% or "\the\mathcode`\-", others do.
+%
+% These routines or their sub-routines are mainly for internal usage.
+% |
+%
+% \subsection{\csh{XINT_cuz_small}}
+% \lverb|&
+% \XINT_cuz_small removes leading zeroes from the first eight digits. Expands
+% following \romannumeral0. At least one digit is produced.|
+% \begin{macrocode}
+\def\XINT_cuz_small#1{%
+\def\XINT_cuz_small ##1##2##3##4##5##6##7##8%
+{%
+ \expandafter#1\the\numexpr ##1##2##3##4##5##6##7##8\relax
+}}\XINT_cuz_small{ }%
+% \end{macrocode}
+% \subsection{\csh{xintNum}, \csh{xintiNum}}
+% \lverb|&
+% For example \xintNum {----+-+++---+----000000000000003}
+%
+% Very old routine got completely rewritten at 1.2l.
+%
+% New code uses \numexpr governed expansion and fixes some issues of former
+% version particularly regarding inputs of the \numexpr...\relax type without
+% \the or \number prefix, and/or possibly no terminating \relax.
+%
+% \xintiNum{\numexpr 1}\foo in earlier versions caused premature expansion of
+% \foo.
+%
+% \xintiNum{\the\numexpr 1} was ok, but a bit luckily so.
+%
+% Also, up to 1.2k inclusive, the macro fetched tokens eight by eight, and not
+% nine by nine as is done now. I have no idea why.
+%
+% \xintNum gets redefined by $xintfracnameimp.
+% |
+% \begin{macrocode}
+\def\xintiNum {\romannumeral0\xintinum }%
+\def\xintinum #1%
+{%
+ \expandafter\XINT_num_cleanup\the\numexpr\expandafter\XINT_num_loop
+ \romannumeral`&&@#1\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\Z
+}%
+\def\xintNum {\romannumeral0\xintnum }%
+\let\xintnum\xintinum
+\def\XINT_num #1%
+{%
+ \expandafter\XINT_num_cleanup\the\numexpr\XINT_num_loop
+ #1\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\Z
+}%
+\def\XINT_num_loop #1#2#3#4#5#6#7#8#9%
+{%
+ \xint_gob_til_xint: #9\XINT_num_end\xint:
+ #1#2#3#4#5#6#7#8#9%
+ \ifnum \numexpr #1#2#3#4#5#6#7#8#9+\xint_c_ = \xint_c_
+% \end{macrocode}
+% \lverb|&
+% means that so far only signs encountered, (if syntax is legal) then possibly
+% zeroes
+% or a terminated or not terminated \numexpr evaluating to zero
+% In that latter case a correct zero will be produced in the end.
+% |
+% \begin{macrocode}
+ \expandafter\XINT_num_loop
+ \else
+% \end{macrocode}
+% \lverb|&
+% non terminated \numexpr (with nine tokens total) are
+% safe as after \fi, there is then \xint:
+% |
+% \begin{macrocode}
+ \expandafter\relax
+ \fi
+}%
+\def\XINT_num_end\xint:#1\xint:{#1+\xint_c_\xint:}% empty input ok
+\def\XINT_num_cleanup #1\xint:#2\Z { #1}%
+% \end{macrocode}
+% \subsection{\csh{xintiiSgn}}
+% \lverb|&
+% 1.2l made \xintiiSgn robust against non terminated input.
+%
+% 1.2o deprecates here \xintSgn (it requires xintfrac.sty).
+% |
+% \begin{macrocode}
+\def\xintiiSgn {\romannumeral0\xintiisgn }%
+\def\xintiisgn #1%
+{%
+ \expandafter\XINT_sgn \romannumeral`&&@#1\xint:
+}%
+\def\XINT_sgn #1#2\xint:
+{%
+ \xint_UDzerominusfork
+ #1-{ 0}%
+ 0#1{-1}%
+ 0-{ 1}%
+ \krof
+}%
+\def\XINT_Sgn #1#2\xint:
+{%
+ \xint_UDzerominusfork
+ #1-{0}%
+ 0#1{-1}%
+ 0-{1}%
+ \krof
+}%
+\def\XINT_cntSgn #1#2\xint:
+{%
+ \xint_UDzerominusfork
+ #1-\xint_c_
+ 0#1\xint_c_mone
+ 0-\xint_c_i
+ \krof
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiOpp}}
+% \lverb|Attention, \xintiiOpp non robust against non terminated inputs.
+% Reason is I don't want to have to grab a delimiter at the end, as everything
+% happens "upfront".|
+% \begin{macrocode}
+\def\xintiiOpp {\romannumeral0\xintiiopp }%
+\def\xintiiopp #1%
+{%
+ \expandafter\XINT_opp \romannumeral`&&@#1%
+}%
+\def\XINT_Opp #1{\romannumeral0\XINT_opp #1}%
+\def\XINT_opp #1%
+{%
+ \xint_UDzerominusfork
+ #1-{ 0}% zero
+ 0#1{ }% negative
+ 0-{ -#1}% positive
+ \krof
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiAbs}}
+% \lverb|&
+% Attention \xintiiAbs non robust against non terminated input.
+%|
+% \begin{macrocode}
+\def\xintiiAbs {\romannumeral0\xintiiabs }%
+\def\xintiiabs #1%
+{%
+ \expandafter\XINT_abs \romannumeral`&&@#1%
+}%
+\def\XINT_abs #1%
+{%
+ \xint_UDsignfork
+ #1{ }%
+ -{ #1}%
+ \krof
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFDg}}
+% \lverb|&
+% FIRST DIGIT.
+%
+% 1.2l: \xintiiFDg made robust against non terminated input.
+%
+% 1.2o deprecates \xintiiFDg, gives to \xintFDg former meaning of \xintiiFDg.|
+% \begin{macrocode}
+\def\xintFDg {\romannumeral0\xintfdg }%
+\def\xintfdg #1{\expandafter\XINT_fdg \romannumeral`&&@#1\xint:\Z}%
+\def\XINT_FDg #1%
+ {\romannumeral0\expandafter\XINT_fdg\romannumeral`&&@\xintnum{#1}\xint:\Z }%
+\def\XINT_fdg #1#2#3\Z
+{%
+ \xint_UDzerominusfork
+ #1-{ 0}% zero
+ 0#1{ #2}% negative
+ 0-{ #1}% positive
+ \krof
+}%
+% \end{macrocode}
+% \subsection{\csh{xintLDg}}
+% \lverb|&
+% LAST DIGIT.
+%
+% Rewritten for 1.2i (2016/12/10). Surprisingly perhaps, it is faster than
+% \xintLastItem from xintkernel.sty despite the \numexpr operations.
+%
+% 1.2o deprecates \xintiiLDg, gives to \xintLDg former meaning of \xintiiLDg.
+%
+% Attention \xintLDg non robust against non terminated input.
+% |
+% \begin{macrocode}
+\def\xintLDg {\romannumeral0\xintldg }%
+\def\xintldg #1{\expandafter\XINT_ldg_fork\romannumeral`&&@#1%
+ \XINT_ldg_c{}{}{}{}{}{}{}{}\xint_bye\relax}%
+\def\XINT_ldg_fork #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_ldg
+ -{\XINT_ldg#1}%
+ \krof
+}%
+\def\XINT_ldg #1{%
+\def\XINT_ldg ##1##2##3##4##5##6##7##8##9%
+ {\expandafter#1%
+ \the\numexpr##9##8##7##6##5##4##3##2##1*\xint_c_+\XINT_ldg_a##9}%
+}\XINT_ldg{ }%
+\def\XINT_ldg_a#1#2{\XINT_ldg_cbye#2\XINT_ldg_d#1\XINT_ldg_c\XINT_ldg_b#2}%
+\def\XINT_ldg_b#1#2#3#4#5#6#7#8#9{#9#8#7#6#5#4#3#2#1*\xint_c_+\XINT_ldg_a#9}%
+\def\XINT_ldg_c #1#2\xint_bye{#1}%
+\def\XINT_ldg_cbye #1\XINT_ldg_c{}%
+\def\XINT_ldg_d#1#2\xint_bye{#1}%
+% \end{macrocode}
+%
+% \subsection{\csh{xintDouble}}
+% \lverb|Attention \xintDouble non robust against non terminated input.|
+% \begin{macrocode}
+\def\xintDouble {\romannumeral0\xintdouble}%
+\def\xintdouble #1{\expandafter\XINT_dbl_fork\romannumeral`&&@#1%
+ \xint_bye2345678\xint_bye*\xint_c_ii\relax}%
+\def\XINT_dbl_fork #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_dbl_neg
+ -\XINT_dbl
+ \krof #1%
+}%
+\def\XINT_dbl_neg-{\expandafter-\romannumeral0\XINT_dbl}%
+\def\XINT_dbl #1{%
+\def\XINT_dbl ##1##2##3##4##5##6##7##8%
+ {\expandafter#1\the\numexpr##1##2##3##4##5##6##7##8\XINT_dbl_a}%
+}\XINT_dbl{ }%
+\def\XINT_dbl_a #1#2#3#4#5#6#7#8%
+ {\expandafter\XINT_dbl_e\the\numexpr 1#1#2#3#4#5#6#7#8\XINT_dbl_a}%
+\def\XINT_dbl_e#1{*\xint_c_ii\if#13+\xint_c_i\fi\relax}%
+% \end{macrocode}
+% \subsection{\csh{xintHalf}}
+% \lverb|Attention \xintHalf non robust against non terminated input.|
+% \begin{macrocode}
+\def\xintHalf {\romannumeral0\xinthalf}%
+\def\xinthalf #1{\expandafter\XINT_half_fork\romannumeral`&&@#1%
+ \xint_bye\xint_Bye345678\xint_bye
+ *\xint_c_v+\xint_c_v)/\xint_c_x-\xint_c_i\relax}%
+\def\XINT_half_fork #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_half_neg
+ -\XINT_half
+ \krof #1%
+}%
+\def\XINT_half_neg-{\xintiiopp\XINT_half}%
+\def\XINT_half #1{%
+\def\XINT_half ##1##2##3##4##5##6##7##8%
+ {\expandafter#1\the\numexpr(##1##2##3##4##5##6##7##8\XINT_half_a}%
+}\XINT_half{ }%
+\def\XINT_half_a#1{\xint_Bye#1\xint_bye\XINT_half_b#1}%
+\def\XINT_half_b #1#2#3#4#5#6#7#8%
+ {\expandafter\XINT_half_e\the\numexpr(1#1#2#3#4#5#6#7#8\XINT_half_a}%
+\def\XINT_half_e#1{*\xint_c_v+#1-\xint_c_v)\relax}%
+% \end{macrocode}
+% \subsection{\csh{xintInc}}
+% \lverb|1.2i much delayed complete rewrite in 1.2 style.
+%
+% As we take 9 by 9 with the input save stack at 5000 this allows a bit less
+% than 9 times 2500 = 22500 digits on input.
+%
+% Attention \xintInc non robust against non terminated input.|
+% \begin{macrocode}
+\def\xintInc {\romannumeral0\xintinc}%
+\def\xintinc #1{\expandafter\XINT_inc_fork\romannumeral`&&@#1%
+ \xint_bye23456789\xint_bye+\xint_c_i\relax}%
+\def\XINT_inc_fork #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_inc_neg
+ -\XINT_inc
+ \krof #1%
+}%
+\def\XINT_inc_neg-#1\xint_bye#2\relax
+ {\xintiiopp\XINT_dec #1\XINT_dec_bye234567890\xint_bye}%
+\def\XINT_inc #1{%
+\def\XINT_inc ##1##2##3##4##5##6##7##8##9%
+ {\expandafter#1\the\numexpr##1##2##3##4##5##6##7##8##9\XINT_inc_a}%
+}\XINT_inc{ }%
+\def\XINT_inc_a #1#2#3#4#5#6#7#8#9%
+ {\expandafter\XINT_inc_e\the\numexpr 1#1#2#3#4#5#6#7#8#9\XINT_inc_a}%
+\def\XINT_inc_e#1{\if#12+\xint_c_i\fi\relax}%
+% \end{macrocode}
+% \subsection{\csh{xintDec}}
+% \lverb|1.2i much delayed complete rewrite in the 1.2 style. Things are a
+% bit more complicated than \xintInc because 2999999999 is too big for TeX.
+%
+% Attention \xintDec non robust against non terminated input.|
+% \begin{macrocode}
+\def\xintDec {\romannumeral0\xintdec}%
+\def\xintdec #1{\expandafter\XINT_dec_fork\romannumeral`&&@#1%
+ \XINT_dec_bye234567890\xint_bye}%
+\def\XINT_dec_fork #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_dec_neg
+ -\XINT_dec
+ \krof #1%
+}%
+\def\XINT_dec_neg-#1\XINT_dec_bye#2\xint_bye
+ {\expandafter-%
+ \romannumeral0\XINT_inc #1\xint_bye23456789\xint_bye+\xint_c_i\relax}%
+\def\XINT_dec #1{%
+\def\XINT_dec ##1##2##3##4##5##6##7##8##9%
+ {\expandafter#1\the\numexpr##1##2##3##4##5##6##7##8##9\XINT_dec_a}%
+}\XINT_dec{ }%
+\def\XINT_dec_a #1#2#3#4#5#6#7#8#9%
+ {\expandafter\XINT_dec_e\the\numexpr 1#1#2#3#4#5#6#7#8#9\XINT_dec_a}%
+\def\XINT_dec_bye #1\XINT_dec_a#2#3\xint_bye
+ {\if#20-\xint_c_ii\relax+\else-\fi\xint_c_i\relax}%
+\def\XINT_dec_e#1{\unless\if#11\xint_dothis{-\xint_c_i#1}\fi\xint_orthat\relax}%
+% \end{macrocode}
+% \subsection{\csh{xintDSL}}
+% \lverb|DECIMAL SHIFT LEFT (=MULTIPLICATION PAR 10). Rewritten for 1.2i.
+% This was very old code... I never came back to it, but I should have
+% rewritten it long time ago.
+%
+% Attention \xintDSL non robust against non terminated input.|
+% \begin{macrocode}
+\def\xintDSL {\romannumeral0\xintdsl }%
+\def\xintdsl #1{\expandafter\XINT_dsl\romannumeral`&&@#10}%
+\def\XINT_dsl#1{%
+\def\XINT_dsl ##1{\xint_gob_til_zero ##1\xint_dsl_zero 0#1##1}%
+}\XINT_dsl{ }%
+\def\xint_dsl_zero 0 0{ }%
+% \end{macrocode}
+% \subsection{\csh{xintDSR}}
+% \lverb|Decimal shift right, truncates towards zero. Rewritten for 1.2i.
+% Limited to 22483 digits on input.
+%
+% Attention \xintDSR non robust against non terminated input.|
+% \begin{macrocode}
+\def\xintDSR{\romannumeral0\xintdsr}%
+\def\xintdsr #1{\expandafter\XINT_dsr_fork\romannumeral`&&@#1%
+ \xint_bye\xint_Bye3456789\xint_bye+\xint_c_v)/\xint_c_x-\xint_c_i\relax}%
+\def\XINT_dsr_fork #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_dsr_neg
+ -\XINT_dsr
+ \krof #1%
+}%
+\def\XINT_dsr_neg-{\xintiiopp\XINT_dsr}%
+\def\XINT_dsr #1{%
+\def\XINT_dsr ##1##2##3##4##5##6##7##8##9%
+ {\expandafter#1\the\numexpr(##1##2##3##4##5##6##7##8##9\XINT_dsr_a}%
+}\XINT_dsr{ }%
+\def\XINT_dsr_a#1{\xint_Bye#1\xint_bye\XINT_dsr_b#1}%
+\def\XINT_dsr_b #1#2#3#4#5#6#7#8#9%
+ {\expandafter\XINT_dsr_e\the\numexpr(1#1#2#3#4#5#6#7#8#9\XINT_dsr_a}%
+\def\XINT_dsr_e #1{)\relax}%
+% \end{macrocode}
+% \subsection{\csh{xintDSRr}}
+% \lverb|New with 1.2i. Decimal shift right, rounds away from zero; done in
+% the 1.2 spirit (with much delay, sorry). Used by \xintRound, \xintDivRound.
+%
+% This is about the first time I am happy that the division in \numexpr
+% rounds!
+%
+% Attention \xintDSRr non robust against non terminated input.|
+% \begin{macrocode}
+\def\xintDSRr{\romannumeral0\xintdsrr}%
+\def\xintdsrr #1{\expandafter\XINT_dsrr_fork\romannumeral`&&@#1%
+ \xint_bye\xint_Bye3456789\xint_bye/\xint_c_x\relax}%
+\def\XINT_dsrr_fork #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_dsrr_neg
+ -\XINT_dsrr
+ \krof #1%
+}%
+\def\XINT_dsrr_neg-{\xintiiopp\XINT_dsrr}%
+\def\XINT_dsrr #1{%
+\def\XINT_dsrr ##1##2##3##4##5##6##7##8##9%
+ {\expandafter#1\the\numexpr##1##2##3##4##5##6##7##8##9\XINT_dsrr_a}%
+}\XINT_dsrr{ }%
+\def\XINT_dsrr_a#1{\xint_Bye#1\xint_bye\XINT_dsrr_b#1}%
+\def\XINT_dsrr_b #1#2#3#4#5#6#7#8#9%
+ {\expandafter\XINT_dsrr_e\the\numexpr1#1#2#3#4#5#6#7#8#9\XINT_dsrr_a}%
+\let\XINT_dsrr_e\XINT_inc_e
+% \end{macrocode}
+% \subsection*{Blocks of eight digits}
+% \addcontentsline{toc}{subsection}{Blocks of eight digits}
+% \lverb|The lingua of release 1.2.|
+%
+% \subsection{\csh{XINT_cuz}}
+% \lverb|This (launched by \romannumeral0) iterately removes all leading
+% zeroes from a sequence of 8N digits ended by \R.
+%
+% Rewritten for 1.2l, now uses \numexpr governed expansion and \ifnum test
+% rather than delimited gobbling macros.
+%
+% Note 2015/11/28: with only four digits the gob_til_fourzeroes had proved
+% in some old testing faster than \ifnum test. But with eight digits, the
+% execution times are much closer, as I tested back then.
+% |
+% \begin{macrocode}
+\def\XINT_cuz #1{%
+\def\XINT_cuz {\expandafter#1\the\numexpr\XINT_cuz_loop}%
+}\XINT_cuz{ }%
+\def\XINT_cuz_loop #1#2#3#4#5#6#7#8#9%
+{%
+ #1#2#3#4#5#6#7#8%
+ \xint_gob_til_R #9\XINT_cuz_hitend\R
+ \ifnum #1#2#3#4#5#6#7#8>\xint_c_
+ \expandafter\XINT_cuz_cleantoend
+ \else\expandafter\XINT_cuz_loop
+ \fi #9%
+}%
+\def\XINT_cuz_hitend\R #1\R{\relax}%
+\def\XINT_cuz_cleantoend #1\R{\relax #1}%
+% \end{macrocode}
+% \subsection{\csh{XINT_cuz_byviii}}
+% \lverb|This removes eight by eight leading zeroes from a sequence of 8N digits
+% ended by \R. Thus, we still have 8N digits on output. Expansion started by
+% \romannumeral0 |
+% \begin{macrocode}
+\def\XINT_cuz_byviii #1#2#3#4#5#6#7#8#9%
+{%
+ \xint_gob_til_R #9\XINT_cuz_byviii_e \R
+ \xint_gob_til_eightzeroes #1#2#3#4#5#6#7#8\XINT_cuz_byviii_z 00000000%
+ \XINT_cuz_byviii_done #1#2#3#4#5#6#7#8#9%
+}%
+\def\XINT_cuz_byviii_z 00000000\XINT_cuz_byviii_done 00000000{\XINT_cuz_byviii}%
+\def\XINT_cuz_byviii_done #1\R { #1}%
+\def\XINT_cuz_byviii_e\R #1\XINT_cuz_byviii_done #2\R{ #2}%
+% \end{macrocode}
+% \subsection{\csh{XINT_unsep_loop}}
+%
+% \lverb|This is used as
+%( \the\numexpr0\XINT_unsep_loop (blocks of 1<8digits>!)%
+%: \xint_bye!2!3!4!5!6!7!8!9!\xint_bye\xint_c_i\relax
+%)
+% It removes the 1's and !'s, and outputs the 8N digits with a 0 token as
+% as prefix which will have to be cleaned out by caller.
+%
+% Actually it does not matter whether the blocks contain really 8 digits, all
+% that matters is that they have 1 as first digit (and at most 9 digits after
+% that to obey the TeX-\numexpr bound).
+%
+% Done at 1.2l for usage by other macros. The similar code in earlier releases
+% was strangely in O(N^2) style, apparently to avoid some memory constraints.
+% But these memory constraints related to \numexpr chaining seems to be in
+% many places in xint code base. The 1.2l version is written in the 1.2i style
+% of \xintInc etc... and is compatible with some 1! block without digits
+% among the treated blocks, they will disappear.|
+% \begin{macrocode}
+\def\XINT_unsep_loop #1!#2!#3!#4!#5!#6!#7!#8!#9!%
+{%
+ \expandafter\XINT_unsep_clean
+ \the\numexpr #1\expandafter\XINT_unsep_clean
+ \the\numexpr #2\expandafter\XINT_unsep_clean
+ \the\numexpr #3\expandafter\XINT_unsep_clean
+ \the\numexpr #4\expandafter\XINT_unsep_clean
+ \the\numexpr #5\expandafter\XINT_unsep_clean
+ \the\numexpr #6\expandafter\XINT_unsep_clean
+ \the\numexpr #7\expandafter\XINT_unsep_clean
+ \the\numexpr #8\expandafter\XINT_unsep_clean
+ \the\numexpr #9\XINT_unsep_loop
+}%
+\def\XINT_unsep_clean 1{\relax}%
+% \end{macrocode}
+% \subsection{\csh{XINT_unsep_cuzsmall}}
+%
+% \lverb|This is used as
+%( \romannumeral0\XINT_unsep_cuzsmall (blocks of 1<8d>!)%
+%: \xint_bye!2!3!4!5!6!7!8!9!\xint_bye\xint_c_i\relax
+%)
+% It removes the 1's and !'s, and removes the leading zeroes *of
+% the first block*.
+%
+% Redone for 1.2l: the 1.2 variant was strangely in O(N^2) style.|
+% \begin{macrocode}
+\def\XINT_unsep_cuzsmall
+{%
+ \expandafter\XINT_unsep_cuzsmall_x\the\numexpr0\XINT_unsep_loop
+}%
+\def\XINT_unsep_cuzsmall_x #1{%
+\def\XINT_unsep_cuzsmall_x 0##1##2##3##4##5##6##7##8%
+{%
+ \expandafter#1\the\numexpr ##1##2##3##4##5##6##7##8\relax
+}}\XINT_unsep_cuzsmall_x{ }%
+% \end{macrocode}
+% \subsection{\csh{XINT_div_unsepQ}}
+%
+% \lverb|This is used by division to remove separators from the produced
+% quotient. The quotient is produced in the correct order. The routine will
+% also remove leading zeroes. An extra initial block of 8 zeroes is possible
+% and thus if present must be removed. Then the next eight digits must be
+% cleaned of leading zeroes. Attention that there might be a single
+% block of 8 zeroes. Expansion launched by \romannumeral0.
+%
+% Rewritten for 1.2l in 1.2i style.|
+% \begin{macrocode}
+\def\XINT_div_unsepQ_delim {\xint_bye!2!3!4!5!6!7!8!9!\xint_bye\xint_c_i\relax\Z}%
+\def\XINT_div_unsepQ
+{%
+ \expandafter\XINT_div_unsepQ_x\the\numexpr0\XINT_unsep_loop
+}%
+\def\XINT_div_unsepQ_x #1{%
+\def\XINT_div_unsepQ_x 0##1##2##3##4##5##6##7##8##9%
+{%
+ \xint_gob_til_Z ##9\XINT_div_unsepQ_one\Z
+ \xint_gob_til_eightzeroes ##1##2##3##4##5##6##7##8\XINT_div_unsepQ_y 00000000%
+ \expandafter#1\the\numexpr ##1##2##3##4##5##6##7##8\relax ##9%
+}}\XINT_div_unsepQ_x{ }%
+\def\XINT_div_unsepQ_y #1{%
+\def\XINT_div_unsepQ_y ##1\relax ##2##3##4##5##6##7##8##9%
+{%
+ \expandafter#1\the\numexpr ##2##3##4##5##6##7##8##9\relax
+}}\XINT_div_unsepQ_y{ }%
+\def\XINT_div_unsepQ_one#1\expandafter{\expandafter}%
+% \end{macrocode}
+% \subsection{\csh{XINT_div_unsepR}}
+%
+% \lverb|This is used by division to remove separators from the produced
+% remainder. The remainder is here in correct order. It must be cleaned of
+% leading zeroes, possibly all the way.
+%
+% Also rewritten for 1.2l, the 1.2 version was O(N^2) style.
+%
+% Terminator \xint_bye!2!3!4!5!6!7!8!9!\xint_bye\xint_c_i\relax\R
+%
+% We have a need for something like \R because it is not guaranteed the thing
+% is not actually zero.|
+% \begin{macrocode}
+\def\XINT_div_unsepR
+{%
+ \expandafter\XINT_div_unsepR_x\the\numexpr0\XINT_unsep_loop
+}%
+\def\XINT_div_unsepR_x#1{%
+\def\XINT_div_unsepR_x 0{\expandafter#1\the\numexpr\XINT_cuz_loop}%
+}\XINT_div_unsepR_x{ }%
+% \end{macrocode}
+% \subsection{\csh{XINT_zeroes_forviii}}
+%
+% \lverb|&
+%( \romannumeral0\XINT_zeroes_forviii #1\R\R\R\R\R\R\R\R{10}0000001\W
+%)
+% produces a string of k 0's such that k+length(#1) is smallest bigger multiple
+% of eight.|
+% \begin{macrocode}
+\def\XINT_zeroes_forviii #1#2#3#4#5#6#7#8%
+{%
+ \xint_gob_til_R #8\XINT_zeroes_forviii_end\R\XINT_zeroes_forviii
+}%
+\def\XINT_zeroes_forviii_end#1{%
+\def\XINT_zeroes_forviii_end\R\XINT_zeroes_forviii ##1##2##3##4##5##6##7##8##9\W
+{%
+ \expandafter#1\xint_gob_til_one ##2##3##4##5##6##7##8%
+}}\XINT_zeroes_forviii_end{ }%
+% \end{macrocode}
+% \subsection{\csh{XINT_sepbyviii_Z}}
+%
+% \lverb|This is used as
+%( \the\numexpr\XINT_sepbyviii_Z <8Ndigits>\XINT_sepbyviii_Z_end 2345678\relax
+%)
+% It produces 1<8d>!...1<8d>!1;!
+%
+% Prior to 1.2l it used \Z as terminator not the semi-colon (hence the name).
+% The switch to ; was done at a time I thought perhaps I would use an internal
+% format maintaining such 8 digits blocks, and this has to be compatible with
+% the \csname...\endcsname encapsulation in \xintexpr parsers.|
+% \begin{macrocode}
+\def\XINT_sepbyviii_Z #1#2#3#4#5#6#7#8%
+{%
+ 1#1#2#3#4#5#6#7#8\expandafter!\the\numexpr\XINT_sepbyviii_Z
+}%
+\def\XINT_sepbyviii_Z_end #1\relax {;!}%
+% \end{macrocode}
+% \subsection{\csh{XINT_sepbyviii_andcount}}
+%
+% \lverb|This is used as
+%( \the\numexpr\XINT_sepbyviii_andcount <8Ndigits>$%
+%: \XINT_sepbyviii_end 2345678\relax
+%: \xint_c_vii!\xint_c_vi!\xint_c_v!\xint_c_iv!$%
+%: \xint_c_iii!\xint_c_ii!\xint_c_i!\xint_c_\W
+%)
+% It will produce
+%( 1<8d>!1<8d>!....1<8d>!1\xint:<count of blocks>\xint:
+%)
+% Used by
+% \XINT_div_prepare_g for \XINT_div_prepare_h, and also by \xintiiCmp.|
+% \begin{macrocode}
+\def\XINT_sepbyviii_andcount
+{%
+ \expandafter\XINT_sepbyviii_andcount_a\the\numexpr\XINT_sepbyviii
+}%
+\def\XINT_sepbyviii #1#2#3#4#5#6#7#8%
+{%
+ 1#1#2#3#4#5#6#7#8\expandafter!\the\numexpr\XINT_sepbyviii
+}%
+\def\XINT_sepbyviii_end #1\relax {\relax\XINT_sepbyviii_andcount_end!}%
+\def\XINT_sepbyviii_andcount_a {\XINT_sepbyviii_andcount_b \xint_c_\xint:}%
+\def\XINT_sepbyviii_andcount_b #1\xint:#2!#3!#4!#5!#6!#7!#8!#9!%
+{%
+ #2\expandafter!\the\numexpr#3\expandafter!\the\numexpr#4\expandafter
+ !\the\numexpr#5\expandafter!\the\numexpr#6\expandafter!\the\numexpr
+ #7\expandafter!\the\numexpr#8\expandafter!\the\numexpr#9\expandafter!\the\numexpr
+ \expandafter\XINT_sepbyviii_andcount_b\the\numexpr #1+\xint_c_viii\xint:%
+}%
+\def\XINT_sepbyviii_andcount_end #1\XINT_sepbyviii_andcount_b\the\numexpr
+ #2+\xint_c_viii\xint:#3#4\W {\expandafter\xint:\the\numexpr #2+#3\xint:}%
+% \end{macrocode}
+% \subsection{\csh{XINT_rsepbyviii}}
+%
+% \lverb|This is used as
+%( \the\numexpr1\XINT_rsepbyviii <8Ndigits>$%
+%: \XINT_rsepbyviii_end_A 2345678$%
+%: \XINT_rsepbyviii_end_B 2345678\relax UV$%
+%)
+% and will produce
+%( 1<8digits>!1<8digits>\xint:1<8digits>!...
+%)
+% where the original
+% digits are organized by eight, and the order inside successive pairs of
+% blocks separated by \xint: has been reversed. Output ends either in
+% 1<8d>!1<8d>\xint:1U\xint: (even) or 1<8d>!1<8d>\xint:1V!1<8d>\xint: (odd)
+%
+% The U an V should be \numexpr1 stoppers (or will expand and be ended by !).
+% This macro is currently (1.2..1.2l) exclusively used in combination with
+% \XINT_sepandrev_andcount or \XINT_sepandrev.
+% |
+% \begin{macrocode}
+\def\XINT_rsepbyviii #1#2#3#4#5#6#7#8%
+{%
+ \XINT_rsepbyviii_b {#1#2#3#4#5#6#7#8}%
+}%
+\def\XINT_rsepbyviii_b #1#2#3#4#5#6#7#8#9%
+{%
+ #2#3#4#5#6#7#8#9\expandafter!\the\numexpr
+ 1#1\expandafter\xint:\the\numexpr 1\XINT_rsepbyviii
+}%
+\def\XINT_rsepbyviii_end_B #1\relax #2#3{#2\xint:}%
+\def\XINT_rsepbyviii_end_A #11#2\expandafter #3\relax #4#5{#5!1#2\xint:}%
+% \end{macrocode}
+% \subsection{\csh{XINT_sepandrev}}
+% \lverb|This is used typically as
+%( \romannumeral0\XINT_sepandrev <8Ndigits>$%
+%: \XINT_rsepbyviii_end_A 2345678$%
+%: \XINT_rsepbyviii_end_B 2345678\relax UV$%
+%: \R\xint:\R\xint:\R\xint:\R\xint:\R\xint:\R\xint:\R\xint:\R\xint:\W
+%)
+% and will produce
+%( 1<8digits>!1<8digits>!1<8digits>!...
+%)
+% where the blocks have
+% been globally reversed. The UV here are only place holders (must be \numexpr1
+% stoppers) to share same
+% syntax as \XINT_sepandrev_andcount, they are gobbled (#2 in \XINT_sepandrev_done).|
+% \begin{macrocode}
+\def\XINT_sepandrev
+{%
+ \expandafter\XINT_sepandrev_a\the\numexpr 1\XINT_rsepbyviii
+}%
+\def\XINT_sepandrev_a {\XINT_sepandrev_b {}}%
+\def\XINT_sepandrev_b #1#2\xint:#3\xint:#4\xint:#5\xint:#6\xint:#7\xint:#8\xint:#9\xint:%
+{%
+ \xint_gob_til_R #9\XINT_sepandrev_end\R
+ \XINT_sepandrev_b {#9!#8!#7!#6!#5!#4!#3!#2!#1}%
+}%
+\def\XINT_sepandrev_end\R\XINT_sepandrev_b #1#2\W {\XINT_sepandrev_done #1}%
+\def\XINT_sepandrev_done #11#2!{ }%
+% \end{macrocode}
+% \subsection{\csh{XINT_sepandrev_andcount}}
+% \lverb|This is used typically as
+%( \romannumeral0\XINT_sepandrev_andcount <8Ndigits>$%
+%: \XINT_rsepbyviii_end_A 2345678$%
+%: \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_i
+%: \R\xint:\xint_c_xii \R\xint:\xint_c_x \R\xint:\xint_c_viii \R\xint:\xint_c_vi
+%: \R\xint:\xint_c_iv \R\xint:\xint_c_ii \R\xint:\xint_c_\W
+%)
+% and will produce
+%( <length>.1<8digits>!1<8digits>!1<8digits>!...
+%)
+% where the
+% blocks have been globally reversed and <length> is the number of blocks.|
+% \begin{macrocode}
+\def\XINT_sepandrev_andcount
+{%
+ \expandafter\XINT_sepandrev_andcount_a\the\numexpr 1\XINT_rsepbyviii
+}%
+\def\XINT_sepandrev_andcount_a {\XINT_sepandrev_andcount_b 0!{}}%
+\def\XINT_sepandrev_andcount_b #1!#2#3\xint:#4\xint:#5\xint:#6\xint:#7\xint:#8\xint:#9\xint:%
+{%
+ \xint_gob_til_R #9\XINT_sepandrev_andcount_end\R
+ \expandafter\XINT_sepandrev_andcount_b \the\numexpr #1+\xint_c_i!%
+ {#9!#8!#7!#6!#5!#4!#3!#2}%
+}%
+\def\XINT_sepandrev_andcount_end\R
+ \expandafter\XINT_sepandrev_andcount_b\the\numexpr #1+\xint_c_i!#2#3#4\W
+{\expandafter\XINT_sepandrev_andcount_done\the\numexpr #3+\xint_c_xiv*#1!#2}%
+\def\XINT_sepandrev_andcount_done#1{%
+\def\XINT_sepandrev_andcount_done##1!##21##3!{\expandafter#1\the\numexpr##1-##3\xint:}%
+}\XINT_sepandrev_andcount_done{ }%
+% \end{macrocode}
+% \subsection{\csh{XINT_rev_nounsep}}
+% \lverb|This is used as
+%( \romannumeral0\XINT_rev_nounsep {}<blocks 1<8d>!>\R!\R!\R!\R!\R!\R!\R!\R!\W
+%)
+% It reverses the blocks, keeping the 1's and ! separators. Used multiple
+% times in the division algorithm. The inserted {} here is not optional.|
+% \begin{macrocode}
+\def\XINT_rev_nounsep #1#2!#3!#4!#5!#6!#7!#8!#9!%
+{%
+ \xint_gob_til_R #9\XINT_rev_nounsep_end\R
+ \XINT_rev_nounsep {#9!#8!#7!#6!#5!#4!#3!#2!#1}%
+}%
+\def\XINT_rev_nounsep_end\R\XINT_rev_nounsep #1#2\W {\XINT_rev_nounsep_done #1}%
+\def\XINT_rev_nounsep_done #11{ 1}%
+% \end{macrocode}
+% \subsection{\csh{XINT_unrevbyviii}}
+% \lverb|Used as \romannumeral0\XINT_unrevbyviii 1<8d>!....1<8d>! terminated
+% by
+%( 1;!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
+%)
+% The \romannumeral in unrevbyviii_a is for special effects (expand some token
+% which was put as 1<token>! at the end of the original blocks). This
+% mechanism is used by 1.2 subtraction (still true for 1.2l).|
+% \begin{macrocode}
+\def\XINT_unrevbyviii #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!%
+{%
+ \xint_gob_til_R #9\XINT_unrevbyviii_a\R
+ \XINT_unrevbyviii {#9#8#7#6#5#4#3#2#1}%
+}%
+\def\XINT_unrevbyviii_a#1{%
+\def\XINT_unrevbyviii_a\R\XINT_unrevbyviii ##1##2\W
+ {\expandafter#1\romannumeral`&&@\xint_gob_til_sc ##1}%
+}\XINT_unrevbyviii_a{ }%
+% \end{macrocode}
+% \lverb|Can work with shorter ending pattern: 1;!1\R!1\R!1\R!1\R!1\R!1\R!\W
+% but the longer one of unrevbyviii is ok here too. Used currently (1.2) only
+% by addition, now (1.2c) with long ending pattern. Does the final clean up of
+% leading zeroes contrarily to general \XINT_unrevbyviii.|
+% \begin{macrocode}
+\def\XINT_smallunrevbyviii 1#1!1#2!1#3!1#4!1#5!1#6!1#7!1#8!#9\W%
+{%
+ \expandafter\XINT_cuz_small\xint_gob_til_sc #8#7#6#5#4#3#2#1%
+}%
+% \end{macrocode}
+% \subsection*{Core arithmetic}
+% \addcontentsline{toc}{subsection}{Core arithmetic}
+% \lverb|The four operations have been rewritten entirely for release 1.2.
+% The new routines works with separated blocks of eight digits. They all measure
+% first the lengths of the arguments, even addition and subtraction (this was
+% not the case with xintcore.sty 1.1 or earlier.)
+%
+% The technique of chaining \the\numexpr induces a limitation on the
+% maximal size depending on the size of the input save stack and the maximum
+% expansion depth. For the current (TL2015) settings (5000, resp. 10000), the
+% induced limit for addition of numbers is at 19968 and for multiplication
+% it is observed to be 19959 (valid as of 2015/10/07).
+%
+% Side remark: I tested that \the\numexpr was more efficient than \number. But
+% it reduced the allowable numbers for addition from 19976 digits to 19968
+% digits.|
+%
+% \subsection{\csh{xintiiAdd}}
+% \lverb|1.2l: \xintiiAdd made robust against non terminated input.|
+% \begin{macrocode}
+\def\xintiiAdd {\romannumeral0\xintiiadd }%
+\def\xintiiadd #1{\expandafter\XINT_iiadd\romannumeral`&&@#1\xint:}%
+\def\XINT_iiadd #1#2\xint:#3%
+{%
+ \expandafter\XINT_add_nfork\expandafter#1\romannumeral`&&@#3\xint:#2\xint:
+}%
+\def\XINT_iadd #1#2\xint:#3%
+{%
+ \expandafter\XINT_add_nfork\expandafter
+ #1\romannumeral0\xintnum{#3}\xint:#2\xint:
+}%
+\def\XINT_add_fork #1#2\xint:#3\xint:{\XINT_add_nfork #1#3\xint:#2\xint:}%
+\def\XINT_add_nfork #1#2%
+{%
+ \xint_UDzerofork
+ #1\XINT_add_firstiszero
+ #2\XINT_add_secondiszero
+ 0{}%
+ \krof
+ \xint_UDsignsfork
+ #1#2\XINT_add_minusminus
+ #1-\XINT_add_minusplus
+ #2-\XINT_add_plusminus
+ --\XINT_add_plusplus
+ \krof #1#2%
+}%
+\def\XINT_add_firstiszero #1\krof 0#2#3\xint:#4\xint:{ #2#3}%
+\def\XINT_add_secondiszero #1\krof #20#3\xint:#4\xint:{ #2#4}%
+\def\XINT_add_minusminus #1#2%
+ {\expandafter-\romannumeral0\XINT_add_pp_a {}{}}%
+\def\XINT_add_minusplus #1#2{\XINT_sub_mm_a {}#2}%
+\def\XINT_add_plusminus #1#2%
+ {\expandafter\XINT_opp\romannumeral0\XINT_sub_mm_a #1{}}%
+\def\XINT_add_pp_a #1#2#3\xint:
+{%
+ \expandafter\XINT_add_pp_b
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #2#3\R\R\R\R\R\R\R\R{10}0000001\W
+ #2#3\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_i
+ \R\xint:\xint_c_xii \R\xint:\xint_c_x \R\xint:\xint_c_viii \R\xint:\xint_c_vi
+ \R\xint:\xint_c_iv \R\xint:\xint_c_ii \R\xint:\xint_c_\W
+ \X #1%
+}%
+\let\XINT_add_plusplus \XINT_add_pp_a
+% \end{macrocode}
+% \begin{macrocode}
+\def\XINT_add_pp_b #1\xint:#2\X #3\xint:
+{%
+ \expandafter\XINT_add_checklengths
+ \the\numexpr #1\expandafter\xint:%
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #3\R\R\R\R\R\R\R\R{10}0000001\W
+ #3\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_i
+ \R\xint:\xint_c_xii \R\xint:\xint_c_x \R\xint:\xint_c_viii \R\xint:\xint_c_vi
+ \R\xint:\xint_c_iv \R\xint:\xint_c_ii \R\xint:\xint_c_\W
+ 1;!1;!1;!1;!\W #21;!1;!1;!1;!\W
+ 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
+}%
+% \end{macrocode}
+% \lverb|I keep #1.#2. to check if at most 6 + 6 base 10^8 digits which can be
+% treated faster for final reverse. But is this overhead at all useful ? |
+% \begin{macrocode}
+\def\XINT_add_checklengths #1\xint:#2\xint:%
+{%
+ \ifnum #2>#1
+ \expandafter\XINT_add_exchange
+ \else
+ \expandafter\XINT_add_A
+ \fi
+ #1\xint:#2\xint:%
+}%
+\def\XINT_add_exchange #1\xint:#2\xint:#3\W #4\W
+{%
+ \XINT_add_A #2\xint:#1\xint:#4\W #3\W
+}%
+\def\XINT_add_A #1\xint:#2\xint:%
+{%
+ \ifnum #1>\xint_c_vi
+ \expandafter\XINT_add_aa
+ \else \expandafter\XINT_add_aa_small
+ \fi
+}%
+\def\XINT_add_aa {\expandafter\XINT_add_out\the\numexpr\XINT_add_a \xint_c_ii}%
+\def\XINT_add_out{\expandafter\XINT_cuz_small\romannumeral0\XINT_unrevbyviii {}}%
+\def\XINT_add_aa_small
+ {\expandafter\XINT_smallunrevbyviii\the\numexpr\XINT_add_a \xint_c_ii}%
+% \end{macrocode}
+% \lverb|2 as first token of #1 stands for "no carry", 3 will mean a carry (we
+% are adding 1<8digits> to 1<8digits>.) Version 1.2c has terminators of the
+% shape 1;!, replacing the \Z! used in 1.2.
+%
+% Call: \the\numexpr\XINT_add_a 2#11;!1;!1;!1;!\W #21;!1;!1;!1;!\W
+% where #1 and #2 are blocks of 1<8d>!, and #1 is at most as long as #2. This
+% last requirement is a bit annoying (if one wants to do recursive algorithms
+% but not have to check lengths), and I will probably remove it at some point.
+%
+% Output: blocks of 1<8d>! representing the addition, (least significant
+% first), and a final 1;!. In recursive algotithm this 1;! terminator can
+% thus conveniently be reused as part of input terminator (up to the length
+% problem).
+%
+%|
+% \begin{macrocode}
+\def\XINT_add_a #1!#2!#3!#4!#5\W
+ #6!#7!#8!#9!%
+{%
+ \XINT_add_b
+ #1!#6!#2!#7!#3!#8!#4!#9!%
+ #5\W
+}%
+\def\XINT_add_b #11#2#3!#4!%
+{%
+ \xint_gob_til_sc #2\XINT_add_bi ;%
+ \expandafter\XINT_add_c\the\numexpr#1+1#2#3+#4-\xint_c_ii\xint:%
+}%
+\def\XINT_add_bi;\expandafter\XINT_add_c
+ \the\numexpr#1+#2+#3-\xint_c_ii\xint:#4!#5!#6!#7!#8!#9!\W
+{%
+ \XINT_add_k #1#3!#5!#7!#9!%
+}%
+\def\XINT_add_c #1#2\xint:%
+{%
+ 1#2\expandafter!\the\numexpr\XINT_add_d #1%
+}%
+\def\XINT_add_d #11#2#3!#4!%
+{%
+ \xint_gob_til_sc #2\XINT_add_di ;%
+ \expandafter\XINT_add_e\the\numexpr#1+1#2#3+#4-\xint_c_ii\xint:%
+}%
+\def\XINT_add_di;\expandafter\XINT_add_e
+ \the\numexpr#1+#2+#3-\xint_c_ii\xint:#4!#5!#6!#7!#8\W
+{%
+ \XINT_add_k #1#3!#5!#7!%
+}%
+\def\XINT_add_e #1#2\xint:%
+{%
+ 1#2\expandafter!\the\numexpr\XINT_add_f #1%
+}%
+\def\XINT_add_f #11#2#3!#4!%
+{%
+ \xint_gob_til_sc #2\XINT_add_fi ;%
+ \expandafter\XINT_add_g\the\numexpr#1+1#2#3+#4-\xint_c_ii\xint:%
+}%
+\def\XINT_add_fi;\expandafter\XINT_add_g
+ \the\numexpr#1+#2+#3-\xint_c_ii\xint:#4!#5!#6\W
+{%
+ \XINT_add_k #1#3!#5!%
+}%
+\def\XINT_add_g #1#2\xint:%
+{%
+ 1#2\expandafter!\the\numexpr\XINT_add_h #1%
+}%
+\def\XINT_add_h #11#2#3!#4!%
+{%
+ \xint_gob_til_sc #2\XINT_add_hi ;%
+ \expandafter\XINT_add_i\the\numexpr#1+1#2#3+#4-\xint_c_ii\xint:%
+}%
+\def\XINT_add_hi;%
+ \expandafter\XINT_add_i\the\numexpr#1+#2+#3-\xint_c_ii\xint:#4\W
+{%
+ \XINT_add_k #1#3!%
+}%
+\def\XINT_add_i #1#2\xint:%
+{%
+ 1#2\expandafter!\the\numexpr\XINT_add_a #1%
+}%
+% \end{macrocode}
+% \begin{macrocode}
+\def\XINT_add_k #1{\if #12\expandafter\XINT_add_ke\else\expandafter\XINT_add_l \fi}%
+\def\XINT_add_ke #11;#2\W {\XINT_add_kf #11;!}%
+\def\XINT_add_kf 1{1\relax }%
+\def\XINT_add_l 1#1#2{\xint_gob_til_sc #1\XINT_add_lf ;\XINT_add_m 1#1#2}%
+\def\XINT_add_lf #1\W {1\relax 00000001!1;!}%
+\def\XINT_add_m #1!{\expandafter\XINT_add_n\the\numexpr\xint_c_i+#1\xint:}%
+\def\XINT_add_n #1#2\xint:{1#2\expandafter!\the\numexpr\XINT_add_o #1}%
+% \end{macrocode}
+% \lverb|Here 2 stands for "carry", and 1 for "no carry" (we have been adding
+% 1 to 1<8digits>.)|
+% \begin{macrocode}
+\def\XINT_add_o #1{\if #12\expandafter\XINT_add_l\else\expandafter\XINT_add_ke \fi}%
+% \end{macrocode}
+% \subsection{\csh{xintiiCmp}}
+% \lverb|Moved from xint.sty to xintcore.sty and rewritten for 1.2l.
+%
+% 1.2l's \xintiiCmp is robust against non terminated input.
+%
+% 1.2o deprecates \xintCmp, with xintfrac loaded it will get overwritten anyhow.
+%|
+% \begin{macrocode}
+\def\xintiiCmp {\romannumeral0\xintiicmp }%
+\def\xintiicmp #1{\expandafter\XINT_iicmp\romannumeral`&&@#1\xint:}%
+\def\XINT_iicmp #1#2\xint:#3%
+{%
+ \expandafter\XINT_cmp_nfork\expandafter #1\romannumeral`&&@#3\xint:#2\xint:
+}%
+\def\XINT_icmp #1#2\xint:#3%
+{%
+ \expandafter\XINT_cmp_nfork\expandafter #1\romannumeral0\xintnum{#3}\xint:#2\xint:
+}%
+\def\XINT_cmp_nfork #1#2%
+{%
+ \xint_UDzerofork
+ #1\XINT_cmp_firstiszero
+ #2\XINT_cmp_secondiszero
+ 0{}%
+ \krof
+ \xint_UDsignsfork
+ #1#2\XINT_cmp_minusminus
+ #1-\XINT_cmp_minusplus
+ #2-\XINT_cmp_plusminus
+ --\XINT_cmp_plusplus
+ \krof #1#2%
+}%
+\def\XINT_cmp_firstiszero #1\krof 0#2#3\xint:#4\xint:
+{%
+ \xint_UDzerominusfork
+ #2-{ 0}%
+ 0#2{ 1}%
+ 0-{ -1}%
+ \krof
+}%
+\def\XINT_cmp_secondiszero #1\krof #20#3\xint:#4\xint:
+{%
+ \xint_UDzerominusfork
+ #2-{ 0}%
+ 0#2{ -1}%
+ 0-{ 1}%
+ \krof
+}%
+\def\XINT_cmp_plusminus #1\xint:#2\xint:{ 1}%
+\def\XINT_cmp_minusplus #1\xint:#2\xint:{ -1}%
+\def\XINT_cmp_minusminus
+ --{\expandafter\XINT_opp\romannumeral0\XINT_cmp_plusplus {}{}}%
+\def\XINT_cmp_plusplus #1#2#3\xint:
+{%
+ \expandafter\XINT_cmp_pp
+ \the\numexpr\expandafter\XINT_sepbyviii_andcount
+ \romannumeral0\XINT_zeroes_forviii #2#3\R\R\R\R\R\R\R\R{10}0000001\W
+ #2#3\XINT_sepbyviii_end 2345678\relax
+ \xint_c_vii!\xint_c_vi!\xint_c_v!\xint_c_iv!%
+ \xint_c_iii!\xint_c_ii!\xint_c_i!\xint_c_\W
+ #1%
+}%
+\def\XINT_cmp_pp #1\xint:#2\xint:#3\xint:
+{%
+ \expandafter\XINT_cmp_checklengths
+ \the\numexpr #2\expandafter\xint:%
+ \the\numexpr\expandafter\XINT_sepbyviii_andcount
+ \romannumeral0\XINT_zeroes_forviii #3\R\R\R\R\R\R\R\R{10}0000001\W
+ #3\XINT_sepbyviii_end 2345678\relax
+ \xint_c_vii!\xint_c_vi!\xint_c_v!\xint_c_iv!%
+ \xint_c_iii!\xint_c_ii!\xint_c_i!\xint_c_\W
+ #1;!1;!1;!1;!\W
+}%
+\def\XINT_cmp_checklengths #1\xint:#2\xint:#3\xint:
+{%
+ \ifnum #1=#3
+ \expandafter\xint_firstoftwo
+ \else
+ \expandafter\xint_secondoftwo
+ \fi
+ \XINT_cmp_a {\XINT_cmp_distinctlengths {#1}{#3}}#2;!1;!1;!1;!\W
+}%
+\def\XINT_cmp_distinctlengths #1#2#3\W #4\W
+{%
+ \ifnum #1>#2
+ \expandafter\xint_firstoftwo
+ \else
+ \expandafter\xint_secondoftwo
+ \fi
+ { -1}{ 1}%
+}%
+\def\XINT_cmp_a 1#1!1#2!1#3!1#4!#5\W 1#6!1#7!1#8!1#9!%
+{%
+ \xint_gob_til_sc #1\XINT_cmp_equal ;%
+ \ifnum #1>#6 \XINT_cmp_gt\fi
+ \ifnum #1<#6 \XINT_cmp_lt\fi
+ \xint_gob_til_sc #2\XINT_cmp_equal ;%
+ \ifnum #2>#7 \XINT_cmp_gt\fi
+ \ifnum #2<#7 \XINT_cmp_lt\fi
+ \xint_gob_til_sc #3\XINT_cmp_equal ;%
+ \ifnum #3>#8 \XINT_cmp_gt\fi
+ \ifnum #3<#8 \XINT_cmp_lt\fi
+ \xint_gob_til_sc #4\XINT_cmp_equal ;%
+ \ifnum #4>#9 \XINT_cmp_gt\fi
+ \ifnum #4<#9 \XINT_cmp_lt\fi
+ \XINT_cmp_a #5\W
+}%
+\def\XINT_cmp_lt#1{\def\XINT_cmp_lt\fi ##1\W ##2\W {\fi#1-1}}\XINT_cmp_lt{ }%
+\def\XINT_cmp_gt#1{\def\XINT_cmp_gt\fi ##1\W ##2\W {\fi#11}}\XINT_cmp_gt{ }%
+\def\XINT_cmp_equal #1\W #2\W { 0}%
+% \end{macrocode}
+% \subsection{\csh{xintiiSub}}
+% \lverb|Entirely rewritten for 1.2.
+%
+% Refactored at 1.2l. I was initially aiming at clinching some internal format
+% of the type 1<8digits>!....1<8digits>! for chaining the arithmetic
+% operations (as a preliminary step to decided upon some internal format for
+% $xintfracnameimp macros), thus I wanted to uniformize delimiters in
+% particular and have some core macros inputting and outputting such formats.
+% But the way division is implemented makes it currently very hard to obtain a
+% satisfactory solution. For subtraction I got there almost, but there was
+% added overhead and, as the core sub-routine still assumed the shorter number
+% will be positioned first, one would need to record the length also in the
+% basic internal format, or add the overhead to not make assumption on which
+% one is shorter. I thus but back-tracked my steps but in passing I improved
+% the efficiency (probably) in the worst case branch.
+%
+% Sadly this 1.2l refactoring left an extra ! in macro \XINT_sub_l_Ida. This
+% bug shows only in rare circumstances which escaped out test suite :(
+% Fixed at 1.2q.
+%
+% The other reason for backtracking was in relation with the decimal numbers.
+% Having a core format in base 10^8 but ultimately the radix is actually 10
+% leads to complications. I could use radix 10^8 for \xintiiexpr only, but
+% then I need to make it compatible with sub-\xintiiexpr in \xintexpr, etc...
+% there are many issues of this type.
+%
+% I considered also an approach like in the 1.2l \xintiiCmp, but decided to
+% stick with the method here for now.|
+% \begin{macrocode}
+\def\xintiiSub {\romannumeral0\xintiisub }%
+\def\xintiisub #1{\expandafter\XINT_iisub\romannumeral`&&@#1\xint:}%
+\def\XINT_iisub #1#2\xint:#3%
+{%
+ \expandafter\XINT_sub_nfork\expandafter
+ #1\romannumeral`&&@#3\xint:#2\xint:
+}%
+\def\XINT_isub #1#2\xint:#3%
+{%
+ \expandafter\XINT_sub_nfork\expandafter
+ #1\romannumeral0\xintnum{#3}\xint:#2\xint:
+}%
+\def\XINT_sub_nfork #1#2%
+{%
+ \xint_UDzerofork
+ #1\XINT_sub_firstiszero
+ #2\XINT_sub_secondiszero
+ 0{}%
+ \krof
+ \xint_UDsignsfork
+ #1#2\XINT_sub_minusminus
+ #1-\XINT_sub_minusplus
+ #2-\XINT_sub_plusminus
+ --\XINT_sub_plusplus
+ \krof #1#2%
+}%
+\def\XINT_sub_firstiszero #1\krof 0#2#3\xint:#4\xint:{\XINT_opp #2#3}%
+\def\XINT_sub_secondiszero #1\krof #20#3\xint:#4\xint:{ #2#4}%
+\def\XINT_sub_plusminus #1#2{\XINT_add_pp_a #1{}}%
+\def\XINT_sub_plusplus #1#2%
+ {\expandafter\XINT_opp\romannumeral0\XINT_sub_mm_a #1#2}%
+\def\XINT_sub_minusplus #1#2%
+ {\expandafter-\romannumeral0\XINT_add_pp_a {}#2}%
+\def\XINT_sub_minusminus #1#2{\XINT_sub_mm_a {}{}}%
+% \end{macrocode}
+% \begin{macrocode}
+\def\XINT_sub_mm_a #1#2#3\xint:
+{%
+ \expandafter\XINT_sub_mm_b
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #2#3\R\R\R\R\R\R\R\R{10}0000001\W
+ #2#3\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_i
+ \R\xint:\xint_c_xii \R\xint:\xint_c_x \R\xint:\xint_c_viii \R\xint:\xint_c_vi
+ \R\xint:\xint_c_iv \R\xint:\xint_c_ii \R\xint:\xint_c_\W
+ \X #1%
+}%
+\def\XINT_sub_mm_b #1\xint:#2\X #3\xint:
+{%
+ \expandafter\XINT_sub_checklengths
+ \the\numexpr #1\expandafter\xint:%
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #3\R\R\R\R\R\R\R\R{10}0000001\W
+ #3\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_i
+ \R\xint:\xint_c_xii \R\xint:\xint_c_x \R\xint:\xint_c_viii \R\xint:\xint_c_vi
+ \R\xint:\xint_c_iv \R\xint:\xint_c_ii \R\xint:\xint_c_\W
+ 1;!1;!1;!1;!\W
+ #21;!1;!1;!1;!\W
+ 1;!1\R!1\R!1\R!1\R!%
+ 1\R!1\R!1\R!1\R!\W
+}%
+\def\XINT_sub_checklengths #1\xint:#2\xint:%
+{%
+ \ifnum #2>#1
+ \expandafter\XINT_sub_exchange
+ \else
+ \expandafter\XINT_sub_aa
+ \fi
+}%
+\def\XINT_sub_exchange #1\W #2\W
+{%
+ \expandafter\XINT_opp\romannumeral0\XINT_sub_aa #2\W #1\W
+}%
+\def\XINT_sub_aa
+{%
+ \expandafter\XINT_sub_out\the\numexpr\XINT_sub_a\xint_c_i
+}%
+% \end{macrocode}
+% \lverb|The post-processing (clean-up of zeros, or rescue of situation with
+% A-B where actually B turns out bigger than A) will be done by a macro which
+% depends on circumstances and will be initially last token before the
+% reversion done by \XINT_unrevbyviii.|
+% \begin{macrocode}
+\def\XINT_sub_out {\XINT_unrevbyviii{}}%
+% \end{macrocode}
+% \lverb|1 as first token of #1 stands for "no carry", 0 will mean a carry.
+%
+%( Call: \the\numexpr
+%: \XINT_sub_a 1#11;!1;!1;!1;!\W
+%: #21;!1;!1;!1;!\W
+%)
+% where #1 and #2
+% are blocks of 1<8d>!, #1 (=B) *must* be at most as long as #2 (=A),
+% (in radix 10^8)
+% and the routine wants to compute #2-#1 = A - B
+%
+% 1.2l uses 1;! delimiters to match those of addition (and multiplication).
+% But in the end I reverted the code branch which made it possible to chain
+% such operations keeping internal format in 8 digits blocks throughout.
+%
+% \numexpr governed expansion stops with various possibilities:
+%
+%- Type Ia: #1 shorter than #2, no final carry
+%- Type Ib: #1 shorter than #2, a final carry but next block of #2 > 1
+%- Type Ica: #1 shorter than #2, a final carry, next block of #2 is final and = 1
+%- Type Icb: as Ica except that 00000001 block from #2 was not final
+%- Type Id: #1 shorter than #2, a final carry, next block of #2 = 0
+%- Type IIa: #1 same length as #2, turns out it was <= #2.
+%- Type IIb: #1 same length as #2, but turned out > #2.
+%
+% Various type of post actions are then needed:
+%
+%- Ia: clean up of zeros in most significant block of 8 digits
+%
+%- Ib: as Ia
+%
+%- Ic: there may be significant blocks of 8 zeros to clean up from result.
+% Only case Ica may have arbitrarily many of them, case Icb has only one such
+% block.
+%
+%- Id: blocks of 99999999 may propagate and there might a be final zero block
+% created which has to be cleaned up.
+%
+%- IIa: arbitrarily many zeros might have to be removed.
+%
+%- IIb: We wanted #2-#1 = - (#1-#2), but we got 10^{8N}+#2 -#1 = 10^{8N}-(#1-#2).
+% We need to do the correction then we are as in IIa situation, except that
+% final result can not be zero.
+%
+% The 1.2l method for this correction is (presumably, testing takes lots of
+% time, which I do not have) more efficient than in 1.2 release. |
+% \begin{macrocode}
+\def\XINT_sub_a #1!#2!#3!#4!#5\W #6!#7!#8!#9!%
+{%
+ \XINT_sub_b
+ #1!#6!#2!#7!#3!#8!#4!#9!%
+ #5\W
+}%
+% \end{macrocode}
+% \lverb|As 1.2l code uses 1<8digits>! blocks one has to be careful with
+% the carry digit 1 or 0: A #11#2#3 pattern would result into an empty #1
+% if the carry digit which is upfront is 1, rather than setting #1=1.|
+% \begin{macrocode}
+\def\XINT_sub_b #1#2#3#4!#5!%
+{%
+ \xint_gob_til_sc #3\XINT_sub_bi ;%
+ \expandafter\XINT_sub_c\the\numexpr#1+1#5-#3#4-\xint_c_i\xint:%
+}%
+\def\XINT_sub_c 1#1#2\xint:%
+{%
+ 1#2\expandafter!\the\numexpr\XINT_sub_d #1%
+}%
+\def\XINT_sub_d #1#2#3#4!#5!%
+{%
+ \xint_gob_til_sc #3\XINT_sub_di ;%
+ \expandafter\XINT_sub_e\the\numexpr#1+1#5-#3#4-\xint_c_i\xint:
+}%
+\def\XINT_sub_e 1#1#2\xint:%
+{%
+ 1#2\expandafter!\the\numexpr\XINT_sub_f #1%
+}%
+\def\XINT_sub_f #1#2#3#4!#5!%
+{%
+ \xint_gob_til_sc #3\XINT_sub_fi ;%
+ \expandafter\XINT_sub_g\the\numexpr#1+1#5-#3#4-\xint_c_i\xint:
+}%
+\def\XINT_sub_g 1#1#2\xint:%
+{%
+ 1#2\expandafter!\the\numexpr\XINT_sub_h #1%
+}%
+\def\XINT_sub_h #1#2#3#4!#5!%
+{%
+ \xint_gob_til_sc #3\XINT_sub_hi ;%
+ \expandafter\XINT_sub_i\the\numexpr#1+1#5-#3#4-\xint_c_i\xint:
+}%
+\def\XINT_sub_i 1#1#2\xint:%
+{%
+ 1#2\expandafter!\the\numexpr\XINT_sub_a #1%
+}%
+\def\XINT_sub_bi;%
+ \expandafter\XINT_sub_c\the\numexpr#1+1#2-#3\xint:
+ #4!#5!#6!#7!#8!#9!\W
+{%
+ \XINT_sub_k #1#2!#5!#7!#9!%
+}%
+\def\XINT_sub_di;%
+ \expandafter\XINT_sub_e\the\numexpr#1+1#2-#3\xint:
+ #4!#5!#6!#7!#8\W
+{%
+ \XINT_sub_k #1#2!#5!#7!%
+}%
+\def\XINT_sub_fi;%
+ \expandafter\XINT_sub_g\the\numexpr#1+1#2-#3\xint:
+ #4!#5!#6\W
+{%
+ \XINT_sub_k #1#2!#5!%
+}%
+\def\XINT_sub_hi;%
+ \expandafter\XINT_sub_i\the\numexpr#1+1#2-#3\xint:
+ #4\W
+{%
+ \XINT_sub_k #1#2!%
+}%
+% \end{macrocode}
+% \lverb|B terminated. Have we reached the end of A (necessarily at least as
+% long as B) ? (we are computing A-B, digits of B come first).
+%
+% If not, then we are certain that even if there is carry it will not
+% propagate beyond the end of A. But it may propagate far transforming chains
+% of 00000000 into 99999999, and if it does go to the final block which possibly is
+% just 1<00000001>!, we will have those eight zeros to clean up.
+%
+% If A and B have the same length (in base 10^8) then arbitrarily many zeros
+% might have to be cleaned up, and if A<B, the whole result will have to be
+% complemented first.|
+% \begin{macrocode}
+\def\XINT_sub_k #1#2#3%
+{%
+ \xint_gob_til_sc #3\XINT_sub_p;\XINT_sub_l #1#2#3%
+}%
+\def\XINT_sub_l #1%
+ {\xint_UDzerofork #1\XINT_sub_l_carry 0\XINT_sub_l_Ia\krof}%
+\def\XINT_sub_l_Ia 1#1;!#2\W{1\relax#1;!1\XINT_sub_fix_none!}%
+% \end{macrocode}
+% \lverb|
+%
+% |
+% \begin{macrocode}
+\def\XINT_sub_l_carry 1#1!{\ifcase #1
+ \expandafter \XINT_sub_l_Id
+ \or \expandafter \XINT_sub_l_Ic
+ \else\expandafter \XINT_sub_l_Ib\fi 1#1!}%
+\def\XINT_sub_l_Ib #1;#2\W {-\xint_c_i+#1;!1\XINT_sub_fix_none!}%
+\def\XINT_sub_l_Ic 1#1!1#2#3!#4;#5\W
+{%
+ \xint_gob_til_sc #2\XINT_sub_l_Ica;%
+ 1\relax 00000000!1#2#3!#4;!1\XINT_sub_fix_none!%
+}%
+% \end{macrocode}
+% \lverb|&
+% We need to add some extra delimiters at the end for post-action by
+% \XINT_num, so we first grab the material up to \W
+% |
+% \begin{macrocode}
+\def\XINT_sub_l_Ica#1\W
+{%
+ 1;!1\XINT_sub_fix_cuz!%
+ 1;!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
+ \xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\Z
+}%
+\def\XINT_sub_l_Id 1#1!%
+ {199999999\expandafter!\the\numexpr \XINT_sub_l_Id_a}%
+\def\XINT_sub_l_Id_a 1#1!{\ifcase #1
+ \expandafter \XINT_sub_l_Id
+ \or \expandafter \XINT_sub_l_Id_b
+ \else\expandafter \XINT_sub_l_Ib\fi 1#1!}%
+\def\XINT_sub_l_Id_b 1#1!1#2#3!#4;#5\W
+{%
+ \xint_gob_til_sc #2\XINT_sub_l_Ida;%
+ 1\relax 00000000!1#2#3!#4;!1\XINT_sub_fix_none!%
+}%
+\def\XINT_sub_l_Ida#1\XINT_sub_fix_none{1;!1\XINT_sub_fix_none}%
+% \end{macrocode}
+% \lverb|&
+% This is the case where both operands have same 10^8-base length.
+%
+% We were handling A-B but perhaps B>A. The situation with A=B is also
+% annoying because we then have to clean up all zeros but don't know where to
+% stop (if A>B the first non-zero 8 digits block would tell use when).
+%
+% Here again we need to grab #3\W to position the actually used terminating
+% delimiters.
+% |
+% \begin{macrocode}
+\def\XINT_sub_p;\XINT_sub_l #1#2\W #3\W
+{%
+ \xint_UDzerofork
+ #1{1;!1\XINT_sub_fix_neg!%
+ 1;!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
+ \xint_bye2345678\xint_bye1099999988\relax}% A - B, B > A
+ 0{1;!1\XINT_sub_fix_cuz!%
+ 1;!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W}%
+ \krof
+ \xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\Z
+}%
+% \end{macrocode}
+% \lverb|Routines for post-processing after reversal, and removal of
+% separators. It is a matter of cleaning up zeros, and possibly in the bad
+% case to take a complement before that.|
+% \begin{macrocode}
+\def\XINT_sub_fix_none;{\XINT_cuz_small}%
+\def\XINT_sub_fix_cuz ;{\expandafter\XINT_num_cleanup\the\numexpr\XINT_num_loop}%
+% \end{macrocode}
+% \lverb|Case with A and B same number of digits in base 10^8 and B>A.
+%
+% 1.2l subtle chaining on the model of the 1.2i rewrite of \xintInc and
+% similar routines. After taking complement, leading zeroes need to be
+% cleaned up as in B<=A branch.|
+% \begin{macrocode}
+\def\XINT_sub_fix_neg;%
+{%
+ \expandafter-\romannumeral0\expandafter
+ \XINT_sub_comp_finish\the\numexpr\XINT_sub_comp_loop
+}%
+\def\XINT_sub_comp_finish 0{\XINT_sub_fix_cuz;}%
+\def\XINT_sub_comp_loop #1#2#3#4#5#6#7#8%
+{%
+ \expandafter\XINT_sub_comp_clean
+ \the\numexpr \xint_c_xi_e_viii_mone-#1#2#3#4#5#6#7#8\XINT_sub_comp_loop
+}%
+% \end{macrocode}
+% \lverb|#1 = 0 signifie une retenue, #1 = 1 pas de retenue, ce qui ne peut
+% arriver que tant qu'il n'y a que des zéros du côté non significatif.
+% Lorsqu'on est revenu au début on a forcément une retenue.|
+% \begin{macrocode}
+\def\XINT_sub_comp_clean 1#1{+#1\relax}%
+% \end{macrocode}
+% \subsection{\csh{xintiiMul}}
+% \lverb|Completely rewritten for 1.2.
+%
+% 1.2l: \xintiiMul made robust against non terminated input.|
+% \begin{macrocode}
+\def\xintiiMul {\romannumeral0\xintiimul }%
+\def\xintiimul #1%
+{%
+ \expandafter\XINT_iimul\romannumeral`&&@#1\xint:
+}%
+\def\XINT_iimul #1#2\xint:#3%
+{%
+ \expandafter\XINT_mul_nfork\expandafter #1\romannumeral`&&@#3\xint:#2\xint:
+}%
+% \end{macrocode}
+% \lverb|(1.2) I have changed the fork, and it complicates matters elsewhere.|
+% \begin{macrocode}
+\def\XINT_mul_fork #1#2\xint:#3\xint:{\XINT_mul_nfork #1#3\xint:#2\xint:}%
+\def\XINT_mul_nfork #1#2%
+{%
+ \xint_UDzerofork
+ #1\XINT_mul_zero
+ #2\XINT_mul_zero
+ 0{}%
+ \krof
+ \xint_UDsignsfork
+ #1#2\XINT_mul_minusminus
+ #1-\XINT_mul_minusplus
+ #2-\XINT_mul_plusminus
+ --\XINT_mul_plusplus
+ \krof #1#2%
+}%
+\def\XINT_mul_zero #1\krof #2#3\xint:#4\xint:{ 0}%
+\def\XINT_mul_minusminus #1#2{\XINT_mul_plusplus {}{}}%
+\def\XINT_mul_minusplus #1#2%
+ {\expandafter-\romannumeral0\XINT_mul_plusplus {}#2}%
+\def\XINT_mul_plusminus #1#2%
+ {\expandafter-\romannumeral0\XINT_mul_plusplus #1{}}%
+\def\XINT_mul_plusplus #1#2#3\xint:
+{%
+ \expandafter\XINT_mul_pre_b
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #2#3\R\R\R\R\R\R\R\R{10}0000001\W
+ #2#3\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_i
+ \R\xint:\xint_c_xii \R\xint:\xint_c_x \R\xint:\xint_c_viii \R\xint:\xint_c_vi
+ \R\xint:\xint_c_iv \R\xint:\xint_c_ii \R\xint:\xint_c_\W
+ \W #1%
+}%
+\def\XINT_mul_pre_b #1\xint:#2\W #3\xint:
+{%
+ \expandafter\XINT_mul_checklengths
+ \the\numexpr #1\expandafter\xint:%
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #3\R\R\R\R\R\R\R\R{10}0000001\W
+ #3\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_i
+ \R\xint:\xint_c_xii \R\xint:\xint_c_x \R\xint:\xint_c_viii \R\xint:\xint_c_vi
+ \R\xint:\xint_c_iv \R\xint:\xint_c_ii \R\xint:\xint_c_\W
+ 1;!\W #21;!%
+ 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
+}%
+% \end{macrocode}
+% \lverb|Cooking recipe, 2015/10/05.|
+% \begin{macrocode}
+\def\XINT_mul_checklengths #1\xint:#2\xint:%
+{%
+ \ifnum #2=\xint_c_i\expandafter\XINT_mul_smallbyfirst\fi
+ \ifnum #1=\xint_c_i\expandafter\XINT_mul_smallbysecond\fi
+ \ifnum #2<#1
+ \ifnum \numexpr (#2-\xint_c_i)*(#1-#2)<383
+ \XINT_mul_exchange
+ \fi
+ \else
+ \ifnum \numexpr (#1-\xint_c_i)*(#2-#1)>383
+ \XINT_mul_exchange
+ \fi
+ \fi
+ \XINT_mul_start
+}%
+\def\XINT_mul_smallbyfirst #1\XINT_mul_start 1#2!1;!\W
+{%
+ \ifnum#2=\xint_c_i\expandafter\XINT_mul_oneisone\fi
+ \ifnum#2<\xint_c_xxii\expandafter\XINT_mul_verysmall\fi
+ \expandafter\XINT_mul_out\the\numexpr\XINT_smallmul 1#2!%
+}%
+\def\XINT_mul_smallbysecond #1\XINT_mul_start #2\W 1#3!1;!%
+{%
+ \ifnum#3=\xint_c_i\expandafter\XINT_mul_oneisone\fi
+ \ifnum#3<\xint_c_xxii\expandafter\XINT_mul_verysmall\fi
+ \expandafter\XINT_mul_out\the\numexpr\XINT_smallmul 1#3!#2%
+}%
+\def\XINT_mul_oneisone #1!{\XINT_mul_out }%
+\def\XINT_mul_verysmall\expandafter\XINT_mul_out
+ \the\numexpr\XINT_smallmul 1#1!%
+ {\expandafter\XINT_mul_out\the\numexpr\XINT_verysmallmul 0\xint:#1!}%
+\def\XINT_mul_exchange #1\XINT_mul_start #2\W #31;!%
+ {\fi\fi\XINT_mul_start #31;!\W #2}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_mul_start
+ {\expandafter\XINT_mul_out\the\numexpr\XINT_mul_loop 100000000!1;!\W}%
+\def\XINT_mul_out
+ {\expandafter\XINT_cuz_small\romannumeral0\XINT_unrevbyviii {}}%
+% \end{macrocode}
+% \lverb|&
+%
+%( Call:
+%: \the\numexpr \XINT_mul_loop 100000000!1;!\W #11;!\W #21;!
+%)
+% where #1 and #2 are (globally reversed) blocks 1<8d>!. Its is generally more
+% efficient if #1 is the shorter one, but a better recipe is implemented in
+% \XINT_mul_checklengths. One may call \XINT_mul_loop directly (but
+% multiplication by zero will produce many 100000000! blocks on output).
+%
+% Ends after having produced: 1<8d>!....1<8d>!1;!. The last 8-digits block is
+% significant one. It can not be 100000000! except if the loop was called with
+% a zero operand.
+%
+% Thus \XINT_mul_loop can be conveniently called directly in recursive
+% routines, as the output terminator can serve as input terminator, we can
+% arrange to not have to grab the whole thing again.|
+% \begin{macrocode}
+\def\XINT_mul_loop #1\W #2\W 1#3!%
+{%
+ \xint_gob_til_sc #3\XINT_mul_e ;%
+ \expandafter\XINT_mul_a\the\numexpr \XINT_smallmul 1#3!#2\W
+ #1\W #2\W
+}%
+% \end{macrocode}
+% \lverb|Each of #1 and #2 brings its 1;! for \XINT_add_a.|
+% \begin{macrocode}
+\def\XINT_mul_a #1\W #2\W
+{%
+ \expandafter\XINT_mul_b\the\numexpr
+ \XINT_add_a \xint_c_ii #21;!1;!1;!\W #11;!1;!1;!\W\W
+}%
+\def\XINT_mul_b 1#1!{1#1\expandafter!\the\numexpr\XINT_mul_loop }%
+\def\XINT_mul_e;#1\W 1#2\W #3\W {1\relax #2}%
+% \end{macrocode}
+% \lverb|1.2 small and mini multiplication in base 10^8 with carry. Used by
+% the main multiplication routines. But division, float factorial, etc.. have
+% their own variants as they need output with specific constraints.
+%
+% The minimulwc has 1<8digits carry>.<4 high digits>.<4 low digits!<8digits>.
+%
+% It produces a block 1<8d>! and then jump back into \XINT_smallmul_a with the
+% new 8digits carry as argument. The \XINT_smallmul_a fetches a new 1<8d>!
+% block to multiply, and calls back \XINT_minimul_wc having stored the
+% multiplicand for re-use later. When the loop terminates, the final carry is
+% checked for being nul, and in all cases the output is terminated by a 1;!
+%
+% Multiplication by zero will produce blocks of zeros.|
+% \begin{macrocode}
+\def\XINT_minimulwc_a 1#1\xint:#2\xint:#3!#4#5#6#7#8\xint:%
+{%
+ \expandafter\XINT_minimulwc_b
+ \the\numexpr \xint_c_x^ix+#1+#3*#8\xint:
+ #3*#4#5#6#7+#2*#8\xint:
+ #2*#4#5#6#7\xint:%
+}%
+\def\XINT_minimulwc_b 1#1#2#3#4#5#6\xint:#7\xint:%
+{%
+ \expandafter\XINT_minimulwc_c
+ \the\numexpr \xint_c_x^ix+#1#2#3#4#5+#7\xint:#6\xint:%
+}%
+\def\XINT_minimulwc_c 1#1#2#3#4#5#6\xint:#7\xint:#8\xint:%
+{%
+ 1#6#7\expandafter!%
+ \the\numexpr\expandafter\XINT_smallmul_a
+ \the\numexpr \xint_c_x^viii+#1#2#3#4#5+#8\xint:%
+}%
+\def\XINT_smallmul 1#1#2#3#4#5!{\XINT_smallmul_a 100000000\xint:#1#2#3#4\xint:#5!}%
+\def\XINT_smallmul_a #1\xint:#2\xint:#3!1#4!%
+{%
+ \xint_gob_til_sc #4\XINT_smallmul_e;%
+ \XINT_minimulwc_a #1\xint:#2\xint:#3!#4\xint:#2\xint:#3!%
+}%
+\def\XINT_smallmul_e;\XINT_minimulwc_a 1#1\xint:#2;#3!%
+ {\xint_gob_til_eightzeroes #1\XINT_smallmul_f 000000001\relax #1!1;!}%
+\def\XINT_smallmul_f 000000001\relax 00000000!1{1\relax}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_verysmallmul #1\xint:#2!1#3!%
+{%
+ \xint_gob_til_sc #3\XINT_verysmallmul_e;%
+ \expandafter\XINT_verysmallmul_a
+ \the\numexpr #2*#3+#1\xint:#2!%
+}%
+\def\XINT_verysmallmul_e;\expandafter\XINT_verysmallmul_a\the\numexpr
+ #1+#2#3\xint:#4!%
+{\xint_gob_til_zero #2\XINT_verysmallmul_f 0\xint_c_x^viii+#2#3!1;!}%
+\def\XINT_verysmallmul_f #1!1{1\relax}%
+\def\XINT_verysmallmul_a #1#2\xint:%
+{%
+ \unless\ifnum #1#2<\xint_c_x^ix
+ \expandafter\XINT_verysmallmul_bi\else
+ \expandafter\XINT_verysmallmul_bj\fi
+ \the\numexpr \xint_c_x^ix+#1#2\xint:%
+}%
+\def\XINT_verysmallmul_bj{\expandafter\XINT_verysmallmul_cj }%
+\def\XINT_verysmallmul_cj 1#1#2\xint:%
+ {1#2\expandafter!\the\numexpr\XINT_verysmallmul #1\xint:}%
+\def\XINT_verysmallmul_bi\the\numexpr\xint_c_x^ix+#1#2#3\xint:%
+ {1#3\expandafter!\the\numexpr\XINT_verysmallmul #1#2\xint:}%
+% \end{macrocode}
+% \lverb|Used by division and by squaring, not by multiplication itself.
+%
+% This routine does not loop, it only does one mini multiplication with input
+% format <4 high digits>.<4 low digits>!<8 digits>!, and on output
+% 1<8d>!1<8d>!, with least significant block first.|
+% \begin{macrocode}
+\def\XINT_minimul_a #1\xint:#2!#3#4#5#6#7!%
+{%
+ \expandafter\XINT_minimul_b
+ \the\numexpr \xint_c_x^viii+#2*#7\xint:#2*#3#4#5#6+#1*#7\xint:#1*#3#4#5#6\xint:%
+}%
+\def\XINT_minimul_b 1#1#2#3#4#5\xint:#6\xint:%
+{%
+ \expandafter\XINT_minimul_c
+ \the\numexpr \xint_c_x^ix+#1#2#3#4+#6\xint:#5\xint:%
+}%
+\def\XINT_minimul_c 1#1#2#3#4#5#6\xint:#7\xint:#8\xint:%
+{%
+ 1#6#7\expandafter!\the\numexpr \xint_c_x^viii+#1#2#3#4#5+#8!%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiDivision}}
+% \lverb|Completely rewritten for 1.2.
+%
+% WARNING: some comments below try to describe the flow of tokens but they
+% date back to xint 1.09j and I updated them on the fly while doing the 1.2
+% version. As the routine now works in base 10^8, not 10^4 and "drops" the
+% quotient digits,rather than store them upfront as the earlier code, I may
+% well have not correctly converted all such comments. At the last minute some
+% previously #1 became stuff like #1#2#3#4, then of course the old comments
+% describing what the macro parameters stand for are necessarily wrong.
+%
+% Side remark: the way tokens are grouped was not essentially modified in
+% 1.2, although the situation has changed. It was fine-tuned in xint
+% 1.0/1.1 but the context has changed, and perhaps I should revisit this.
+% As a corollary to the fact that quotient digits are now left behind thanks
+% to the chains of \numexpr, some macros which in 1.0/1.1 fetched up to 9
+% parameters now need handle less such parameters. Thus, some rationale for
+% the way the code was structured has disappeared.
+%
+%
+% 1.2l: \xintiiDivision et al. made robust against non terminated input.
+% |
+% \lverb-#1 = A, #2 = B. On calcule le quotient et le reste dans la division
+% euclidienne de A par B: A=BQ+R, 0<= R < |B|.-
+% \begin{macrocode}
+\def\xintiiDivision {\romannumeral0\xintiidivision }%
+\def\xintiidivision #1{\expandafter\XINT_iidivision \romannumeral`&&@#1\xint:}%
+\def\XINT_iidivision #1#2\xint:#3{\expandafter\XINT_iidivision_a\expandafter #1%
+ \romannumeral`&&@#3\xint:#2\xint:}%
+% \end{macrocode}
+% \lverb|On regarde les signes de A et de B.|
+% \begin{macrocode}
+\def\XINT_iidivision_a #1#2% #1 de A, #2 de B.
+{%
+ \if0#2\xint_dothis{\XINT_iidivision_divbyzero #1#2}\fi
+ \if0#1\xint_dothis\XINT_iidivision_aiszero\fi
+ \if-#2\xint_dothis{\expandafter\XINT_iidivision_bneg
+ \romannumeral0\XINT_iidivision_bpos #1}\fi
+ \xint_orthat{\XINT_iidivision_bpos #1#2}%
+}%
+\def\XINT_iidivision_divbyzero#1#2#3\xint:#4\xint:
+ {\if0#1\xint_dothis{\XINT_signalcondition{DivisionUndefined}}\fi
+ \xint_orthat{\XINT_signalcondition{DivisionByZero}}%
+ {Division of #1#4 by #2#3}{}{{0}{0}}}%
+\def\XINT_iidivision_aiszero #1\xint:#2\xint:{{0}{0}}%
+\def\XINT_iidivision_bneg #1% q->-q, r unchanged
+ {\expandafter{\romannumeral0\XINT_opp #1}}%
+\def\XINT_iidivision_bpos #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_iidivision_aneg
+ -{\XINT_iidivision_apos #1}%
+ \krof
+}%
+% \end{macrocode}
+% \lverb|Donc attention malgré son nom \XINT_div_prepare va jusqu'au bout.
+% C'est donc en fait l'entrée principale (pour B>0, A>0) mais elle va
+% regarder si B est < 10^8 et s'il vaut alors 1 ou 2, et si A < 10^8. Dans
+% tous les cas le résultat est produit sous la forme {Q}{R}, avec Q et R sous
+% leur forme final. On doit ensuite ajuster si le B ou le A initial était
+% négatif. Je n'ai pas fait beaucoup d'efforts pour être un minimum efficace
+% si A ou B n'est pas positif.|
+% \begin{macrocode}
+\def\XINT_iidivision_apos #1#2\xint:#3\xint:{\XINT_div_prepare {#2}{#1#3}}%
+\def\XINT_iidivision_aneg #1\xint:#2\xint:
+ {\expandafter
+ \XINT_iidivision_aneg_b\romannumeral0\XINT_div_prepare {#1}{#2}{#1}}%
+\def\XINT_iidivision_aneg_b #1#2{\if0\XINT_Sgn #2\xint:
+ \expandafter\XINT_iidivision_aneg_rzero
+ \else
+ \expandafter\XINT_iidivision_aneg_rpos
+ \fi {#1}{#2}}%
+\def\XINT_iidivision_aneg_rzero #1#2#3{{-#1}{0}}% necessarily q was >0
+\def\XINT_iidivision_aneg_rpos #1%
+{%
+ \expandafter\XINT_iidivision_aneg_end\expandafter
+ {\expandafter-\romannumeral0\xintinc {#1}}% q-> -(1+q)
+}%
+\def\XINT_iidivision_aneg_end #1#2#3%
+{%
+ \expandafter\xint_exchangetwo_keepbraces
+ \expandafter{\romannumeral0\XINT_sub_mm_a {}{}#3\xint:#2\xint:}{#1}% r-> b-r
+}%
+% \end{macrocode}
+% \lverb|Le diviseur B va être étendu par des zéros pour que sa longueur soit
+% multiple de huit. Les zéros seront mis du côté non significatif.|
+% \begin{macrocode}
+\def\XINT_div_prepare #1%
+{%
+ \XINT_div_prepare_a #1\R\R\R\R\R\R\R\R {10}0000001\W !{#1}%
+}%
+\def\XINT_div_prepare_a #1#2#3#4#5#6#7#8#9%
+{%
+ \xint_gob_til_R #9\XINT_div_prepare_small\R
+ \XINT_div_prepare_b #9%
+}%
+% \end{macrocode}
+% \lverb|B a au plus huit chiffres. On se débarrasse des trucs superflus. Si
+% B>0 n'est ni 1 ni 2, le point d'entrée est \XINT_div_small_a {B}{A} (avec un
+% A positif).|
+% \begin{macrocode}
+\def\XINT_div_prepare_small\R #1!#2%
+{%
+ \ifcase #2
+ \or\expandafter\XINT_div_BisOne
+ \or\expandafter\XINT_div_BisTwo
+ \else\expandafter\XINT_div_small_a
+ \fi {#2}%
+}%
+\def\XINT_div_BisOne #1#2{{#2}{0}}%
+\def\XINT_div_BisTwo #1#2%
+{%
+ \expandafter\expandafter\expandafter\XINT_div_BisTwo_a
+ \ifodd\xintLDg{#2} \expandafter1\else \expandafter0\fi {#2}%
+}%
+\def\XINT_div_BisTwo_a #1#2%
+{%
+ \expandafter{\romannumeral0\XINT_half
+ #2\xint_bye\xint_Bye345678\xint_bye
+ *\xint_c_v+\xint_c_v)/\xint_c_x-\xint_c_i\relax}{#1}%
+}%
+% \end{macrocode}
+% \lverb|B a au plus huit chiffres et est au moins 3. On va l'utiliser
+% directement, sans d'abord le multiplier par une puissance de 10 pour qu'il
+% ait 8 chiffres.|
+% \begin{macrocode}
+\def\XINT_div_small_a #1#2%
+{%
+ \expandafter\XINT_div_small_b
+ \the\numexpr #1/\xint_c_ii\expandafter
+ \xint:\the\numexpr \xint_c_x^viii+#1\expandafter!%
+ \romannumeral0%
+ \XINT_div_small_ba #2\R\R\R\R\R\R\R\R{10}0000001\W
+ #2\XINT_sepbyviii_Z_end 2345678\relax
+}%
+% \end{macrocode}
+% \lverb|Le #2 poursuivra l'expansion par \XINT_div_dosmallsmall ou par
+% \XINT_smalldivx_a suivi de \XINT_sdiv_out.|
+% \begin{macrocode}
+\def\XINT_div_small_b #1!#2{#2#1!}%
+% \end{macrocode}
+% \lverb|On ajoute des zéros avant A, puis on le prépare sous la forme de
+% blocs 1<8d>! Au passage on repère le cas d'un A<10^8.|
+% \begin{macrocode}
+\def\XINT_div_small_ba #1#2#3#4#5#6#7#8#9%
+{%
+ \xint_gob_til_R #9\XINT_div_smallsmall\R
+ \expandafter\XINT_div_dosmalldiv
+ \the\numexpr\expandafter\XINT_sepbyviii_Z
+ \romannumeral0\XINT_zeroes_forviii
+ #1#2#3#4#5#6#7#8#9%
+}%
+% \end{macrocode}
+% \lverb|Si A<10^8, on va poursuivre par \XINT_div_dosmallsmall
+% round(B/2).10^8+B!{A}. On fait la division directe par \numexpr. Le résultat
+% est produit sous la forme {Q}{R}.|
+% \begin{macrocode}
+\def\XINT_div_smallsmall\R
+ \expandafter\XINT_div_dosmalldiv
+ \the\numexpr\expandafter\XINT_sepbyviii_Z
+ \romannumeral0\XINT_zeroes_forviii #1\R #2\relax
+ {{\XINT_div_dosmallsmall}{#1}}%
+\def\XINT_div_dosmallsmall #1\xint:1#2!#3%
+{%
+ \expandafter\XINT_div_smallsmallend
+ \the\numexpr (#3+#1)/#2-\xint_c_i\xint:#2\xint:#3\xint:%
+}%
+\def\XINT_div_smallsmallend #1\xint:#2\xint:#3\xint:{\expandafter
+ {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #3-#1*#2}}%
+% \end{macrocode}
+% \lverb|Si A>=10^8, il est maintenant sous la forme 1<8d>!...1<8d>!1;! avec
+% plus significatifs en premier. Donc on poursuit par$newline
+% \expandafter\XINT_sdiv_out\the\numexpr\XINT_smalldivx_a
+% x.1B!1<8d>!...1<8d>!1;! avec x =round(B/2), 1B=10^8+B.|
+% \begin{macrocode}
+\def\XINT_div_dosmalldiv
+ {{\expandafter\XINT_sdiv_out\the\numexpr\XINT_smalldivx_a}}%
+% \end{macrocode}
+% \lverb|Ici B est au moins 10^8, on détermine combien de zéros lui adjoindre
+% pour qu'il soit de longueur 8N.|
+% \begin{macrocode}
+\def\XINT_div_prepare_b
+ {\expandafter\XINT_div_prepare_c\romannumeral0\XINT_zeroes_forviii }%
+\def\XINT_div_prepare_c #1!%
+{%
+ \XINT_div_prepare_d #1.00000000!{#1}%
+}%
+\def\XINT_div_prepare_d #1#2#3#4#5#6#7#8#9%
+{%
+ \expandafter\XINT_div_prepare_e\xint_gob_til_dot #1#2#3#4#5#6#7#8#9!%
+}%
+\def\XINT_div_prepare_e #1!#2!#3#4%
+{%
+ \XINT_div_prepare_f #4#3\X {#1}{#3}%
+}%
+% \end{macrocode}
+% \lverb|attention qu'on calcule ici x'=x+1 (x = huit premiers chiffres du
+% diviseur) et que si x=99999999, x' aura donc 9 chiffres, pas compatible avec
+% div_mini (avant 1.2, x avait 4 chiffres, et on faisait la division avec x'
+% dans un \numexpr). Bon, facile à dire après avoir laissé passer ce bug dans
+% 1.2. C'est le problème lorsqu'au lieu de tout refaire à partir de zéro on
+% recycle d'anciennes routines qui avaient un contexte différent.|
+% \begin{macrocode}
+\def\XINT_div_prepare_f #1#2#3#4#5#6#7#8#9\X
+{%
+ \expandafter\XINT_div_prepare_g
+ \the\numexpr #1#2#3#4#5#6#7#8+\xint_c_i\expandafter
+ \xint:\the\numexpr (#1#2#3#4#5#6#7#8+\xint_c_i)/\xint_c_ii\expandafter
+ \xint:\the\numexpr #1#2#3#4#5#6#7#8\expandafter
+ \xint:\romannumeral0\XINT_sepandrev_andcount
+ #1#2#3#4#5#6#7#8#9\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_i
+ \R\xint:\xint_c_xii \R\xint:\xint_c_x \R\xint:\xint_c_viii \R\xint:\xint_c_vi
+ \R\xint:\xint_c_iv \R\xint:\xint_c_ii \R\xint:\xint_c_\W
+ \X
+}%
+\def\XINT_div_prepare_g #1\xint:#2\xint:#3\xint:#4\xint:#5\X #6#7#8%
+{%
+ \expandafter\XINT_div_prepare_h
+ \the\numexpr\expandafter\XINT_sepbyviii_andcount
+ \romannumeral0\XINT_zeroes_forviii #8#7\R\R\R\R\R\R\R\R{10}0000001\W
+ #8#7\XINT_sepbyviii_end 2345678\relax
+ \xint_c_vii!\xint_c_vi!\xint_c_v!\xint_c_iv!%
+ \xint_c_iii!\xint_c_ii!\xint_c_i!\xint_c_\W
+ {#1}{#2}{#3}{#4}{#5}{#6}%
+}%
+\def\XINT_div_prepare_h #11\xint:#2\xint:#3#4#5#6%#7#8%
+{%
+ \XINT_div_start_a {#2}{#6}{#1}{#3}{#4}{#5}%{#7}{#8}%
+}%
+% \end{macrocode}
+% \lverb|L, K, A, x',y,x, B, «c». Attention que K est diminué de 1 plus loin.
+% Comme xint 1.2 a déjà repéré K=1, on a ici au minimum K=2. Attention B est à
+% l'envers, A est à l'endroit et les deux avec séparateurs. Attention que ce
+% n'est pas ici qu'on boucle mais en \XINT_div_I_a.|
+% \begin{macrocode}
+\def\XINT_div_start_a #1#2%
+{%
+ \ifnum #1 < #2
+ \expandafter\XINT_div_zeroQ
+ \else
+ \expandafter\XINT_div_start_b
+ \fi
+ {#1}{#2}%
+}%
+\def\XINT_div_zeroQ #1#2#3#4#5#6#7%
+{%
+ \expandafter\XINT_div_zeroQ_end
+ \romannumeral0\XINT_unsep_cuzsmall
+ #3\xint_bye!2!3!4!5!6!7!8!9!\xint_bye\xint_c_i\relax\xint:
+}%
+\def\XINT_div_zeroQ_end #1\xint:#2%
+ {\expandafter{\expandafter0\expandafter}\XINT_div_cleanR #1#2\xint:}%
+% \end{macrocode}
+% \lverb|L, K, A, x',y,x, B, «c»->K.A.x{LK{x'y}x}B«c»|
+% \begin{macrocode}
+\def\XINT_div_start_b #1#2#3#4#5#6%
+{%
+ \expandafter\XINT_div_finish\the\numexpr
+ \XINT_div_start_c {#2}\xint:#3\xint:{#6}{{#1}{#2}{{#4}{#5}}{#6}}%
+}%
+\def\XINT_div_finish
+{%
+ \expandafter\XINT_div_finish_a \romannumeral`&&@\XINT_div_unsepQ
+}%
+\def\XINT_div_finish_a #1\Z #2\xint:{\XINT_div_finish_b #2\xint:{#1}}%
+% \end{macrocode}
+% \lverb|Ici ce sont routines de fin. Le reste déjà nettoyé. R.Q«c».|
+% \begin{macrocode}
+\def\XINT_div_finish_b #1%
+{%
+ \if0#1%
+ \expandafter\XINT_div_finish_bRzero
+ \else
+ \expandafter\XINT_div_finish_bRpos
+ \fi
+ #1%
+}%
+\def\XINT_div_finish_bRzero 0\xint:#1#2{{#1}{0}}%
+\def\XINT_div_finish_bRpos #1\xint:#2#3%
+{%
+ \expandafter\xint_exchangetwo_keepbraces\XINT_div_cleanR #1#3\xint:{#2}%
+}%
+\def\XINT_div_cleanR #100000000\xint:{{#1}}%
+% \end{macrocode}
+% \lverb|Kalpha.A.x{LK{x'y}x}, B, «c», au début #2=alpha est vide. On fait une
+% boucle pour prendre K unités de A (on a au moins L égal à K) et les mettre
+% dans alpha.|
+% \begin{macrocode}
+\def\XINT_div_start_c #1%
+{%
+ \ifnum #1>\xint_c_vi
+ \expandafter\XINT_div_start_ca
+ \else
+ \expandafter\XINT_div_start_cb
+ \fi {#1}%
+}%
+\def\XINT_div_start_ca #1#2\xint:#3!#4!#5!#6!#7!#8!#9!%
+{%
+ \expandafter\XINT_div_start_c\expandafter
+ {\the\numexpr #1-\xint_c_vii}#2#3!#4!#5!#6!#7!#8!#9!\xint:%
+}%
+\def\XINT_div_start_cb #1%
+ {\csname XINT_div_start_c_\romannumeral\numexpr#1\endcsname}%
+\def\XINT_div_start_c_i #1\xint:#2!%
+ {\XINT_div_start_c_ #1#2!\xint:}%
+\def\XINT_div_start_c_ii #1\xint:#2!#3!%
+ {\XINT_div_start_c_ #1#2!#3!\xint:}%
+\def\XINT_div_start_c_iii #1\xint:#2!#3!#4!%
+ {\XINT_div_start_c_ #1#2!#3!#4!\xint:}%
+\def\XINT_div_start_c_iv #1\xint:#2!#3!#4!#5!%
+ {\XINT_div_start_c_ #1#2!#3!#4!#5!\xint:}%
+\def\XINT_div_start_c_v #1\xint:#2!#3!#4!#5!#6!%
+ {\XINT_div_start_c_ #1#2!#3!#4!#5!#6!\xint:}%
+\def\XINT_div_start_c_vi #1\xint:#2!#3!#4!#5!#6!#7!%
+ {\XINT_div_start_c_ #1#2!#3!#4!#5!#6!#7!\xint:}%
+% \end{macrocode}
+% \lverb|#1=a, #2=alpha (de longueur K, à l'endroit).#3=reste de A.#4=x,
+% #5={LK{x'y}x},#6=B,«c» -> a, x, alpha, B, {00000000}, L, K, {x'y},x,
+% alpha'=reste de A, B«c».|
+% \begin{macrocode}
+\def\XINT_div_start_c_ 1#1!#2\xint:#3\xint:#4#5#6%
+{%
+ \XINT_div_I_a {#1}{#4}{1#1!#2}{#6}{00000000}#5{#3}{#6}%
+}%
+% \end{macrocode}
+% \lverb|Ceci est le point de retour de la boucle principale. a, x, alpha, B,
+% q0, L, K, {x'y}, x, alpha', B«c» |
+% \begin{macrocode}
+\def\XINT_div_I_a #1#2%
+{%
+ \expandafter\XINT_div_I_b\the\numexpr #1/#2\xint:{#1}{#2}%
+}%
+\def\XINT_div_I_b #1%
+{%
+ \xint_gob_til_zero #1\XINT_div_I_czero 0\XINT_div_I_c #1%
+}%
+% \end{macrocode}
+% \lverb|On intercepte petit quotient nul: #1=a, x, alpha, B, #5=q0, L, K,
+% {x'y}, x, alpha', B«c» -> on lâche un q puis {alpha} L, K, {x'y}, x,
+% alpha', B«c».|
+% \begin{macrocode}
+\def\XINT_div_I_czero 0\XINT_div_I_c 0\xint:#1#2#3#4#5{1#5\XINT_div_I_g {#3}}%
+\def\XINT_div_I_c #1\xint:#2#3%
+{%
+ \expandafter\XINT_div_I_da\the\numexpr #2-#1*#3\xint:#1\xint:{#2}{#3}%
+}%
+% \end{macrocode}
+% \lverb|r.q.alpha, B, q0, L, K, {x'y}, x, alpha', B«c»|
+% \begin{macrocode}
+\def\XINT_div_I_da #1\xint:%
+{%
+ \ifnum #1>\xint_c_ix
+ \expandafter\XINT_div_I_dP
+ \else
+ \ifnum #1<\xint_c_
+ \expandafter\expandafter\expandafter\XINT_div_I_dN
+ \else
+ \expandafter\expandafter\expandafter\XINT_div_I_db
+ \fi
+ \fi
+}%
+% \end{macrocode}
+% \lverb|attention très mauvaises notations avec _b et _db.|
+% \begin{macrocode}
+\def\XINT_div_I_dN #1\xint:%
+{%
+ \expandafter\XINT_div_I_b\the\numexpr #1-\xint_c_i\xint:%
+}%
+\def\XINT_div_I_db #1\xint:#2#3#4#5%
+{%
+ \expandafter\XINT_div_I_dc\expandafter #1%
+ \romannumeral0\expandafter\XINT_div_sub\expandafter
+ {\romannumeral0\XINT_rev_nounsep {}#4\R!\R!\R!\R!\R!\R!\R!\R!\W}%
+ {\the\numexpr\XINT_div_verysmallmul #1!#51;!}%
+ \Z {#4}{#5}%
+}%
+% \end{macrocode}
+% \lverb|La soustraction spéciale renvoie simplement - si le chiffre q est
+% trop grand. On invoque dans ce cas I_dP.|
+% \begin{macrocode}
+\def\XINT_div_I_dc #1#2%
+{%
+ \if-#2\expandafter\XINT_div_I_dd\else\expandafter\XINT_div_I_de\fi
+ #1#2%
+}%
+\def\XINT_div_I_dd #1-\Z
+{%
+ \if #11\expandafter\XINT_div_I_dz\fi
+ \expandafter\XINT_div_I_dP\the\numexpr #1-\xint_c_i\xint: XX%
+}%
+\def\XINT_div_I_dz #1XX#2#3#4%
+{%
+ 1#4\XINT_div_I_g {#2}%
+}%
+\def\XINT_div_I_de #1#2\Z #3#4#5{1#5+#1\XINT_div_I_g {#2}}%
+% \end{macrocode}
+% \lverb|q.alpha, B, q0, L, K, {x'y},x, alpha'B«c» (q=0 has been intercepted)
+% -> 1nouveauq.nouvel alpha, L, K, {x'y}, x, alpha',B«c»|
+% \begin{macrocode}
+\def\XINT_div_I_dP #1\xint:#2#3#4#5#6%
+{%
+ 1#6+#1\expandafter\XINT_div_I_g\expandafter
+ {\romannumeral0\expandafter\XINT_div_sub\expandafter
+ {\romannumeral0\XINT_rev_nounsep {}#4\R!\R!\R!\R!\R!\R!\R!\R!\W}%
+ {\the\numexpr\XINT_div_verysmallmul #1!#51;!}%
+ }%
+}%
+% \end{macrocode}
+% \lverb|1#1=nouveau q. nouvel alpha, L, K, {x'y},x,alpha', BQ«c»|
+% \begin{macrocode}
+% \end{macrocode}
+% \lverb|#1=q,#2=nouvel alpha,#3=L, #4=K, #5={x'y}, #6=x, #7= alpha',#8=B,
+% «c» -> on laisse q puis {x'y}alpha.alpha'.{{x'y}xKL}B«c»|
+% \begin{macrocode}
+\def\XINT_div_I_g #1#2#3#4#5#6#7%
+{%
+ \expandafter !\the\numexpr
+ \ifnum#2=#3
+ \expandafter\XINT_div_exittofinish
+ \else
+ \expandafter\XINT_div_I_h
+ \fi
+ {#4}#1\xint:#6\xint:{{#4}{#5}{#3}{#2}}{#7}%
+}%
+% \end{macrocode}
+% \lverb|{x'y}alpha.alpha'.{{x'y}xKL}B«c» -> Attention retour à l'envoyeur ici
+% par terminaison des \the\numexpr. On doit reprendre le Q déjà sorti, qui n'a
+% plus de séparateurs, ni de leading 1. Ensuite R sans leading zeros.«c»|
+% \begin{macrocode}
+\def\XINT_div_exittofinish #1#2\xint:#3\xint:#4#5%
+{%
+ 1\expandafter\expandafter\expandafter!\expandafter\XINT_div_unsepQ_delim
+ \romannumeral0\XINT_div_unsepR #2#3%
+ \xint_bye!2!3!4!5!6!7!8!9!\xint_bye\xint_c_i\relax\R\xint:
+}%
+% \end{macrocode}
+% \lverb|ATTENTION DESCRIPTION OBSOLÈTE. #1={x'y}alpha.#2!#3=reste de A.
+% #4={{x'y},x,K,L},#5=B,«c» devient {x'y},alpha sur K+4 chiffres.B,
+% {{x'y},x,K,L}, #6= nouvel alpha',B,«c»|
+% \begin{macrocode}
+\def\XINT_div_I_h #1\xint:#2!#3\xint:#4#5%
+{%
+ \XINT_div_II_b #1#2!\xint:{#5}{#4}{#3}{#5}%
+}%
+% \end{macrocode}
+% \lverb|{x'y}alpha.B, {{x'y},x,K,L}, nouveau alpha',B,«c»|
+% \begin{macrocode}
+\def\XINT_div_II_b #11#2!#3!%
+{%
+ \xint_gob_til_eightzeroes #2\XINT_div_II_skipc 00000000%
+ \XINT_div_II_c #1{1#2}{#3}%
+}%
+% \end{macrocode}
+% \lverb|x'y{100000000}{1<8>}reste de alpha.#6=B,#7={{x'y},x,K,L}, alpha',B,
+% «c» -> {x'y}x,K,L (à diminuer de 4), {alpha sur
+% K}B{q1=00000000}{alpha'}B,«c»|
+% \begin{macrocode}
+\def\XINT_div_II_skipc 00000000\XINT_div_II_c #1#2#3#4#5\xint:#6#7%
+{%
+ \XINT_div_II_k #7{#4!#5}{#6}{00000000}%
+}%
+% \end{macrocode}
+% \lverb|x'ya->1qx'yalpha.B, {{x'y},x,K,L}, nouveau alpha',B, «c». En fait,
+% attention, ici #3 et #4 sont les 16 premiers chiffres du numérateur,sous la
+% forme blocs 1<8chiffres>.
+% |
+% \begin{macrocode}
+\def\XINT_div_II_c #1#2#3#4%
+{%
+ \expandafter\XINT_div_II_d\the\numexpr\XINT_div_xmini
+ #1\xint:#2!#3!#4!{#1}{#2}#3!#4!%
+}%
+\def\XINT_div_xmini #1%
+{%
+ \xint_gob_til_one #1\XINT_div_xmini_a 1\XINT_div_mini #1%
+}%
+\def\XINT_div_xmini_a 1\XINT_div_mini 1#1%
+{%
+ \xint_gob_til_zero #1\XINT_div_xmini_b 0\XINT_div_mini 1#1%
+}%
+\def\XINT_div_xmini_b 0\XINT_div_mini 10#1#2#3#4#5#6#7%
+{%
+ \xint_gob_til_zero #7\XINT_div_xmini_c 0\XINT_div_mini 10#1#2#3#4#5#6#7%
+}%
+% \end{macrocode}
+% \lverb|x'=10^8 and we return #1=1<8digits>.|
+% \begin{macrocode}
+\def\XINT_div_xmini_c 0\XINT_div_mini 100000000\xint:50000000!#1!#2!{#1!}%
+% \end{macrocode}
+% \lverb|1 suivi de q1 sur huit chiffres! #2=x', #3=y, #4=alpha.#5=B,
+% {{x'y},x,K,L}, alpha', B, «c» --> nouvel alpha.x',y,B,q1,{{x'y},x,K,L},
+% alpha', B, «c» |
+% \begin{macrocode}
+\def\XINT_div_II_d 1#1#2#3#4#5!#6#7#8\xint:#9%
+{%
+ \expandafter\XINT_div_II_e
+ \romannumeral0\expandafter\XINT_div_sub\expandafter
+ {\romannumeral0\XINT_rev_nounsep {}#8\R!\R!\R!\R!\R!\R!\R!\R!\W}%
+ {\the\numexpr\XINT_div_smallmul_a 100000000\xint:#1#2#3#4\xint:#5!#91;!}%
+ \xint:{#6}{#7}{#9}{#1#2#3#4#5}%
+}%
+% \end{macrocode}
+% \lverb|alpha.x',y,B,q1, {{x'y},x,K,L}, alpha', B, «c». Attention la
+% soustraction spéciale doit maintenir les blocs 1<8>!|
+% \begin{macrocode}
+\def\XINT_div_II_e 1#1!%
+{%
+ \xint_gob_til_eightzeroes #1\XINT_div_II_skipf 00000000%
+ \XINT_div_II_f 1#1!%
+}%
+% \end{macrocode}
+% \lverb|100000000! alpha sur K chiffres.#2=x',#3=y,#4=B,#5=q1, #6={{x'y},x,K,L},
+% #7=alpha',B«c» -> {x'y}x,K,L (à diminuer de 1),
+% {alpha sur K}B{q1}{alpha'}B«c»|
+% \begin{macrocode}
+\def\XINT_div_II_skipf 00000000\XINT_div_II_f 100000000!#1\xint:#2#3#4#5#6%
+{%
+ \XINT_div_II_k #6{#1}{#4}{#5}%
+}%
+% \end{macrocode}
+% \lverb|1<a1>!1<a2>!, alpha (sur K+1 blocs de 8). x', y, B, q1, {{x'y},x,K,L},
+% alpha', B,«c».
+%
+% Here also we are dividing with x' which could be 10^8 in the exceptional
+% case x=99999999. Must intercept it before sending to \XINT_div_mini.|
+% \begin{macrocode}
+\def\XINT_div_II_f #1!#2!#3\xint:%
+{%
+ \XINT_div_II_fa {#1!#2!}{#1!#2!#3}%
+}%
+\def\XINT_div_II_fa #1#2#3#4%
+{%
+ \expandafter\XINT_div_II_g \the\numexpr\XINT_div_xmini #3\xint:#4!#1{#2}%
+}%
+% \end{macrocode}
+% \lverb|#1=q, #2=alpha (K+4), #3=B, #4=q1, {{x'y},x,K,L}, alpha', BQ«c»
+% -> 1 puis nouveau q sur 8 chiffres. nouvel alpha sur K blocs,
+% B, {{x'y},x,K,L}, alpha',B«c» |
+% \begin{macrocode}
+\def\XINT_div_II_g 1#1#2#3#4#5!#6#7#8%
+{%
+ \expandafter \XINT_div_II_h
+ \the\numexpr 1#1#2#3#4#5+#8\expandafter\expandafter\expandafter
+ \xint:\expandafter\expandafter\expandafter
+ {\expandafter\xint_gob_til_exclam
+ \romannumeral0\expandafter\XINT_div_sub\expandafter
+ {\romannumeral0\XINT_rev_nounsep {}#6\R!\R!\R!\R!\R!\R!\R!\R!\W}%
+ {\the\numexpr\XINT_div_smallmul_a 100000000\xint:#1#2#3#4\xint:#5!#71;!}}%
+ {#7}%
+}%
+% \end{macrocode}
+% \lverb|1 puis nouveau q sur 8 chiffres, #2=nouvel alpha sur K blocs,
+% #3=B, #4={{x'y},x,K,L} avec L à ajuster, alpha', BQ«c»
+% -> {x'y}x,K,L à diminuer de 1, {alpha}B{q}, alpha', BQ«c»|
+% \begin{macrocode}
+\def\XINT_div_II_h 1#1\xint:#2#3#4%
+{%
+ \XINT_div_II_k #4{#2}{#3}{#1}%
+}%
+% \end{macrocode}
+% \lverb|{x'y}x,K,L à diminuer de 1, alpha, B{q}alpha',B«c»
+% ->nouveau L.K,x',y,x,alpha.B,q,alpha',B,«c»
+% ->{LK{x'y}x},x,a,alpha.B,q,alpha',B,«c»|
+% \begin{macrocode}
+\def\XINT_div_II_k #1#2#3#4#5%
+{%
+ \expandafter\XINT_div_II_l \the\numexpr #4-\xint_c_i\xint:{#3}#1{#2}#5\xint:%
+}%
+\def\XINT_div_II_l #1\xint:#2#3#4#51#6!%
+{%
+ \XINT_div_II_m {{#1}{#2}{{#3}{#4}}{#5}}{#5}{#6}1#6!%
+}%
+% \end{macrocode}
+% \lverb|{LK{x'y}x},x,a,alpha.B{q}alpha'B -> a, x, alpha, B, q,
+% L, K, {x'y}, x, alpha', B«c» |
+% \begin{macrocode}
+\def\XINT_div_II_m #1#2#3#4\xint:#5#6%
+{%
+ \XINT_div_I_a {#3}{#2}{#4}{#5}{#6}#1%
+}%
+% \end{macrocode}
+% \lverb|This multiplication is exactly like \XINT_smallmul -- apart from not
+% inserting an ending 1;! --, but keeps ever a vanishing ending carry.|
+% \begin{macrocode}
+\def\XINT_div_minimulwc_a 1#1\xint:#2\xint:#3!#4#5#6#7#8\xint:%
+{%
+ \expandafter\XINT_div_minimulwc_b
+ \the\numexpr \xint_c_x^ix+#1+#3*#8\xint:#3*#4#5#6#7+#2*#8\xint:#2*#4#5#6#7\xint:%
+}%
+\def\XINT_div_minimulwc_b 1#1#2#3#4#5#6\xint:#7\xint:%
+{%
+ \expandafter\XINT_div_minimulwc_c
+ \the\numexpr \xint_c_x^ix+#1#2#3#4#5+#7\xint:#6\xint:%
+}%
+\def\XINT_div_minimulwc_c 1#1#2#3#4#5#6\xint:#7\xint:#8\xint:%
+{%
+ 1#6#7\expandafter!%
+ \the\numexpr\expandafter\XINT_div_smallmul_a
+ \the\numexpr \xint_c_x^viii+#1#2#3#4#5+#8\xint:%
+}%
+\def\XINT_div_smallmul_a #1\xint:#2\xint:#3!1#4!%
+{%
+ \xint_gob_til_sc #4\XINT_div_smallmul_e;%
+ \XINT_div_minimulwc_a #1\xint:#2\xint:#3!#4\xint:#2\xint:#3!%
+}%
+\def\XINT_div_smallmul_e;\XINT_div_minimulwc_a 1#1\xint:#2;#3!{1\relax #1!}%
+% \end{macrocode}
+% \lverb|Special very small multiplication for division. We only need to cater
+% for multiplicands from 1 to 9. The ending is different from standard
+% verysmallmul, a zero carry is not suppressed. And no final 1;! is added. If
+% multiplicand is just 1 let's not forget to add the zero carry 100000000! at
+% the end.|
+% \begin{macrocode}
+\def\XINT_div_verysmallmul #1%
+ {\xint_gob_til_one #1\XINT_div_verysmallisone 1\XINT_div_verysmallmul_a 0\xint:#1}%
+\def\XINT_div_verysmallisone 1\XINT_div_verysmallmul_a 0\xint:1!1#11;!%
+ {1\relax #1100000000!}%
+\def\XINT_div_verysmallmul_a #1\xint:#2!1#3!%
+{%
+ \xint_gob_til_sc #3\XINT_div_verysmallmul_e;%
+ \expandafter\XINT_div_verysmallmul_b
+ \the\numexpr \xint_c_x^ix+#2*#3+#1\xint:#2!%
+}%
+\def\XINT_div_verysmallmul_b 1#1#2\xint:%
+ {1#2\expandafter!\the\numexpr\XINT_div_verysmallmul_a #1\xint:}%
+\def\XINT_div_verysmallmul_e;#1;+#2#3!{1\relax 0000000#2!}%
+% \end{macrocode}
+% \lverb|Special subtraction for division purposes. If the subtracted thing
+% turns out to be bigger, then just return a -. If not, then we must reverse
+% the result, keeping the separators.|
+% \begin{macrocode}
+\def\XINT_div_sub #1#2%
+{%
+ \expandafter\XINT_div_sub_clean
+ \the\numexpr\expandafter\XINT_div_sub_a\expandafter
+ 1#2;!;!;!;!;!\W #1;!;!;!;!;!\W
+}%
+\def\XINT_div_sub_clean #1-#2#3\W
+{%
+ \if1#2\expandafter\XINT_rev_nounsep\else\expandafter\XINT_div_sub_neg\fi
+ {}#1\R!\R!\R!\R!\R!\R!\R!\R!\W
+}%
+\def\XINT_div_sub_neg #1\W { -}%
+\def\XINT_div_sub_a #1!#2!#3!#4!#5\W #6!#7!#8!#9!%
+{%
+ \XINT_div_sub_b #1!#6!#2!#7!#3!#8!#4!#9!#5\W
+}%
+\def\XINT_div_sub_b #1#2#3!#4!%
+{%
+ \xint_gob_til_sc #4\XINT_div_sub_bi ;%
+ \expandafter\XINT_div_sub_c\the\numexpr#1-#3+1#4-\xint_c_i\xint:%
+}%
+\def\XINT_div_sub_c 1#1#2\xint:%
+{%
+ 1#2\expandafter!\the\numexpr\XINT_div_sub_d #1%
+}%
+\def\XINT_div_sub_d #1#2#3!#4!%
+{%
+ \xint_gob_til_sc #4\XINT_div_sub_di ;%
+ \expandafter\XINT_div_sub_e\the\numexpr#1-#3+1#4-\xint_c_i\xint:%
+}%
+\def\XINT_div_sub_e 1#1#2\xint:%
+{%
+ 1#2\expandafter!\the\numexpr\XINT_div_sub_f #1%
+}%
+\def\XINT_div_sub_f #1#2#3!#4!%
+{%
+ \xint_gob_til_sc #4\XINT_div_sub_fi ;%
+ \expandafter\XINT_div_sub_g\the\numexpr#1-#3+1#4-\xint_c_i\xint:%
+}%
+\def\XINT_div_sub_g 1#1#2\xint:%
+{%
+ 1#2\expandafter!\the\numexpr\XINT_div_sub_h #1%
+}%
+\def\XINT_div_sub_h #1#2#3!#4!%
+{%
+ \xint_gob_til_sc #4\XINT_div_sub_hi ;%
+ \expandafter\XINT_div_sub_i\the\numexpr#1-#3+1#4-\xint_c_i\xint:%
+}%
+\def\XINT_div_sub_i 1#1#2\xint:%
+{%
+ 1#2\expandafter!\the\numexpr\XINT_div_sub_a #1%
+}%
+\def\XINT_div_sub_bi;%
+ \expandafter\XINT_div_sub_c\the\numexpr#1-#2+#3\xint:#4!#5!#6!#7!#8!#9!;!\W
+{%
+ \XINT_div_sub_l #1#2!#5!#7!#9!%
+}%
+\def\XINT_div_sub_di;%
+ \expandafter\XINT_div_sub_e\the\numexpr#1-#2+#3\xint:#4!#5!#6!#7!#8\W
+{%
+ \XINT_div_sub_l #1#2!#5!#7!%
+}%
+\def\XINT_div_sub_fi;%
+ \expandafter\XINT_div_sub_g\the\numexpr#1-#2+#3\xint:#4!#5!#6\W
+{%
+ \XINT_div_sub_l #1#2!#5!%
+}%
+\def\XINT_div_sub_hi;%
+ \expandafter\XINT_div_sub_i\the\numexpr#1-#2+#3\xint:#4\W
+{%
+ \XINT_div_sub_l #1#2!%
+}%
+\def\XINT_div_sub_l #1%
+{%
+ \xint_UDzerofork
+ #1{-2\relax}%
+ 0\XINT_div_sub_r
+ \krof
+}%
+\def\XINT_div_sub_r #1!%
+{%
+ -\ifnum 0#1=\xint_c_ 1\else2\fi\relax
+}%
+% \end{macrocode}
+% \lverb|Ici B<10^8 (et est >2). On
+% exécute$newline
+% \expandafter\XINT_sdiv_out\the\numexpr\XINT_smalldivx_a
+% x.1B!1<8d>!...1<8d>!1;!$newline
+% avec x =round(B/2), 1B=10^8+B, et A déjà en
+% blocs 1<8d>! (non renversés). Le \the\numexpr\XINT_smalldivx_a va produire
+% Q\Z R\W avec un R<10^8, et un Q sous forme de blocs 1<8d>! terminé par 1!
+% et nécessitant le nettoyage du premier bloc. Dans cette branche le B n'a pas
+% été multiplié par une puissance de 10, il peut avoir moins de huit chiffres.
+%
+% |
+% \begin{macrocode}
+\def\XINT_sdiv_out #1;!#2!%
+ {\expandafter
+ {\romannumeral0\XINT_unsep_cuzsmall
+ #1\xint_bye!2!3!4!5!6!7!8!9!\xint_bye\xint_c_i\relax}%
+ {#2}}%
+% \end{macrocode}
+% \lverb|La toute première étape fait la première division pour être sûr par
+% la suite d'avoir un premier bloc pour A qui sera < B.|
+% \begin{macrocode}
+\def\XINT_smalldivx_a #1\xint:1#2!1#3!%
+{%
+ \expandafter\XINT_smalldivx_b
+ \the\numexpr (#3+#1)/#2-\xint_c_i!#1\xint:#2!#3!%
+}%
+\def\XINT_smalldivx_b #1#2!%
+{%
+ \if0#1\else
+ \xint_c_x^viii+#1#2\xint_afterfi{\expandafter!\the\numexpr}\fi
+ \XINT_smalldiv_c #1#2!%
+}%
+\def\XINT_smalldiv_c #1!#2\xint:#3!#4!%
+{%
+ \expandafter\XINT_smalldiv_d\the\numexpr #4-#1*#3!#2\xint:#3!%
+}%
+% \end{macrocode}
+% \lverb|On va boucler ici: #1 est un reste, #2 est x.B (avec B sans le 1 mais
+% sur huit chiffres). #3#4 est le premier bloc qui reste de A. Si on a terminé
+% avec A, alors #1 est le reste final. Le quotient lui est terminé par un 1!
+% ce 1! disparaîtra dans le nettoyage par \XINT_unsep_cuzsmall.
+% |
+% \begin{macrocode}
+\def\XINT_smalldiv_d #1!#2!1#3#4!%
+{%
+ \xint_gob_til_sc #3\XINT_smalldiv_end ;%
+ \XINT_smalldiv_e #1!#2!1#3#4!%
+}%
+\def\XINT_smalldiv_end;\XINT_smalldiv_e #1!#2!1;!{1!;!#1!}%
+% \end{macrocode}
+% \lverb|Il est crucial que le reste #1 est < #3. J'ai documenté cette routine
+% dans le fichier où j'ai préparé 1.2, il faudra transférer ici. Il n'est pas
+% nécessaire pour cette routine que le diviseur B ait au moins 8 chiffres.
+% Mais il doit être < 10^8.|
+% \begin{macrocode}
+\def\XINT_smalldiv_e #1!#2\xint:#3!%
+{%
+ \expandafter\XINT_smalldiv_f\the\numexpr
+ \xint_c_xi_e_viii_mone+#1*\xint_c_x^viii/#3!#2\xint:#3!#1!%
+}%
+\def\XINT_smalldiv_f 1#1#2#3#4#5#6!#7\xint:#8!%
+{%
+ \xint_gob_til_zero #1\XINT_smalldiv_fz 0%
+ \expandafter\XINT_smalldiv_g
+ \the\numexpr\XINT_minimul_a #2#3#4#5\xint:#6!#8!#2#3#4#5#6!#7\xint:#8!%
+}%
+\def\XINT_smalldiv_fz 0%
+ \expandafter\XINT_smalldiv_g\the\numexpr\XINT_minimul_a
+ 9999\xint:9999!#1!99999999!#2!0!1#3!%
+{%
+ \XINT_smalldiv_i \xint:#3!\xint_c_!#2!%
+}%
+\def\XINT_smalldiv_g 1#1!1#2!#3!#4!#5!#6!%
+{%
+ \expandafter\XINT_smalldiv_h\the\numexpr 1#6-#1\xint:#2!#5!#3!#4!%
+}%
+\def\XINT_smalldiv_h 1#1#2\xint:#3!#4!%
+{%
+ \expandafter\XINT_smalldiv_i\the\numexpr #4-#3+#1-\xint_c_i\xint:#2!%
+}%
+\def\XINT_smalldiv_i #1\xint:#2!#3!#4\xint:#5!%
+{%
+ \expandafter\XINT_smalldiv_j\the\numexpr (#1#2+#4)/#5-\xint_c_i!#3!#1#2!#4\xint:#5!%
+}%
+\def\XINT_smalldiv_j #1!#2!%
+{%
+ \xint_c_x^viii+#1+#2\expandafter!\the\numexpr\XINT_smalldiv_k
+ #1!%
+}%
+% \end{macrocode}
+% \lverb|On boucle vers \XINT_smalldiv_d.|
+% \begin{macrocode}
+\def\XINT_smalldiv_k #1!#2!#3\xint:#4!%
+{%
+ \expandafter\XINT_smalldiv_d\the\numexpr #2-#1*#4!#3\xint:#4!%
+}%
+% \end{macrocode}
+% \lverb|Cette routine fait la division euclidienne d'un nombre de seize
+% chiffres par #1 = C = diviseur sur huit chiffres >= 10^7, avec #2 = sa
+% moitié utilisée dans \numexpr pour contrebalancer l'arrondi
+% (ARRRRRRGGGGGHHHH) fait par /. Le nombre divisé XY = X*10^8+Y se présente
+% sous la forme 1<8chiffres>!1<8chiffres>! avec plus significatif en premier.
+%
+% Seul le quotient est calculé, pas le reste. En effet la routine de division
+% principale va utiliser ce quotient pour déterminer le "grand" reste, et le
+% petit reste ici ne nous serait d'à peu près aucune utilité.
+%
+% ATTENTION UNIQUEMENT UTILISÉ POUR DES SITUATIONS OÙ IL EST GARANTI QUE X <
+% C ! (et C au moins 10^7) le quotient euclidien de X*10^8+Y par C sera donc <
+% 10^8. Il sera renvoyé sous la forme 1<8chiffres>.|
+% \begin{macrocode}
+\def\XINT_div_mini #1\xint:#2!1#3!%
+{%
+ \expandafter\XINT_div_mini_a\the\numexpr
+ \xint_c_xi_e_viii_mone+#3*\xint_c_x^viii/#1!#1\xint:#2!#3!%
+}%
+% \end{macrocode}
+% \lverb|Note (2015/10/08). Attention à la différence dans l'ordre des
+% arguments avec ce que je vois en dans \XINT_smalldiv_f. Je ne me souviens
+% plus du tout s'il y a une raison quelconque.|
+% \begin{macrocode}
+\def\XINT_div_mini_a 1#1#2#3#4#5#6!#7\xint:#8!%
+{%
+ \xint_gob_til_zero #1\XINT_div_mini_w 0%
+ \expandafter\XINT_div_mini_b
+ \the\numexpr\XINT_minimul_a #2#3#4#5\xint:#6!#7!#2#3#4#5#6!#7\xint:#8!%
+}%
+\def\XINT_div_mini_w 0%
+ \expandafter\XINT_div_mini_b\the\numexpr\XINT_minimul_a
+ 9999\xint:9999!#1!99999999!#2\xint:#3!00000000!#4!%
+{%
+ \xint_c_x^viii_mone+(#4+#3)/#2!%
+}%
+\def\XINT_div_mini_b 1#1!1#2!#3!#4!#5!#6!%
+{%
+ \expandafter\XINT_div_mini_c
+ \the\numexpr 1#6-#1\xint:#2!#5!#3!#4!%
+}%
+\def\XINT_div_mini_c 1#1#2\xint:#3!#4!%
+{%
+ \expandafter\XINT_div_mini_d
+ \the\numexpr #4-#3+#1-\xint_c_i\xint:#2!%
+}%
+\def\XINT_div_mini_d #1\xint:#2!#3!#4\xint:#5!%
+{%
+ \xint_c_x^viii_mone+#3+(#1#2+#5)/#4!%
+}%
+% \end{macrocode}
+% \subsection*{Derived arithmetic}
+% \addcontentsline{toc}{subsection}{Derived arithmetic}
+% \subsection{\csh{xintiiQuo}, \csh{xintiiRem}}
+% \begin{macrocode}
+\def\xintiiQuo {\romannumeral0\xintiiquo }%
+\def\xintiiRem {\romannumeral0\xintiirem }%
+\def\xintiiquo
+ {\expandafter\xint_stop_atfirstoftwo\romannumeral0\xintiidivision }%
+\def\xintiirem
+ {\expandafter\xint_stop_atsecondoftwo\romannumeral0\xintiidivision }%
+% \end{macrocode}
+% \subsection{\csh{xintiiDivRound}}
+% \lverb|1.1, transferred from first release of bnumexpr. Rewritten for 1.2.
+% Ending rewritten for 1.2i. (new \xintDSRr).
+%
+% 1.2l: \xintiiDivRound made robust against non terminated input.|
+% \begin{macrocode}
+\def\xintiiDivRound {\romannumeral0\xintiidivround }%
+\def\xintiidivround #1{\expandafter\XINT_iidivround\romannumeral`&&@#1\xint:}%
+\def\XINT_idivround #1#2\xint:#3%
+ {\expandafter\XINT_iidivround_a\expandafter #1%
+ \romannumeral0\xintnum{#3}\xint:#2\xint:}%
+\def\XINT_iidivround #1#2\xint:#3%
+ {\expandafter\XINT_iidivround_a\expandafter #1\romannumeral`&&@#3\xint:#2\xint:}%
+\def\XINT_iidivround_a #1#2% #1 de A, #2 de B.
+{%
+ \if0#2\xint_dothis{\XINT_iidivround_divbyzero#1#2}\fi
+ \if0#1\xint_dothis\XINT_iidivround_aiszero\fi
+ \if-#2\xint_dothis{\XINT_iidivround_bneg #1}\fi
+ \xint_orthat{\XINT_iidivround_bpos #1#2}%
+}%
+\def\XINT_iidivround_divbyzero #1#2#3\xint:#4\xint:
+ {\XINT_signalcondition{DivisionByZero}{Division of #1#4 by #2#3}{}{0}}%
+\def\XINT_iidivround_aiszero #1\xint:#2\xint:{ 0}%
+\def\XINT_iidivround_bpos #1%
+{%
+ \xint_UDsignfork
+ #1{\xintiiopp\XINT_iidivround_pos {}}%
+ -{\XINT_iidivround_pos #1}%
+ \krof
+}%
+\def\XINT_iidivround_bneg #1%
+{%
+ \xint_UDsignfork
+ #1{\XINT_iidivround_pos {}}%
+ -{\xintiiopp\XINT_iidivround_pos #1}%
+ \krof
+}%
+\def\XINT_iidivround_pos #1#2\xint:#3\xint:
+{%
+ \expandafter\expandafter\expandafter\XINT_dsrr
+ \expandafter\xint_firstoftwo
+ \romannumeral0\XINT_div_prepare {#2}{#1#30}%
+ \xint_bye\xint_Bye3456789\xint_bye/\xint_c_x\relax
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiDivTrunc}}
+% \lverb|1.2l: \xintiiDivTrunc made robust against non terminated input.|
+% \begin{macrocode}
+\def\xintiiDivTrunc {\romannumeral0\xintiidivtrunc }%
+\def\xintiidivtrunc #1{\expandafter\XINT_iidivtrunc\romannumeral`&&@#1\xint:}%
+\def\XINT_iidivtrunc #1#2\xint:#3{\expandafter\XINT_iidivtrunc_a\expandafter #1%
+ \romannumeral`&&@#3\xint:#2\xint:}%
+\def\XINT_iidivtrunc_a #1#2% #1 de A, #2 de B.
+{%
+ \if0#2\xint_dothis{\XINT_iidivtrunc_divbyzero#1#2}\fi
+ \if0#1\xint_dothis\XINT_iidivtrunc_aiszero\fi
+ \if-#2\xint_dothis{\XINT_iidivtrunc_bneg #1}\fi
+ \xint_orthat{\XINT_iidivtrunc_bpos #1#2}%
+}%
+% \end{macrocode}
+% \lverb|Attention to not move DivRound code beyond that point.|
+% \begin{macrocode}
+\let\XINT_iidivtrunc_divbyzero\XINT_iidivround_divbyzero
+\let\XINT_iidivtrunc_aiszero \XINT_iidivround_aiszero
+\def\XINT_iidivtrunc_bpos #1%
+{%
+ \xint_UDsignfork
+ #1{\xintiiopp\XINT_iidivtrunc_pos {}}%
+ -{\XINT_iidivtrunc_pos #1}%
+ \krof
+}%
+\def\XINT_iidivtrunc_bneg #1%
+{%
+ \xint_UDsignfork
+ #1{\XINT_iidivtrunc_pos {}}%
+ -{\xintiiopp\XINT_iidivtrunc_pos #1}%
+ \krof
+}%
+\def\XINT_iidivtrunc_pos #1#2\xint:#3\xint:
+ {\expandafter\xint_stop_atfirstoftwo
+ \romannumeral0\XINT_div_prepare {#2}{#1#3}}%
+% \end{macrocode}
+% \subsection{\csh{xintiiModTrunc}}
+% \lverb|Renamed from \xintiiMod to \xintiiModTrunc at 1.2p.|
+% \begin{macrocode}
+\def\xintiiModTrunc {\romannumeral0\xintiimodtrunc }%
+\def\xintiimodtrunc #1{\expandafter\XINT_iimodtrunc\romannumeral`&&@#1\xint:}%
+\def\XINT_iimodtrunc #1#2\xint:#3{\expandafter\XINT_iimodtrunc_a\expandafter #1%
+ \romannumeral`&&@#3\xint:#2\xint:}%
+\def\XINT_iimodtrunc_a #1#2% #1 de A, #2 de B.
+{%
+ \if0#2\xint_dothis{\XINT_iimodtrunc_divbyzero#1#2}\fi
+ \if0#1\xint_dothis\XINT_iimodtrunc_aiszero\fi
+ \if-#2\xint_dothis{\XINT_iimodtrunc_bneg #1}\fi
+ \xint_orthat{\XINT_iimodtrunc_bpos #1#2}%
+}%
+% \end{macrocode}
+% \lverb|Attention to not move DivRound code beyond that point. A bit of abuse
+% here for divbyzero defaulted-to value, which happily works in both.|
+% \begin{macrocode}
+\let\XINT_iimodtrunc_divbyzero\XINT_iidivround_divbyzero
+\let\XINT_iimodtrunc_aiszero \XINT_iidivround_aiszero
+\def\XINT_iimodtrunc_bpos #1%
+{%
+ \xint_UDsignfork
+ #1{\xintiiopp\XINT_iimodtrunc_pos {}}%
+ -{\XINT_iimodtrunc_pos #1}%
+ \krof
+}%
+\def\XINT_iimodtrunc_bneg #1%
+{%
+ \xint_UDsignfork
+ #1{\xintiiopp\XINT_iimodtrunc_pos {}}%
+ -{\XINT_iimodtrunc_pos #1}%
+ \krof
+}%
+\def\XINT_iimodtrunc_pos #1#2\xint:#3\xint:
+ {\expandafter\xint_stop_atsecondoftwo\romannumeral0\XINT_div_prepare
+ {#2}{#1#3}}%
+% \end{macrocode}
+% \subsection{\csh{xintiiDivMod}}
+% \changed{1.2p}{}
+% It is associated with floored division (like Python divmod
+% function), and with the |//| operator in \csbxint{iiexpr}.
+% \begin{macrocode}
+\def\xintiiDivMod {\romannumeral0\xintiidivmod }%
+\def\xintiidivmod #1{\expandafter\XINT_iidivmod\romannumeral`&&@#1\xint:}%
+\def\XINT_iidivmod #1#2\xint:#3{\expandafter\XINT_iidivmod_a\expandafter #1%
+ \romannumeral`&&@#3\xint:#2\xint:}%
+\def\XINT_iidivmod_a #1#2% #1 de A, #2 de B.
+{%
+ \if0#2\xint_dothis{\XINT_iidivmod_divbyzero#1#2}\fi
+ \if0#1\xint_dothis\XINT_iidivmod_aiszero\fi
+ \if-#2\xint_dothis{\XINT_iidivmod_bneg #1}\fi
+ \xint_orthat{\XINT_iidivmod_bpos #1#2}%
+}%
+\def\XINT_iidivmod_divbyzero #1#2\xint:#3\xint:
+{%
+ \XINT_signalcondition{DivisionByZero}{Division by #2 of #1#3}{}%
+ {{0}{0}}% à revoir...
+}%
+\def\XINT_iidivmod_aiszero #1\xint:#2\xint:{{0}{0}}%
+\def\XINT_iidivmod_bneg #1%
+{%
+ \expandafter\XINT_iidivmod_bneg_finish
+ \romannumeral0\xint_UDsignfork
+ #1{\XINT_iidivmod_bpos {}}%
+ -{\XINT_iidivmod_bpos {-#1}}%
+ \krof
+}%
+\def\XINT_iidivmod_bneg_finish#1#2%
+{%
+ \expandafter\xint_exchangetwo_keepbraces\expandafter
+ {\romannumeral0\xintiiopp#2}{#1}%
+}%
+\def\XINT_iidivmod_bpos #1#2\xint:#3\xint:{\xintiidivision{#1#3}{#2}}%
+% \end{macrocode}
+% \subsection{\csh{xintiiDivFloor}}
+% \lverb|1.2p. For bnumexpr actually, because \xintiiexpr could use
+% \xintDivFloor which also outputs an integer in strict format.|
+% \begin{macrocode}
+\def\xintiiDivFloor {\romannumeral0\xintiidivfloor}%
+\def\xintiidivfloor {\expandafter\xint_stop_atfirstoftwo
+ \romannumeral0\xintiidivmod}%
+% \end{macrocode}
+% \subsection{\csh{xintiiMod}}
+% \lverb|Associated with floored division at 1.2p. Formerly was associated with
+% truncated division.|
+% \begin{macrocode}
+\def\xintiiMod {\romannumeral0\xintiimod}%
+\def\xintiimod {\expandafter\xint_stop_atsecondoftwo
+ \romannumeral0\xintiidivmod}%
+% \end{macrocode}
+% \subsection{\csh{xintiiSqr}}
+% \lverb|1.2l: \xintiiSqr made robust against non terminated input.|
+% \begin{macrocode}
+\def\xintiiSqr {\romannumeral0\xintiisqr }%
+\def\xintiisqr #1%
+{%
+ \expandafter\XINT_sqr\romannumeral0\xintiiabs{#1}\xint:
+}%
+\def\XINT_sqr #1\xint:
+{%
+ \expandafter\XINT_sqr_a
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #1\R\R\R\R\R\R\R\R{10}0000001\W
+ #1\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_i
+ \R\xint:\xint_c_xii \R\xint:\xint_c_x \R\xint:\xint_c_viii \R\xint:\xint_c_vi
+ \R\xint:\xint_c_iv \R\xint:\xint_c_ii \R\xint:\xint_c_\W
+ \xint:
+}%
+% \end{macrocode}
+% \lverb|1.2c \XINT_mul_loop can now be called directly even with small
+% arguments, thus the following check is not anymore a necessity.|
+% \begin{macrocode}
+\def\XINT_sqr_a #1\xint:
+{%
+ \ifnum #1=\xint_c_i \expandafter\XINT_sqr_small
+ \else\expandafter\XINT_sqr_start\fi
+}%
+\def\XINT_sqr_small 1#1#2#3#4#5!\xint:
+{%
+ \ifnum #1#2#3#4#5<46341 \expandafter\XINT_sqr_verysmall\fi
+ \expandafter\XINT_sqr_small_out
+ \the\numexpr\XINT_minimul_a #1#2#3#4\xint:#5!#1#2#3#4#5!%
+}%
+\def\XINT_sqr_verysmall#1{%
+\def\XINT_sqr_verysmall
+ \expandafter\XINT_sqr_small_out\the\numexpr\XINT_minimul_a ##1!##2!%
+ {\expandafter#1\the\numexpr ##2*##2\relax}%
+}\XINT_sqr_verysmall{ }%
+\def\XINT_sqr_small_out 1#1!1#2!%
+{%
+ \XINT_cuz #2#1\R
+}%
+% \end{macrocode}
+% \lverb|An ending 1;! is produced on output for \XINT_mul_loop and gets
+% incorporated to the delimiter needed by the \XINT_unrevbyviii done by
+% \XINT_mul_out.|
+% \begin{macrocode}
+\def\XINT_sqr_start #1\xint:
+{%
+ \expandafter\XINT_mul_out
+ \the\numexpr\XINT_mul_loop
+ 100000000!1;!\W #11;!\W #11;!%
+ 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiPow}}
+% \lverb|&
+% The exponent is not limited but with current default settings of tex memory,
+% with xint 1.2, the maximal exponent for 2^N is N = 2^17 = 131072.
+%
+% 1.2f Modifies the initial steps: 1) in order to be able to let more easily
+% \xintiPow use \xintNum on the exponent once xintfrac.sty is loaded; 2) also
+% because I noticed it was not very well coded. And it did only a \numexpr on
+% the exponent, contradicting the documentation related to the "i" convention
+% in names.
+%
+% 1.2l: \xintiiPow made robust against non terminated input.|
+% \begin{macrocode}
+\def\xintiiPow {\romannumeral0\xintiipow }%
+\def\xintiipow #1#2%
+{%
+ \expandafter\xint_pow\the\numexpr #2\expandafter
+ .\romannumeral`&&@#1\xint:
+}%
+\def\xint_pow #1.#2%#3\xint:
+{%
+ \xint_UDzerominusfork
+ #2-\XINT_pow_AisZero
+ 0#2\XINT_pow_Aneg
+ 0-{\XINT_pow_Apos #2}%
+ \krof {#1}%
+}%
+\def\XINT_pow_AisZero #1#2\xint:
+{%
+ \ifcase\XINT_cntSgn #1\xint:
+ \xint_afterfi { 1}%
+ \or
+ \xint_afterfi { 0}%
+ \else
+ \xint_afterfi
+ {\XINT_signalcondition{DivisionByZero}{Zero to power #1}{}{0}}%
+ \fi
+}%
+\def\XINT_pow_Aneg #1%
+{%
+ \ifodd #1
+ \expandafter\XINT_opp\romannumeral0%
+ \fi
+ \XINT_pow_Apos {}{#1}%
+}%
+\def\XINT_pow_Apos #1#2{\XINT_pow_Apos_a {#2}#1}%
+\def\XINT_pow_Apos_a #1#2#3%
+{%
+ \xint_gob_til_xint: #3\XINT_pow_Apos_short\xint:
+ \XINT_pow_AatleastTwo {#1}#2#3%
+}%
+\def\XINT_pow_Apos_short\xint:\XINT_pow_AatleastTwo #1#2\xint:
+{%
+ \ifcase #2
+ \xintError:thiscannothappen
+ \or \expandafter\XINT_pow_AisOne
+ \else\expandafter\XINT_pow_AatleastTwo
+ \fi {#1}#2\xint:
+}%
+\def\XINT_pow_AisOne #1\xint:{ 1}%
+\def\XINT_pow_AatleastTwo #1%
+{%
+ \ifcase\XINT_cntSgn #1\xint:
+ \expandafter\XINT_pow_BisZero
+ \or
+ \expandafter\XINT_pow_I_in
+ \else
+ \expandafter\XINT_pow_BisNegative
+ \fi
+ {#1}%
+}%
+\def\XINT_pow_BisNegative #1\xint:{\XINT_signalcondition{Underflow}{Inverse power
+ can not be represented by an integer}{}{0}}%
+\def\XINT_pow_BisZero #1\xint:{ 1}%
+% \end{macrocode}
+% \lverb|B = #1 > 0, A = #2 > 1. Earlier code checked if size of B did not
+% exceed a given limit (for example 131000).|
+% \begin{macrocode}
+\def\XINT_pow_I_in #1#2\xint:
+{%
+ \expandafter\XINT_pow_I_loop
+ \the\numexpr #1\expandafter\xint:%
+ \romannumeral0\expandafter\XINT_sepandrev
+ \romannumeral0\XINT_zeroes_forviii #2\R\R\R\R\R\R\R\R{10}0000001\W
+ #2\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax XX%
+ \R\xint:\R\xint:\R\xint:\R\xint:\R\xint:\R\xint:\R\xint:\R\xint:\W
+ 1;!\W
+ 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
+}%
+\def\XINT_pow_I_loop #1\xint:%
+{%
+ \ifnum #1 = \xint_c_i\expandafter\XINT_pow_I_exit\fi
+ \ifodd #1
+ \expandafter\XINT_pow_II_in
+ \else
+ \expandafter\XINT_pow_I_squareit
+ \fi #1\xint:%
+}%
+\def\XINT_pow_I_exit \ifodd #1\fi #2\xint:#3\W {\XINT_mul_out #3}%
+% \end{macrocode}
+% \lverb|The 1.2c \XINT_mul_loop can be called directly even with small
+% arguments, hence the "butcheckifsmall" is not a necessity as it was earlier
+% with 1.2. On 2^30, it does bring roughly a 40$char37 $space time gain
+% though, and 30$char37 $space gain for 2^60. The overhead on big computations
+% should be negligible.|
+% \begin{macrocode}
+\def\XINT_pow_I_squareit #1\xint:#2\W%
+{%
+ \expandafter\XINT_pow_I_loop
+ \the\numexpr #1/\xint_c_ii\expandafter\xint:%
+ \the\numexpr\XINT_pow_mulbutcheckifsmall #2\W #2\W
+}%
+\def\XINT_pow_mulbutcheckifsmall #1!1#2%
+{%
+ \xint_gob_til_sc #2\XINT_pow_mul_small;%
+ \XINT_mul_loop 100000000!1;!\W #1!1#2%
+}%
+\def\XINT_pow_mul_small;\XINT_mul_loop
+ 100000000!1;!\W 1#1!1;!\W
+{%
+ \XINT_smallmul 1#1!%
+}%
+\def\XINT_pow_II_in #1\xint:#2\W
+{%
+ \expandafter\XINT_pow_II_loop
+ \the\numexpr #1/\xint_c_ii-\xint_c_i\expandafter\xint:%
+ \the\numexpr\XINT_pow_mulbutcheckifsmall #2\W #2\W #2\W
+}%
+\def\XINT_pow_II_loop #1\xint:%
+{%
+ \ifnum #1 = \xint_c_i\expandafter\XINT_pow_II_exit\fi
+ \ifodd #1
+ \expandafter\XINT_pow_II_odda
+ \else
+ \expandafter\XINT_pow_II_even
+ \fi #1\xint:%
+}%
+\def\XINT_pow_II_exit\ifodd #1\fi #2\xint:#3\W #4\W
+{%
+ \expandafter\XINT_mul_out
+ \the\numexpr\XINT_pow_mulbutcheckifsmall #4\W #3%
+}%
+\def\XINT_pow_II_even #1\xint:#2\W
+{%
+ \expandafter\XINT_pow_II_loop
+ \the\numexpr #1/\xint_c_ii\expandafter\xint:%
+ \the\numexpr\XINT_pow_mulbutcheckifsmall #2\W #2\W
+}%
+\def\XINT_pow_II_odda #1\xint:#2\W #3\W
+{%
+ \expandafter\XINT_pow_II_oddb
+ \the\numexpr #1/\xint_c_ii-\xint_c_i\expandafter\xint:%
+ \the\numexpr\XINT_pow_mulbutcheckifsmall #3\W #2\W #2\W
+}%
+\def\XINT_pow_II_oddb #1\xint:#2\W #3\W
+{%
+ \expandafter\XINT_pow_II_loop
+ \the\numexpr #1\expandafter\xint:%
+ \the\numexpr\XINT_pow_mulbutcheckifsmall #3\W #3\W #2\W
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiFac}}
+% \lverb|Moved here from xint.sty with release 1.2 (to be usable by \bnumexpr).
+%
+% An \xintiFac is needed by xintexpr.sty. Prior to 1.2o it was defined here
+% as an alias to \xintiiFac, then redefined by xintfrac to use \xintNum. This
+% was incoherent. Contrarily to other similarly named macros,
+% \xintiiFac uses \numexpr on its input. This is also incoherent with the
+% naming scheme, alas.
+%
+% Partially rewritten with release 1.2 to benefit from the inner format of the
+% 1.2 multiplication.
+%
+% With current default settings of the etex memory and a.t.t.o.w (11/2015) the
+% maximal possible computation is 5971! (which has 19956 digits).
+%
+%
+%
+% Note (end november 2015): I also tried out a quickly written recursive
+% (binary split) implementation
+%
+%( \catcode`_ 11
+%: \catcode`^ 11
+%: \long\def\xint_firstofthree #1#2#3{#1}$%
+%: \long\def\xint_secondofthree #1#2#3{#2}$%
+%: \long\def\xint_thirdofthree #1#2#3{#3}$%
+%: $% quickly written factorial using binary split recursive method
+%: \def\tFac {\romannumeral-`0\tfac }$%
+%: \def\tfac #1{\expandafter\XINT_mul_out
+%: \romannumeral-`0\ufac {1}{#1}1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W}$%
+%: \def\ufac #1#2{\ifcase\numexpr#2-#1\relax
+%: \expandafter\xint_firstofthree
+%: \or
+%: \expandafter\xint_secondofthree
+%: \else
+%: \expandafter\xint_thirdofthree
+%: \fi
+%: {\the\numexpr\xint_c_x^viii+#1!1;!}$%
+%: {\the\numexpr\xint_c_x^viii+#1*#2!1;!}$%
+%: {\expandafter\vfac\the\numexpr (#1+#2)/\xint_c_ii.#1.#2.}$%
+%: }$%
+%: \def\vfac #1.#2.#3.$%
+%: {$%
+%: \expandafter
+%: \wfac\expandafter
+%: {\romannumeral-`0\expandafter
+%: \ufac\expandafter{\the\numexpr #1+\xint_c_i}{#3}}$%
+%: {\ufac {#2}{#1}}$%
+%: }$%
+%: \def\wfac #1#2{\expandafter\zfac\romannumeral-`0#2\W #1}$%
+%: \def\zfac {\the\numexpr\XINT_mul_loop 100000000!1;!\W }$% core multiplication...
+%: \catcode`_ 8
+%: \catcode`^ 7
+%)
+% and I was quite surprised that it was only about 1.6x--2x slower in the range
+% N=200 to 2000 than the \xintiiFac here which attempts to be smarter...
+%
+% Note (2017, 1.2l): I found out some code comment of mine that the code here
+% should be more in the style of \xintiiBinomial, but I left matters
+% untouched.
+%
+%
+%
+% 1.2o modifies \xintiFac to be coherent with \xintiBinomial: only with
+% xintfrac.sty loaded does it use \xintNum. It is documented only as macro of
+% xintfrac.sty, not as macro of xint.sty.
+% |
+% \begin{macrocode}
+\def\xintiiFac {\romannumeral0\xintiifac }%
+\def\xintiifac #1{\expandafter\XINT_fac_fork\the\numexpr#1.}%
+\def\XINT_fac_fork #1#2.%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_fac_zero
+ 0#1\XINT_fac_neg
+ 0-\XINT_fac_checksize
+ \krof #1#2.%
+}%
+\def\XINT_fac_zero #1.{ 1}%
+\def\XINT_fac_neg #1.{\XINT_signalcondition{InvalidOperation}{Factorial of
+ negative: (#1)!}{}{0}}%
+% \end{macrocode}
+% \begin{macrocode}
+\def\XINT_fac_checksize #1.%
+{%
+ \ifnum #1>\xint_c_x^iv \xint_dothis{\XINT_fac_toobig #1.}\fi
+ \ifnum #1>465 \xint_dothis{\XINT_fac_bigloop_a #1.}\fi
+ \ifnum #1>101 \xint_dothis{\XINT_fac_medloop_a #1.\XINT_mul_out}\fi
+ \xint_orthat{\XINT_fac_smallloop_a #1.\XINT_mul_out}%
+ 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
+}%
+\def\XINT_fac_toobig #1.#2\W{\XINT_signalcondition{InvalidOperation}{Factorial
+ of too big argument: #1 > 10000}{}{0}}%
+\def\XINT_fac_bigloop_a #1.%
+{%
+ \expandafter\XINT_fac_bigloop_b \the\numexpr
+ #1+\xint_c_i-\xint_c_ii*((#1-464)/\xint_c_ii).#1.%
+}%
+\def\XINT_fac_bigloop_b #1.#2.%
+{%
+ \expandafter\XINT_fac_medloop_a
+ \the\numexpr #1-\xint_c_i.{\XINT_fac_bigloop_loop #1.#2.}%
+}%
+\def\XINT_fac_bigloop_loop #1.#2.%
+{%
+ \ifnum #1>#2 \expandafter\XINT_fac_bigloop_exit\fi
+ \expandafter\XINT_fac_bigloop_loop
+ \the\numexpr #1+\xint_c_ii\expandafter.%
+ \the\numexpr #2\expandafter.\the\numexpr\XINT_fac_bigloop_mul #1!%
+}%
+\def\XINT_fac_bigloop_exit #1!{\XINT_mul_out}%
+\def\XINT_fac_bigloop_mul #1!%
+{%
+ \expandafter\XINT_smallmul
+ \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!%
+}%
+\def\XINT_fac_medloop_a #1.%
+{%
+ \expandafter\XINT_fac_medloop_b
+ \the\numexpr #1+\xint_c_i-\xint_c_iii*((#1-100)/\xint_c_iii).#1.%
+}%
+\def\XINT_fac_medloop_b #1.#2.%
+{%
+ \expandafter\XINT_fac_smallloop_a
+ \the\numexpr #1-\xint_c_i.{\XINT_fac_medloop_loop #1.#2.}%
+}%
+\def\XINT_fac_medloop_loop #1.#2.%
+{%
+ \ifnum #1>#2 \expandafter\XINT_fac_loop_exit\fi
+ \expandafter\XINT_fac_medloop_loop
+ \the\numexpr #1+\xint_c_iii\expandafter.%
+ \the\numexpr #2\expandafter.\the\numexpr\XINT_fac_medloop_mul #1!%
+}%
+\def\XINT_fac_medloop_mul #1!%
+{%
+ \expandafter\XINT_smallmul
+ \the\numexpr
+ \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!%
+}%
+\def\XINT_fac_smallloop_a #1.%
+{%
+ \csname
+ XINT_fac_smallloop_\the\numexpr #1-\xint_c_iv*(#1/\xint_c_iv)\relax
+ \endcsname #1.%
+}%
+\expandafter\def\csname XINT_fac_smallloop_1\endcsname #1.%
+{%
+ \XINT_fac_smallloop_loop 2.#1.100000001!1;!%
+}%
+\expandafter\def\csname XINT_fac_smallloop_-2\endcsname #1.%
+{%
+ \XINT_fac_smallloop_loop 3.#1.100000002!1;!%
+}%
+\expandafter\def\csname XINT_fac_smallloop_-1\endcsname #1.%
+{%
+ \XINT_fac_smallloop_loop 4.#1.100000006!1;!%
+}%
+\expandafter\def\csname XINT_fac_smallloop_0\endcsname #1.%
+{%
+ \XINT_fac_smallloop_loop 5.#1.1000000024!1;!%
+}%
+\def\XINT_fac_smallloop_loop #1.#2.%
+{%
+ \ifnum #1>#2 \expandafter\XINT_fac_loop_exit\fi
+ \expandafter\XINT_fac_smallloop_loop
+ \the\numexpr #1+\xint_c_iv\expandafter.%
+ \the\numexpr #2\expandafter.\the\numexpr\XINT_fac_smallloop_mul #1!%
+}%
+\def\XINT_fac_smallloop_mul #1!%
+{%
+ \expandafter\XINT_smallmul
+ \the\numexpr
+ \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!%
+}%
+\def\XINT_fac_loop_exit #1!#2;!#3{#3#2;!}%
+% \end{macrocode}
+% \subsection{\csh{XINT_useiimessage}}
+% \lverb|1.2o|
+% \begin{macrocode}
+\def\XINT_useiimessage #1% used in LaTeX only
+{%
+ \XINT_ifFlagRaised {#1}%
+ {\@backslashchar#1
+ (load xintfrac or use \@backslashchar xintii\xint_gobble_iv#1!)\MessageBreak}%
+ {}%
+}%
+\XINT_restorecatcodes_endinput%
+% \end{macrocode}
+% \StoreCodelineNo {xintcore}
+% \cleardoublepage\let\xintcorenameUp\undefined
+%\gardesactifs
+%\let</xintcore>\relax
+%\let<*xint>\gardesinactifs
+%</xintcore>^^A---------------------------------------------------
+%<*xint>^^A-------------------------------------------------------
+%^^A -*- coding: utf-8; mode: doctex -*-
+% \clearpage\csname xintnameUp\endcsname
+% \section{Package \xintnameimp implementation}
+% \RaisedLabel{sec:xintimp}
+%
+% \localtableofcontents
+%
+% With release |1.1| the core arithmetic routines |\xintiiAdd|,
+% |\xintiiSub|, |\xintiiMul|, |\xintiiQuo|, |\xintiiPow| were separated to be
+% the main component of the then new
+% \xintcorenameimp.
+%
+% At |1.3| the macros deprecated at |1.2o| got all removed.
+%
+% |1.3b| adds randomness related macros.
+% \begin{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+ \catcode13=5 % ^^M
+ \endlinechar=13 %
+ \catcode123=1 % {
+ \catcode125=2 % }
+ \catcode64=11 % @
+ \catcode35=6 % #
+ \catcode44=12 % ,
+ \catcode45=12 % -
+ \catcode46=12 % .
+ \catcode58=12 % :
+ \let\z\endgroup
+ \expandafter\let\expandafter\x\csname ver@xint.sty\endcsname
+ \expandafter\let\expandafter\w\csname ver@xintcore.sty\endcsname
+ \expandafter
+ \ifx\csname PackageInfo\endcsname\relax
+ \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}%
+ \else
+ \def\y#1#2{\PackageInfo{#1}{#2}}%
+ \fi
+ \expandafter
+ \ifx\csname numexpr\endcsname\relax
+ \y{xint}{\numexpr not available, aborting input}%
+ \aftergroup\endinput
+ \else
+ \ifx\x\relax % plain-TeX, first loading of xintcore.sty
+ \ifx\w\relax % but xintkernel.sty not yet loaded.
+ \def\z{\endgroup\input xintcore.sty\relax}%
+ \fi
+ \else
+ \def\empty {}%
+ \ifx\x\empty % LaTeX, first loading,
+ % variable is initialized, but \ProvidesPackage not yet seen
+ \ifx\w\relax % xintcore.sty not yet loaded.
+ \def\z{\endgroup\RequirePackage{xintcore}}%
+ \fi
+ \else
+ \aftergroup\endinput % xint already loaded.
+ \fi
+ \fi
+ \fi
+\z%
+\XINTsetupcatcodes% defined in xintkernel.sty (loaded by xintcore.sty)
+% \end{macrocode}
+% \subsection{Package identification}
+% \begin{macrocode}
+\XINT_providespackage
+\ProvidesPackage{xint}%
+ [2019/04/05 1.3e Expandable operations on big integers (JFB)]%
+% \end{macrocode}
+% \subsection{More token management}
+% \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{(WIP) A constant needed by \cshnolabel{xintRandomDigits} et al.}
+% \begin{macrocode}
+\ifdefined\xint_texuniformdeviate
+ \unless\ifdefined\xint_c_nine_x^viii
+ \csname newcount\endcsname\xint_c_nine_x^viii
+ \xint_c_nine_x^viii 900000000
+ \fi
+\fi
+% \end{macrocode}
+% \subsection{\csh{xintLen}, \csh{xintiLen}}
+% \lverb|\xintLen gets extended to fractions by xintfrac.sty: A/B is given
+% length len(A)+len(B)-1 (somewhat arbitrary). It applies \xintNum to its
+% argument. A minus sign is accepted and ignored.
+%
+%
+% For parallelism with \xintiNum/\xintNum, 1.2o defines \xintiLen.
+%
+% \xintLen gets redefined by $xintfracnameimp.
+% |
+% \begin{macrocode}
+\def\xintiLen {\romannumeral0\xintilen }%
+\def\xintilen #1{\def\xintilen ##1%
+{%
+ \expandafter#1\the\numexpr
+ \expandafter\XINT_len_fork\romannumeral0\xintinum{##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
+}}\xintilen{ }%
+\def\xintLen {\romannumeral0\xintlen }%
+\let\xintlen\xintilen
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_len_fork #1%
+{%
+ \expandafter\XINT_length_loop\xint_UDsignfork#1{}-#1\krof
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiLogTen}}
+% \lverb|1.3e. Support for ilog10() function in \xintiiexpr. See \XINTiLogTen
+% in xintfrac.sty which also currently uses -"7FFF8000 as value if input is
+% zero.|
+% \begin{macrocode}
+\def\xintiiLogTen {\the\numexpr\xintiilogten }%
+\def\xintiilogten #1%
+{%
+ \expandafter\XINT_iilogten\romannumeral`&&@#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
+}%
+\def\XINT_iilogten #1{\if#10-"7FFF8000\fi -1+%
+ \expandafter\XINT_length_loop\xint_UDsignfork#1{}-#1\krof}%
+% \end{macrocode}
+% \subsection{\csh{xintReverseDigits}}
+% \lverb|&
+% 1.2.
+%
+% This puts digits in reverse order, not suppressing leading zeros
+% after reverse. Despite lacking the "ii" in its name, it does not apply
+% \xintNum to its argument (contrarily to \xintLen, this is not very coherent).
+%
+% 1.2l variant is robust against non terminated \the\numexpr input.
+%
+% This macro is currently not used elsewhere in xint code.
+% |
+% \begin{macrocode}
+\def\xintReverseDigits {\romannumeral0\xintreversedigits }%
+\def\xintreversedigits #1%
+{%
+ \expandafter\XINT_revdigits\romannumeral`&&@#1%
+ {\XINT_microrevsep_end\W}\XINT_microrevsep_end
+ \XINT_microrevsep_end\XINT_microrevsep_end
+ \XINT_microrevsep_end\XINT_microrevsep_end
+ \XINT_microrevsep_end\XINT_microrevsep_end\XINT_microrevsep_end\Z
+ 1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
+}%
+\def\XINT_revdigits #1%
+{%
+ \xint_UDsignfork
+ #1{\expandafter-\romannumeral0\XINT_revdigits_a}%
+ -{\XINT_revdigits_a #1}%
+ \krof
+}%
+\def\XINT_revdigits_a
+{%
+ \expandafter\XINT_revdigits_b\expandafter{\expandafter}%
+ \the\numexpr\XINT_microrevsep
+}%
+\def\XINT_microrevsep #1#2#3#4#5#6#7#8#9%
+{%
+ 1#9#8#7#6#5#4#3#2#1\expandafter!\the\numexpr\XINT_microrevsep
+}%
+\def\XINT_microrevsep_end #1\W #2\expandafter #3\Z{\relax#2!}%
+\def\XINT_revdigits_b #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!%
+{%
+ \xint_gob_til_R #9\XINT_revdigits_end\R
+ \XINT_revdigits_b {#9#8#7#6#5#4#3#2#1}%
+}%
+\def\XINT_revdigits_end#1{%
+\def\XINT_revdigits_end\R\XINT_revdigits_b ##1##2\W
+ {\expandafter#1\xint_gob_til_Z ##1}%
+}\XINT_revdigits_end{ }%
+\let\xintRev\xintReverseDigits
+% \end{macrocode}
+% \subsection{\csh{xintiiE}}
+% \lverb|Originally was used in \xintiiexpr. Transferred from xintfrac for
+% 1.1.
+% Code rewritten for 1.2i.
+% \xintiiE{x}{e} extends x with e zeroes if e is positive and simply outputs
+% x if e is zero or negative. Attention, le comportement pour e < 0 ne doit
+% pas être modifié car \xintMod et autres macros en dépendent.
+% |
+% \begin{macrocode}
+\def\xintiiE {\romannumeral0\xintiie }%
+\def\xintiie #1#2%
+ {\expandafter\XINT_iie_fork\the\numexpr #2\expandafter.\romannumeral`&&@#1;}%
+\def\XINT_iie_fork #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_iie_neg
+ -\XINT_iie_a
+ \krof #1%
+}%
+% \end{macrocode}
+% \lverb|&
+% le #2 a le bon pattern terminé par ; #1=0 est OK pour \XINT_rep.
+% |
+% \begin{macrocode}
+\def\XINT_iie_a #1.%
+ {\expandafter\XINT_dsx_append\romannumeral\XINT_rep #1\endcsname 0.}%
+\def\XINT_iie_neg #1.#2;{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintDecSplit}}
+% \lverb@DECIMAL SPLIT
+%
+% The macro \xintDecSplit {x}{A} cuts A which is composed of digits (leading
+% zeroes ok, but no sign) (*) into two (each possibly empty) pieces L and R.
+% The concatenation LR always reproduces A.
+%
+% The position of the cut is specified by the first argument x. If x is zero
+% or positive the cut location is x slots to the left of the right end of the
+% number. If x becomes equal to or larger than the length of the number then L
+% becomes empty. If x is negative the location of the cut is |x| slots to the
+% right of the left end of the number.
+%
+% (*) versions earlier than 1.2i first replaced A with its absolute value.
+% This is not the case anymore. This macro should NOT be used for A with a
+% leading sign (+ or -).
+%
+% Entirely rewritten for 1.2i (2016/12/11).
+%
+% Attention: \xintDecSplit not robust against non terminated second argument.
+% @
+% \begin{macrocode}
+\def\xintDecSplit {\romannumeral0\xintdecsplit }%
+\def\xintdecsplit #1#2%
+{%
+ \expandafter\XINT_split_finish
+ \romannumeral0\expandafter\XINT_split_xfork
+ \the\numexpr #1\expandafter.\romannumeral`&&@#2%
+ \xint_bye2345678\xint_bye..%
+}%
+\def\XINT_split_finish #1.#2.{{#1}{#2}}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_split_xfork #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_split_zerosplit
+ 0#1\XINT_split_fromleft
+ 0-{\XINT_split_fromright #1}%
+ \krof
+}%
+\def\XINT_split_zerosplit .#1\xint_bye#2\xint_bye..{ #1..}%
+\def\XINT_split_fromleft
+ {\expandafter\XINT_split_fromleft_a\the\numexpr\xint_c_viii-}%
+\def\XINT_split_fromleft_a #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_split_fromleft_b
+ -{\XINT_split_fromleft_end_a #1}%
+ \krof
+}%
+\def\XINT_split_fromleft_b #1.#2#3#4#5#6#7#8#9%
+{%
+ \expandafter\XINT_split_fromleft_clean
+ \the\numexpr1#2#3#4#5#6#7#8#9\expandafter
+ \XINT_split_fromleft_a\the\numexpr\xint_c_viii-#1.%
+}%
+\def\XINT_split_fromleft_end_a #1.%
+{%
+ \expandafter\XINT_split_fromleft_clean
+ \the\numexpr1\csname XINT_split_fromleft_end#1\endcsname
+}%
+\def\XINT_split_fromleft_clean 1{ }%
+\expandafter\def\csname XINT_split_fromleft_end7\endcsname #1%
+ {#1\XINT_split_fromleft_end_b}%
+\expandafter\def\csname XINT_split_fromleft_end6\endcsname #1#2%
+ {#1#2\XINT_split_fromleft_end_b}%
+\expandafter\def\csname XINT_split_fromleft_end5\endcsname #1#2#3%
+ {#1#2#3\XINT_split_fromleft_end_b}%
+\expandafter\def\csname XINT_split_fromleft_end4\endcsname #1#2#3#4%
+ {#1#2#3#4\XINT_split_fromleft_end_b}%
+\expandafter\def\csname XINT_split_fromleft_end3\endcsname #1#2#3#4#5%
+ {#1#2#3#4#5\XINT_split_fromleft_end_b}%
+\expandafter\def\csname XINT_split_fromleft_end2\endcsname #1#2#3#4#5#6%
+ {#1#2#3#4#5#6\XINT_split_fromleft_end_b}%
+\expandafter\def\csname XINT_split_fromleft_end1\endcsname #1#2#3#4#5#6#7%
+ {#1#2#3#4#5#6#7\XINT_split_fromleft_end_b}%
+\expandafter\def\csname XINT_split_fromleft_end0\endcsname #1#2#3#4#5#6#7#8%
+ {#1#2#3#4#5#6#7#8\XINT_split_fromleft_end_b}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_split_fromleft_end_b #1\xint_bye#2\xint_bye.{.#1}% puis .
+\def\XINT_split_fromright #1.#2\xint_bye
+{%
+ \expandafter\XINT_split_fromright_a
+ \the\numexpr#1-\numexpr\XINT_length_loop
+ #2\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
+ .#2\xint_bye
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_split_fromright_a #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_split_fromleft
+ -\XINT_split_fromright_Lempty
+ \krof
+}%
+\def\XINT_split_fromright_Lempty #1.#2\xint_bye#3..{.#2.}%
+% \end{macrocode}
+% \subsection{\csh{xintDecSplitL}}
+% \begin{macrocode}
+\def\xintDecSplitL {\romannumeral0\xintdecsplitl }%
+\def\xintdecsplitl #1#2%
+{%
+ \expandafter\XINT_splitl_finish
+ \romannumeral0\expandafter\XINT_split_xfork
+ \the\numexpr #1\expandafter.\romannumeral`&&@#2%
+ \xint_bye2345678\xint_bye..%
+}%
+\def\XINT_splitl_finish #1.#2.{ #1}%
+% \end{macrocode}
+% \subsection{\csh{xintDecSplitR}}
+% \begin{macrocode}
+\def\xintDecSplitR {\romannumeral0\xintdecsplitr }%
+\def\xintdecsplitr #1#2%
+{%
+ \expandafter\XINT_splitr_finish
+ \romannumeral0\expandafter\XINT_split_xfork
+ \the\numexpr #1\expandafter.\romannumeral`&&@#2%
+ \xint_bye2345678\xint_bye..%
+}%
+\def\XINT_splitr_finish #1.#2.{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintDSHr}}
+% \lverb@DECIMAL SHIFTS \xintDSH {x}{A}$\
+% si x <= 0, fait A -> A.10^(|x|).
+% si x > 0, et A >=0, fait A -> quo(A,10^(x))$\
+% si x > 0, et A < 0, fait A -> -quo(-A,10^(x))$\
+% (donc pour x > 0 c'est comme DSR itéré x fois)$\
+% \xintDSHr donne le `reste' (si x<=0 donne zéro).
+%
+% Badly named macros.
+%
+% Rewritten for 1.2i, this was old code and \xintDSx has changed interface.
+% @
+% \begin{macrocode}
+\def\xintDSHr {\romannumeral0\xintdshr }%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\xintdshr #1#2%
+{%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \expandafter\XINT_dshr_fork\the\numexpr#1\expandafter.\romannumeral`&&@#2;%
+}%
+\def\XINT_dshr_fork #1%
+{%
+ \xint_UDzerominusfork
+ 0#1\XINT_dshr_xzeroorneg
+ #1-\XINT_dshr_xzeroorneg
+ 0-\XINT_dshr_xpositive
+ \krof #1%
+}%
+\def\XINT_dshr_xzeroorneg #1;{ 0}%
+\def\XINT_dshr_xpositive
+{%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \expandafter\xint_stop_atsecondoftwo\romannumeral0\XINT_dsx_xisPos
+}%
+% \end{macrocode}
+% \subsection{\csh{xintDSH}}
+% \begin{macrocode}
+\def\xintDSH {\romannumeral0\xintdsh }%
+\def\xintdsh #1#2%
+{%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \expandafter\XINT_dsh_fork\the\numexpr#1\expandafter.\romannumeral`&&@#2;%
+}%
+\def\XINT_dsh_fork #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_dsh_xiszero
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ 0#1\XINT_dsx_xisNeg_checkA
+ 0-{\XINT_dsh_xisPos #1}%
+ \krof
+}%
+\def\XINT_dsh_xiszero #1.#2;{ #2}%
+\def\XINT_dsh_xisPos
+{%
+% \end{macrocode}
+% \lverb|&
+ \expandafter\xint_stop_atfirstoftwo\romannumeral0\XINT_dsx_xisPos
+% |
+% \begin{macrocode}
+}%
+% \end{macrocode}
+% \subsection{\csh{xintDSx}}
+% \lverb@&
+% --> Attention le cas x=0 est traité dans la même catégorie que x > 0 <--
+%
+%( si x < 0, fait A -> A.10^(|x|)
+%: si x >= 0, et A >=0, fait A -> {quo(A,10^(x))}{rem(A,10^(x))}
+%: si x >= 0, et A < 0, d'abord on calcule {quo(-A,10^(x))}{rem(-A,10^(x))}
+%: puis, si le premier n'est pas nul on lui donne le signe -
+%: si le premier est nul on donne le signe - au second.
+%)
+% On peut donc toujours reconstituer l'original A par 10^x Q \pm R
+% où il faut prendre le signe plus si Q est positif ou nul et le signe moins si
+% Q est strictement négatif.
+%
+% Rewritten for 1.2i, this was old code.
+%
+% @
+% \begin{macrocode}
+\def\xintDSx {\romannumeral0\xintdsx }%
+\def\xintdsx #1#2%
+{%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \expandafter\XINT_dsx_fork\the\numexpr#1\expandafter.\romannumeral`&&@#2;%
+}%
+\def\XINT_dsx_fork #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_dsx_xisZero
+ 0#1\XINT_dsx_xisNeg_checkA
+ 0-{\XINT_dsx_xisPos #1}%
+ \krof
+}%
+\def\XINT_dsx_xisZero #1.#2;{{#2}{0}}%
+\def\XINT_dsx_xisNeg_checkA #1.#2%
+{%
+ \xint_gob_til_zero #2\XINT_dsx_xisNeg_Azero 0%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \expandafter\XINT_dsx_append\romannumeral\XINT_rep #1\endcsname 0.#2%
+}%
+\def\XINT_dsx_xisNeg_Azero #1;{ 0}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_dsx_addzeros #1%
+ {\expandafter\XINT_dsx_append\romannumeral\XINT_rep#1\endcsname0.}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_dsx_addzerosnofuss #1%
+ {\expandafter\XINT_dsx_append\romannumeral\xintreplicate{#1}0.}%
+\def\XINT_dsx_append #1.#2;{ #2#1}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_dsx_xisPos #1.#2%
+{%
+ \xint_UDzerominusfork
+ #2-\XINT_dsx_AisZero
+ 0#2\XINT_dsx_AisNeg
+ 0-\XINT_dsx_AisPos
+ \krof #1.#2%
+}%
+\def\XINT_dsx_AisZero #1;{{0}{0}}%
+\def\XINT_dsx_AisNeg #1.-#2;%
+{%
+ \expandafter\XINT_dsx_AisNeg_checkiffirstempty
+ \romannumeral0\XINT_split_xfork #1.#2\xint_bye2345678\xint_bye..%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_dsx_AisNeg_checkiffirstempty #1%
+{%
+ \xint_gob_til_dot #1\XINT_dsx_AisNeg_finish_zero.%
+ \XINT_dsx_AisNeg_finish_notzero #1%
+}%
+\def\XINT_dsx_AisNeg_finish_zero.\XINT_dsx_AisNeg_finish_notzero.#1.%
+{%
+ \expandafter\XINT_dsx_end
+ \expandafter {\romannumeral0\XINT_num {-#1}}{0}%
+}%
+\def\XINT_dsx_AisNeg_finish_notzero #1.#2.%
+{%
+ \expandafter\XINT_dsx_end
+ \expandafter {\romannumeral0\XINT_num {#2}}{-#1}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_dsx_AisPos #1.#2;%
+{%
+ \expandafter\XINT_dsx_AisPos_finish
+ \romannumeral0\XINT_split_xfork #1.#2\xint_bye2345678\xint_bye..%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_dsx_AisPos_finish #1.#2.%
+{%
+ \expandafter\XINT_dsx_end
+ \expandafter {\romannumeral0\XINT_num {#2}}%
+ {\romannumeral0\XINT_num {#1}}%
+}%
+\def\XINT_dsx_end #1#2{\expandafter{#2}{#1}}%
+% \end{macrocode}
+% \subsection{\csh{xintiiEq}}
+% \lverb|no \xintiieq.|
+% \begin{macrocode}
+\def\xintiiEq #1#2{\romannumeral0\xintiiifeq{#1}{#2}{1}{0}}%
+% \end{macrocode}
+% \subsection{\csh{xintiiNotEq}}
+% \lverb|Pour xintexpr. Pas de version en lowercase.|
+% \begin{macrocode}
+\def\xintiiNotEq #1#2{\romannumeral0\xintiiifeq {#1}{#2}{0}{1}}%
+% \end{macrocode}
+% \subsection{\csh{xintiiGeq}}
+% \lverb|&
+% PLUS GRAND OU ÉGAL
+% attention compare les **valeurs absolues**
+%
+% 1.2l made \xintiiGeq robust against non terminated items.
+%
+% 1.2l rewrote \xintiiCmp, but forgot to handle \xintiiGeq too. Done at 1.2m.
+%
+% This macro should have been called \xintGEq for example.
+% |
+% \begin{macrocode}
+\def\xintiiGeq {\romannumeral0\xintiigeq }%
+\def\xintiigeq #1{\expandafter\XINT_iigeq\romannumeral`&&@#1\xint:}%
+\def\XINT_iigeq #1#2\xint:#3%
+{%
+ \expandafter\XINT_geq_fork\expandafter #1\romannumeral`&&@#3\xint:#2\xint:
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_geq #1#2\xint:#3%
+{%
+ \expandafter\XINT_geq_fork\expandafter #1\romannumeral0\xintnum{#3}\xint:#2\xint:
+}%
+\def\XINT_geq_fork #1#2%
+{%
+ \xint_UDzerofork
+ #1\XINT_geq_firstiszero
+ #2\XINT_geq_secondiszero
+ 0{}%
+ \krof
+ \xint_UDsignsfork
+ #1#2\XINT_geq_minusminus
+ #1-\XINT_geq_minusplus
+ #2-\XINT_geq_plusminus
+ --\XINT_geq_plusplus
+ \krof #1#2%
+}%
+\def\XINT_geq_firstiszero #1\krof 0#2#3\xint:#4\xint:
+ {\xint_UDzerofork #2{ 1}0{ 0}\krof }%
+\def\XINT_geq_secondiszero #1\krof #20#3\xint:#4\xint:{ 1}%
+\def\XINT_geq_plusminus #1-{\XINT_geq_plusplus #1{}}%
+\def\XINT_geq_minusplus -#1{\XINT_geq_plusplus {}#1}%
+\def\XINT_geq_minusminus --{\XINT_geq_plusplus {}{}}%
+\def\XINT_geq_plusplus
+ {\expandafter\XINT_geq_finish\romannumeral0\XINT_cmp_plusplus}%
+\def\XINT_geq_finish #1{\if-#1\expandafter\XINT_geq_no
+ \else\expandafter\XINT_geq_yes\fi}%
+\def\XINT_geq_no 1{ 0}%
+\def\XINT_geq_yes { 1}%
+% \end{macrocode}
+% \subsection{\csh{xintiiGt}}
+% \begin{macrocode}
+\def\xintiiGt #1#2{\romannumeral0\xintiiifgt{#1}{#2}{1}{0}}%
+% \end{macrocode}
+% \subsection{\csh{xintiiLt}}
+% \begin{macrocode}
+\def\xintiiLt #1#2{\romannumeral0\xintiiiflt{#1}{#2}{1}{0}}%
+% \end{macrocode}
+% \subsection{\csh{xintiiGtorEq}}
+% \begin{macrocode}
+\def\xintiiGtorEq #1#2{\romannumeral0\xintiiiflt {#1}{#2}{0}{1}}%
+% \end{macrocode}
+% \subsection{\csh{xintiiLtorEq}}
+% \begin{macrocode}
+\def\xintiiLtorEq #1#2{\romannumeral0\xintiiifgt {#1}{#2}{0}{1}}%
+% \end{macrocode}
+% \subsection{\csh{xintiiIsZero}}
+% \lverb|1.09a. restyled in 1.09i. 1.1 adds \xintiiIsZero, etc... for
+% optimization in \xintexpr|
+% \begin{macrocode}
+\def\xintiiIsZero {\romannumeral0\xintiiiszero }%
+\def\xintiiiszero #1{\if0\xintiiSgn{#1}\xint_afterfi{ 1}\else\xint_afterfi{ 0}\fi}%
+% \end{macrocode}
+% \subsection{\csh{xintiiIsNotZero}}
+% \lverb|1.09a. restyled in 1.09i. 1.1 adds \xintiiIsZero, etc... for
+% optimization in \xintexpr|
+% \begin{macrocode}
+\def\xintiiIsNotZero {\romannumeral0\xintiiisnotzero }%
+\def\xintiiisnotzero
+ #1{\if0\xintiiSgn{#1}\xint_afterfi{ 0}\else\xint_afterfi{ 1}\fi}%
+% \end{macrocode}
+% \subsection{\csh{xintiiIsOne}}
+% \lverb|Added in 1.03. 1.09a defines \xintIsOne. 1.1a adds \xintiiIsOne.
+%
+% \XINT_isOne rewritten for 1.2g. Works with expanded strict integers,
+% positive or negative.
+%
+%
+%
+%|
+% \begin{macrocode}
+\def\xintiiIsOne {\romannumeral0\xintiiisone }%
+\def\xintiiisone #1{\expandafter\XINT_isone\romannumeral`&&@#1XY}%
+\def\XINT_isone #1#2#3Y%
+{%
+ \unless\if#2X\xint_dothis{ 0}\fi
+ \unless\if#11\xint_dothis{ 0}\fi
+ \xint_orthat{ 1}%
+}%
+\def\XINT_isOne #1{\XINT_is_One#1XY}%
+\def\XINT_is_One #1#2#3Y%
+{%
+ \unless\if#2X\xint_dothis0\fi
+ \unless\if#11\xint_dothis0\fi
+ \xint_orthat1%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiOdd}}
+% \lverb|\xintOdd is needed for the xintexpr-essions even() and odd()
+% functions (and also by \xintNewExpr).|
+% \begin{macrocode}
+\def\xintiiOdd {\romannumeral0\xintiiodd }%
+\def\xintiiodd #1%
+{%
+ \ifodd\xintLDg{#1} %<- intentional space
+ \xint_afterfi{ 1}%
+ \else
+ \xint_afterfi{ 0}%
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiEven}}
+% \begin{macrocode}
+\def\xintiiEven {\romannumeral0\xintiieven }%
+\def\xintiieven #1%
+{%
+ \ifodd\xintLDg{#1} %<- intentional space
+ \xint_afterfi{ 0}%
+ \else
+ \xint_afterfi{ 1}%
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiMON}}
+% \lverb|MINUS ONE TO THE POWER N|
+% \begin{macrocode}
+\def\xintiiMON {\romannumeral0\xintiimon }%
+\def\xintiimon #1%
+{%
+ \ifodd\xintLDg {#1} %<- intentional space
+ \xint_afterfi{ -1}%
+ \else
+ \xint_afterfi{ 1}%
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiMMON}}
+% \lverb|MINUS ONE TO THE POWER N-1|
+% \begin{macrocode}
+\def\xintiiMMON {\romannumeral0\xintiimmon }%
+\def\xintiimmon #1%
+{%
+ \ifodd\xintLDg {#1} %<- intentional space
+ \xint_afterfi{ 1}%
+ \else
+ \xint_afterfi{ -1}%
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintSgnFork}}
+% \lverb|Expandable three-way fork added in 1.07. The argument #1 must expand
+% to non-self-ending -1,0 or 1. 1.09i with _thenstop (now _stop_at...).|
+% \begin{macrocode}
+\def\xintSgnFork {\romannumeral0\xintsgnfork }%
+\def\xintsgnfork #1%
+{%
+ \ifcase #1 \expandafter\xint_stop_atsecondofthree
+ \or\expandafter\xint_stop_atthirdofthree
+ \else\expandafter\xint_stop_atfirstofthree
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiifSgn}}
+% \lverb|Expandable three-way fork added in 1.09a. Branches expandably
+% depending on whether <0, =0, >0. Choice of branch guaranteed in two steps.
+%
+% 1.09i has \xint_firstofthreeafterstop (now \xint_stop_atfirstofthree) etc
+% for faster expansion.
+%
+% 1.1 adds \xintiiifSgn for optimization in xintexpr-essions. Should I move
+% them to xintcore? (for bnumexpr)|
+% \begin{macrocode}
+\def\xintiiifSgn {\romannumeral0\xintiiifsgn }%
+\def\xintiiifsgn #1%
+{%
+ \ifcase \xintiiSgn{#1}
+ \expandafter\xint_stop_atsecondofthree
+ \or\expandafter\xint_stop_atthirdofthree
+ \else\expandafter\xint_stop_atfirstofthree
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiifCmp}}
+% \lverb|1.09e
+% \xintifCmp {n}{m}{if n<m}{if n=m}{if n>m}. 1.1a adds ii variant|
+% \begin{macrocode}
+\def\xintiiifCmp {\romannumeral0\xintiiifcmp }%
+\def\xintiiifcmp #1#2%
+{%
+ \ifcase\xintiiCmp {#1}{#2}
+ \expandafter\xint_stop_atsecondofthree
+ \or\expandafter\xint_stop_atthirdofthree
+ \else\expandafter\xint_stop_atfirstofthree
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiifEq}}
+% \lverb|1.09a \xintifEq {n}{m}{YES if n=m}{NO if n<>m}. 1.1a adds ii variant|
+% \begin{macrocode}
+\def\xintiiifEq {\romannumeral0\xintiiifeq }%
+\def\xintiiifeq #1#2%
+{%
+ \if0\xintiiCmp{#1}{#2}%
+ \expandafter\xint_stop_atfirstoftwo
+ \else\expandafter\xint_stop_atsecondoftwo
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiifGt}}
+% \lverb|1.09a \xintifGt {n}{m}{YES if n>m}{NO if n<=m}. 1.1a adds ii variant|
+% \begin{macrocode}
+\def\xintiiifGt {\romannumeral0\xintiiifgt }%
+\def\xintiiifgt #1#2%
+{%
+ \if1\xintiiCmp{#1}{#2}%
+ \expandafter\xint_stop_atfirstoftwo
+ \else\expandafter\xint_stop_atsecondoftwo
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiifLt}}
+% \lverb|1.09a \xintifLt {n}{m}{YES if n<m}{NO if n>=m}. Restyled in 1.09i.
+% 1.1a adds ii variant|
+% \begin{macrocode}
+\def\xintiiifLt {\romannumeral0\xintiiiflt }%
+\def\xintiiiflt #1#2%
+{%
+ \ifnum\xintiiCmp{#1}{#2}<\xint_c_
+ \expandafter\xint_stop_atfirstoftwo
+ \else \expandafter\xint_stop_atsecondoftwo
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiifZero}}
+% \lverb|Expandable two-way fork added in 1.09a. Branches expandably depending on
+% whether the argument is zero (branch A) or not (branch B). 1.09i restyling. By
+% the way it appears (not thoroughly tested, though) that \if tests are faster
+% than \ifnum tests. 1.1 adds ii versions.
+%
+% 1.2o deprecates \xintifZero.|
+% \begin{macrocode}
+\def\xintiiifZero {\romannumeral0\xintiiifzero }%
+\def\xintiiifzero #1%
+{%
+ \if0\xintiiSgn{#1}%
+ \expandafter\xint_stop_atfirstoftwo
+ \else
+ \expandafter\xint_stop_atsecondoftwo
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiifNotZero}}
+% \begin{macrocode}
+\def\xintiiifNotZero {\romannumeral0\xintiiifnotzero }%
+\def\xintiiifnotzero #1%
+{%
+ \if0\xintiiSgn{#1}%
+ \expandafter\xint_stop_atsecondoftwo
+ \else
+ \expandafter\xint_stop_atfirstoftwo
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiifOne}}
+% \lverb|added in 1.09i. 1.1a adds \xintiiifOne.|
+% \begin{macrocode}
+\def\xintiiifOne {\romannumeral0\xintiiifone }%
+\def\xintiiifone #1%
+{%
+ \if1\xintiiIsOne{#1}%
+ \expandafter\xint_stop_atfirstoftwo
+ \else
+ \expandafter\xint_stop_atsecondoftwo
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiifOdd}}
+% \lverb|1.09e. Restyled in 1.09i. 1.1a adds \xintiiifOdd.|
+% \begin{macrocode}
+\def\xintiiifOdd {\romannumeral0\xintiiifodd }%
+\def\xintiiifodd #1%
+{%
+ \if\xintiiOdd{#1}1%
+ \expandafter\xint_stop_atfirstoftwo
+ \else
+ \expandafter\xint_stop_atsecondoftwo
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintifTrueAelseB}, \csh{xintifFalseAelseB}}
+% \lverb|1.09i. 1.2i has removed deprecated \xintifTrueFalse, \xintifTrue.
+%
+% 1.2o uses \xintiiifNotZero, see comments to \xintAND etc... This will work
+% fine with arguments being nested xintfrac.sty macros, without the overhead
+% of \xintNum or \xintRaw parsing.|
+% \begin{macrocode}
+\def\xintifTrueAelseB {\romannumeral0\xintiiifnotzero}%
+\def\xintifFalseAelseB{\romannumeral0\xintiiifzero}%
+% \end{macrocode}
+% \subsection{\csh{xintIsTrue}, \csh{xintIsFalse}}
+% \lverb|1.09c. Suppressed at 1.2o. They seem not to have been documented, fortunately.|
+% \begin{macrocode}
+%\let\xintIsTrue \xintIsNotZero
+%\let\xintIsFalse\xintIsZero
+% \end{macrocode}
+% \subsection{\csh{xintNOT}}
+% \lverb|1.09c. But it should have been called \xintNOT, not \xintNot. Former
+% denomination deprecated at 1.2o. Besides, the macro is now defined as ii-type.
+% |
+% \begin{macrocode}
+\def\xintNOT{\romannumeral0\xintiiiszero}%
+% \end{macrocode}
+% \subsection{\csh{xintAND}, \csh{xintOR}, \csh{xintXOR}}
+% \lverb|Added with 1.09a. But they used \xintSgn, etc... rather than
+% \xintiiSgn. This brings \xintNum overhead which is not really desired, and
+% which is not needed for use by xintexpr.sty. At 1.2o I modify them to use
+% only ii macros. This is enough for sign or zeroness even for xintfrac
+% format, as manipulated inside the \xintexpr. Big hesitation whether there
+% should be however \xintiiAND outputting 1 or 0 versus an \xintAND outputting
+% 1[0] versus 0[0] for example.|
+% \begin{macrocode}
+\def\xintAND {\romannumeral0\xintand }%
+\def\xintand #1#2{\if0\xintiiSgn{#1}\expandafter\xint_firstoftwo
+ \else\expandafter\xint_secondoftwo\fi
+ { 0}{\xintiiisnotzero{#2}}}%
+\def\xintOR {\romannumeral0\xintor }%
+\def\xintor #1#2{\if0\xintiiSgn{#1}\expandafter\xint_firstoftwo
+ \else\expandafter\xint_secondoftwo\fi
+ {\xintiiisnotzero{#2}}{ 1}}%
+\def\xintXOR {\romannumeral0\xintxor }%
+\def\xintxor #1#2{\if\xintiiIsZero{#1}\xintiiIsZero{#2}%
+ \xint_afterfi{ 0}\else\xint_afterfi{ 1}\fi }%
+% \end{macrocode}
+% \subsection{\csh{xintANDof}}
+% \lverb|New with 1.09a. \xintANDof works also with an empty list. Empty items
+% however are not accepted.
+%
+% 1.2l made \xintANDof robust against non terminated items.
+%
+% 1.2o's \xintifTrueAelseB is now an ii macro, actually.
+%
+% This macro as well as ORof and XORof are actually not used by xintexpr,
+% which has its own csv handling macros.|
+% \begin{macrocode}
+\def\xintANDof {\romannumeral0\xintandof }%
+\def\xintandof #1{\expandafter\XINT_andof_a\romannumeral`&&@#1\xint:}%
+\def\XINT_andof_a #1{\expandafter\XINT_andof_b\romannumeral`&&@#1!}%
+\def\XINT_andof_b #1%
+ {\xint_gob_til_xint: #1\XINT_andof_e\xint:\XINT_andof_c #1}%
+\def\XINT_andof_c #1!%
+ {\xintifTrueAelseB {#1}{\XINT_andof_a}{\XINT_andof_no}}%
+\def\XINT_andof_no #1\xint:{ 0}%
+\def\XINT_andof_e #1!{ 1}%
+% \end{macrocode}
+% \subsection{\csh{xintORof}}
+% \lverb|New with 1.09a. Works also with an empty list. Empty items
+% however are not accepted.
+%
+% 1.2l made \xintORof robust against non terminated items.|
+% \begin{macrocode}
+\def\xintORof {\romannumeral0\xintorof }%
+\def\xintorof #1{\expandafter\XINT_orof_a\romannumeral`&&@#1\xint:}%
+\def\XINT_orof_a #1{\expandafter\XINT_orof_b\romannumeral`&&@#1!}%
+\def\XINT_orof_b #1%
+ {\xint_gob_til_xint: #1\XINT_orof_e\xint:\XINT_orof_c #1}%
+\def\XINT_orof_c #1!%
+ {\xintifTrueAelseB {#1}{\XINT_orof_yes}{\XINT_orof_a}}%
+\def\XINT_orof_yes #1\xint:{ 1}%
+\def\XINT_orof_e #1!{ 0}%
+% \end{macrocode}
+% \subsection{\csh{xintXORof}}
+% \lverb|New with 1.09a. Works with an empty list, too. Empty items
+% however are not accepted. \XINT_xorof_c more
+% efficient in 1.09i.
+%
+% 1.2l made \xintXORof robust against non terminated items.|
+% \begin{macrocode}
+\def\xintXORof {\romannumeral0\xintxorof }%
+\def\xintxorof #1{\expandafter\XINT_xorof_a\expandafter
+ 0\romannumeral`&&@#1\xint:}%
+\def\XINT_xorof_a #1#2{\expandafter\XINT_xorof_b\romannumeral`&&@#2!#1}%
+\def\XINT_xorof_b #1%
+ {\xint_gob_til_xint: #1\XINT_xorof_e\xint:\XINT_xorof_c #1}%
+\def\XINT_xorof_c #1!#2%
+ {\xintifTrueAelseB {#1}{\if #20\xint_afterfi{\XINT_xorof_a 1}%
+ \else\xint_afterfi{\XINT_xorof_a 0}\fi}%
+ {\XINT_xorof_a #2}%
+ }%
+\def\XINT_xorof_e #1!#2{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintiiMax}}
+% \lverb|&
+% At 1.2m, a long-standing bug was fixed: \xintiiMax had the overhead of
+% applying \xintNum to its arguments due to use of a sub-macro of \xintGeq
+% code to which this overhead was added at some point.
+%
+% And on this occasion I reduced even more number of times input is grabbed.
+% |
+% \begin{macrocode}
+\def\xintiiMax {\romannumeral0\xintiimax }%
+\def\xintiimax #1%
+{%
+ \expandafter\xint_iimax \romannumeral`&&@#1\xint:
+}%
+\def\xint_iimax #1\xint:#2%
+{%
+ \expandafter\XINT_max_fork\romannumeral`&&@#2\xint:#1\xint:
+}%
+% \end{macrocode}
+% \lverb|&
+% #3#4 vient du *premier*,
+% #1#2 vient du *second*. I have renamed the sub-macros at 1.2m because the
+% terminology was quite counter-intuitive; there was no bug, but still.|
+% \begin{macrocode}
+\def\XINT_max_fork #1#2\xint:#3#4\xint:
+{%
+ \xint_UDsignsfork
+ #1#3\XINT_max_minusminus % A < 0, B < 0
+ #1-\XINT_max_plusminus % B < 0, A >= 0
+ #3-\XINT_max_minusplus % A < 0, B >= 0
+ --{\xint_UDzerosfork
+ #1#3\XINT_max_zerozero % A = B = 0
+ #10\XINT_max_pluszero % B = 0, A > 0
+ #30\XINT_max_zeroplus % A = 0, B > 0
+ 00\XINT_max_plusplus % A, B > 0
+ \krof }%
+ \krof
+ #3#1#2\xint:#4\xint:
+ \expandafter\xint_stop_atfirstoftwo
+ \else
+ \expandafter\xint_stop_atsecondoftwo
+ \fi
+ {#3#4}{#1#2}%
+}%
+% \end{macrocode}
+% \lverb|&
+% Refactored at 1.2m for avoiding grabbing arguments. Position of inputs
+% shared with iiCmp and iiGeq code.|
+% \begin{macrocode}
+\def\XINT_max_zerozero #1\fi{\xint_stop_atfirstoftwo }%
+\def\XINT_max_zeroplus #1\fi{\xint_stop_atsecondoftwo }%
+\def\XINT_max_pluszero #1\fi{\xint_stop_atfirstoftwo }%
+\def\XINT_max_minusplus #1\fi{\xint_stop_atsecondoftwo }%
+\def\XINT_max_plusminus #1\fi{\xint_stop_atfirstoftwo }%
+\def\XINT_max_plusplus
+{%
+ \if1\romannumeral0\XINT_geq_plusplus
+}%
+% \end{macrocode}
+% \lverb+Premier des testés |A|=-A, second est |B|=-B. On veut le max(A,B),
+% c'est donc A si |A|<|B| (ou |A|=|B|, mais peu importe alors). Donc on peut
+% faire cela avec \unless. Simple.+
+% \begin{macrocode}
+\def\XINT_max_minusminus --%
+{%
+ \unless\if1\romannumeral0\XINT_geq_plusplus{}{}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiMin}}
+% \lverb|\xintnum added New with 1.09a. I add \xintiiMin in 1.1 and mark as
+% deprecated \xintMin, renamed \xintiMin. \xintMin NOW REMOVED (1.2, as
+% \xintMax, \xintMaxof), only provided by \xintfracnameimp.
+%
+% At 1.2m, a long-standing bug was fixed: \xintiiMin had the overhead of
+% applying \xintNum to its arguments due to use of a sub-macro of \xintGeq
+% code to which this overhead was added at some point.
+%
+% And on this occasion I reduced even more number of times input is grabbed.
+% |
+% \begin{macrocode}
+\def\xintiiMin {\romannumeral0\xintiimin }%
+\def\xintiimin #1%
+{%
+ \expandafter\xint_iimin \romannumeral`&&@#1\xint:
+}%
+\def\xint_iimin #1\xint:#2%
+{%
+ \expandafter\XINT_min_fork\romannumeral`&&@#2\xint:#1\xint:
+}%
+\def\XINT_min_fork #1#2\xint:#3#4\xint:
+{%
+ \xint_UDsignsfork
+ #1#3\XINT_min_minusminus % A < 0, B < 0
+ #1-\XINT_min_plusminus % B < 0, A >= 0
+ #3-\XINT_min_minusplus % A < 0, B >= 0
+ --{\xint_UDzerosfork
+ #1#3\XINT_min_zerozero % A = B = 0
+ #10\XINT_min_pluszero % B = 0, A > 0
+ #30\XINT_min_zeroplus % A = 0, B > 0
+ 00\XINT_min_plusplus % A, B > 0
+ \krof }%
+ \krof
+ #3#1#2\xint:#4\xint:
+ \expandafter\xint_stop_atsecondoftwo
+ \else
+ \expandafter\xint_stop_atfirstoftwo
+ \fi
+ {#3#4}{#1#2}%
+}%
+\def\XINT_min_zerozero #1\fi{\xint_stop_atfirstoftwo }%
+\def\XINT_min_zeroplus #1\fi{\xint_stop_atfirstoftwo }%
+\def\XINT_min_pluszero #1\fi{\xint_stop_atsecondoftwo }%
+\def\XINT_min_minusplus #1\fi{\xint_stop_atfirstoftwo }%
+\def\XINT_min_plusminus #1\fi{\xint_stop_atsecondoftwo }%
+\def\XINT_min_plusplus
+{%
+ \if1\romannumeral0\XINT_geq_plusplus
+}%
+\def\XINT_min_minusminus --%
+{%
+ \unless\if1\romannumeral0\XINT_geq_plusplus{}{}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiiMaxof}}
+% \lverb|New with 1.09a. 1.2 has NO MORE \xintMaxof, requires \xintfracname.
+% 1.2a adds \xintiiMaxof, as \xintiiMaxof:csv is not public.
+%
+% NOT compatible with empty list.
+%
+% 1.2l made \xintiiMaxof robust against non terminated items.|
+% \begin{macrocode}
+\def\xintiiMaxof {\romannumeral0\xintiimaxof }%
+\def\xintiimaxof #1{\expandafter\XINT_iimaxof_a\romannumeral`&&@#1\xint:}%
+\def\XINT_iimaxof_a #1{\expandafter\XINT_iimaxof_b\romannumeral`&&@#1!}%
+\def\XINT_iimaxof_b #1!#2%
+ {\expandafter\XINT_iimaxof_c\romannumeral`&&@#2!{#1}!}%
+\def\XINT_iimaxof_c #1%
+ {\xint_gob_til_xint: #1\XINT_iimaxof_e\xint:\XINT_iimaxof_d #1}%
+\def\XINT_iimaxof_d #1!%
+ {\expandafter\XINT_iimaxof_b\romannumeral0\xintiimax {#1}}%
+\def\XINT_iimaxof_e #1!#2!{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintiiMinof}}
+% \lverb|1.09a. 1.2a adds \xintiiMinof which was lacking.|
+% \begin{macrocode}
+\def\xintiiMinof {\romannumeral0\xintiiminof }%
+\def\xintiiminof #1{\expandafter\XINT_iiminof_a\romannumeral`&&@#1\xint:}%
+\def\XINT_iiminof_a #1{\expandafter\XINT_iiminof_b\romannumeral`&&@#1!}%
+\def\XINT_iiminof_b #1!#2%
+ {\expandafter\XINT_iiminof_c\romannumeral`&&@#2!{#1}!}%
+\def\XINT_iiminof_c #1%
+ {\xint_gob_til_xint: #1\XINT_iiminof_e\xint:\XINT_iiminof_d #1}%
+\def\XINT_iiminof_d #1!%
+ {\expandafter\XINT_iiminof_b\romannumeral0\xintiimin {#1}}%
+\def\XINT_iiminof_e #1!#2!{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintiiSum}}
+% \lverb|\xintiiSum {{a}{b}...{z}}
+%|
+% \begin{macrocode}
+\def\xintiiSum {\romannumeral0\xintiisum }%
+\def\xintiisum #1{\expandafter\XINT_sumexpr\romannumeral`&&@#1\xint:}%
+\def\XINT_sumexpr {\XINT_sum_loop_a 0\Z }%
+\def\XINT_sum_loop_a #1\Z #2%
+ {\expandafter\XINT_sum_loop_b \romannumeral`&&@#2\xint:#1\xint:\Z}%
+\def\XINT_sum_loop_b #1%
+ {\xint_gob_til_xint: #1\XINT_sum_finished\xint:\XINT_sum_loop_c #1}%
+\def\XINT_sum_loop_c
+ {\expandafter\XINT_sum_loop_a\romannumeral0\XINT_add_fork }%
+\def\XINT_sum_finished\xint:\XINT_sum_loop_c\xint:\xint:#1\xint:\Z{ #1}%
+% \end{macrocode}
+% \subsection{\csh{xintiiPrd}}
+% \lverb|\xintiiPrd {{a}...{z}}
+%|
+% \begin{macrocode}
+\def\xintiiPrd {\romannumeral0\xintiiprd }%
+\def\xintiiprd #1{\expandafter\XINT_prdexpr\romannumeral`&&@#1\xint:}%
+\def\XINT_prdexpr {\XINT_prod_loop_a 1\Z }%
+\def\XINT_prod_loop_a #1\Z #2%
+ {\expandafter\XINT_prod_loop_b\romannumeral`&&@#2\xint:#1\xint:\Z}%
+\def\XINT_prod_loop_b #1%
+ {\xint_gob_til_xint: #1\XINT_prod_finished\xint:\XINT_prod_loop_c #1}%
+\def\XINT_prod_loop_c
+ {\expandafter\XINT_prod_loop_a\romannumeral0\XINT_mul_fork }%
+\def\XINT_prod_finished\xint:\XINT_prod_loop_c\xint:\xint:#1\xint:\Z { #1}%
+% \end{macrocode}
+% \subsection{\csh{xintiiSquareRoot}}
+% \lverb|First done with 1.08.
+%
+% 1.1 added \xintiiSquareRoot.
+%
+% 1.1a added \xintiiSqrtR.
+%
+% 1.2f (2016/03/01-02-03) has rewritten the implementation, the underlying
+% mathematics remaining about the same. The routine is much faster for inputs
+% having up to 16 digits (because it does it all with \numexpr directly now),
+% and also much faster for very long inputs (because it now fetches only the
+% needed new digits after the first 16 (or 17) ones, via the geometric
+% sequence 16, then 32, then 64, etc...; earlier version did the computations
+% with all remaining digits after a suitable starting point with correct 4 or
+% 5 leading digits). Note however that the fetching of tokens is via
+% intrinsically O(N^2) macros, hence inevitably inputs with thousands of
+% digits start being treated less well.
+%
+% Actually there is some room for improvements, one could prepare better
+% input X for the upcoming treatment of fetching its digits by 16, then 32,
+% then 64, etc...
+%
+% Incidently, as \xintiiSqrt uses subtraction and subtraction was broken from
+% 1.2 to 1.2c, then for another reason from 1.2c to 1.2f, it could
+% get wrong in certain (relatively rare) cases. There was also a bug that
+% made it unneedlessly slow for odd number of digits on input.
+%
+% 1.2f also modifies \xintFloatSqrt in xintfrac.sty which now has more
+% code in common with here and benefits from the same speed improvements.
+%
+% 1.2k belatedly corrects the output to {1}{1} and not 11 when input is zero.
+% As braces are used in all other cases they should have been used here too.
+%
+% Also, 1.2k adds an \xintiSqrtR macro, for coherence as \xintiSqrt is
+% defined (and mentioned in user manual.)
+%
+% |
+%
+% \begin{macrocode}
+\def\xintiiSquareRoot {\romannumeral0\xintiisquareroot }%
+\def\xintiisquareroot #1{\expandafter\XINT_sqrt_checkin\romannumeral`&&@#1\xint:}%
+\def\XINT_sqrt_checkin #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_sqrt_iszero
+ 0#1\XINT_sqrt_isneg
+ 0-\XINT_sqrt
+ \krof #1%
+}%
+\def\XINT_sqrt_iszero #1\xint:{{1}{1}}%
+\def\XINT_sqrt_isneg #1\xint:{\XINT_signalcondition{InvalidOperation}{square
+ root of negative: #1}{}{{0}{0}}}%
+\def\XINT_sqrt #1\xint:
+{%
+ \expandafter\XINT_sqrt_start\romannumeral0\xintlength {#1}.#1.%
+}%
+\def\XINT_sqrt_start #1.%
+{%
+ \ifnum #1<\xint_c_x\xint_dothis\XINT_sqrt_small_a\fi
+ \xint_orthat\XINT_sqrt_big_a #1.%
+}%
+\def\XINT_sqrt_small_a #1.{\XINT_sqrt_a #1.\XINT_sqrt_small_d }%
+\def\XINT_sqrt_big_a #1.{\XINT_sqrt_a #1.\XINT_sqrt_big_d }%
+\def\XINT_sqrt_a #1.%
+{%
+ \ifodd #1
+ \expandafter\XINT_sqrt_bO
+ \else
+ \expandafter\XINT_sqrt_bE
+ \fi
+ #1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_bE #1.#2#3#4%
+{%
+ \XINT_sqrt_c {#3#4}#2{#1}#3#4%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_bO #1.#2#3%
+{%
+ \XINT_sqrt_c #3#2{#1}#3%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_c #1#2%
+{%
+ \expandafter #2%
+ \the\numexpr \ifnum #1>\xint_c_ii
+ \ifnum #1>\xint_c_vi
+ \ifnum #1>12 \ifnum #1>20 \ifnum #1>30
+ \ifnum #1>42 \ifnum #1>56 \ifnum #1>72
+ \ifnum #1>90
+ 10\else 9\fi \else 8\fi \else 7\fi \else 6\fi \else 5\fi
+ \else 4\fi \else 3\fi \else 2\fi \else 1\fi .%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_small_d #1.#2%
+{%
+ \expandafter\XINT_sqrt_small_e
+ \the\numexpr #1\ifcase \numexpr #2/\xint_c_ii-\xint_c_i\relax
+ \or 0\or 00\or 000\or 0000\fi .%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_small_e #1.#2.%
+{%
+ \expandafter\XINT_sqrt_small_ea\the\numexpr #1*#1-#2.#1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_small_ea #1%
+{%
+ \if0#1\xint_dothis\XINT_sqrt_small_ez\fi
+ \if-#1\xint_dothis\XINT_sqrt_small_eb\fi
+ \xint_orthat\XINT_sqrt_small_f #1%
+}%
+\def\XINT_sqrt_small_ez 0.#1.{\expandafter{\the\numexpr#1+\xint_c_i
+ \expandafter}\expandafter{\the\numexpr #1*\xint_c_ii+\xint_c_i}}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_small_eb -#1.#2.%
+{%
+ \expandafter\XINT_sqrt_small_ec \the\numexpr
+ (#1-\xint_c_i+#2)/(\xint_c_ii*#2).#1.#2.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_small_ec #1.#2.#3.%
+{%
+ \expandafter\XINT_sqrt_small_f \the\numexpr
+ -#2+\xint_c_ii*#3*#1+#1*#1\expandafter.\the\numexpr #3+#1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_small_f #1.#2.%
+{%
+ \expandafter\XINT_sqrt_small_g
+ \the\numexpr (#1+#2)/(\xint_c_ii*#2)-\xint_c_i.#1.#2.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_small_g #1#2.%
+{%
+ \if 0#1%
+ \expandafter\XINT_sqrt_small_end
+ \else
+ \expandafter\XINT_sqrt_small_h
+ \fi
+ #1#2.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_small_h #1.#2.#3.%
+{%
+ \expandafter\XINT_sqrt_small_f
+ \the\numexpr #2-\xint_c_ii*#1*#3+#1*#1\expandafter.%
+ \the\numexpr #3-#1.%
+}%
+\def\XINT_sqrt_small_end #1.#2.#3.{{#3}{#2}}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_d #1.#2%
+{%
+ \ifodd #2 \xint_dothis{\expandafter\XINT_sqrt_big_eO}\fi
+ \xint_orthat{\expandafter\XINT_sqrt_big_eE}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \the\numexpr (#2-\xint_c_i)/\xint_c_ii.#1;%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_eE #1;#2#3#4#5#6#7#8#9%
+{%
+ \XINT_sqrt_big_eE_a #1;{#2#3#4#5#6#7#8#9}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_eE_a #1.#2;#3%
+{%
+ \expandafter\XINT_sqrt_bigormed_f
+ \romannumeral0\XINT_sqrt_small_e #2000.#3.#1;%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_eO #1;#2#3#4#5#6#7#8#9%
+{%
+ \XINT_sqrt_big_eO_a #1;{#2#3#4#5#6#7#8#9}%
+}%
+\def\XINT_sqrt_big_eO_a #1.#2;#3#4%
+{%
+ \expandafter\XINT_sqrt_bigormed_f
+ \romannumeral0\XINT_sqrt_small_e #20000.#3#4.#1;%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_bigormed_f #1#2#3;%
+{%
+ \ifnum#3<\xint_c_ix
+ \xint_dothis {\csname XINT_sqrt_med_f\romannumeral#3\endcsname}%
+ \fi
+ \xint_orthat\XINT_sqrt_big_f #1.#2.#3;%
+}%
+\def\XINT_sqrt_med_fv {\XINT_sqrt_med_fa .}%
+\def\XINT_sqrt_med_fvi {\XINT_sqrt_med_fa 0.}%
+\def\XINT_sqrt_med_fvii {\XINT_sqrt_med_fa 00.}%
+\def\XINT_sqrt_med_fviii{\XINT_sqrt_med_fa 000.}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_med_fa #1.#2.#3.#4;%
+{%
+ \expandafter\XINT_sqrt_med_fb
+ \the\numexpr (#30#1-5#1)/(\xint_c_ii*#2).#1.#2.#3.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_med_fb #1.#2.#3.#4.#5.%
+{%
+ \expandafter\XINT_sqrt_small_ea
+ \the\numexpr (#40#2-\xint_c_ii*#3*#1)*10#2+(#1*#1-#5)\expandafter.%
+ \the\numexpr #30#2-#1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_f #1;#2#3#4#5#6#7#8#9%
+{%
+ \XINT_sqrt_big_fa #1;{#2#3#4#5#6#7#8#9}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_fa #1.#2.#3;#4%
+{%
+ \expandafter\XINT_sqrt_big_ga
+ \the\numexpr #3-\xint_c_viii\expandafter.%
+ \romannumeral0\XINT_sqrt_med_fa 000.#1.#2.;#4.%
+}%
+% \end{macrocode}
+% \lverb|&
+%
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_ga #1.#2#3%
+{%
+ \ifnum #1>\xint_c_viii
+ \expandafter\XINT_sqrt_big_gb\else
+ \expandafter\XINT_sqrt_big_ka
+ \fi #1.#3.#2.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_gb #1.#2.#3.%
+{%
+ \expandafter\XINT_sqrt_big_gc
+ \the\numexpr (\xint_c_ii*#2-\xint_c_i)*\xint_c_x^viii/(\xint_c_iv*#3).%
+ #3.#2.#1;%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_gc #1.#2.#3.%
+{%
+ \expandafter\XINT_sqrt_big_gd
+ \romannumeral0\xintiiadd
+ {\xintiiSub {#300000000}{\xintDouble{\xintiiMul{#2}{#1}}}00000000}%
+ {\xintiiSqr {#1}}.%
+ \romannumeral0\xintiisub{#200000000}{#1}.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_gd #1.#2.%
+{%
+ \expandafter\XINT_sqrt_big_ge #2.#1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_ge #1;#2#3#4#5#6#7#8#9%
+ {\XINT_sqrt_big_gf #1.#2#3#4#5#6#7#8#9;}%
+\def\XINT_sqrt_big_gf #1;#2#3#4#5#6#7#8#9%
+ {\XINT_sqrt_big_gg #1#2#3#4#5#6#7#8#9.}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_gg #1.#2.#3.#4.%
+{%
+ \expandafter\XINT_sqrt_big_gloop
+ \expandafter\xint_c_xvi\expandafter.%
+ \the\numexpr #3-\xint_c_viii\expandafter.%
+ \romannumeral0\xintiisub {#2}{\xintiNum{#4}}.#1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_gloop #1.#2.%
+{%
+ \unless\ifnum #1<#2 \xint_dothis\XINT_sqrt_big_ka \fi
+ \xint_orthat{\XINT_sqrt_big_gi #1.}#2.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_gi #1.%
+{%
+ \expandafter\XINT_sqrt_big_gj\romannumeral\xintreplicate{#1}0.#1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_gj #1.#2.#3.#4.#5.%
+{%
+ \expandafter\XINT_sqrt_big_gk
+ \romannumeral0\xintiidivision {#4#1}%
+ {\XINT_dbl #5\xint_bye2345678\xint_bye*\xint_c_ii\relax}.%
+ #1.#5.#2.#3.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_gk #1#2.#3.#4.%
+{%
+ \expandafter\XINT_sqrt_big_gl
+ \romannumeral0\xintiiadd {#2#3}{\xintiiSqr{#1}}.%
+ \romannumeral0\xintiisub {#4#3}{#1}.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_gl #1.#2.%
+{%
+ \expandafter\XINT_sqrt_big_gm #2.#1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_gm #1.#2.#3.#4.#5.%
+{%
+ \expandafter\XINT_sqrt_big_gn
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \romannumeral0\XINT_split_fromleft\xint_c_ii*#3.#5\xint_bye2345678\xint_bye..%
+ #1.#2.#3.#4.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_gn #1.#2.#3.#4.#5.#6.%
+{%
+ \expandafter\XINT_sqrt_big_gloop
+ \the\numexpr \xint_c_ii*#5\expandafter.%
+ \the\numexpr #6-#5\expandafter.%
+ \romannumeral0\xintiisub{#4}{\xintiNum{#1}}.#3.#2.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_ka #1.#2.#3.#4.%
+{%
+ \expandafter\XINT_sqrt_big_kb
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \romannumeral0\XINT_dsx_addzeros {#1}#3;.%
+ \romannumeral0\xintiisub
+ {\XINT_dsx_addzerosnofuss {\xint_c_ii*#1}#2;}%
+ {\xintiNum{#4}}.%
+}%
+\def\XINT_sqrt_big_kb #1.#2.%
+{%
+ \expandafter\XINT_sqrt_big_kc #2.#1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_kc #1%
+{%
+ \if0#1\xint_dothis\XINT_sqrt_big_kz\fi
+ \xint_orthat\XINT_sqrt_big_kloop #1%
+}%
+\def\XINT_sqrt_big_kz 0.#1.%
+{%
+ \expandafter\XINT_sqrt_big_kend
+ \romannumeral0%
+ \xintinc{\XINT_dbl#1\xint_bye2345678\xint_bye*\xint_c_ii\relax}.#1.%
+}%
+\def\XINT_sqrt_big_kend #1.#2.%
+{%
+ \expandafter{\romannumeral0\xintinc{#2}}{#1}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_kloop #1.#2.%
+{%
+ \expandafter\XINT_sqrt_big_ke
+ \romannumeral0\xintiidivision{#1}%
+ {\romannumeral0\XINT_dbl #2\xint_bye2345678\xint_bye*\xint_c_ii\relax}{#2}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_ke #1%
+{%
+ \if0\XINT_Sgn #1\xint:
+ \expandafter \XINT_sqrt_big_end
+ \else \expandafter \XINT_sqrt_big_kf
+ \fi {#1}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_kf #1#2#3%
+{%
+ \expandafter\XINT_sqrt_big_kg
+ \romannumeral0\xintiisub {#3}{#1}.%
+ \romannumeral0\xintiiadd {#2}{\xintiiSqr {#1}}.%
+}%
+\def\XINT_sqrt_big_kg #1.#2.%
+{%
+ \expandafter\XINT_sqrt_big_kloop #2.#1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_sqrt_big_end #1#2#3{{#3}{#2}}%
+% \end{macrocode}
+% \subsection{\csh{xintiiSqrt}, \csh{xintiiSqrtR}}
+% \begin{macrocode}
+\def\xintiiSqrt {\romannumeral0\xintiisqrt }%
+\def\xintiisqrt {\expandafter\XINT_sqrt_post\romannumeral0\xintiisquareroot }%
+\def\XINT_sqrt_post #1#2{\XINT_dec #1\XINT_dec_bye234567890\xint_bye}%
+\def\xintiiSqrtR {\romannumeral0\xintiisqrtr }%
+\def\xintiisqrtr {\expandafter\XINT_sqrtr_post\romannumeral0\xintiisquareroot }%
+% \end{macrocode}
+% \lverb|N = (#1)^2 - #2 avec #1 le plus petit possible et #2>0 (hence #2<2*#1).
+% (#1-.5)^2=#1^2-#1+.25=N+#2-#1+.25. Si 0<#2<#1, <= N-0.75<N, donc rounded->#1
+% si #2>=#1, (#1-.5)^2>=N+.25>N, donc rounded->#1-1.|
+% \begin{macrocode}
+\def\XINT_sqrtr_post #1#2%
+ {\xintiiifLt {#2}{#1}{ #1}{\XINT_dec #1\XINT_dec_bye234567890\xint_bye}}%
+% \end{macrocode}
+% \subsection{\csh{xintiiBinomial}}
+% \lverb|2015/11/28-29 for 1.2f.
+%
+% 2016/11/19 for 1.2h: I truly can't understand why I hard-coded last
+% year an error-message for arguments outside of the range for binomial
+% formula. Naturally there should be no error but a rather a 0 return
+% value for binomial(x,y), if y<0 or x<y !
+%
+% I really lack some kind of infinity or NaN value.
+%
+% 1.2o deprecates \xintiBinomial. (which xintfrac.sty redefined to use
+% \xintNum)
+% |
+% \begin{macrocode}
+\def\xintiiBinomial {\romannumeral0\xintiibinomial }%
+\def\xintiibinomial #1#2%
+{%
+ \expandafter\XINT_binom_pre\the\numexpr #1\expandafter.\the\numexpr #2.%
+}%
+\def\XINT_binom_pre #1.#2.%
+{%
+ \expandafter\XINT_binom_fork \the\numexpr#1-#2.#2.#1.%
+}%
+% \end{macrocode}
+% \lverb|k.x-k.x. I hesitated to restrict maximal allowed value of x to 10000.
+% Finally I don't. But due to using small multiplication and small division, x
+% must have at most eight digits. If x>=2^31 an arithmetic overflow error will
+% have happened already.|
+% \begin{macrocode}
+\def\XINT_binom_fork #1#2.#3#4.#5#6.%
+{%
+ \if-#5\xint_dothis{\XINT_signalcondition{InvalidOperation}{Binomial with
+ negative first arg: #5#6}{}{0}}\fi
+ \if-#1\xint_dothis{ 0}\fi
+ \if-#3\xint_dothis{ 0}\fi
+ \if0#1\xint_dothis{ 1}\fi
+ \if0#3\xint_dothis{ 1}\fi
+ \ifnum #5#6>\xint_c_x^viii_mone\xint_dothis
+ {\XINT_signalcondition{InvalidOperation}{Binomial with too
+ large argument: 99999999 < #5#6}{}{0}}\fi
+ \ifnum #1#2>#3#4 \xint_dothis{\XINT_binom_a #1#2.#3#4.}\fi
+ \xint_orthat{\XINT_binom_a #3#4.#1#2.}%
+}%
+% \end{macrocode}
+% \lverb|x-k.k. avec 0<k<x, k<=x-k. Les divisions produiront en extra après le
+% quotient un terminateur 1!\Z!0!. On va procéder par petite multiplication
+% suivie par petite division. Donc ici on met le 1!\Z!0! pour amorcer.
+%
+% Le \xint_bye!2!3!4!5!6!7!8!9!\xint_bye\xint_c_i\relax est le terminateur pour le
+% \XINT_unsep_cuzsmall final.|
+% \begin{macrocode}
+\def\XINT_binom_a #1.#2.%
+{%
+ \expandafter\XINT_binom_b\the\numexpr \xint_c_i+#1.1.#2.100000001!1!;!0!%
+}%
+% \end{macrocode}
+% \lverb|y=x-k+1.j=1.k. On va évaluer par y/1*(y+1)/2*(y+2)/3 etc... On essaie
+% de regrouper de manière à utiliser au mieux \numexpr. On peut aller jusqu'à
+% x=10000 car 9999*10000<10^8. 463*464*465=99896880, 98*99*100*101=97990200.
+% On va vérifier à chaque étape si on dépasse un seuil. Le style de
+% l'implémentation diffère de celui que j'avais utilisé pour \xintiiFac. On
+% pourrait tout-à-fait avoir une verybigloop, mais bon. Je rajoute aussi un
+% verysmall. Le traitement est un peu différent pour elle afin d'aller jusqu'à
+% x=29 (et pas seulement 26 si je suivais le modèle des autres, mais je veux
+% pouvoir faire binomial(29,1), binomial(29,2), ... en vsmall).|
+% \begin{macrocode}
+\def\XINT_binom_b #1.%
+{%
+ \ifnum #1>9999 \xint_dothis\XINT_binom_vbigloop \fi
+ \ifnum #1>463 \xint_dothis\XINT_binom_bigloop \fi
+ \ifnum #1>98 \xint_dothis\XINT_binom_medloop \fi
+ \ifnum #1>29 \xint_dothis\XINT_binom_smallloop \fi
+ \xint_orthat\XINT_binom_vsmallloop #1.%
+}%
+% \end{macrocode}
+% \lverb|y.j.k. Au départ on avait x-k+1.1.k. Ensuite on a des blocs 1<8d>!
+% donnant le résultat intermédiaire, dans l'ordre, et à la fin on a 1!1;!0!.
+% Dans smallloop on peut prendre 4 par 4.|
+% \begin{macrocode}
+\def\XINT_binom_smallloop #1.#2.#3.%
+{%
+ \ifcase\numexpr #3-#2\relax
+ \expandafter\XINT_binom_end_
+ \or \expandafter\XINT_binom_end_i
+ \or \expandafter\XINT_binom_end_ii
+ \or \expandafter\XINT_binom_end_iii
+ \else\expandafter\XINT_binom_smallloop_a
+ \fi #1.#2.#3.%
+}%
+% \end{macrocode}
+% \lverb|Ça m'ennuie un peu de reprendre les #1, #2, #3 ici. On a besoin de
+% \numexpr pour \XINT_binom_div, mais de \romannumeral0 pour le unsep après
+% \XINT_binom_mul.|
+% \begin{macrocode}
+\def\XINT_binom_smallloop_a #1.#2.#3.%
+{%
+ \expandafter\XINT_binom_smallloop_b
+ \the\numexpr #1+\xint_c_iv\expandafter.%
+ \the\numexpr #2+\xint_c_iv\expandafter.%
+ \the\numexpr #3\expandafter.%
+ \the\numexpr\expandafter\XINT_binom_div
+ \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)*(#2+\xint_c_iii)\expandafter
+ !\romannumeral0\expandafter\XINT_binom_mul
+ \the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!%
+}%
+\def\XINT_binom_smallloop_b #1.%
+{%
+ \ifnum #1>98 \expandafter\XINT_binom_medloop \else
+ \expandafter\XINT_binom_smallloop \fi #1.%
+}%
+% \end{macrocode}
+% \lverb|Ici on prend trois par trois.|
+% \begin{macrocode}
+\def\XINT_binom_medloop #1.#2.#3.%
+{%
+ \ifcase\numexpr #3-#2\relax
+ \expandafter\XINT_binom_end_
+ \or \expandafter\XINT_binom_end_i
+ \or \expandafter\XINT_binom_end_ii
+ \else\expandafter\XINT_binom_medloop_a
+ \fi #1.#2.#3.%
+}%
+\def\XINT_binom_medloop_a #1.#2.#3.%
+{%
+ \expandafter\XINT_binom_medloop_b
+ \the\numexpr #1+\xint_c_iii\expandafter.%
+ \the\numexpr #2+\xint_c_iii\expandafter.%
+ \the\numexpr #3\expandafter.%
+ \the\numexpr\expandafter\XINT_binom_div
+ \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)\expandafter
+ !\romannumeral0\expandafter\XINT_binom_mul
+ \the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)!%
+}%
+\def\XINT_binom_medloop_b #1.%
+{%
+ \ifnum #1>463 \expandafter\XINT_binom_bigloop \else
+ \expandafter\XINT_binom_medloop \fi #1.%
+}%
+% \end{macrocode}
+% \lverb|Ici on prend deux par deux.|
+% \begin{macrocode}
+\def\XINT_binom_bigloop #1.#2.#3.%
+{%
+ \ifcase\numexpr #3-#2\relax
+ \expandafter\XINT_binom_end_
+ \or \expandafter\XINT_binom_end_i
+ \else\expandafter\XINT_binom_bigloop_a
+ \fi #1.#2.#3.%
+}%
+\def\XINT_binom_bigloop_a #1.#2.#3.%
+{%
+ \expandafter\XINT_binom_bigloop_b
+ \the\numexpr #1+\xint_c_ii\expandafter.%
+ \the\numexpr #2+\xint_c_ii\expandafter.%
+ \the\numexpr #3\expandafter.%
+ \the\numexpr\expandafter\XINT_binom_div
+ \the\numexpr #2*(#2+\xint_c_i)\expandafter
+ !\romannumeral0\expandafter\XINT_binom_mul
+ \the\numexpr #1*(#1+\xint_c_i)!%
+}%
+\def\XINT_binom_bigloop_b #1.%
+{%
+ \ifnum #1>9999 \expandafter\XINT_binom_vbigloop \else
+ \expandafter\XINT_binom_bigloop \fi #1.%
+}%
+% \end{macrocode}
+% \lverb|Et finalement un par un.|
+% \begin{macrocode}
+\def\XINT_binom_vbigloop #1.#2.#3.%
+{%
+ \ifnum #3=#2
+ \expandafter\XINT_binom_end_
+ \else\expandafter\XINT_binom_vbigloop_a
+ \fi #1.#2.#3.%
+}%
+\def\XINT_binom_vbigloop_a #1.#2.#3.%
+{%
+ \expandafter\XINT_binom_vbigloop
+ \the\numexpr #1+\xint_c_i\expandafter.%
+ \the\numexpr #2+\xint_c_i\expandafter.%
+ \the\numexpr #3\expandafter.%
+ \the\numexpr\expandafter\XINT_binom_div\the\numexpr #2\expandafter
+ !\romannumeral0\XINT_binom_mul #1!%
+}%
+% \end{macrocode}
+% \lverb|y.j.k. La partie very small. y est au plus 26 (non 29 mais retesté
+% dans \XINT_binom_vsmallloop_a), et tous les binomial(29,n) sont <10^8. On
+% peut donc faire y(y+1)(y+2)(y+3) et aussi il y a le fait que etex fait a*b/c
+% en double precision. Pour ne pas bifurquer à la fin sur smallloop, si n=27,
+% 27, ou 29 on procède un peu différemment des autres boucles. Si je testais
+% aussi #1 après #3-#2 pour les autres il faudrait des terminaisons
+% différentes.|
+% \begin{macrocode}
+\def\XINT_binom_vsmallloop #1.#2.#3.%
+{%
+ \ifcase\numexpr #3-#2\relax
+ \expandafter\XINT_binom_vsmallend_
+ \or \expandafter\XINT_binom_vsmallend_i
+ \or \expandafter\XINT_binom_vsmallend_ii
+ \or \expandafter\XINT_binom_vsmallend_iii
+ \else\expandafter\XINT_binom_vsmallloop_a
+ \fi #1.#2.#3.%
+}%
+\def\XINT_binom_vsmallloop_a #1.%
+{%
+ \ifnum #1>26 \expandafter\XINT_binom_smallloop_a \else
+ \expandafter\XINT_binom_vsmallloop_b \fi #1.%
+}%
+\def\XINT_binom_vsmallloop_b #1.#2.#3.%
+{%
+ \expandafter\XINT_binom_vsmallloop
+ \the\numexpr #1+\xint_c_iv\expandafter.%
+ \the\numexpr #2+\xint_c_iv\expandafter.%
+ \the\numexpr #3\expandafter.%
+ \the\numexpr \expandafter\XINT_binom_vsmallmuldiv
+ \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)*(#2+\xint_c_iii)\expandafter
+ !\the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!%
+}%
+% \end{macrocode}
+% \begin{macrocode}
+\def\XINT_binom_mul #1!#21!;!0!%
+{%
+ \expandafter\XINT_rev_nounsep\expandafter{\expandafter}%
+ \the\numexpr\expandafter\XINT_smallmul
+ \the\numexpr\xint_c_x^viii+#1\expandafter
+ !\romannumeral0\XINT_rev_nounsep {}1;!#2%
+ \R!\R!\R!\R!\R!\R!\R!\R!\W
+ \R!\R!\R!\R!\R!\R!\R!\R!\W
+ 1;!%
+}%
+\def\XINT_binom_div #1!1;!%
+{%
+ \expandafter\XINT_smalldivx_a
+ \the\numexpr #1/\xint_c_ii\expandafter\xint:
+ \the\numexpr \xint_c_x^viii+#1!%
+}%
+% \end{macrocode}
+% \lverb|Vaguement envisagé d'éviter le 10^8+ mais bon.|
+% \begin{macrocode}
+\def\XINT_binom_vsmallmuldiv #1!#2!1#3!{\xint_c_x^viii+#2*#3/#1!}%
+% \end{macrocode}
+% \lverb|On a des terminaisons communes aux trois situations small, med, big,
+% et on est sûr de pouvoir faire les multiplications dans \numexpr, car on
+% vient ici *après* avoir comparé à 9999 ou 463 ou 98.|
+% \begin{macrocode}
+\def\XINT_binom_end_iii #1.#2.#3.%
+{%
+ \expandafter\XINT_binom_finish
+ \the\numexpr\expandafter\XINT_binom_div
+ \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)*(#2+\xint_c_iii)\expandafter
+ !\romannumeral0\expandafter\XINT_binom_mul
+ \the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!%
+}%
+\def\XINT_binom_end_ii #1.#2.#3.%
+{%
+ \expandafter\XINT_binom_finish
+ \the\numexpr\expandafter\XINT_binom_div
+ \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)\expandafter
+ !\romannumeral0\expandafter\XINT_binom_mul
+ \the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)!%
+}%
+\def\XINT_binom_end_i #1.#2.#3.%
+{%
+ \expandafter\XINT_binom_finish
+ \the\numexpr\expandafter\XINT_binom_div
+ \the\numexpr #2*(#2+\xint_c_i)\expandafter
+ !\romannumeral0\expandafter\XINT_binom_mul
+ \the\numexpr #1*(#1+\xint_c_i)!%
+}%
+\def\XINT_binom_end_ #1.#2.#3.%
+{%
+ \expandafter\XINT_binom_finish
+ \the\numexpr\expandafter\XINT_binom_div\the\numexpr #2\expandafter
+ !\romannumeral0\XINT_binom_mul #1!%
+}%
+% \end{macrocode}
+% \begin{macrocode}
+\def\XINT_binom_finish #1;!0!%
+ {\XINT_unsep_cuzsmall #1\xint_bye!2!3!4!5!6!7!8!9!\xint_bye\xint_c_i\relax}%
+% \end{macrocode}
+% \lverb|Duplication de code seulement pour la boucle avec très
+% petits coeffs, mais en plus on fait au maximum des possibilités. (on
+% pourrait tester plus le résultat déjà obtenu).|
+% \begin{macrocode}
+\def\XINT_binom_vsmallend_iii #1.%
+{%
+ \ifnum #1>26 \expandafter\XINT_binom_end_iii \else
+ \expandafter\XINT_binom_vsmallend_iiib \fi #1.%
+}%
+\def\XINT_binom_vsmallend_iiib #1.#2.#3.%
+{%
+ \expandafter\XINT_binom_vsmallfinish
+ \the\numexpr \expandafter\XINT_binom_vsmallmuldiv
+ \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)*(#2+\xint_c_iii)\expandafter
+ !\the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!%
+}%
+\def\XINT_binom_vsmallend_ii #1.%
+{%
+ \ifnum #1>27 \expandafter\XINT_binom_end_ii \else
+ \expandafter\XINT_binom_vsmallend_iib \fi #1.%
+}%
+\def\XINT_binom_vsmallend_iib #1.#2.#3.%
+{%
+ \expandafter\XINT_binom_vsmallfinish
+ \the\numexpr \expandafter\XINT_binom_vsmallmuldiv
+ \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)\expandafter
+ !\the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)!%
+}%
+\def\XINT_binom_vsmallend_i #1.%
+{%
+ \ifnum #1>28 \expandafter\XINT_binom_end_i \else
+ \expandafter\XINT_binom_vsmallend_ib \fi #1.%
+}%
+\def\XINT_binom_vsmallend_ib #1.#2.#3.%
+{%
+ \expandafter\XINT_binom_vsmallfinish
+ \the\numexpr \expandafter\XINT_binom_vsmallmuldiv
+ \the\numexpr #2*(#2+\xint_c_i)\expandafter
+ !\the\numexpr #1*(#1+\xint_c_i)!%
+}%
+\def\XINT_binom_vsmallend_ #1.%
+{%
+ \ifnum #1>29 \expandafter\XINT_binom_end_ \else
+ \expandafter\XINT_binom_vsmallend_b \fi #1.%
+}%
+\def\XINT_binom_vsmallend_b #1.#2.#3.%
+{%
+ \expandafter\XINT_binom_vsmallfinish
+ \the\numexpr\XINT_binom_vsmallmuldiv #2!#1!%
+}%
+\def\XINT_binom_vsmallfinish#1{%
+\def\XINT_binom_vsmallfinish1##1!1!;!0!{\expandafter#1\the\numexpr##1\relax}%
+}\XINT_binom_vsmallfinish{ }%
+% \end{macrocode}
+% \subsection{\csh{xintiiPFactorial}}
+% \lverb?2015/11/29 for 1.2f. Partial factorial pfac(a,b)=(a+1)...b, only for
+% non-negative integers with a<=b<10^8.
+%
+% 1.2h (2016/11/20) removes the non-negativity condition. It was a bit
+% unfortunate that the code raised \xintError:OutOfRangePFac if 0<=a<=b<10^8
+% was violated. The rule now applied is to interpret pfac(a,b) as the product
+% for a<j<=b (not as a ratio of Gamma function), hence if a>=b, return 1
+% because of an empty product. If a<b: if a<0, return 0 for b>=0 and
+% (-1)^(b-a) times |b|...(|a|-1) for b<0. But only for the range 0<=
+% a <= b < 10^8 is the macro result to be considered as stable.?
+% \begin{macrocode}
+\def\xintiiPFactorial {\romannumeral0\xintiipfactorial }%
+\def\xintiipfactorial #1#2%
+{%
+ \expandafter\XINT_pfac_fork\the\numexpr#1\expandafter.\the\numexpr #2.%
+}%
+\def\xintPFactorial{\romannumeral0\xintpfactorial}%
+\let\xintpfactorial\xintiipfactorial
+% \end{macrocode}
+% \lverb|Code is a simplified version of the one for \xintiiBinomial, with no
+% attempt at implementing a "very small" branch.|
+% \begin{macrocode}
+\def\XINT_pfac_fork #1#2.#3#4.%
+{%
+ \unless\ifnum #1#2<#3#4 \xint_dothis\XINT_pfac_one\fi
+ \if-#3\xint_dothis\XINT_pfac_neg\fi
+ \if-#1\xint_dothis\XINT_pfac_zero\fi
+ \ifnum #3#4>\xint_c_x^viii_mone\xint_dothis\XINT_pfac_outofrange\fi
+ \xint_orthat \XINT_pfac_a #1#2.#3#4.%
+}%
+\def\XINT_pfac_outofrange #1.#2.%
+ {\XINT_signalcondition{InvalidOperation}{PFactorial with
+ too big second arg: 99999999 < #2}{}{0}}%
+\def\XINT_pfac_one #1.#2.{ 1}%
+\def\XINT_pfac_zero #1.#2.{ 0}%
+\def\XINT_pfac_neg -#1.-#2.%
+{%
+ \ifnum #1>\xint_c_x^viii\xint_dothis\XINT_pfac_outofrange\fi
+ \xint_orthat
+ {\ifodd\numexpr#2-#1\relax\xint_afterfi{\expandafter-\romannumeral`&&@}\fi
+ \expandafter\XINT_pfac_a }%
+ \the\numexpr #2-\xint_c_i\expandafter.\the\numexpr#1-\xint_c_i.%
+}%
+\def\XINT_pfac_a #1.#2.%
+{%
+ \expandafter\XINT_pfac_b\the\numexpr \xint_c_i+#1.#2.100000001!1;!%
+ 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
+}%
+\def\XINT_pfac_b #1.%
+{%
+ \ifnum #1>9999 \xint_dothis\XINT_pfac_vbigloop \fi
+ \ifnum #1>463 \xint_dothis\XINT_pfac_bigloop \fi
+ \ifnum #1>98 \xint_dothis\XINT_pfac_medloop \fi
+ \xint_orthat\XINT_pfac_smallloop #1.%
+}%
+\def\XINT_pfac_smallloop #1.#2.%
+{%
+ \ifcase\numexpr #2-#1\relax
+ \expandafter\XINT_pfac_end_
+ \or \expandafter\XINT_pfac_end_i
+ \or \expandafter\XINT_pfac_end_ii
+ \or \expandafter\XINT_pfac_end_iii
+ \else\expandafter\XINT_pfac_smallloop_a
+ \fi #1.#2.%
+}%
+\def\XINT_pfac_smallloop_a #1.#2.%
+{%
+ \expandafter\XINT_pfac_smallloop_b
+ \the\numexpr #1+\xint_c_iv\expandafter.%
+ \the\numexpr #2\expandafter.%
+ \the\numexpr\expandafter\XINT_smallmul
+ \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!%
+}%
+\def\XINT_pfac_smallloop_b #1.%
+{%
+ \ifnum #1>98 \expandafter\XINT_pfac_medloop \else
+ \expandafter\XINT_pfac_smallloop \fi #1.%
+}%
+\def\XINT_pfac_medloop #1.#2.%
+{%
+ \ifcase\numexpr #2-#1\relax
+ \expandafter\XINT_pfac_end_
+ \or \expandafter\XINT_pfac_end_i
+ \or \expandafter\XINT_pfac_end_ii
+ \else\expandafter\XINT_pfac_medloop_a
+ \fi #1.#2.%
+}%
+\def\XINT_pfac_medloop_a #1.#2.%
+{%
+ \expandafter\XINT_pfac_medloop_b
+ \the\numexpr #1+\xint_c_iii\expandafter.%
+ \the\numexpr #2\expandafter.%
+ \the\numexpr\expandafter\XINT_smallmul
+ \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!%
+}%
+\def\XINT_pfac_medloop_b #1.%
+{%
+ \ifnum #1>463 \expandafter\XINT_pfac_bigloop \else
+ \expandafter\XINT_pfac_medloop \fi #1.%
+}%
+\def\XINT_pfac_bigloop #1.#2.%
+{%
+ \ifcase\numexpr #2-#1\relax
+ \expandafter\XINT_pfac_end_
+ \or \expandafter\XINT_pfac_end_i
+ \else\expandafter\XINT_pfac_bigloop_a
+ \fi #1.#2.%
+}%
+\def\XINT_pfac_bigloop_a #1.#2.%
+{%
+ \expandafter\XINT_pfac_bigloop_b
+ \the\numexpr #1+\xint_c_ii\expandafter.%
+ \the\numexpr #2\expandafter.%
+ \the\numexpr\expandafter
+ \XINT_smallmul\the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!%
+}%
+\def\XINT_pfac_bigloop_b #1.%
+{%
+ \ifnum #1>9999 \expandafter\XINT_pfac_vbigloop \else
+ \expandafter\XINT_pfac_bigloop \fi #1.%
+}%
+\def\XINT_pfac_vbigloop #1.#2.%
+{%
+ \ifnum #2=#1
+ \expandafter\XINT_pfac_end_
+ \else\expandafter\XINT_pfac_vbigloop_a
+ \fi #1.#2.%
+}%
+\def\XINT_pfac_vbigloop_a #1.#2.%
+{%
+ \expandafter\XINT_pfac_vbigloop
+ \the\numexpr #1+\xint_c_i\expandafter.%
+ \the\numexpr #2\expandafter.%
+ \the\numexpr\expandafter\XINT_smallmul\the\numexpr\xint_c_x^viii+#1!%
+}%
+\def\XINT_pfac_end_iii #1.#2.%
+{%
+ \expandafter\XINT_mul_out
+ \the\numexpr\expandafter\XINT_smallmul
+ \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!%
+}%
+\def\XINT_pfac_end_ii #1.#2.%
+{%
+ \expandafter\XINT_mul_out
+ \the\numexpr\expandafter\XINT_smallmul
+ \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!%
+}%
+\def\XINT_pfac_end_i #1.#2.%
+{%
+ \expandafter\XINT_mul_out
+ \the\numexpr\expandafter\XINT_smallmul
+ \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!%
+}%
+\def\XINT_pfac_end_ #1.#2.%
+{%
+ \expandafter\XINT_mul_out
+ \the\numexpr\expandafter\XINT_smallmul\the\numexpr \xint_c_x^viii+#1!%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintBool}, \csh{xintToggle}}
+% \lverb|1.09c|
+% \begin{macrocode}
+\def\xintBool #1{\romannumeral`&&@%
+ \csname if#1\endcsname\expandafter1\else\expandafter0\fi }%
+\def\xintToggle #1{\romannumeral`&&@\iftoggle{#1}{1}{0}}%
+% \end{macrocode}
+% \subsection{\cshnolabel{xintGCD}, \cshnolabel{xintiiGCD}}
+% Copied over from \csbxint{iiGCD} of \xintgcdnameimp at |1.3d| to
+% support |gcd()| function in \csbxint{iiexpr}.
+% \begin{macrocode}
+\def\xintiiGCD {\romannumeral0\xintiigcd }%
+\def\xintiigcd #1{\expandafter\XINT_iigcd\romannumeral0\xintiiabs#1\xint:}%
+\def\XINT_iigcd #1#2\xint:#3%
+{%
+ \expandafter\XINT_gcd_fork\expandafter#1%
+ \romannumeral0\xintiiabs#3\xint:#1#2\xint:
+}%
+\def\XINT_gcd_fork #1#2%
+{%
+ \xint_UDzerofork
+ #1\XINT_gcd_Aiszero
+ #2\XINT_gcd_Biszero
+ 0\XINT_gcd_loop
+ \krof
+ #2%
+}%
+\def\XINT_gcd_AisZero #1\xint:#2\xint:{ #1}%
+\def\XINT_gcd_BisZero #1\xint:#2\xint:{ #2}%
+\def\XINT_gcd_loop #1\xint:#2\xint:
+{%
+ \expandafter\expandafter\expandafter\XINT_gcd_CheckRem
+ \expandafter\xint_secondoftwo
+ \romannumeral0\XINT_div_prepare {#1}{#2}\xint:#1\xint:
+}%
+\def\XINT_gcd_CheckRem #1%
+{%
+ \xint_gob_til_zero #1\XINT_gcd_end0\XINT_gcd_loop #1%
+}%
+\def\XINT_gcd_end0\XINT_gcd_loop #1\xint:#2\xint:{ #2}%
+% \end{macrocode}
+% \subsection{\cshnolabel{xintLCM}, \cshnolabel{xintiiLCM}}
+% \begin{macrocode}
+\def\xintiiLCM {\romannumeral0\xintiilcm}%
+\def\xintiilcm #1{\expandafter\XINT_iilcm\romannumeral0\xintiiabs#1\xint:}%
+\def\XINT_iilcm #1#2\xint:#3%
+{%
+ \expandafter\XINT_lcm_fork\expandafter#1%
+ \romannumeral0\xintiiabs#3\xint:#1#2\xint:
+}%
+\def\XINT_lcm_fork #1#2%
+{%
+ \xint_UDzerofork
+ #1\XINT_lcm_iszero
+ #2\XINT_lcm_iszero
+ 0\XINT_lcm_notzero
+ \krof
+ #2%
+}%
+\def\XINT_lcm_iszero #1\xint:#2\xint:{ 0}%
+\def\XINT_lcm_notzero #1\xint:#2\xint:
+{%
+ \expandafter\XINT_lcm_end\romannumeral0%
+ \expandafter\expandafter\expandafter\XINT_gcd_CheckRem
+ \expandafter\xint_secondoftwo
+ \romannumeral0\XINT_div_prepare {#1}{#2}\xint:#1\xint:
+ \xint:#1\xint:#2\xint:
+}%
+\def\XINT_lcm_end #1\xint:#2\xint:#3\xint:{\xintiimul {#2}{\xintiiQuo{#3}{#1}}}%
+% \end{macrocode}
+% \subsection{(WIP) \csh{xintRandomDigits}}
+% \lverb|1.3b. See user manual. Whether this will be part of xintkernel,
+% xintcore, or xint is yet to be decided.|
+% \begin{macrocode}
+\def\xintRandomDigits{\romannumeral0\xintrandomdigits}%
+\def\xintrandomdigits#1%
+{%
+ \csname xint_gob_andstop_\expandafter\XINT_randomdigits\the\numexpr#1\xint:
+}%
+\def\XINT_randomdigits#1\xint:
+{%
+ \expandafter\XINT_randomdigits_a
+ \the\numexpr(#1+\xint_c_iii)/\xint_c_viii\xint:#1\xint:
+}%
+\def\XINT_randomdigits_a#1\xint:#2\xint:
+{%
+ \romannumeral\numexpr\xint_c_viii*#1-#2\csname XINT_%
+ \romannumeral\XINT_replicate #1\endcsname \csname
+ XINT_rdg\endcsname
+}%
+\def\XINT_rdg
+{%
+ \expandafter\XINT_rdg_aux\the\numexpr%
+ \xint_c_nine_x^viii%
+ -\xint_texuniformdeviate\xint_c_ii^vii%
+ -\xint_c_ii^vii*\xint_texuniformdeviate\xint_c_ii^vii%
+ -\xint_c_ii^xiv*\xint_texuniformdeviate\xint_c_ii^vii%
+ -\xint_c_ii^xxi*\xint_texuniformdeviate\xint_c_ii^vii%
+ +\xint_texuniformdeviate\xint_c_x^viii%
+ \relax%
+}%
+\def\XINT_rdg_aux#1{XINT_rdg\endcsname}%
+\let\XINT_XINT_rdg\endcsname
+% \end{macrocode}
+% \subsection{(WIP) \csh{XINT_eightrandomdigits}}
+% \lverb|1.3b.|
+% \begin{macrocode}
+\def\XINT_eightrandomdigits
+{%
+ \expandafter\xint_gobble_i\the\numexpr%
+ \xint_c_nine_x^viii%
+ -\xint_texuniformdeviate\xint_c_ii^vii%
+ -\xint_c_ii^vii*\xint_texuniformdeviate\xint_c_ii^vii%
+ -\xint_c_ii^xiv*\xint_texuniformdeviate\xint_c_ii^vii%
+ -\xint_c_ii^xxi*\xint_texuniformdeviate\xint_c_ii^vii%
+ +\xint_texuniformdeviate\xint_c_x^viii%
+ \relax%
+}%
+% \end{macrocode}
+% \subsection{(WIP) \csh{xintXRandomDigits}}
+% \lverb|1.3b.|
+% \begin{macrocode}
+\def\xintXRandomDigits#1%
+{%
+ \csname xint_gobble_\expandafter\XINT_xrandomdigits\the\numexpr#1\xint:
+}%
+\def\XINT_xrandomdigits#1\xint:
+{%
+ \expandafter\XINT_xrandomdigits_a
+ \the\numexpr(#1+\xint_c_iii)/\xint_c_viii\xint:#1\xint:
+}%
+\def\XINT_xrandomdigits_a#1\xint:#2\xint:
+{%
+ \romannumeral\numexpr\xint_c_viii*#1-#2\expandafter\endcsname
+ \romannumeral`&&@\romannumeral
+ \XINT_replicate #1\endcsname\XINT_eightrandomdigits
+}%
+% \end{macrocode}
+% \subsection{(WIP) \csh{xintiiRandRangeAtoB}}
+% \lverb|1.3b. Support for randrange() function.
+%
+% Wee do it f-expandably for matters of \xintNewExpr etc... The \xintexpr will
+% add \xintNum wrapper to possible fractional input. But \xintiiexpr will call
+% as is.
+%
+% TODO: ? implement third argument (STEP)
+% TODO: \xintNum wrapper (which truncates) not so good in floatexpr. Use round?
+%
+% It is an error if b<=a, as in Python.|
+% \begin{macrocode}
+\def\xintiiRandRangeAtoB{\romannumeral`&&@\xintiirandrangeAtoB}%
+\def\xintiirandrangeAtoB#1%
+{%
+ \expandafter\XINT_randrangeAtoB_a\romannumeral`&&@#1\xint:
+}%
+\def\XINT_randrangeAtoB_a#1\xint:#2%
+{%
+ \xintiiadd{\expandafter\XINT_randrange
+ \romannumeral0\xintiisub{#2}{#1}\xint:}%
+ {#1}%
+}%
+% \end{macrocode}
+% \subsection{(WIP) \csh{xintiiRandRange}}
+% \lverb|1.3b. Support for randrange().|
+% \begin{macrocode}
+\def\xintiiRandRange{\romannumeral`&&@\xintiirandrange}%
+\def\xintiirandrange#1%
+{%
+ \expandafter\XINT_randrange\romannumeral`&&@#1\xint:
+}%
+\def\XINT_randrange #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_randrange_err:empty
+ 0#1\XINT_randrange_err:empty
+ 0-\XINT_randrange_a
+ \krof #1%
+}%
+\def\XINT_randrange_err:empty#1\xint:
+{%
+ \XINT_expandableerror{Empty range for randrange.} 0%
+}%
+\def\XINT_randrange_a #1\xint:
+{%
+ \expandafter\XINT_randrange_b\romannumeral0\xintlength{#1}.#1\xint:
+}%
+\def\XINT_randrange_b #1.%
+{%
+ \ifnum#1<\xint_c_x\xint_dothis{\the\numexpr\XINT_uniformdeviate{}}\fi
+ \xint_orthat{\XINT_randrange_c #1.}%
+}%
+\def\XINT_randrange_c #1.#2#3#4#5#6#7#8#9%
+{%
+ \expandafter\XINT_randrange_d
+ \the\numexpr\expandafter\XINT_uniformdeviate\expandafter
+ {\expandafter}\the\numexpr\xint_c_i+#2#3#4#5#6#7#8#9\xint:\xint:
+ #2#3#4#5#6#7#8#9\xint:#1\xint:
+}%
+% \end{macrocode}
+% \lverb|This raises following annex question: immediately after setting the
+% seed is it possible for \xintUniformDeviate{N} where N>0 has exactly eight
+% digits to return either 0 or N-1 ? It could be that this is never the case,
+% then there is a bias in randrange(). Of course there are anyhow only 2^28
+% seeds so randrange(10^X) is by necessity biased when executed immediately
+% after setting the seed, if X is at least 9.|
+% \begin{macrocode}
+\def\XINT_randrange_d #1\xint:#2\xint:
+{%
+ \ifnum#1=\xint_c_\xint_dothis\XINT_randrange_Z\fi
+ \ifnum#1=#2 \xint_dothis\XINT_randrange_A\fi
+ \xint_orthat\XINT_randrange_e #1\xint:
+}%
+\def\XINT_randrange_e #1\xint:#2\xint:#3\xint:
+{%
+ \the\numexpr#1\expandafter\relax
+ \romannumeral0\xintrandomdigits{#2-\xint_c_viii}%
+}%
+% \end{macrocode}
+% \lverb|This is quite unlikely to get executed but if it does it must
+% pay attention to leading zeros, hence the \xintinum.
+% We don't have to be
+% overly obstinate about removing overheads...|
+% \begin{macrocode}
+\def\XINT_randrange_Z 0\xint:#1\xint:#2\xint:
+{%
+ \xintinum{\xintRandomDigits{#1-\xint_c_viii}}%
+}%
+% \end{macrocode}
+% \lverb|Here too, overhead is not such a problem. The idea is that we got by
+% extraordinary same first 8 digits as upper range bound so we pick at random
+% the remaining needed digits in one go and compare with the upper bound. If too
+% big, we start again with another random 8 leading digits in given range. No
+% need to aim at any kind of efficiency for the check and loop back.|
+% \begin{macrocode}
+\def\XINT_randrange_A #1\xint:#2\xint:#3\xint:
+{%
+ \expandafter\XINT_randrange_B
+ \romannumeral0\xintrandomdigits{#2-\xint_c_viii}\xint:
+ #3\xint:#2.#1\xint:
+}%
+\def\XINT_randrange_B #1\xint:#2\xint:#3.#4\xint:
+{%
+ \xintiiifLt{#1}{#2}{\XINT_randrange_E}{\XINT_randrange_again}%
+ #4#1\xint:#3.#4#2\xint:
+}%
+\def\XINT_randrange_E #1\xint:#2\xint:{ #1}%
+\def\XINT_randrange_again #1\xint:{\XINT_randrange_c}%
+% \end{macrocode}
+% \subsection{Adjustments for engines without uniformdeviate primitive}
+% \lverb|1.3b.|
+% \begin{macrocode}
+\ifdefined\xint_texuniformdeviate
+\else
+ \def\xintrandomdigits#1%
+ {%
+ \XINT_expandableerror
+ {No uniformdeviate at engine level, returning 0.} 0%
+ }%
+ \let\xintXRandomDigits\xintRandomDigits
+ \def\XINT_randrange#1\xint:
+ {%
+ \XINT_expandableerror
+ {No uniformdeviate at engine level, returning 0.} 0%
+ }%
+\fi
+\XINT_restorecatcodes_endinput%
+% \end{macrocode}
+% \StoreCodelineNo {xint}
+% \cleardoublepage\let\xintnameUp\undefined
+%\gardesactifs
+%\let</xint>\relax
+%\let<*xintbinhex>\gardesinactifs
+%</xint>^^A-------------------------------------------------------
+%<*xintbinhex>^^A-------------------------------------------------
+%^^A -*- coding: utf-8; mode: doctex; -*-
+% \clearpage\csname xintbinhexnameUp\endcsname
+% \section{Package \xintbinhexnameimp implementation}
+% \RaisedLabel{sec:binheximp}
+%
+% \localtableofcontents
+%
+% The commenting is currently (\xintdocdate) very sparse.
+%
+% The macros from |1.08| (|2013/06/07|) remained unchanged
+% until their complete rewrite at |1.2m| (|2017/07/31|).
+%
+% At |1.2n| dependencies on \xintcorenameimp were removed, so now the package
+% loads only \xintkernelnameimp (this could have been done earlier).
+%
+% Also at |1.2n|, macros evolved again, the main improvements being in the
+% increased allowable sizes of the input for |\xintDecToHex|, |\xintDecToBin|,
+% |\xintBinToHex|. Use of |\csname| governed expansion at some places rather
+% than |\numexpr| with some clean-up after it.
+%
+% \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{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+ \catcode13=5 % ^^M
+ \endlinechar=13 %
+ \catcode123=1 % {
+ \catcode125=2 % }
+ \catcode64=11 % @
+ \catcode35=6 % #
+ \catcode44=12 % ,
+ \catcode45=12 % -
+ \catcode46=12 % .
+ \catcode58=12 % :
+ \let\z\endgroup
+ \expandafter\let\expandafter\x\csname ver@xintbinhex.sty\endcsname
+ \expandafter\let\expandafter\w\csname ver@xintkernel.sty\endcsname
+ \expandafter
+ \ifx\csname PackageInfo\endcsname\relax
+ \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}%
+ \else
+ \def\y#1#2{\PackageInfo{#1}{#2}}%
+ \fi
+ \expandafter
+ \ifx\csname numexpr\endcsname\relax
+ \y{xintbinhex}{\numexpr not available, aborting input}%
+ \aftergroup\endinput
+ \else
+ \ifx\x\relax % plain-TeX, first loading of xintbinhex.sty
+ \ifx\w\relax % but xintkernel.sty not yet loaded.
+ \def\z{\endgroup\input xintkernel.sty\relax}%
+ \fi
+ \else
+ \def\empty {}%
+ \ifx\x\empty % LaTeX, first loading,
+ % variable is initialized, but \ProvidesPackage not yet seen
+ \ifx\w\relax % xintkernel.sty not yet loaded.
+ \def\z{\endgroup\RequirePackage{xintkernel}}%
+ \fi
+ \else
+ \aftergroup\endinput % xintbinhex already loaded.
+ \fi
+ \fi
+ \fi
+\z%
+\XINTsetupcatcodes% defined in xintkernel.sty
+% \end{macrocode}
+% \subsection{Package identification}
+% \begin{macrocode}
+\XINT_providespackage
+\ProvidesPackage{xintbinhex}%
+ [2019/04/05 1.3e Expandable binary and hexadecimal conversions (JFB)]%
+% \end{macrocode}
+% \subsection{Constants, etc...}
+% \lverb|1.2n switches to \csname-governed expansion at various places.|
+% \begin{macrocode}
+\newcount\xint_c_ii^xv \xint_c_ii^xv 32768
+\newcount\xint_c_ii^xvi \xint_c_ii^xvi 65536
+\def\XINT_tmpa #1{\ifx\relax#1\else
+ \expandafter\edef\csname XINT_csdth_#1\endcsname
+ {\endcsname\ifcase #1 0\or 1\or 2\or 3\or 4\or 5\or 6\or 7\or
+ 8\or 9\or A\or B\or C\or D\or E\or F\fi}%
+ \expandafter\XINT_tmpa\fi }%
+\XINT_tmpa {0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}\relax
+\def\XINT_tmpa #1{\ifx\relax#1\else
+ \expandafter\edef\csname XINT_csdtb_#1\endcsname
+ {\endcsname\ifcase #1
+ 0000\or 0001\or 0010\or 0011\or 0100\or 0101\or 0110\or 0111\or
+ 1000\or 1001\or 1010\or 1011\or 1100\or 1101\or 1110\or 1111\fi}%
+ \expandafter\XINT_tmpa\fi }%
+\XINT_tmpa {0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}\relax
+\let\XINT_tmpa\relax
+\expandafter\def\csname XINT_csbth_0000\endcsname {\endcsname0}%
+\expandafter\def\csname XINT_csbth_0001\endcsname {\endcsname1}%
+\expandafter\def\csname XINT_csbth_0010\endcsname {\endcsname2}%
+\expandafter\def\csname XINT_csbth_0011\endcsname {\endcsname3}%
+\expandafter\def\csname XINT_csbth_0100\endcsname {\endcsname4}%
+\expandafter\def\csname XINT_csbth_0101\endcsname {\endcsname5}%
+\expandafter\def\csname XINT_csbth_0110\endcsname {\endcsname6}%
+\expandafter\def\csname XINT_csbth_0111\endcsname {\endcsname7}%
+\expandafter\def\csname XINT_csbth_1000\endcsname {\endcsname8}%
+\expandafter\def\csname XINT_csbth_1001\endcsname {\endcsname9}%
+\expandafter\def\csname XINT_csbth_1010\endcsname {\endcsname A}%
+\expandafter\def\csname XINT_csbth_1011\endcsname {\endcsname B}%
+\expandafter\def\csname XINT_csbth_1100\endcsname {\endcsname C}%
+\expandafter\def\csname XINT_csbth_1101\endcsname {\endcsname D}%
+\expandafter\def\csname XINT_csbth_1110\endcsname {\endcsname E}%
+\expandafter\def\csname XINT_csbth_1111\endcsname {\endcsname F}%
+\let\XINT_csbth_none \endcsname
+\expandafter\def\csname XINT_cshtb_0\endcsname {\endcsname0000}%
+\expandafter\def\csname XINT_cshtb_1\endcsname {\endcsname0001}%
+\expandafter\def\csname XINT_cshtb_2\endcsname {\endcsname0010}%
+\expandafter\def\csname XINT_cshtb_3\endcsname {\endcsname0011}%
+\expandafter\def\csname XINT_cshtb_4\endcsname {\endcsname0100}%
+\expandafter\def\csname XINT_cshtb_5\endcsname {\endcsname0101}%
+\expandafter\def\csname XINT_cshtb_6\endcsname {\endcsname0110}%
+\expandafter\def\csname XINT_cshtb_7\endcsname {\endcsname0111}%
+\expandafter\def\csname XINT_cshtb_8\endcsname {\endcsname1000}%
+\expandafter\def\csname XINT_cshtb_9\endcsname {\endcsname1001}%
+\def\XINT_cshtb_A {\endcsname1010}%
+\def\XINT_cshtb_B {\endcsname1011}%
+\def\XINT_cshtb_C {\endcsname1100}%
+\def\XINT_cshtb_D {\endcsname1101}%
+\def\XINT_cshtb_E {\endcsname1110}%
+\def\XINT_cshtb_F {\endcsname1111}%
+\let\XINT_cshtb_none \endcsname
+% \end{macrocode}
+% \subsection{Helper macros}
+% \subsubsection{\csh{XINT_zeroes_foriv}}
+% \lverb|&
+%( \romannumeral0\XINT_zeroes_foriv #1\R{0\R}{00\R}{000\R}$%
+%: \R{0\R}{00\R}{000\R}\R\W
+%)
+% expands to the <empty> or 0 or 00 or 000 needed which when adjoined to #1
+% extend it to length 4N.|
+% \begin{macrocode}
+\def\XINT_zeroes_foriv #1#2#3#4#5#6#7#8%
+{%
+ \xint_gob_til_R #8\XINT_zeroes_foriv_end\R\XINT_zeroes_foriv
+}%
+\def\XINT_zeroes_foriv_end\R\XINT_zeroes_foriv #1#2\W
+ {\XINT_zeroes_foriv_done #1}%
+\def\XINT_zeroes_foriv_done #1\R{ #1}%
+% \end{macrocode}
+% \subsection{\csh{xintDecToHex}}
+% \lverb|Complete rewrite at 1.2m in the 1.2 style. Also, 1.2m is robust
+% against non terminated inputs.
+%
+% Improvements of coding at 1.2n, increased maximal size. Again some coding
+% improvement at 1.2o, about 6$% speed gain.
+%
+% An input without leading zeroes gives an output without leading zeroes.|
+% \begin{macrocode}
+\def\xintDecToHex {\romannumeral0\xintdectohex }%
+\def\xintdectohex #1%
+{%
+ \expandafter\XINT_dth_checkin\romannumeral`&&@#1\xint:
+}%
+\def\XINT_dth_checkin #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_dth_neg
+ -{\XINT_dth_main #1}%
+ \krof
+}%
+\def\XINT_dth_neg {\expandafter-\romannumeral0\XINT_dth_main}%
+\def\XINT_dth_main #1\xint:
+{%
+ \expandafter\XINT_dth_finish
+ \romannumeral`&&@\expandafter\XINT_dthb_start
+ \romannumeral0\XINT_zeroes_foriv
+ #1\R{0\R}{00\R}{000\R}\R{0\R}{00\R}{000\R}\R\W
+ #1\xint_bye\XINT_dth_tohex
+}%
+\def\XINT_dthb_start #1#2#3#4#5%
+{%
+ \xint_bye#5\XINT_dthb_small\xint_bye\XINT_dthb_start_a #1#2#3#4#5%
+}%
+\def\XINT_dthb_small\xint_bye\XINT_dthb_start_a #1\xint_bye#2{#2#1!}%
+\def\XINT_dthb_start_a #1#2#3#4#5#6#7#8#9%
+{%
+ \expandafter\XINT_dthb_again\the\numexpr\expandafter\XINT_dthb_update
+ \the\numexpr#1#2#3#4%
+ \xint_bye#9\XINT_dthb_lastpass\xint_bye
+ #5#6#7#8!\XINT_dthb_exclam\relax\XINT_dthb_nextfour #9%
+}%
+% \end{macrocode}
+% \lverb|The 1.2n inserted
+% exclamations marks, which when bumping back from \XINT_dthb_again gave rise
+% to a \numexpr-loop which gathered the ! delimited arguments and inserted
+% \expandafter\XINT_dthb_update\the\numexpr dynamically. The 1.2o trick is to
+% insert it here immediately. Then at \XINT_dthb_again the \numexpr will
+% trigger an already prepared chain.
+%
+% The crux of the thing is handling of #3 at \XINT_dthb_update_a.
+% |
+% \begin{macrocode}
+\def\XINT_dthb_exclam {!\XINT_dthb_exclam\relax
+ \expandafter\XINT_dthb_update\the\numexpr}%
+\def\XINT_dthb_update #1!%
+{%
+ \expandafter\XINT_dthb_update_a
+ \the\numexpr (#1+\xint_c_ii^xv)/\xint_c_ii^xvi-\xint_c_i\xint:
+ #1\xint:%
+}%
+\def\XINT_dthb_update_a #1\xint:#2\xint:#3%
+{%
+ 0000+#1\expandafter#3\the\numexpr#2-#1*\xint_c_ii^xvi
+}%
+% \end{macrocode}
+% \lverb|1.2m and 1.2n had some unduly complicated ending pattern for
+% \XINT_dthb_nextfour as inheritance of a loop needing ! separators which was
+% pruned out at 1.2o (see previous comment).
+% |
+% \begin{macrocode}
+\def\XINT_dthb_nextfour #1#2#3#4#5%
+{%
+ \xint_bye#5\XINT_dthb_lastpass\xint_bye
+ #1#2#3#4!\XINT_dthb_exclam\relax\XINT_dthb_nextfour#5%
+}%
+\def\XINT_dthb_lastpass\xint_bye #1!#2\xint_bye#3{#1!#3!}%
+\def\XINT_dth_tohex
+{%
+ \expandafter\expandafter\expandafter\XINT_dth_tohex_a\csname\XINT_tofourhex
+}%
+\def\XINT_dth_tohex_a\endcsname{!\XINT_dth_tohex!}%
+\def\XINT_dthb_again #1!#2#3%
+{%
+ \ifx#3\relax
+ \expandafter\xint_firstoftwo
+ \else
+ \expandafter\xint_secondoftwo
+ \fi
+ {\expandafter\XINT_dthb_again
+ \the\numexpr
+ \ifnum #1>\xint_c_
+ \xint_afterfi{\expandafter\XINT_dthb_update\the\numexpr#1}%
+ \fi}%
+ {\ifnum #1>\xint_c_ \xint_dothis{#2#1!}\fi\xint_orthat{!#2!}}%
+}%
+\def\XINT_tofourhex #1!%
+{%
+ \expandafter\XINT_tofourhex_a
+ \the\numexpr (#1+\xint_c_ii^vii)/\xint_c_ii^viii-\xint_c_i\xint:
+ #1\xint:
+}%
+\def\XINT_tofourhex_a #1\xint:#2\xint:
+{%
+ \expandafter\XINT_tofourhex_c
+ \the\numexpr (#1+\xint_c_viii)/\xint_c_xvi-\xint_c_i\xint:
+ #1\xint:
+ \the\numexpr #2-\xint_c_ii^viii*#1!%
+}%
+\def\XINT_tofourhex_c #1\xint:#2\xint:
+{%
+ XINT_csdth_#1%
+ \csname XINT_csdth_\the\numexpr #2-\xint_c_xvi*#1\relax
+ \csname \expandafter\XINT_tofourhex_d
+}%
+\def\XINT_tofourhex_d #1!%
+{%
+ \expandafter\XINT_tofourhex_e
+ \the\numexpr (#1+\xint_c_viii)/\xint_c_xvi-\xint_c_i\xint:
+ #1\xint:
+}%
+\def\XINT_tofourhex_e #1\xint:#2\xint:
+{%
+ XINT_csdth_#1%
+ \csname XINT_csdth_\the\numexpr #2-\xint_c_xvi*#1\endcsname
+}%
+% \end{macrocode}
+% \lverb|We only clean-up up to 3 zero hexadecimal digits, as output was
+% produced in chunks of 4 hex digits. If input had no leading zero, output
+% will have none either. If input had many leading zeroes, output will have
+% some number (unspecified, but a recipe can be given...) of leading zeroes...
+%
+% The coding is for varying a bit, I did not check if efficient, it does not
+% matter.|
+% \begin{macrocode}
+\def\XINT_dth_finish !\XINT_dth_tohex!#1#2#3%
+{%
+ \unless\if#10\xint_dothis{ #1#2#3}\fi
+ \unless\if#20\xint_dothis{ #2#3}\fi
+ \unless\if#30\xint_dothis{ #3}\fi
+ \xint_orthat{ }%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintDecToBin}}
+% \lverb|Complete rewrite at 1.2m in the 1.2 style. Also, 1.2m is robust
+% against non terminated inputs.
+%
+% Revisited at 1.2n like in \xintDecToHex: increased maximal size.
+%
+% An input without leading zeroes gives an output without leading zeroes.
+%
+% Most of the code canvas is shared with \xintDecToHex.
+% |
+% \begin{macrocode}
+\def\xintDecToBin {\romannumeral0\xintdectobin }%
+\def\xintdectobin #1%
+{%
+ \expandafter\XINT_dtb_checkin\romannumeral`&&@#1\xint:
+}%
+\def\XINT_dtb_checkin #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_dtb_neg
+ -{\XINT_dtb_main #1}%
+ \krof
+}%
+\def\XINT_dtb_neg {\expandafter-\romannumeral0\XINT_dtb_main}%
+\def\XINT_dtb_main #1\xint:
+{%
+ \expandafter\XINT_dtb_finish
+ \romannumeral`&&@\expandafter\XINT_dthb_start
+ \romannumeral0\XINT_zeroes_foriv
+ #1\R{0\R}{00\R}{000\R}\R{0\R}{00\R}{000\R}\R\W
+ #1\xint_bye\XINT_dtb_tobin
+}%
+\def\XINT_dtb_tobin
+{%
+ \expandafter\expandafter\expandafter\XINT_dtb_tobin_a\csname\XINT_tosixteenbits
+}%
+\def\XINT_dtb_tobin_a\endcsname{!\XINT_dtb_tobin!}%
+\def\XINT_tosixteenbits #1!%
+{%
+ \expandafter\XINT_tosixteenbits_a
+ \the\numexpr (#1+\xint_c_ii^vii)/\xint_c_ii^viii-\xint_c_i\xint:
+ #1\xint:
+}%
+\def\XINT_tosixteenbits_a #1\xint:#2\xint:
+{%
+ \expandafter\XINT_tosixteenbits_c
+ \the\numexpr (#1+\xint_c_viii)/\xint_c_xvi-\xint_c_i\xint:
+ #1\xint:
+ \the\numexpr #2-\xint_c_ii^viii*#1!%
+}%
+\def\XINT_tosixteenbits_c #1\xint:#2\xint:
+{%
+ XINT_csdtb_#1%
+ \csname XINT_csdtb_\the\numexpr #2-\xint_c_xvi*#1\relax
+ \csname \expandafter\XINT_tosixteenbits_d
+}%
+\def\XINT_tosixteenbits_d #1!%
+{%
+ \expandafter\XINT_tosixteenbits_e
+ \the\numexpr (#1+\xint_c_viii)/\xint_c_xvi-\xint_c_i\xint:
+ #1\xint:
+}%
+\def\XINT_tosixteenbits_e #1\xint:#2\xint:
+{%
+ XINT_csdtb_#1%
+ \csname XINT_csdtb_\the\numexpr #2-\xint_c_xvi*#1\endcsname
+}%
+\def\XINT_dtb_finish !\XINT_dtb_tobin!#1#2#3#4#5#6#7#8%
+{%
+ \expandafter\XINT_dtb_finish_a\the\numexpr #1#2#3#4#5#6#7#8\relax
+}%
+\def\XINT_dtb_finish_a #1{%
+\def\XINT_dtb_finish_a ##1##2##3##4##5##6##7##8##9%
+{%
+ \expandafter#1\the\numexpr ##1##2##3##4##5##6##7##8##9\relax
+}}\XINT_dtb_finish_a { }%
+% \end{macrocode}
+% \subsection{\csh{xintHexToDec}}
+% \lverb|Completely (and belatedly) rewritten at 1.2m in the 1.2 style.
+%
+% 1.2m version robust against non terminated inputs, but there is no primitive
+% from TeX which may generate hexadecimal digits and provoke expansion ahead,
+% afaik, except of course if decimal digits are treated as hexadecimal. This
+% robustness is not on purpose but from need to expand argument and then grab
+% it again. So we do it safely.
+%
+% Increased maximal size at 1.2n.
+%
+% 1.2m version robust against non terminated inputs.
+%
+% An input without leading zeroes gives an output without leading zeroes.
+% |
+% \begin{macrocode}
+\def\xintHexToDec {\romannumeral0\xinthextodec }%
+\def\xinthextodec #1%
+{%
+ \expandafter\XINT_htd_checkin\romannumeral`&&@#1\xint:
+}%
+\def\XINT_htd_checkin #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_htd_neg
+ -{\XINT_htd_main #1}%
+ \krof
+}%
+\def\XINT_htd_neg {\expandafter-\romannumeral0\XINT_htd_main}%
+\def\XINT_htd_main #1\xint:
+{%
+ \expandafter\XINT_htd_startb
+ \the\numexpr\expandafter\XINT_htd_starta
+ \romannumeral0\XINT_zeroes_foriv
+ #1\R{0\R}{00\R}{000\R}\R{0\R}{00\R}{000\R}\R\W
+ #1\xint_bye!2!3!4!5!6!7!8!9!\xint_bye\relax
+}%
+\def\XINT_htd_starta #1#2#3#4{"#1#2#3#4+100000!}%
+\def\XINT_htd_startb 1#1%
+{%
+ \if#10\expandafter\XINT_htd_startba\else
+ \expandafter\XINT_htd_startbb
+ \fi 1#1%
+}%
+\def\XINT_htd_startba 10#1!{\XINT_htd_again #1%
+ \xint_bye!2!3!4!5!6!7!8!9!\xint_bye\XINT_htd_nextfour}%
+\def\XINT_htd_startbb 1#1#2!{\XINT_htd_again #1!#2%
+ \xint_bye!2!3!4!5!6!7!8!9!\xint_bye\XINT_htd_nextfour}%
+% \end{macrocode}
+% \lverb|It is a bit annoying to grab all to the end here. I have a version,
+% modeled on the 1.2n variant of \xintDecToHex which solved that problem
+% there, but it did not prove enough if at all faster in my brief testing and
+% it had the defect of a reduced maximal allowed size of the input. |
+% \begin{macrocode}
+\def\XINT_htd_again #1\XINT_htd_nextfour #2%
+{%
+ \xint_bye #2\XINT_htd_finish\xint_bye
+ \expandafter\XINT_htd_A\the\numexpr
+ \XINT_htd_a #1\XINT_htd_nextfour #2%
+}%
+\def\XINT_htd_a #1!#2!#3!#4!#5!#6!#7!#8!#9!%
+{%
+ #1\expandafter\XINT_htd_update
+ \the\numexpr #2\expandafter\XINT_htd_update
+ \the\numexpr #3\expandafter\XINT_htd_update
+ \the\numexpr #4\expandafter\XINT_htd_update
+ \the\numexpr #5\expandafter\XINT_htd_update
+ \the\numexpr #6\expandafter\XINT_htd_update
+ \the\numexpr #7\expandafter\XINT_htd_update
+ \the\numexpr #8\expandafter\XINT_htd_update
+ \the\numexpr #9\expandafter\XINT_htd_update
+ \the\numexpr \XINT_htd_a
+}%
+\def\XINT_htd_nextfour #1#2#3#4%
+{%
+ *\xint_c_ii^xvi+"#1#2#3#4+1000000000\relax\xint_bye!%
+ 2!3!4!5!6!7!8!9!\xint_bye\XINT_htd_nextfour
+}%
+% \end{macrocode}
+% \lverb|If the innocent looking commented out $#6 is left in the pattern as
+% was the case at 1.2m, the maximal size becomes limited at 5538 digits, not
+% 8298! (with parameter stack size = 10000.) |
+% \begin{macrocode}
+\def\XINT_htd_update 1#1#2#3#4#5%#6!%
+{%
+ *\xint_c_ii^xvi+10000#1#2#3#4#5!%#6!%
+}%
+\def\XINT_htd_A 1#1%
+{%
+ \if#10\expandafter\XINT_htd_Aa\else
+ \expandafter\XINT_htd_Ab
+ \fi 1#1%
+}%
+\def\XINT_htd_Aa 10#1#2#3#4{\XINT_htd_again #1#2#3#4!}%
+\def\XINT_htd_Ab 1#1#2#3#4#5{\XINT_htd_again #1!#2#3#4#5!}%
+\def\XINT_htd_finish\xint_bye
+ \expandafter\XINT_htd_A\the\numexpr \XINT_htd_a #1\XINT_htd_nextfour
+{%
+ \expandafter\XINT_htd_finish_cuz\the\numexpr0\XINT_htd_unsep_loop #1%
+}%
+\def\XINT_htd_unsep_loop #1!#2!#3!#4!#5!#6!#7!#8!#9!%
+{%
+ \expandafter\XINT_unsep_clean
+ \the\numexpr 1#1#2\expandafter\XINT_unsep_clean
+ \the\numexpr 1#3#4\expandafter\XINT_unsep_clean
+ \the\numexpr 1#5#6\expandafter\XINT_unsep_clean
+ \the\numexpr 1#7#8\expandafter\XINT_unsep_clean
+ \the\numexpr 1#9\XINT_htd_unsep_loop_a
+}%
+\def\XINT_htd_unsep_loop_a #1!#2!#3!#4!#5!#6!#7!#8!#9!%
+{%
+ #1\expandafter\XINT_unsep_clean
+ \the\numexpr 1#2#3\expandafter\XINT_unsep_clean
+ \the\numexpr 1#4#5\expandafter\XINT_unsep_clean
+ \the\numexpr 1#6#7\expandafter\XINT_unsep_clean
+ \the\numexpr 1#8#9\XINT_htd_unsep_loop
+}%
+\def\XINT_unsep_clean 1{\relax}% also in xintcore
+\def\XINT_htd_finish_cuz #1{%
+\def\XINT_htd_finish_cuz ##1##2##3##4##5%
+ {\expandafter#1\the\numexpr ##1##2##3##4##5\relax}%
+}\XINT_htd_finish_cuz{ }%
+% \end{macrocode}
+% \subsection{\csh{xintBinToDec}}
+% \lverb|Redone entirely for 1.2m. Starts by converting to hexadecimal
+% first.
+%
+% Increased maximal size at 1.2n.
+%
+% An input without leading zeroes gives an output without leading zeroes.
+%
+% Robust against non-terminated input.|
+% \begin{macrocode}
+\def\xintBinToDec {\romannumeral0\xintbintodec }%
+\def\xintbintodec #1%
+{%
+ \expandafter\XINT_btd_checkin\romannumeral`&&@#1\xint:
+}%
+\def\XINT_btd_checkin #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_btd_N
+ -{\XINT_btd_main #1}%
+ \krof
+}%
+\def\XINT_btd_N {\expandafter-\romannumeral0\XINT_btd_main }%
+\def\XINT_btd_main #1\xint:
+{%
+ \csname XINT_btd_htd\csname\expandafter\XINT_bth_loop
+ \romannumeral0\XINT_zeroes_foriv
+ #1\R{0\R}{00\R}{000\R}\R{0\R}{00\R}{000\R}\R\W
+ #1\xint_bye2345678\xint_bye none\endcsname\xint:
+}%
+\def\XINT_btd_htd #1\xint:
+{%
+ \expandafter\XINT_htd_startb
+ \the\numexpr\expandafter\XINT_htd_starta
+ \romannumeral0\XINT_zeroes_foriv
+ #1\R{0\R}{00\R}{000\R}\R{0\R}{00\R}{000\R}\R\W
+ #1\xint_bye!2!3!4!5!6!7!8!9!\xint_bye\relax
+}%
+% \end{macrocode}
+% \subsection{\csh{xintBinToHex}}
+% \lverb|Complete rewrite for 1.2m.
+% But input for 1.2m version limited to about 13320 binary digits (expansion
+% depth=10000).
+%
+% Again redone for 1.2n for \csname governed expansion: increased maximal size.
+%
+% Size of output is ceil(size(input)/4), leading zeroes in output (inherited
+% from the input) are not trimmed.
+%
+% An input without leading zeroes gives an output without leading zeroes.
+%
+% Robust against non-terminated input.
+% |
+% \begin{macrocode}
+\def\xintBinToHex {\romannumeral0\xintbintohex }%
+\def\xintbintohex #1%
+{%
+ \expandafter\XINT_bth_checkin\romannumeral`&&@#1\xint:
+}%
+\def\XINT_bth_checkin #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_bth_N
+ -{\XINT_bth_main #1}%
+ \krof
+}%
+\def\XINT_bth_N {\expandafter-\romannumeral0\XINT_bth_main }%
+\def\XINT_bth_main #1\xint:
+{%
+ \csname space\csname\expandafter\XINT_bth_loop
+ \romannumeral0\XINT_zeroes_foriv
+ #1\R{0\R}{00\R}{000\R}\R{0\R}{00\R}{000\R}\R\W
+ #1\xint_bye2345678\xint_bye none\endcsname
+}%
+\def\XINT_bth_loop #1#2#3#4#5#6#7#8%
+{%
+ XINT_csbth_#1#2#3#4%
+ \csname XINT_csbth_#5#6#7#8%
+ \csname\XINT_bth_loop
+}%
+% \end{macrocode}
+% \subsection{\csh{xintHexToBin}}
+% \lverb|Completely rewritten for 1.2m.
+%
+% Attention this macro is not robust against arguments expanding after
+% themselves.
+%
+% Only up to three zeros are removed on front of output: if the input had a
+% leading zero, there will be a leading zero (and then possibly 4n of them if
+% inputs had more leading zeroes) on output.
+%
+% Rewritten again at 1.2n for \csname governed expansion.|
+% \begin{macrocode}
+\def\xintHexToBin {\romannumeral0\xinthextobin }%
+\def\xinthextobin #1%
+{%
+ \expandafter\XINT_htb_checkin\romannumeral`&&@#1%
+ \xint_bye 23456789\xint_bye none\endcsname
+}%
+\def\XINT_htb_checkin #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_htb_N
+ -{\XINT_htb_main #1}%
+ \krof
+}%
+\def\XINT_htb_N {\expandafter-\romannumeral0\XINT_htb_main }%
+\def\XINT_htb_main {\csname XINT_htb_cuz\csname\XINT_htb_loop}%
+\def\XINT_htb_loop #1#2#3#4#5#6#7#8#9%
+{%
+ XINT_cshtb_#1%
+ \csname XINT_cshtb_#2%
+ \csname XINT_cshtb_#3%
+ \csname XINT_cshtb_#4%
+ \csname XINT_cshtb_#5%
+ \csname XINT_cshtb_#6%
+ \csname XINT_cshtb_#7%
+ \csname XINT_cshtb_#8%
+ \csname XINT_cshtb_#9%
+ \csname \XINT_htb_loop
+}%
+\def\XINT_htb_cuz #1{%
+\def\XINT_htb_cuz ##1##2##3##4%
+ {\expandafter#1\the\numexpr##1##2##3##4\relax}%
+}\XINT_htb_cuz { }%
+% \end{macrocode}
+% \subsection{\csh{xintCHexToBin}}
+% \lverb|The 1.08 macro had same functionality as \xintHexToBin, and slightly
+% different code, the 1.2m version has the same code as \xintHexToBin except
+% that it does not remove leading zeros from output: if the input had N
+% hexadecimal digits, the output will have exactly 4N binary digits.
+%
+% Rewritten again at 1.2n for \csname governed expansion.|
+% \begin{macrocode}
+\def\xintCHexToBin {\romannumeral0\xintchextobin }%
+\def\xintchextobin #1%
+{%
+ \expandafter\XINT_chtb_checkin\romannumeral`&&@#1%
+ \xint_bye 23456789\xint_bye none\endcsname
+}%
+\def\XINT_chtb_checkin #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_chtb_N
+ -{\XINT_chtb_main #1}%
+ \krof
+}%
+\def\XINT_chtb_N {\expandafter-\romannumeral0\XINT_chtb_main }%
+\def\XINT_chtb_main {\csname space\csname\XINT_htb_loop}%
+\XINT_restorecatcodes_endinput%
+% \end{macrocode}
+% \StoreCodelineNo {xintbinhex}
+% \cleardoublepage\let\xintbinhexnameUp\undefined
+%\gardesactifs
+%\let</xintbinhex>\relax
+%\let<*xintgcd>\gardesinactifs
+%</xintbinhex>^^A-------------------------------------------------
+%<*xintgcd>^^A----------------------------------------------------
+%^^A -*- coding: utf-8; mode: doctex; -*-
+% \clearpage\csname xintgcdnameUp\endcsname
+% \section{Package \xintgcdnameimp implementation}
+% \RaisedLabel{sec:gcdimp}
+%
+% \localtableofcontents
+%
+% The commenting is currently (\xintdocdate) very sparse. Release |1.09h| has
+% modified a bit the |\xintTypesetEuclideAlgorithm| and
+% |\xintTypesetBezoutAlgorithm| layout with respect to line indentation in
+% particular. And they use the \xinttoolsnameimp |\xintloop| rather than the
+% Plain \TeX{} or \LaTeX{}'s |\loop|.
+%
+% Since |1.1| the package only loads \xintcorenameimp, not \xintnameimp. And
+% for the |\xintTypesetEuclideAlgorithm| and |\xintTypesetBezoutAlgorithm|
+% macros to be functional the package \xinttoolsnameimp needs to be loaded
+% explicitely by the user.
+%
+% Breaking change at |1.2p|: |\xintBezout{A}{B}| formerly had output
+% |{A}{B}{U}{V}{D}| with |AU-BV=D|, now it is |{U}{V}{D}| with |AU+BV=D|.
+%
+% \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{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+ \catcode13=5 % ^^M
+ \endlinechar=13 %
+ \catcode123=1 % {
+ \catcode125=2 % }
+ \catcode64=11 % @
+ \catcode35=6 % #
+ \catcode44=12 % ,
+ \catcode45=12 % -
+ \catcode46=12 % .
+ \catcode58=12 % :
+ \let\z\endgroup
+ \expandafter\let\expandafter\x\csname ver@xintgcd.sty\endcsname
+ \expandafter\let\expandafter\w\csname ver@xintcore.sty\endcsname
+ \expandafter
+ \ifx\csname PackageInfo\endcsname\relax
+ \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}%
+ \else
+ \def\y#1#2{\PackageInfo{#1}{#2}}%
+ \fi
+ \expandafter
+ \ifx\csname numexpr\endcsname\relax
+ \y{xintgcd}{\numexpr not available, aborting input}%
+ \aftergroup\endinput
+ \else
+ \ifx\x\relax % plain-TeX, first loading of xintgcd.sty
+ \ifx\w\relax % but xintcore.sty not yet loaded.
+ \def\z{\endgroup\input xintcore.sty\relax}%
+ \fi
+ \else
+ \def\empty {}%
+ \ifx\x\empty % LaTeX, first loading,
+ % variable is initialized, but \ProvidesPackage not yet seen
+ \ifx\w\relax % xintcore.sty not yet loaded.
+ \def\z{\endgroup\RequirePackage{xintcore}}%
+ \fi
+ \else
+ \aftergroup\endinput % xintgcd already loaded.
+ \fi
+ \fi
+ \fi
+\z%
+\XINTsetupcatcodes% defined in xintkernel.sty
+% \end{macrocode}
+% \subsection{Package identification}
+% \begin{macrocode}
+\XINT_providespackage
+\ProvidesPackage{xintgcd}%
+ [2019/04/05 1.3e Euclide algorithm with xint package (JFB)]%
+% \end{macrocode}
+% \subsection{\csh{xintGCD}, \csh{xintiiGCD}}
+% \lverb|&
+% |
+% \changed{1.3d}{}
+% \lverb|Removed some braces in favor of \xint: delimiter at 1.3d (but
+% \xintiiGCD was already robust against non-delimited \numexpr inputs
+% thanks to using \xintiiabs{...}) and refactored the whole
+% \XINT_iigcd_fork. |
+% \begin{macrocode}
+\def\xintGCD {\romannumeral0\xintgcd }%
+\def\xintgcd #1#2{\xintiigcd {\xintNum{#1}}{\xintNum{#2}}}%
+\def\xintiiGCD {\romannumeral0\xintiigcd }%
+% \end{macrocode}
+% \lverb|This abuses the way \xintiiabs expands.|
+% \begin{macrocode}
+\def\xintiigcd #1{\expandafter\XINT_iigcd\romannumeral0\xintiiabs#1\xint:}%
+\def\XINT_iigcd #1#2\xint:#3%
+{%
+ \expandafter\XINT_gcd_fork\expandafter#1%
+ \romannumeral0\xintiiabs#3\xint:#1#2\xint:
+}%
+% \end{macrocode}
+% \lverb|First argument now in second position (after \xint:) but
+% its first digit is also the #1.|
+% \begin{macrocode}
+\def\XINT_gcd_fork #1#2%
+{%
+ \xint_UDzerofork
+ #1\XINT_gcd_Aiszero
+ #2\XINT_gcd_Biszero
+ 0\XINT_gcd_loop
+ \krof
+ #2%
+}%
+\def\XINT_gcd_AisZero #1\xint:#2\xint:{ #1}%
+\def\XINT_gcd_BisZero #1\xint:#2\xint:{ #2}%
+% \end{macrocode}
+% \lverb|\XINT_div_prepare{#1}{#2} divides #2 by #1, and outputs
+% {Quotient}{Remainder}.|
+% \begin{macrocode}
+\def\XINT_gcd_loop #1\xint:#2\xint:
+{%
+ \expandafter\expandafter\expandafter\XINT_gcd_CheckRem
+ \expandafter\xint_secondoftwo
+ \romannumeral0\XINT_div_prepare {#1}{#2}\xint:#1\xint:
+}%
+\def\XINT_gcd_CheckRem #1%
+{%
+ \xint_gob_til_zero #1\XINT_gcd_end0\XINT_gcd_loop #1%
+}%
+\def\XINT_gcd_end0\XINT_gcd_loop #1\xint:#2\xint:{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintLCM}, \csh{xintiiLCM}}
+% \lverb|See comments of \xintiiGCD for the refactoring done at 1.3d.
+% No time to make \xintiiLCM code more efficient now.
+%
+% Macros \xintLCM, \xintlcm only for backwards compatibility.|
+% \begin{macrocode}
+\def\xintLCM {\romannumeral0\xintlcm}%
+\def\xintlcm #1#2{\xintiilcm{\xintNum{#1}}{\xintNum{#2}}}%
+\def\xintiiLCM {\romannumeral0\xintiilcm}%
+\def\xintiilcm #1{\expandafter\XINT_iilcm\romannumeral0\xintiiabs#1\xint:}%
+\def\XINT_iilcm #1#2\xint:#3%
+{%
+ \expandafter\XINT_lcm_fork\expandafter#1%
+ \romannumeral0\xintiiabs#3\xint:#1#2\xint:
+}%
+\def\XINT_lcm_fork #1#2%
+{%
+ \xint_UDzerofork
+ #1\XINT_lcm_iszero
+ #2\XINT_lcm_iszero
+ 0\XINT_lcm_notzero
+ \krof
+ #2%
+}%
+\def\XINT_lcm_iszero #1\xint:#2\xint:{ 0}%
+\def\XINT_lcm_notzero #1\xint:#2\xint:
+{%
+ \expandafter\XINT_lcm_end\romannumeral0%
+ \expandafter\expandafter\expandafter\XINT_gcd_CheckRem
+ \expandafter\xint_secondoftwo
+ \romannumeral0\XINT_div_prepare {#1}{#2}\xint:#1\xint:
+ \xint:#1\xint:#2\xint:
+}%
+\def\XINT_lcm_end #1\xint:#2\xint:#3\xint:{\xintiimul {#2}{\xintiiQuo{#3}{#1}}}%
+% \end{macrocode}
+% \subsection{\csh{xintBezout}}
+% \lverb|&
+% \xintBezout{#1}{#2}
+% produces {U}{V}{D} with UA+VB=D, D = PGCD(A,B) (non-positive),
+% where #1 and #2 f-expand to big integers A and B.
+%
+% I had not checked this macro for about three years when I realized in
+% January 2017 that \xintBezout{A}{B} was buggy for the cases A = 0 or B = 0.
+% I fixed that blemish in 1.2l but overlooked the other blemish that
+% \xintBezout{A}{B} with A multiple of B produced a coefficient U as -0 in
+% place of 0.
+%
+% Hence I rewrote again for 1.2p. On this occasion I modified the output
+% of the macro to be {U}{V}{D} with AU+BV=D, formerly it was
+% {A}{B}{U}{V}{D} with AU - BV = D. This is quite breaking change!
+%
+% Note in particular change of sign of V.
+%
+% I don't know why I had designed this macro to contain {A}{B} in its output.
+% Perhaps I initially intended to output {A//D}{B//D} (but forgot), as this is
+% actually possible from outcome of the last iteration, with no need of
+% actually dividing. Current code however arranges to skip this last update,
+% as U and V are already furnished by the iteration prior to realizing that
+% the last non-zero remainder was found.
+%
+% Also 1.2l raised InvalidOperation if both A and B vanished, but I removed
+% this behaviour at 1.2p.
+%|
+% \begin{macrocode}
+\def\xintBezout {\romannumeral0\xintbezout }%
+\def\xintbezout #1%
+{%
+ \expandafter\XINT_bezout\expandafter {\romannumeral0\xintnum{#1}}%
+}%
+\def\XINT_bezout #1#2%
+{%
+ \expandafter\XINT_bezout_fork \romannumeral0\xintnum{#2}\Z #1\Z
+}%
+% \end{macrocode}
+% \lverb|#3#4 = A, #1#2=B. Micro improvement for 1.2l.|
+% \begin{macrocode}
+\def\XINT_bezout_fork #1#2\Z #3#4\Z
+{%
+ \xint_UDzerosfork
+ #1#3\XINT_bezout_botharezero
+ #10\XINT_bezout_secondiszero
+ #30\XINT_bezout_firstiszero
+ 00\xint_UDsignsfork
+ \krof
+ #1#3\XINT_bezout_minusminus % A < 0, B < 0
+ #1-\XINT_bezout_minusplus % A > 0, B < 0
+ #3-\XINT_bezout_plusminus % A < 0, B > 0
+ --\XINT_bezout_plusplus % A > 0, B > 0
+ \krof
+ {#2}{#4}#1#3% #1#2=B, #3#4=A
+}%
+\def\XINT_bezout_botharezero #1\krof#2#300{{0}{0}{0}}%
+\def\XINT_bezout_firstiszero #1\krof#2#3#4#5%
+{%
+ \xint_UDsignfork
+ #4{{0}{-1}{#2}}%
+ -{{0}{1}{#4#2}}%
+ \krof
+}%
+\def\XINT_bezout_secondiszero #1\krof#2#3#4#5%
+{%
+ \xint_UDsignfork
+ #5{{-1}{0}{#3}}%
+ -{{1}{0}{#5#3}}%
+ \krof
+}%
+% \end{macrocode}
+% \lverb|#4#2= A < 0, #3#1 = B < 0|
+% \begin{macrocode}
+\def\XINT_bezout_minusminus #1#2#3#4%
+{%
+ \expandafter\XINT_bezout_mm_post
+ \romannumeral0\expandafter\XINT_bezout_preloop_a
+ \romannumeral0\XINT_div_prepare {#1}{#2}{#1}%
+}%
+\def\XINT_bezout_mm_post #1#2%
+{%
+ \expandafter\XINT_bezout_mm_postb\expandafter
+ {\romannumeral0\xintiiopp{#2}}{\romannumeral0\xintiiopp{#1}}%
+}%
+\def\XINT_bezout_mm_postb #1#2{\expandafter{#2}{#1}}%
+% \end{macrocode}
+% \lverb|minusplus #4#2= A > 0, B < 0|
+% \begin{macrocode}
+\def\XINT_bezout_minusplus #1#2#3#4%
+{%
+ \expandafter\XINT_bezout_mp_post
+ \romannumeral0\expandafter\XINT_bezout_preloop_a
+ \romannumeral0\XINT_div_prepare {#1}{#4#2}{#1}%
+}%
+\def\XINT_bezout_mp_post #1#2%
+{%
+ \expandafter\xint_exchangetwo_keepbraces\expandafter
+ {\romannumeral0\xintiiopp {#2}}{#1}%
+}%
+% \end{macrocode}
+% \lverb|plusminus A < 0, B > 0|
+% \begin{macrocode}
+\def\XINT_bezout_plusminus #1#2#3#4%
+{%
+ \expandafter\XINT_bezout_pm_post
+ \romannumeral0\expandafter\XINT_bezout_preloop_a
+ \romannumeral0\XINT_div_prepare {#3#1}{#2}{#3#1}%
+}%
+\def\XINT_bezout_pm_post #1{\expandafter{\romannumeral0\xintiiopp{#1}}}%
+% \end{macrocode}
+% \lverb|plusplus, B = #3#1 > 0, A = #4#2 > 0|
+% \begin{macrocode}
+\def\XINT_bezout_plusplus #1#2#3#4%
+{%
+ \expandafter\XINT_bezout_preloop_a
+ \romannumeral0\XINT_div_prepare {#3#1}{#4#2}{#3#1}%
+}%
+% \end{macrocode}
+% \lverb|&
+%( n = 0: BA1001 (B, A, e=1, vv, uu, v, u)
+%: r(1)=B, r(0)=A, après n étapes {r(n+1)}{r(n)}{vv}{uu}{v}{u}
+%: q(n) quotient de r(n-1) par r(n)
+%: si reste nul, exit et renvoie U = -e*uu, V = e*vv, A*U+B*V=D
+%: sinon mise à jour
+%: vv, v = q * vv + v, vv
+%: uu, u = q * uu + u, uu
+%: e = -e
+%: puis calcul quotient reste et itération
+%)
+%
+% We arrange for \xintiiMul sub-routine to be called only with positive
+% arguments, thus skipping some un-needed sign parsing there. For that though
+% we have to screen out the special cases A divides B, or B divides A. And we
+% first want to exchange A and B if A < B. These special cases are the only
+% one possibly leading to U or V zero (for A and B positive which is the case
+% here.) Thus the general case always leads to non-zero U and V's and assigning
+% a final sign is done simply adding a - to one of them, with no fear of
+% producing -0. |
+% \begin{macrocode}
+\def\XINT_bezout_preloop_a #1#2#3%
+{%
+ \if0#1\xint_dothis\XINT_bezout_preloop_exchange\fi
+ \if0#2\xint_dothis\XINT_bezout_preloop_exit\fi
+ \xint_orthat{\expandafter\XINT_bezout_loop_B}%
+ \romannumeral0\XINT_div_prepare {#2}{#3}{#2}{#1}110%
+}%
+\def\XINT_bezout_preloop_exit
+ \romannumeral0\XINT_div_prepare #1#2#3#4#5#6#7%
+{%
+ {0}{1}{#2}%
+}%
+\def\XINT_bezout_preloop_exchange
+{%
+ \expandafter\xint_exchangetwo_keepbraces
+ \romannumeral0\expandafter\XINT_bezout_preloop_A
+}%
+\def\XINT_bezout_preloop_A #1#2#3#4%
+{%
+ \if0#2\xint_dothis\XINT_bezout_preloop_exit\fi
+ \xint_orthat{\expandafter\XINT_bezout_loop_B}%
+ \romannumeral0\XINT_div_prepare {#2}{#3}{#2}{#1}%
+}%
+\def\XINT_bezout_loop_B #1#2%
+{%
+ \if0#2\expandafter\XINT_bezout_exitA
+ \else\expandafter\XINT_bezout_loop_C
+ \fi {#1}{#2}%
+}%
+% \end{macrocode}
+% \lverb|&
+% We use the fact that the \romannumeral-`0 (or equivalent) done by \xintiiadd
+% will absorb the initial space token left by \XINT_mul_plusplus in its
+% output.
+%
+% We arranged for operands here to be always positive which is needed for
+% \XINT_mul_plusplus entry point (last time I checked...). Admittedly this
+% kind of optimization is not good for maintenance of code, but I can't resist
+% temptation of limiting the shuffling around of tokens...
+% |
+% \begin{macrocode}
+\def\XINT_bezout_loop_C #1#2#3#4#5#6#7%
+{%
+ \expandafter\XINT_bezout_loop_D\expandafter
+ {\romannumeral0\xintiiadd{\XINT_mul_plusplus{}{}#1\xint:#4\xint:}{#6}}%
+ {\romannumeral0\xintiiadd{\XINT_mul_plusplus{}{}#1\xint:#5\xint:}{#7}}%
+ {#2}{#3}{#4}{#5}%
+}%
+\def\XINT_bezout_loop_D #1#2%
+{%
+ \expandafter\XINT_bezout_loop_E\expandafter{#2}{#1}%
+}%
+\def\XINT_bezout_loop_E #1#2#3#4%
+{%
+ \expandafter\XINT_bezout_loop_b
+ \romannumeral0\XINT_div_prepare {#3}{#4}{#3}{#2}{#1}%
+}%
+\def\XINT_bezout_loop_b #1#2%
+{%
+ \if0#2\expandafter\XINT_bezout_exita
+ \else\expandafter\XINT_bezout_loop_c
+ \fi {#1}{#2}%
+}%
+\def\XINT_bezout_loop_c #1#2#3#4#5#6#7%
+{%
+ \expandafter\XINT_bezout_loop_d\expandafter
+ {\romannumeral0\xintiiadd{\XINT_mul_plusplus{}{}#1\xint:#4\xint:}{#6}}%
+ {\romannumeral0\xintiiadd{\XINT_mul_plusplus{}{}#1\xint:#5\xint:}{#7}}%
+ {#2}{#3}{#4}{#5}%
+}%
+\def\XINT_bezout_loop_d #1#2%
+{%
+ \expandafter\XINT_bezout_loop_e\expandafter{#2}{#1}%
+}%
+\def\XINT_bezout_loop_e #1#2#3#4%
+{%
+ \expandafter\XINT_bezout_loop_B
+ \romannumeral0\XINT_div_prepare {#3}{#4}{#3}{#2}{#1}%
+}%
+% \end{macrocode}
+% \lverb|&
+% sortir U, V, D mais on a travaillé avec vv, uu, v, u dans cet ordre.$\
+% The code is structured so that #4 and #5 are guaranteed non-zero
+% if we exit here, hence we can not create a -0 in output.|
+% \begin{macrocode}
+\def\XINT_bezout_exita #1#2#3#4#5#6#7{{-#5}{#4}{#3}}%
+\def\XINT_bezout_exitA #1#2#3#4#5#6#7{{#5}{-#4}{#3}}%
+% \end{macrocode}
+% \subsection{\csh{xintEuclideAlgorithm}}
+% \lverb|&
+% Pour Euclide:
+% {N}{A}{D=r(n)}{B}{q1}{r1}{q2}{r2}{q3}{r3}....{qN}{rN=0}$\
+% u<2n> = u<2n+3>u<2n+2> + u<2n+4> à la n ième étape.
+%
+% Formerly, used \xintiabs, but got deprecated at 1.2o.|
+% \begin{macrocode}
+\def\xintEuclideAlgorithm {\romannumeral0\xinteuclidealgorithm }%
+\def\xinteuclidealgorithm #1%
+{%
+ \expandafter\XINT_euc\expandafter{\romannumeral0\xintiiabs{\xintNum{#1}}}%
+}%
+\def\XINT_euc #1#2%
+{%
+ \expandafter\XINT_euc_fork\romannumeral0\xintiiabs{\xintNum{#2}}\Z #1\Z
+}%
+% \end{macrocode}
+% \lverb|Ici #3#4=A, #1#2=B|
+% \begin{macrocode}
+\def\XINT_euc_fork #1#2\Z #3#4\Z
+{%
+ \xint_UDzerofork
+ #1\XINT_euc_BisZero
+ #3\XINT_euc_AisZero
+ 0\XINT_euc_a
+ \krof
+ {0}{#1#2}{#3#4}{{#3#4}{#1#2}}{}\Z
+}%
+% \end{macrocode}
+% \lverb|&
+% Le {} pour protéger {{A}{B}} si on s'arrête après une étape (B divise
+% A).
+% On va renvoyer:$\
+% {N}{A}{D=r(n)}{B}{q1}{r1}{q2}{r2}{q3}{r3}....{qN}{rN=0}|
+% \begin{macrocode}
+\def\XINT_euc_AisZero #1#2#3#4#5#6{{1}{0}{#2}{#2}{0}{0}}%
+\def\XINT_euc_BisZero #1#2#3#4#5#6{{1}{0}{#3}{#3}{0}{0}}%
+% \end{macrocode}
+% \lverb|&
+% {n}{rn}{an}{{qn}{rn}}...{{A}{B}}{}\Z$\
+% a(n) = r(n-1). Pour n=0 on a juste {0}{B}{A}{{A}{B}}{}\Z$\
+% \XINT_div_prepare {u}{v} divise v par u|
+% \begin{macrocode}
+\def\XINT_euc_a #1#2#3%
+{%
+ \expandafter\XINT_euc_b\the\numexpr #1+\xint_c_i\expandafter.%
+ \romannumeral0\XINT_div_prepare {#2}{#3}{#2}%
+}%
+% \end{macrocode}
+% \lverb|{n+1}{q(n+1)}{r(n+1)}{rn}{{qn}{rn}}...|
+% \begin{macrocode}
+\def\XINT_euc_b #1.#2#3#4%
+{%
+ \XINT_euc_c #3\Z {#1}{#3}{#4}{{#2}{#3}}%
+}%
+% \end{macrocode}
+% \lverb|r(n+1)\Z {n+1}{r(n+1)}{r(n)}{{q(n+1)}{r(n+1)}}{{qn}{rn}}...$\
+% Test si r(n+1) est nul.|
+% \begin{macrocode}
+\def\XINT_euc_c #1#2\Z
+{%
+ \xint_gob_til_zero #1\XINT_euc_end0\XINT_euc_a
+}%
+% \end{macrocode}
+% \lverb|&
+% {n+1}{r(n+1)}{r(n)}{{q(n+1)}{r(n+1)}}...{}\Z
+% Ici r(n+1) = 0. On arrête on se prépare à inverser
+% {n+1}{0}{r(n)}{{q(n+1)}{r(n+1)}}.....{{q1}{r1}}{{A}{B}}{}\Z$\
+% On veut renvoyer: {N=n+1}{A}{D=r(n)}{B}{q1}{r1}{q2}{r2}{q3}{r3}....{qN}{rN=0}|
+% \begin{macrocode}
+\def\XINT_euc_end0\XINT_euc_a #1#2#3#4\Z%
+{%
+ \expandafter\XINT_euc_end_a
+ \romannumeral0%
+ \XINT_rord_main {}#4{{#1}{#3}}%
+ \xint:
+ \xint_bye\xint_bye\xint_bye\xint_bye
+ \xint_bye\xint_bye\xint_bye\xint_bye
+ \xint:
+}%
+\def\XINT_euc_end_a #1#2#3{{#1}{#3}{#2}}%
+% \end{macrocode}
+% \subsection{\csh{xintBezoutAlgorithm}}
+% \lverb|&
+% Pour Bezout: objectif, renvoyer$\
+% {N}{A}{0}{1}{D=r(n)}{B}{1}{0}{q1}{r1}{alpha1=q1}{beta1=1}$\
+% {q2}{r2}{alpha2}{beta2}....{qN}{rN=0}{alphaN=A/D}{betaN=B/D}$\
+% alpha0=1, beta0=0, alpha(-1)=0, beta(-1)=1|
+% \begin{macrocode}
+\def\xintBezoutAlgorithm {\romannumeral0\xintbezoutalgorithm }%
+\def\xintbezoutalgorithm #1%
+{%
+ \expandafter \XINT_bezalg
+ \expandafter{\romannumeral0\xintiiabs{\xintNum{#1}}}%
+}%
+\def\XINT_bezalg #1#2%
+{%
+ \expandafter\XINT_bezalg_fork\romannumeral0\xintiiabs{\xintNum{#2}}\Z #1\Z
+}%
+% \end{macrocode}
+% \lverb|Ici #3#4=A, #1#2=B|
+% \begin{macrocode}
+\def\XINT_bezalg_fork #1#2\Z #3#4\Z
+{%
+ \xint_UDzerofork
+ #1\XINT_bezalg_BisZero
+ #3\XINT_bezalg_AisZero
+ 0\XINT_bezalg_a
+ \krof
+ 0{#1#2}{#3#4}1001{{#3#4}{#1#2}}{}\Z
+}%
+\def\XINT_bezalg_AisZero #1#2#3\Z{{1}{0}{0}{1}{#2}{#2}{1}{0}{0}{0}{0}{1}}%
+\def\XINT_bezalg_BisZero #1#2#3#4\Z{{1}{0}{0}{1}{#3}{#3}{1}{0}{0}{0}{0}{1}}%
+% \end{macrocode}
+% \lverb|&
+% pour préparer l'étape n+1 il faut
+% {n}{r(n)}{r(n-1)}{alpha(n)}{beta(n)}{alpha(n-1)}{beta(n-1)}&
+% {{q(n)}{r(n)}{alpha(n)}{beta(n)}}...
+% division de #3 par #2|
+% \begin{macrocode}
+\def\XINT_bezalg_a #1#2#3%
+{%
+ \expandafter\XINT_bezalg_b\the\numexpr #1+\xint_c_i\expandafter.%
+ \romannumeral0\XINT_div_prepare {#2}{#3}{#2}%
+}%
+% \end{macrocode}
+% \lverb|&
+% {n+1}{q(n+1)}{r(n+1)}{r(n)}{alpha(n)}{beta(n)}{alpha(n-1)}{beta(n-1)}...|
+% \begin{macrocode}
+\def\XINT_bezalg_b #1.#2#3#4#5#6#7#8%
+{%
+ \expandafter\XINT_bezalg_c\expandafter
+ {\romannumeral0\xintiiadd {\xintiiMul {#6}{#2}}{#8}}%
+ {\romannumeral0\xintiiadd {\xintiiMul {#5}{#2}}{#7}}%
+ {#1}{#2}{#3}{#4}{#5}{#6}%
+}%
+% \end{macrocode}
+% \lverb|&
+% {beta(n+1)}{alpha(n+1)}{n+1}{q(n+1)}{r(n+1)}{r(n)}{alpha(n)}{beta(n}}|
+% \begin{macrocode}
+\def\XINT_bezalg_c #1#2#3#4#5#6%
+{%
+ \expandafter\XINT_bezalg_d\expandafter {#2}{#3}{#4}{#5}{#6}{#1}%
+}%
+% \end{macrocode}
+% \lverb|{alpha(n+1)}{n+1}{q(n+1)}{r(n+1)}{r(n)}{beta(n+1)}|
+% \begin{macrocode}
+\def\XINT_bezalg_d #1#2#3#4#5#6#7#8%
+{%
+ \XINT_bezalg_e #4\Z {#2}{#4}{#5}{#1}{#6}{#7}{#8}{{#3}{#4}{#1}{#6}}%
+}%
+% \end{macrocode}
+% \lverb|r(n+1)\Z {n+1}{r(n+1)}{r(n)}{alpha(n+1)}{beta(n+1)}$\
+% {alpha(n)}{beta(n)}{q,r,alpha,beta(n+1)}$\
+% Test si r(n+1) est nul.|
+% \begin{macrocode}
+\def\XINT_bezalg_e #1#2\Z
+{%
+ \xint_gob_til_zero #1\XINT_bezalg_end0\XINT_bezalg_a
+}%
+% \end{macrocode}
+% \lverb|&
+% Ici r(n+1) = 0. On arrête on se prépare à inverser.$\
+% {n+1}{r(n+1)}{r(n)}{alpha(n+1)}{beta(n+1)}{alpha(n)}{beta(n)}$\
+% {q,r,alpha,beta(n+1)}...{{A}{B}}{}\Z$\
+% On veut renvoyer$\
+% {N}{A}{0}{1}{D=r(n)}{B}{1}{0}{q1}{r1}{alpha1=q1}{beta1=1}$\
+% {q2}{r2}{alpha2}{beta2}....{qN}{rN=0}{alphaN=A/D}{betaN=B/D}|
+% \begin{macrocode}
+\def\XINT_bezalg_end0\XINT_bezalg_a #1#2#3#4#5#6#7#8\Z
+{%
+ \expandafter\XINT_bezalg_end_a
+ \romannumeral0%
+ \XINT_rord_main {}#8{{#1}{#3}}%
+ \xint:
+ \xint_bye\xint_bye\xint_bye\xint_bye
+ \xint_bye\xint_bye\xint_bye\xint_bye
+ \xint:
+}%
+% \end{macrocode}
+% \lverb|&
+% {N}{D}{A}{B}{q1}{r1}{alpha1=q1}{beta1=1}{q2}{r2}{alpha2}{beta2}$\
+% ....{qN}{rN=0}{alphaN=A/D}{betaN=B/D}$\
+% On veut renvoyer$\
+% {N}{A}{0}{1}{D=r(n)}{B}{1}{0}{q1}{r1}{alpha1=q1}{beta1=1}$\
+% {q2}{r2}{alpha2}{beta2}....{qN}{rN=0}{alphaN=A/D}{betaN=B/D}|
+% \begin{macrocode}
+\def\XINT_bezalg_end_a #1#2#3#4{{#1}{#3}{0}{1}{#2}{#4}{1}{0}}%
+% \end{macrocode}
+% \subsection{\csh{xintGCDof}}
+% \lverb|1.2l adds protection against items being non-terminated \the\numexpr...|
+% \begin{macrocode}
+\def\xintGCDof {\romannumeral0\xintgcdof }%
+\def\xintgcdof #1{\expandafter\XINT_gcdof_a\romannumeral`&&@#1\xint:}%
+\def\XINT_gcdof_a #1{\expandafter\XINT_gcdof_b\romannumeral`&&@#1!}%
+\def\XINT_gcdof_b #1!#2{\expandafter\XINT_gcdof_c\romannumeral`&&@#2!{#1}!}%
+\def\XINT_gcdof_c #1{\xint_gob_til_xint: #1\XINT_gcdof_e\xint:\XINT_gcdof_d #1}%
+\def\XINT_gcdof_d #1!{\expandafter\XINT_gcdof_b\romannumeral0\xintgcd {#1}}%
+\def\XINT_gcdof_e #1!#2!{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintLCMof}}
+% \lverb|New with 1.09a|
+% \lverb|1.2l adds protection against items being non-terminated \the\numexpr...|
+% \begin{macrocode}
+\def\xintLCMof {\romannumeral0\xintlcmof }%
+\def\xintlcmof #1{\expandafter\XINT_lcmof_a\romannumeral`&&@#1\xint:}%
+\def\XINT_lcmof_a #1{\expandafter\XINT_lcmof_b\romannumeral`&&@#1!}%
+\def\XINT_lcmof_b #1!#2{\expandafter\XINT_lcmof_c\romannumeral`&&@#2!{#1}!}%
+\def\XINT_lcmof_c #1{\xint_gob_til_xint: #1\XINT_lcmof_e\xint:\XINT_lcmof_d #1}%
+\def\XINT_lcmof_d #1!{\expandafter\XINT_lcmof_b\romannumeral0\xintlcm {#1}}%
+\def\XINT_lcmof_e #1!#2!{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintTypesetEuclideAlgorithm}}
+% \lverb|&
+% TYPESETTING
+%
+% Organisation:
+%
+% {N}{A}{D}{B}{q1}{r1}{q2}{r2}{q3}{r3}....{qN}{rN=0}$\
+% \U1 = N = nombre d'étapes, \U3 = PGCD, \U2 = A, \U4=B
+% q1 = \U5, q2 = \U7 --> qn = \U<2n+3>, rn = \U<2n+4>
+% bn = rn. B = r0. A=r(-1)
+%
+% r(n-2) = q(n)r(n-1)+r(n) (n e étape)
+%
+% \U{2n} = \U{2n+3} \times \U{2n+2} + \U{2n+4}, n e étape.
+% (avec n entre 1 et N)
+%
+% 1.09h uses \xintloop, and \par rather than \endgraf; and \par rather than
+% \hfill\break|
+% \begin{macrocode}
+\def\xintTypesetEuclideAlgorithm {%
+ \unless\ifdefined\xintAssignArray
+ \errmessage
+ {xintgcd: package xinttools is required for \string\xintTypesetEuclideAlgorithm}%
+ \expandafter\xint_gobble_iii
+ \fi
+ \XINT_TypesetEuclideAlgorithm
+}%
+\def\XINT_TypesetEuclideAlgorithm #1#2%
+{% l'algo remplace #1 et #2 par |#1| et |#2|
+ \par
+ \begingroup
+ \xintAssignArray\xintEuclideAlgorithm {#1}{#2}\to\U
+ \edef\A{\U2}\edef\B{\U4}\edef\N{\U1}%
+ \setbox 0 \vbox{\halign {$##$\cr \A\cr \B \cr}}%
+ \count 255 1
+ \xintloop
+ \indent\hbox to \wd 0 {\hfil$\U{\numexpr 2*\count255\relax}$}%
+ ${} = \U{\numexpr 2*\count255 + 3\relax}
+ \times \U{\numexpr 2*\count255 + 2\relax}
+ + \U{\numexpr 2*\count255 + 4\relax}$%
+ \ifnum \count255 < \N
+ \par
+ \advance \count255 1
+ \repeat
+ \endgroup
+}%
+% \end{macrocode}
+% \subsection{\csh{xintTypesetBezoutAlgorithm}}
+% \lverb|&
+% Pour Bezout on a:
+% {N}{A}{0}{1}{D=r(n)}{B}{1}{0}{q1}{r1}{alpha1=q1}{beta1=1}$\
+% {q2}{r2}{alpha2}{beta2}....{qN}{rN=0}{alphaN=A/D}{betaN=B/D}%
+% Donc 4N+8 termes:
+% U1 = N, U2= A, U5=D, U6=B, q1 = U9, qn = U{4n+5}, n au moins 1$\
+% rn = U{4n+6}, n au moins -1$\
+% alpha(n) = U{4n+7}, n au moins -1$\
+% beta(n) = U{4n+8}, n au moins -1
+%
+% 1.09h uses \xintloop, and \par rather than \endgraf; and no more \parindent0pt
+% |
+% \begin{macrocode}
+\def\xintTypesetBezoutAlgorithm {%
+ \unless\ifdefined\xintAssignArray
+ \errmessage
+ {xintgcd: package xinttools is required for \string\xintTypesetBezoutAlgorithm}%
+ \expandafter\xint_gobble_iii
+ \fi
+ \XINT_TypesetBezoutAlgorithm
+}%
+\def\XINT_TypesetBezoutAlgorithm #1#2%
+{%
+ \par
+ \begingroup
+ \xintAssignArray\xintBezoutAlgorithm {#1}{#2}\to\BEZ
+ \edef\A{\BEZ2}\edef\B{\BEZ6}\edef\N{\BEZ1}% A = |#1|, B = |#2|
+ \setbox 0 \vbox{\halign {$##$\cr \A\cr \B \cr}}%
+ \count255 1
+ \xintloop
+ \indent\hbox to \wd 0 {\hfil$\BEZ{4*\count255 - 2}$}%
+ ${} = \BEZ{4*\count255 + 5}
+ \times \BEZ{4*\count255 + 2}
+ + \BEZ{4*\count255 + 6}$\hfill\break
+ \hbox to \wd 0 {\hfil$\BEZ{4*\count255 +7}$}%
+ ${} = \BEZ{4*\count255 + 5}
+ \times \BEZ{4*\count255 + 3}
+ + \BEZ{4*\count255 - 1}$\hfill\break
+ \hbox to \wd 0 {\hfil$\BEZ{4*\count255 +8}$}%
+ ${} = \BEZ{4*\count255 + 5}
+ \times \BEZ{4*\count255 + 4}
+ + \BEZ{4*\count255 }$
+ \par
+ \ifnum \count255 < \N
+ \advance \count255 1
+ \repeat
+ \edef\U{\BEZ{4*\N + 4}}%
+ \edef\V{\BEZ{4*\N + 3}}%
+ \edef\D{\BEZ5}%
+ \ifodd\N
+ $\U\times\A - \V\times \B = -\D$%
+ \else
+ $\U\times\A - \V\times\B = \D$%
+ \fi
+ \par
+ \endgroup
+}%
+\XINT_restorecatcodes_endinput%
+% \end{macrocode}
+% \StoreCodelineNo {xintgcd}
+% \cleardoublepage\let\xintgcdnameUp\undefined
+%\gardesactifs
+%\let</xintgcd>\relax
+%\let<*xintfrac>\gardesinactifs
+%</xintgcd>^^A----------------------------------------------------
+%<*xintfrac>^^A---------------------------------------------------
+%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*-
+% \clearpage\csname xintfracnameUp\endcsname
+% \section{Package \xintfracnameimp implementation}
+% \RaisedLabel{sec:fracimp}
+%
+% \localtableofcontents
+%
+% The commenting is currently (\xintdocdate) very sparse.
+%
+% \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{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+ \catcode13=5 % ^^M
+ \endlinechar=13 %
+ \catcode123=1 % {
+ \catcode125=2 % }
+ \catcode64=11 % @
+ \catcode35=6 % #
+ \catcode44=12 % ,
+ \catcode45=12 % -
+ \catcode46=12 % .
+ \catcode58=12 % :
+ \let\z\endgroup
+ \expandafter\let\expandafter\x\csname ver@xintfrac.sty\endcsname
+ \expandafter\let\expandafter\w\csname ver@xint.sty\endcsname
+ \expandafter
+ \ifx\csname PackageInfo\endcsname\relax
+ \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}%
+ \else
+ \def\y#1#2{\PackageInfo{#1}{#2}}%
+ \fi
+ \expandafter
+ \ifx\csname numexpr\endcsname\relax
+ \y{xintfrac}{\numexpr not available, aborting input}%
+ \aftergroup\endinput
+ \else
+ \ifx\x\relax % plain-TeX, first loading of xintfrac.sty
+ \ifx\w\relax % but xint.sty not yet loaded.
+ \def\z{\endgroup\input xint.sty\relax}%
+ \fi
+ \else
+ \def\empty {}%
+ \ifx\x\empty % LaTeX, first loading,
+ % variable is initialized, but \ProvidesPackage not yet seen
+ \ifx\w\relax % xint.sty not yet loaded.
+ \def\z{\endgroup\RequirePackage{xint}}%
+ \fi
+ \else
+ \aftergroup\endinput % xintfrac already loaded.
+ \fi
+ \fi
+ \fi
+\z%
+\XINTsetupcatcodes% defined in xintkernel.sty
+% \end{macrocode}
+% \subsection{Package identification}
+% \begin{macrocode}
+\XINT_providespackage
+\ProvidesPackage{xintfrac}%
+ [2019/04/05 1.3e Expandable operations on fractions (JFB)]%
+% \end{macrocode}
+% \subsection{\csh{XINT_cntSgnFork}}
+% \lverb|1.09i. Used internally, #1 must expand to \m@ne, \z@, or \@ne or
+% equivalent. \XINT_cntSgnFork does not insert a romannumeral stopper.|
+% \begin{macrocode}
+\def\XINT_cntSgnFork #1%
+{%
+ \ifcase #1\expandafter\xint_secondofthree
+ \or\expandafter\xint_thirdofthree
+ \else\expandafter\xint_firstofthree
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\cshnolabel{xintLen}}
+% \lverb|The used formula is disputable, the idea is that A/1 and A should have
+% same length. Venerable code rewritten for 1.2i, following updates to
+% \xintLength in xintkernel.sty. And sadly, I forgot on this
+% occasion that this macro is not supposed to count the sign... Fixed in 1.2k.|
+% \begin{macrocode}
+\def\xintLen {\romannumeral0\xintlen }%
+\def\xintlen #1%
+{%
+ \expandafter\XINT_flen\romannumeral0\XINT_infrac {#1}%
+}%
+\def\XINT_flen#1{\def\XINT_flen ##1##2##3%
+{%
+ \expandafter#1%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \the\numexpr \XINT_abs##1+%
+ \XINT_len_fork ##2##3\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-\xint_c_i
+ \relax
+}}\XINT_flen{ }%
+% \end{macrocode}
+% \subsection{\csh{XINT_outfrac}}
+% \lverb|&
+% Months later (2014/10/22): perhaps I should document what this macro does
+% before I forget? from {e}{N}{D} it outputs N/D[e], checking in passing if
+% D=0 or if N=0. It also makes sure D is not < 0. I am not sure but I don't
+% think there is any place in the code which could call \XINT_outfrac with a D
+% < 0, but I should check.|
+% \begin{macrocode}
+\def\XINT_outfrac #1#2#3%
+{%
+ \ifcase\XINT_cntSgn #3\xint:
+ \expandafter \XINT_outfrac_divisionbyzero
+ \or
+ \expandafter \XINT_outfrac_P
+ \else
+ \expandafter \XINT_outfrac_N
+ \fi
+ {#2}{#3}[#1]%
+}%
+\def\XINT_outfrac_divisionbyzero #1#2%
+{%
+ \XINT_signalcondition{DivisionByZero}{Division of #1 by #2}{}{0/1[0]}%
+}%
+\def\XINT_outfrac_P#1{%
+\def\XINT_outfrac_P ##1##2%
+ {\if0\XINT_Sgn ##1\xint:\expandafter\XINT_outfrac_Zero\fi#1##1/##2}%
+}\XINT_outfrac_P{ }%
+\def\XINT_outfrac_Zero #1[#2]{ 0/1[0]}%
+\def\XINT_outfrac_N #1#2%
+{%
+ \expandafter\XINT_outfrac_N_a\expandafter
+ {\romannumeral0\XINT_opp #2}{\romannumeral0\XINT_opp #1}%
+}%
+\def\XINT_outfrac_N_a #1#2%
+{%
+ \expandafter\XINT_outfrac_P\expandafter {#2}{#1}%
+}%
+% \end{macrocode}
+% \subsection{\csh{XINT_inFrac}}\label{src-XINT_infrac}
+% \lverb|&
+% Parses fraction, scientific notation, etc... and produces {n}{A}{B}
+% corresponding to A/B times 10^n. No reduction to smallest terms.
+%
+% Extended in 1.07 to accept scientific notation on input. With lowercase
+% e only. The \xintexpr parser does accept uppercase E also. Ah, by the way,
+% perhaps I should at least say what this macro does? (belated addition
+% 2014/10/22...), before I forget! It prepares the fraction in the internal
+% format {exponent}{Numerator}{Denominator} where Denominator is at least 1.
+%
+% 2015/10/09: this venerable macro from the very early days (1.03, 2013/04/14)
+% has gotten a lifting for release 1.2. There were two kinds of issues:
+%
+% 1) use of \W, \Z, \T delimiters was very poor choice as this could clash with
+% user input,
+%
+% 2) the new \XINT_frac_gen handles macros (possibly empty) in the input as
+% general as \A.\Be\C/\D.\Ee\F. The earlier version would not have expanded
+% the \B or \E: digits after decimal mark were constrained to arise from
+% expansion of the first token. Thus the 1.03 original code would have
+% expanded only \A, \D, \C, and \F for this input.
+%
+% This reminded me think I should revisit the remaining earlier
+% portions of code, as I was still learning TeX coding when I wrote them.
+%
+% Also I thought about parsing even faster the A/B[N] input, not expanding B,
+% but this turned out to clash with some established uses in the documentation
+% such as 1/\xintiiSqr{...}[0]. For the implementation, careful here about
+% potential brace removals with parameter patterns such as like #1/#2#3[#4]for
+% example.
+%
+% While I was at it 1.2 added \numexpr parsing of the N, which earlier was
+% restricted to be only explicit digits. I allowed [] with empty N, but the
+% way I did it in 1.2 with \the\numexpr 0#1 was buggy, as it did not allow #1
+% to be a \count for example or itself a \numexpr (although such inputs were
+% not previously allowed, I later turned out to use them in the code itself,
+% e.g. the float factorial of version 1.2f). The better way would be
+% \the\numexpr#1+\xint_c_ but 1.2f finally does only \the\numexpr #1 and #1 is
+% not allowed to be empty.
+%
+% The 1.2 \XINT_frac_gen had two locations with such a problematic \numexpr
+% 0#1 which I replaced for 1.2f with \numexpr#1+\xint_c_.
+%
+% Regarding calling the macro with an argument A[<expression>], a / inthe
+% expression must be suitably hidden for example in \firstofone type
+% constructs.
+%
+% Note: when the numerator is found to be zero \XINT_inFrac *always* returns
+% {0}{0}{1}. This behaviour must not change because 1.2g \xintFloat and
+% XINTinFloat (for example) rely upon it: if the denominator on output is not
+% 1, then \xintFloat assumes that the numerator is not zero.
+%
+% As described in the manual, if the input contains a (final) [N] part, it is
+% assumed that it is in the shape A[N] or A/B[N] with A (and B) not containing
+% neither decimal mark nor scientific part, moreover B must be positive and A
+% have at most one minus sign (and no plus sign). Else there will be errors,
+% for example -0/2[0] would not be recognized as being zero at this stage and
+% this could cause issues afterwards. When there is no ending [N] part, both
+% numerator and denominator will be parsed for the more general format
+% allowing decimal digits and scientific part and possibly multiple leading
+% signs.
+%
+% 1.2l fixes frailty of \XINT_infrac (hence basically of all xintfrac macros)
+% respective to non terminated \numexpr input: \xintRaw{\the\numexpr1} for
+% example. The issue was that \numexpr sees the / and expands what's next.
+% But even \numexpr 1// for example creates an error, and to my mind this is
+% a defect of \numexpr. It should be able to trace back and see that / was
+% used as delimiter not as operator. Anyway, I thus fixed this problem
+% belatedly here regarding \XINT_infrac.
+% |
+% \begin{macrocode}
+\def\XINT_inFrac {\romannumeral0\XINT_infrac }%
+\def\XINT_infrac #1%
+{%
+ \expandafter\XINT_infrac_fork\romannumeral`&&@#1\xint:/\XINT_W[\XINT_W\XINT_T
+}%
+\def\XINT_infrac_fork #1[#2%
+{%
+ \xint_UDXINTWfork
+ #2\XINT_frac_gen % input has no brackets [N]
+ \XINT_W\XINT_infrac_res_a % there is some [N], must be strict A[N] or A/B[N] input
+ \krof
+ #1[#2%
+}%
+\def\XINT_infrac_res_a #1%
+{%
+ \xint_gob_til_zero #1\XINT_infrac_res_zero 0\XINT_infrac_res_b #1%
+}%
+% \end{macrocode}
+% \lverb|Note that input exponent is here ignored and forced to be zero.|
+% \begin{macrocode}
+\def\XINT_infrac_res_zero 0\XINT_infrac_res_b #1\XINT_T {{0}{0}{1}}%
+\def\XINT_infrac_res_b #1/#2%
+{%
+ \xint_UDXINTWfork
+ #2\XINT_infrac_res_ca % it was A[N] input
+ \XINT_W\XINT_infrac_res_cb % it was A/B[N] input
+ \krof
+ #1/#2%
+}%
+% \end{macrocode}
+% \lverb|An empty [] is not allowed. (this was authorized in 1.2, removed in
+% 1.2f). As nobody reads xint documentation, no one will have noticed the
+% fleeting possibility.|
+% \begin{macrocode}
+\def\XINT_infrac_res_ca #1[#2]\xint:/\XINT_W[\XINT_W\XINT_T
+ {\expandafter{\the\numexpr #2}{#1}{1}}%
+\def\XINT_infrac_res_cb #1/#2[%
+ {\expandafter\XINT_infrac_res_cc\romannumeral`&&@#2~#1[}%
+\def\XINT_infrac_res_cc #1~#2[#3]\xint:/\XINT_W[\XINT_W\XINT_T
+ {\expandafter{\the\numexpr #3}{#2}{#1}}%
+% \end{macrocode}
+% \subsection{\csh{XINT_frac_gen}}
+% \lverb|Extended in 1.07 to recognize and accept scientific notation both at
+% the numerator and (possible) denominator. Only a lowercase e will do here,
+% but uppercase E is possible within an \xintexpr..\relax
+%
+% Completely rewritten for 1.2 2015/10/10. The parsing handles inputs such as
+% \A.\Be\C/\D.\Ee\F where each of \A, \B, \D, and \E may need f-expansion and
+% \C and \F will end up in \numexpr.
+%
+% 1.2f corrects an issue to allow \C and \F to be \count variable (or
+% expressions with \numexpr): 1.2 did a bad \numexpr0#1 which allowed only
+% explicit digits for expanded #1.|
+% \begin{macrocode}
+\def\XINT_frac_gen #1/#2%
+{%
+ \xint_UDXINTWfork
+ #2\XINT_frac_gen_A % there was no /
+ \XINT_W\XINT_frac_gen_B % there was a /
+ \krof
+ #1/#2%
+}%
+% \end{macrocode}
+% \lverb|Note that #1 is only expanded so far up to decimal mark or "e".|
+% \begin{macrocode}
+\def\XINT_frac_gen_A #1\xint:/\XINT_W [\XINT_W {\XINT_frac_gen_C 0~1!#1ee.\XINT_W }%
+\def\XINT_frac_gen_B #1/#2\xint:/\XINT_W[%\XINT_W
+{%
+ \expandafter\XINT_frac_gen_Ba
+ \romannumeral`&&@#2ee.\XINT_W\XINT_Z #1ee.%\XINT_W
+}%
+\def\XINT_frac_gen_Ba #1.#2%
+{%
+ \xint_UDXINTWfork
+ #2\XINT_frac_gen_Bb
+ \XINT_W\XINT_frac_gen_Bc
+ \krof
+ #1.#2%
+}%
+\def\XINT_frac_gen_Bb #1e#2e#3\XINT_Z
+ {\expandafter\XINT_frac_gen_C\the\numexpr #2+\xint_c_~#1!}%
+\def\XINT_frac_gen_Bc #1.#2e%
+{%
+ \expandafter\XINT_frac_gen_Bd\romannumeral`&&@#2.#1e%
+}%
+% \end{macrocode}
+% \begin{macrocode}
+\def\XINT_frac_gen_Bd #1.#2e#3e#4\XINT_Z
+{%
+ \expandafter\XINT_frac_gen_C\the\numexpr #3-%
+ \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
+ ~#2#1!%
+}%
+\def\XINT_frac_gen_C #1!#2.#3%
+{%
+ \xint_UDXINTWfork
+ #3\XINT_frac_gen_Ca
+ \XINT_W\XINT_frac_gen_Cb
+ \krof
+ #1!#2.#3%
+}%
+\def\XINT_frac_gen_Ca #1~#2!#3e#4e#5\XINT_T
+{%
+ \expandafter\XINT_frac_gen_F\the\numexpr #4-#1\expandafter
+ ~\romannumeral0\expandafter\XINT_num_cleanup\the\numexpr\XINT_num_loop
+ #2\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\Z~#3~%
+}%
+\def\XINT_frac_gen_Cb #1.#2e%
+{%
+ \expandafter\XINT_frac_gen_Cc\romannumeral`&&@#2.#1e%
+}%
+\def\XINT_frac_gen_Cc #1.#2~#3!#4e#5e#6\XINT_T
+{%
+ \expandafter\XINT_frac_gen_F\the\numexpr #5-#2-%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \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
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \relax\expandafter~%
+ \romannumeral0\expandafter\XINT_num_cleanup\the\numexpr\XINT_num_loop
+ #3\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\Z
+ ~#4#1~%
+}%
+\def\XINT_frac_gen_F #1~#2%
+{%
+ \xint_UDzerominusfork
+ #2-\XINT_frac_gen_Gdivbyzero
+ 0#2{\XINT_frac_gen_G -{}}%
+ 0-{\XINT_frac_gen_G {}#2}%
+ \krof #1~%
+}%
+\def\XINT_frac_gen_Gdivbyzero #1~~#2~%
+{%
+ \expandafter\XINT_frac_gen_Gdivbyzero_a
+ \romannumeral0\expandafter\XINT_num_cleanup\the\numexpr\XINT_num_loop
+ #2\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\Z~#1~%
+}%
+\def\XINT_frac_gen_Gdivbyzero_a #1~#2~%
+{%
+ \XINT_signalcondition{DivisionByZero}{Division of #1 by zero}{}{{#2}{#1}{0}}%
+}%
+\def\XINT_frac_gen_G #1#2#3~#4~#5~%
+{%
+ \expandafter\XINT_frac_gen_Ga
+ \romannumeral0\expandafter\XINT_num_cleanup\the\numexpr\XINT_num_loop
+ #1#5\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\Z~#3~{#2#4}%
+}%
+\def\XINT_frac_gen_Ga #1#2~#3~%
+{%
+ \xint_gob_til_zero #1\XINT_frac_gen_zero 0%
+ {#3}{#1#2}%
+}%
+\def\XINT_frac_gen_zero 0#1#2#3{{0}{0}{1}}%
+% \end{macrocode}
+% \subsection{\csh{XINT_factortens}}
+% \lverb|This is the core macro for \xintREZ. To be used as
+% \romannumeral0\XINT_factortens{...}. Output is A.N. (formerly {A}{N}) where
+% A is the integer stripped from trailing zeroes and N is the number of
+% removed zeroes. Only for positive strict integers!
+%
+% Completely rewritten at 1.3a to replace a double \xintReverseOrder by a
+% direct \numexpr governed expansion to the end and back, à la 1.2. I should
+% comment more... and perhaps improve again in future.
+%
+% Testing shows significant gain at 100 digits or more.|
+% \begin{macrocode}
+\def\XINT_factortens #1{\expandafter\XINT_factortens_z
+ \romannumeral0\XINT_factortens_a#1%
+ \XINT_factortens_b123456789.}%
+\def\XINT_factortens_z.\XINT_factortens_y{ }%
+\def\XINT_factortens_a #1#2#3#4#5#6#7#8#9%
+ {\expandafter\XINT_factortens_x
+ \the\numexpr 1#1#2#3#4#5#6#7#8#9\XINT_factortens_a}%
+\def\XINT_factortens_b#1\XINT_factortens_a#2#3.%
+ {.\XINT_factortens_cc 000000000-#2.}%
+\def\XINT_factortens_x1#1.#2{#2#1}%
+\def\XINT_factortens_y{.\XINT_factortens_y}%
+\def\XINT_factortens_cc #1#2#3#4#5#6#7#8#9%
+ {\if#90\xint_dothis
+ {\expandafter\XINT_factortens_d\the\numexpr #8#7#6#5#4#3#2#1\relax
+ \xint_c_i 2345678.}\fi
+ \xint_orthat{\XINT_factortens_yy{#1#2#3#4#5#6#7#8#9}}}%
+\def\XINT_factortens_yy #1#2.{.\XINT_factortens_y#1.0.}%
+\def\XINT_factortens_c #1#2#3#4#5#6#7#8#9%
+ {\if#90\xint_dothis
+ {\expandafter\XINT_factortens_d\the\numexpr #8#7#6#5#4#3#2#1\relax
+ \xint_c_i 2345678.}\fi
+ \xint_orthat{.\XINT_factortens_y #1#2#3#4#5#6#7#8#9.}}%
+\def\XINT_factortens_d #1#2#3#4#5#6#7#8#9%
+ {\if#10\expandafter\XINT_factortens_e\fi
+ \XINT_factortens_f #9#9#8#7#6#5#4#3#2#1.}%
+\def\XINT_factortens_f #1#2\xint_c_i#3.#4.#5.%
+ {\expandafter\XINT_factortens_g\the\numexpr#1+#5.#3.}%
+\def\XINT_factortens_g #1.#2.{.\XINT_factortens_y#2.#1.}%
+\def\XINT_factortens_e #1..#2.%
+ {\expandafter.\expandafter\XINT_factortens_c
+ \the\numexpr\xint_c_ix+#2.}%
+% \end{macrocode}
+% \subsection{\xintListWithSep{, }
+% {\xintApply{ \csh}{{xintEq}{xintNotEq}{xintGt}{xintLt}{xintGtorEq}
+% {xintLtorEq}{xintIsZero}{xintIsNotZero}{xintOdd}
+% {xintEven}{xintifSgn}{xintifCmp}{xintifEq}{xintifGt}{xintifLt}
+% {xintifZero}{xintifNotZero}{xintifOne}{xintifOdd}}}}
+%
+% \lverb|Moved here at 1.3. Formerly these macros were already defined in
+% xint.sty or even xintcore.sty. They are slim wrappers of macros defined
+% elsewhere in xintfrac.
+% |
+% \begin{macrocode}
+\def\xintEq {\romannumeral0\xinteq }%
+\def\xinteq #1#2{\xintifeq{#1}{#2}{1}{0}}%
+\def\xintNotEq#1#2{\romannumeral0\xintifeq {#1}{#2}{0}{1}}%
+\def\xintGt {\romannumeral0\xintgt }%
+\def\xintgt #1#2{\xintifgt{#1}{#2}{1}{0}}%
+\def\xintLt {\romannumeral0\xintlt }%
+\def\xintlt #1#2{\xintiflt{#1}{#2}{1}{0}}%
+\def\xintGtorEq #1#2{\romannumeral0\xintiflt {#1}{#2}{0}{1}}%
+\def\xintLtorEq #1#2{\romannumeral0\xintifgt {#1}{#2}{0}{1}}%
+\def\xintIsZero {\romannumeral0\xintiszero }%
+\def\xintiszero #1{\if0\xintSgn{#1}\xint_afterfi{ 1}\else\xint_afterfi{ 0}\fi}%
+\def\xintIsNotZero{\romannumeral0\xintisnotzero }%
+\def\xintisnotzero
+ #1{\if0\xintSgn{#1}\xint_afterfi{ 0}\else\xint_afterfi{ 1}\fi}%
+\def\xintOdd {\romannumeral0\xintodd }%
+\def\xintodd #1%
+{%
+ \ifodd\xintLDg{\xintNum{#1}} %<- intentional space
+ \xint_afterfi{ 1}%
+ \else
+ \xint_afterfi{ 0}%
+ \fi
+}%
+\def\xintEven {\romannumeral0\xinteven }%
+\def\xinteven #1%
+{%
+ \ifodd\xintLDg{\xintNum{#1}} %<- intentional space
+ \xint_afterfi{ 0}%
+ \else
+ \xint_afterfi{ 1}%
+ \fi
+}%
+\def\xintifSgn{\romannumeral0\xintifsgn }%
+\def\xintifsgn #1%
+{%
+ \ifcase \xintSgn{#1}
+ \expandafter\xint_stop_atsecondofthree
+ \or\expandafter\xint_stop_atthirdofthree
+ \else\expandafter\xint_stop_atfirstofthree
+ \fi
+}%
+\def\xintifCmp{\romannumeral0\xintifcmp }%
+\def\xintifcmp #1#2%
+{%
+ \ifcase\xintCmp {#1}{#2}
+ \expandafter\xint_stop_atsecondofthree
+ \or\expandafter\xint_stop_atthirdofthree
+ \else\expandafter\xint_stop_atfirstofthree
+ \fi
+}%
+\def\xintifEq {\romannumeral0\xintifeq }%
+\def\xintifeq #1#2%
+{%
+ \if0\xintCmp{#1}{#2}%
+ \expandafter\xint_stop_atfirstoftwo
+ \else\expandafter\xint_stop_atsecondoftwo
+ \fi
+}%
+\def\xintifGt {\romannumeral0\xintifgt }%
+\def\xintifgt #1#2%
+{%
+ \if1\xintCmp{#1}{#2}%
+ \expandafter\xint_stop_atfirstoftwo
+ \else\expandafter\xint_stop_atsecondoftwo
+ \fi
+}%
+\def\xintifLt {\romannumeral0\xintiflt }%
+\def\xintiflt #1#2%
+{%
+ \ifnum\xintCmp{#1}{#2}<\xint_c_
+ \expandafter\xint_stop_atfirstoftwo
+ \else \expandafter\xint_stop_atsecondoftwo
+ \fi
+}%
+\def\xintifZero {\romannumeral0\xintifzero }%
+\def\xintifzero #1%
+{%
+ \if0\xintSgn{#1}%
+ \expandafter\xint_stop_atfirstoftwo
+ \else
+ \expandafter\xint_stop_atsecondoftwo
+ \fi
+}%
+\def\xintifNotZero{\romannumeral0\xintifnotzero }%
+\def\xintifnotzero #1%
+{%
+ \if0\xintSgn{#1}%
+ \expandafter\xint_stop_atsecondoftwo
+ \else
+ \expandafter\xint_stop_atfirstoftwo
+ \fi
+}%
+\def\xintifOne {\romannumeral0\xintifone }%
+\def\xintifone #1%
+{%
+ \if1\xintIsOne{#1}%
+ \expandafter\xint_stop_atfirstoftwo
+ \else
+ \expandafter\xint_stop_atsecondoftwo
+ \fi
+}%
+\def\xintifOdd {\romannumeral0\xintifodd }%
+\def\xintifodd #1%
+{%
+ \if\xintOdd{#1}1%
+ \expandafter\xint_stop_atfirstoftwo
+ \else
+ \expandafter\xint_stop_atsecondoftwo
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintRaw}}
+% \lverb|&
+% 1.07: this macro simply prints in a user readable form the fraction after its
+% initial scanning. Useful when put inside braces in an \xintexpr, when the
+% input is not yet in the A/B[n] form.|
+% \begin{macrocode}
+\def\xintRaw {\romannumeral0\xintraw }%
+\def\xintraw
+{%
+ \expandafter\XINT_raw\romannumeral0\XINT_infrac
+}%
+\def\XINT_raw #1#2#3{ #2/#3[#1]}%
+% \end{macrocode}
+% \subsection{\csh{xintiLogTen}}
+% \lverb|&
+% New at 1.3e
+% |
+% \begin{macrocode}
+\def\xintiLogTen {\the\numexpr\xintilogten}%
+\def\xintilogten
+{%
+ \expandafter\XINT_ilogten\romannumeral0\xintraw
+}%
+\def\XINT_ilogten #1%
+{%
+ \xint_UDzerominusfork
+ 0#1\XINT_ilogten_p
+ #1-\XINT_ilogten_z
+ 0-{\XINT_ilogten_p#1}%
+ \krof
+}%
+\def\XINT_ilogten_z #1[#2]{-"7FFF8000\relax}%
+\def\XINT_ilogten_p #1/#2[#3]%
+{%
+ #3+\expandafter\XINT_ilogten_a
+ \the\numexpr\xintLength{#1}\expandafter.\the\numexpr\xintLength{#2}.#1.#2.%
+}%
+\def\XINT_ilogten_a #1.#2.%
+{%
+ #1-#2\ifnum#1>#2
+ \expandafter\XINT_ilogten_aa
+ \else
+ \expandafter\XINT_ilogten_ab
+ \fi #1.#2.%
+}%
+\def\XINT_ilogten_aa #1.#2.#3.#4.%
+{%
+ \xintiiifLt{#3}{\XINT_dsx_addzerosnofuss{#1-#2}#4;}{-1}{}\relax
+}%
+\def\XINT_ilogten_ab #1.#2.#3.#4.%
+{%
+ \xintiiifLt{\XINT_dsx_addzerosnofuss{#2-#1}#3;}{#4}{-1}{}\relax
+}%
+% \end{macrocode}
+% \subsection{\csh{xintPRaw}}
+% \lverb|1.09b|
+% \begin{macrocode}
+\def\xintPRaw {\romannumeral0\xintpraw }%
+\def\xintpraw
+{%
+ \expandafter\XINT_praw\romannumeral0\XINT_infrac
+}%
+\def\XINT_praw #1%
+{%
+ \ifnum #1=\xint_c_ \expandafter\XINT_praw_a\fi \XINT_praw_A {#1}%
+}%
+\def\XINT_praw_A #1#2#3%
+{%
+ \if\XINT_isOne{#3}1\expandafter\xint_firstoftwo
+ \else\expandafter\xint_secondoftwo
+ \fi { #2[#1]}{ #2/#3[#1]}%
+}%
+\def\XINT_praw_a\XINT_praw_A #1#2#3%
+{%
+ \if\XINT_isOne{#3}1\expandafter\xint_firstoftwo
+ \else\expandafter\xint_secondoftwo
+ \fi { #2}{ #2/#3}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintRawWithZeros}}
+% \lverb|&
+% This was called \xintRaw in versions earlier than 1.07|
+% \begin{macrocode}
+\def\xintRawWithZeros {\romannumeral0\xintrawwithzeros }%
+\def\xintrawwithzeros
+{%
+ \expandafter\XINT_rawz_fork\romannumeral0\XINT_infrac
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_rawz_fork #1%
+{%
+ \ifnum#1<\xint_c_
+ \expandafter\XINT_rawz_Ba
+ \else
+ \expandafter\XINT_rawz_A
+ \fi
+ #1.%
+}%
+\def\XINT_rawz_A #1.#2#3{\XINT_dsx_addzeros{#1}#2;/#3}%
+\def\XINT_rawz_Ba -#1.#2#3{\expandafter\XINT_rawz_Bb
+ \expandafter{\romannumeral0\XINT_dsx_addzeros{#1}#3;}{#2}}%
+\def\XINT_rawz_Bb #1#2{ #2/#1}%
+% \end{macrocode}
+% \subsection{\csh{xintDecToString}}
+% \lverb|1.3. This is a backport from polexpr 0.4. It is definitely not in
+% final form, consider it to be an unstable macro.|
+% \begin{macrocode}
+\def\xintDecToString{\romannumeral0\xintdectostring}%
+\def\xintdectostring#1{\expandafter\XINT_dectostr\romannumeral0\xintraw{#1}}%
+\def\XINT_dectostr #1/#2[#3]{\xintiiifZero {#1}%
+ \XINT_dectostr_z
+ {\if1\XINT_isOne{#2}\expandafter\XINT_dectostr_a
+ \else\expandafter\XINT_dectostr_b
+ \fi}%
+ #1/#2[#3]%
+}%
+\def\XINT_dectostr_z#1[#2]{ 0}%
+\def\XINT_dectostr_a#1/#2[#3]{%
+ \ifnum#3<\xint_c_\xint_dothis{\xinttrunc{-#3}{#1[#3]}}\fi
+ \xint_orthat{\xintiie{#1}{#3}}%
+}%
+\def\XINT_dectostr_b#1/#2[#3]{% just to handle this somehow
+ \ifnum#3<\xint_c_\xint_dothis{\xinttrunc{-#3}{#1[#3]}/#2}\fi
+ \xint_orthat{\xintiie{#1}{#3}/#2}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFloor}, \csh{xintiFloor}}
+% \lverb|1.09a, 1.1 for \xintiFloor/\xintFloor. Not efficient if big negative
+% decimal exponent. Also sub-efficient if big positive decimal exponent.|
+% \begin{macrocode}
+\def\xintFloor {\romannumeral0\xintfloor }%
+\def\xintfloor #1% devrais-je faire \xintREZ?
+ {\expandafter\XINT_ifloor \romannumeral0\xintrawwithzeros {#1}./1[0]}%
+\def\xintiFloor {\romannumeral0\xintifloor }%
+\def\xintifloor #1%
+ {\expandafter\XINT_ifloor \romannumeral0\xintrawwithzeros {#1}.}%
+\def\XINT_ifloor #1/#2.{\xintiiquo {#1}{#2}}%
+% \end{macrocode}
+% \subsection{\csh{xintCeil}, \csh{xintiCeil}}
+% \lverb|1.09a|
+% \begin{macrocode}
+\def\xintCeil {\romannumeral0\xintceil }%
+\def\xintceil #1{\xintiiopp {\xintFloor {\xintOpp{#1}}}}%
+\def\xintiCeil {\romannumeral0\xinticeil }%
+\def\xinticeil #1{\xintiiopp {\xintiFloor {\xintOpp{#1}}}}%
+% \end{macrocode}
+% \subsection{\csh{xintNumerator}}
+% \begin{macrocode}
+\def\xintNumerator {\romannumeral0\xintnumerator }%
+\def\xintnumerator
+{%
+ \expandafter\XINT_numer\romannumeral0\XINT_infrac
+}%
+\def\XINT_numer #1%
+{%
+ \ifcase\XINT_cntSgn #1\xint:
+ \expandafter\XINT_numer_B
+ \or
+ \expandafter\XINT_numer_A
+ \else
+ \expandafter\XINT_numer_B
+ \fi
+ {#1}%
+}%
+\def\XINT_numer_A #1#2#3{\XINT_dsx_addzeros{#1}#2;}%
+\def\XINT_numer_B #1#2#3{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintDenominator}}
+% \begin{macrocode}
+\def\xintDenominator {\romannumeral0\xintdenominator }%
+\def\xintdenominator
+{%
+ \expandafter\XINT_denom_fork\romannumeral0\XINT_infrac
+}%
+\def\XINT_denom_fork #1%
+{%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \ifnum#1<\xint_c_
+ \expandafter\XINT_denom_B
+ \else
+ \expandafter\XINT_denom_A
+ \fi
+ #1.%
+}%
+\def\XINT_denom_A #1.#2#3{ #3}%
+\def\XINT_denom_B -#1.#2#3{\XINT_dsx_addzeros{#1}#3;}%
+% \end{macrocode}
+% \subsection{\csh{xintFrac}}
+% \lverb|Useless typesetting macro.|
+% \begin{macrocode}
+\def\xintFrac {\romannumeral0\xintfrac }%
+\def\xintfrac #1%
+{%
+ \expandafter\XINT_fracfrac_A\romannumeral0\XINT_infrac {#1}%
+}%
+\def\XINT_fracfrac_A #1{\XINT_fracfrac_B #1\Z }%
+\catcode`^=7
+\def\XINT_fracfrac_B #1#2\Z
+{%
+ \xint_gob_til_zero #1\XINT_fracfrac_C 0\XINT_fracfrac_D {10^{#1#2}}%
+}%
+\def\XINT_fracfrac_C 0\XINT_fracfrac_D #1#2#3%
+{%
+ \if1\XINT_isOne {#3}%
+ \xint_afterfi {\expandafter\xint_stop_atfirstoftwo\xint_gobble_ii }%
+ \fi
+ \space
+ \frac {#2}{#3}%
+}%
+\def\XINT_fracfrac_D #1#2#3%
+{%
+ \if1\XINT_isOne {#3}\XINT_fracfrac_E\fi
+ \space
+ \frac {#2}{#3}#1%
+}%
+\def\XINT_fracfrac_E \fi\space\frac #1#2{\fi \space #1\cdot }%
+% \end{macrocode}
+% \subsection{\csh{xintSignedFrac}}
+% \begin{macrocode}
+\def\xintSignedFrac {\romannumeral0\xintsignedfrac }%
+\def\xintsignedfrac #1%
+{%
+ \expandafter\XINT_sgnfrac_a\romannumeral0\XINT_infrac {#1}%
+}%
+\def\XINT_sgnfrac_a #1#2%
+{%
+ \XINT_sgnfrac_b #2\Z {#1}%
+}%
+\def\XINT_sgnfrac_b #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_sgnfrac_N
+ -{\XINT_sgnfrac_P #1}%
+ \krof
+}%
+\def\XINT_sgnfrac_P #1\Z #2%
+{%
+ \XINT_fracfrac_A {#2}{#1}%
+}%
+\def\XINT_sgnfrac_N
+{%
+ \expandafter-\romannumeral0\XINT_sgnfrac_P
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFwOver}}
+% \begin{macrocode}
+\def\xintFwOver {\romannumeral0\xintfwover }%
+\def\xintfwover #1%
+{%
+ \expandafter\XINT_fwover_A\romannumeral0\XINT_infrac {#1}%
+}%
+\def\XINT_fwover_A #1{\XINT_fwover_B #1\Z }%
+\def\XINT_fwover_B #1#2\Z
+{%
+ \xint_gob_til_zero #1\XINT_fwover_C 0\XINT_fwover_D {10^{#1#2}}%
+}%
+\catcode`^=11
+\def\XINT_fwover_C #1#2#3#4#5%
+{%
+ \if0\XINT_isOne {#5}\xint_afterfi { {#4\over #5}}%
+ \else\xint_afterfi { #4}%
+ \fi
+}%
+\def\XINT_fwover_D #1#2#3%
+{%
+ \if0\XINT_isOne {#3}\xint_afterfi { {#2\over #3}}%
+ \else\xint_afterfi { #2\cdot }%
+ \fi
+ #1%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintSignedFwOver}}
+% \begin{macrocode}
+\def\xintSignedFwOver {\romannumeral0\xintsignedfwover }%
+\def\xintsignedfwover #1%
+{%
+ \expandafter\XINT_sgnfwover_a\romannumeral0\XINT_infrac {#1}%
+}%
+\def\XINT_sgnfwover_a #1#2%
+{%
+ \XINT_sgnfwover_b #2\Z {#1}%
+}%
+\def\XINT_sgnfwover_b #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_sgnfwover_N
+ -{\XINT_sgnfwover_P #1}%
+ \krof
+}%
+\def\XINT_sgnfwover_P #1\Z #2%
+{%
+ \XINT_fwover_A {#2}{#1}%
+}%
+\def\XINT_sgnfwover_N
+{%
+ \expandafter-\romannumeral0\XINT_sgnfwover_P
+}%
+% \end{macrocode}
+% \subsection{\csh{xintREZ}}
+% \lverb|Removes trailing zeros from A and B and adjust the N in A/B[N].
+%
+% The macro really doing the job \XINT_factortens was redone at 1.3a. But
+% speed gain really noticeable only beyond about 100 digits.|
+% \begin{macrocode}
+\def\xintREZ {\romannumeral0\xintrez }%
+\def\xintrez
+{%
+ \expandafter\XINT_rez_A\romannumeral0\XINT_infrac
+}%
+\def\XINT_rez_A #1#2%
+{%
+ \XINT_rez_AB #2\Z {#1}%
+}%
+\def\XINT_rez_AB #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_rez_zero
+ 0#1\XINT_rez_neg
+ 0-{\XINT_rez_B #1}%
+ \krof
+}%
+\def\XINT_rez_zero #1\Z #2#3{ 0/1[0]}%
+\def\XINT_rez_neg {\expandafter-\romannumeral0\XINT_rez_B }%
+\def\XINT_rez_B #1\Z
+{%
+ \expandafter\XINT_rez_C\romannumeral0\XINT_factortens {#1}%
+}%
+\def\XINT_rez_C #1.#2.#3#4%
+{%
+ \expandafter\XINT_rez_D\romannumeral0\XINT_factortens {#4}#3+#2.#1.%
+}%
+\def\XINT_rez_D #1.#2.#3.%
+{%
+ \expandafter\XINT_rez_E\the\numexpr #3-#2.#1.%
+}%
+\def\XINT_rez_E #1.#2.#3.{ #3/#2[#1]}%
+% \end{macrocode}
+% \subsection{\csh{xintE}}
+% \lverb|1.07: The fraction is the first argument contrarily to \xintTrunc and
+% \xintRound.
+%
+% 1.1 modifies and moves \xintiiE to xint.sty.|
+% \begin{macrocode}
+\def\xintE {\romannumeral0\xinte }%
+\def\xinte #1%
+{%
+ \expandafter\XINT_e \romannumeral0\XINT_infrac {#1}%
+}%
+\def\XINT_e #1#2#3#4%
+{%
+ \expandafter\XINT_e_end\the\numexpr #1+#4.{#2}{#3}%
+}%
+\def\XINT_e_end #1.#2#3{ #2/#3[#1]}%
+% \end{macrocode}
+% \subsection{\csh{xintIrr}, \csh{xintPIrr}}
+% \lverb|\xintPIrr (partial Irr, which ignores the decimal part) added at 1.3.|
+% \begin{macrocode}
+\def\xintIrr {\romannumeral0\xintirr }%
+\def\xintPIrr{\romannumeral0\xintpirr }%
+\def\xintirr #1%
+{%
+ \expandafter\XINT_irr_start\romannumeral0\xintrawwithzeros {#1}\Z
+}%
+\def\xintpirr #1%
+{%
+ \expandafter\XINT_pirr_start\romannumeral0\xintraw{#1}%
+}%
+\def\XINT_irr_start #1#2/#3\Z
+{%
+ \if0\XINT_isOne {#3}%
+ \xint_afterfi
+ {\xint_UDsignfork
+ #1\XINT_irr_negative
+ -{\XINT_irr_nonneg #1}%
+ \krof}%
+ \else
+ \xint_afterfi{\XINT_irr_denomisone #1}%
+ \fi
+ #2\Z {#3}%
+}%
+\def\XINT_pirr_start #1#2/#3[%
+{%
+ \if0\XINT_isOne {#3}%
+ \xint_afterfi
+ {\xint_UDsignfork
+ #1\XINT_irr_negative
+ -{\XINT_irr_nonneg #1}%
+ \krof}%
+ \else
+ \xint_afterfi{\XINT_irr_denomisone #1}%
+ \fi
+ #2\Z {#3}[%
+}%
+\def\XINT_irr_denomisone #1\Z #2{ #1/1}% changed in 1.08
+\def\XINT_irr_negative #1\Z #2{\XINT_irr_D #1\Z #2\Z -}%
+\def\XINT_irr_nonneg #1\Z #2{\XINT_irr_D #1\Z #2\Z \space}%
+\def\XINT_irr_D #1#2\Z #3#4\Z
+{%
+ \xint_UDzerosfork
+ #3#1\XINT_irr_indeterminate
+ #30\XINT_irr_divisionbyzero
+ #10\XINT_irr_zero
+ 00\XINT_irr_loop_a
+ \krof
+ {#3#4}{#1#2}{#3#4}{#1#2}%
+}%
+\def\XINT_irr_indeterminate #1#2#3#4#5%
+{%
+ \XINT_signalcondition{DivisionUndefined}{indeterminate: 0/0}{}{0/1}%
+}%
+\def\XINT_irr_divisionbyzero #1#2#3#4#5%
+{%
+ \XINT_signalcondition{DivisionByZero}{vanishing denominator: #5#2/0}{}{0/1}%
+}%
+\def\XINT_irr_zero #1#2#3#4#5{ 0/1}% changed in 1.08
+\def\XINT_irr_loop_a #1#2%
+{%
+ \expandafter\XINT_irr_loop_d
+ \romannumeral0\XINT_div_prepare {#1}{#2}{#1}%
+}%
+\def\XINT_irr_loop_d #1#2%
+{%
+ \XINT_irr_loop_e #2\Z
+}%
+\def\XINT_irr_loop_e #1#2\Z
+{%
+ \xint_gob_til_zero #1\XINT_irr_loop_exit0\XINT_irr_loop_a {#1#2}%
+}%
+\def\XINT_irr_loop_exit0\XINT_irr_loop_a #1#2#3#4%
+{%
+ \expandafter\XINT_irr_loop_exitb\expandafter
+ {\romannumeral0\xintiiquo {#3}{#2}}%
+ {\romannumeral0\xintiiquo {#4}{#2}}%
+}%
+\def\XINT_irr_loop_exitb #1#2%
+{%
+ \expandafter\XINT_irr_finish\expandafter {#2}{#1}%
+}%
+\def\XINT_irr_finish #1#2#3{#3#1/#2}% changed in 1.08
+% \end{macrocode}
+% \subsection{\csh{xintifInt}}
+% \begin{macrocode}
+\def\xintifInt {\romannumeral0\xintifint }%
+\def\xintifint #1{\expandafter\XINT_ifint\romannumeral0\xintrawwithzeros {#1}.}%
+\def\XINT_ifint #1/#2.%
+{%
+ \if 0\xintiiRem {#1}{#2}%
+ \expandafter\xint_stop_atfirstoftwo
+ \else
+ \expandafter\xint_stop_atsecondoftwo
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintIsInt}}
+% \lverb|Added at 1.3d only, for isint() xintexpr function.|
+% \begin{macrocode}
+\def\xintIsInt {\romannumeral0\xintisint }%
+\def\xintisint #1%
+ {\expandafter\XINT_ifint\romannumeral0\xintrawwithzeros {#1}.10}%
+% \end{macrocode}
+% \subsection{\csh{xintJrr}}
+% \begin{macrocode}
+\def\xintJrr {\romannumeral0\xintjrr }%
+\def\xintjrr #1%
+{%
+ \expandafter\XINT_jrr_start\romannumeral0\xintrawwithzeros {#1}\Z
+}%
+\def\XINT_jrr_start #1#2/#3\Z
+{%
+ \if0\XINT_isOne {#3}\xint_afterfi
+ {\xint_UDsignfork
+ #1\XINT_jrr_negative
+ -{\XINT_jrr_nonneg #1}%
+ \krof}%
+ \else
+ \xint_afterfi{\XINT_jrr_denomisone #1}%
+ \fi
+ #2\Z {#3}%
+}%
+\def\XINT_jrr_denomisone #1\Z #2{ #1/1}% changed in 1.08
+\def\XINT_jrr_negative #1\Z #2{\XINT_jrr_D #1\Z #2\Z -}%
+\def\XINT_jrr_nonneg #1\Z #2{\XINT_jrr_D #1\Z #2\Z \space}%
+\def\XINT_jrr_D #1#2\Z #3#4\Z
+{%
+ \xint_UDzerosfork
+ #3#1\XINT_jrr_indeterminate
+ #30\XINT_jrr_divisionbyzero
+ #10\XINT_jrr_zero
+ 00\XINT_jrr_loop_a
+ \krof
+ {#3#4}{#1#2}1001%
+}%
+\def\XINT_jrr_indeterminate #1#2#3#4#5#6#7%
+{%
+ \XINT_signalcondition{DivisionUndefined}{indeterminate: 0/0}{}{0/1}%
+}%
+\def\XINT_jrr_divisionbyzero #1#2#3#4#5#6#7%
+{%
+ \XINT_signalcondition{DivisionByZero}{Vanishing denominator: #7#2/0}{}{0/1}%
+}%
+\def\XINT_jrr_zero #1#2#3#4#5#6#7{ 0/1}% changed in 1.08
+\def\XINT_jrr_loop_a #1#2%
+{%
+ \expandafter\XINT_jrr_loop_b
+ \romannumeral0\XINT_div_prepare {#1}{#2}{#1}%
+}%
+\def\XINT_jrr_loop_b #1#2#3#4#5#6#7%
+{%
+ \expandafter \XINT_jrr_loop_c \expandafter
+ {\romannumeral0\xintiiadd{\XINT_mul_fork #4\xint:#1\xint:}{#6}}%
+ {\romannumeral0\xintiiadd{\XINT_mul_fork #5\xint:#1\xint:}{#7}}%
+ {#2}{#3}{#4}{#5}%
+}%
+\def\XINT_jrr_loop_c #1#2%
+{%
+ \expandafter \XINT_jrr_loop_d \expandafter{#2}{#1}%
+}%
+\def\XINT_jrr_loop_d #1#2#3#4%
+{%
+ \XINT_jrr_loop_e #3\Z {#4}{#2}{#1}%
+}%
+\def\XINT_jrr_loop_e #1#2\Z
+{%
+ \xint_gob_til_zero #1\XINT_jrr_loop_exit0\XINT_jrr_loop_a {#1#2}%
+}%
+\def\XINT_jrr_loop_exit0\XINT_jrr_loop_a #1#2#3#4#5#6%
+{%
+ \XINT_irr_finish {#3}{#4}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintTFrac}}
+% \lverb|1.09i, for frac in \xintexpr. And \xintFrac is already assigned. T for
+% truncation. However, potentially not very efficient with numbers in scientific
+% notations, with big exponents. Will have to think it again some day. I
+% hesitated how to call the macro. Same convention as in maple, but some people
+% reserve fractional part to x - floor(x). Also, not clear if I had to make it
+% negative (or zero) if x < 0, or rather always positive. There should be in
+% fact such a thing for each rounding function, trunc, round, floor, ceil. |
+% \begin{macrocode}
+\def\xintTFrac {\romannumeral0\xinttfrac }%
+\def\xinttfrac #1{\expandafter\XINT_tfrac_fork\romannumeral0\xintrawwithzeros {#1}\Z }%
+\def\XINT_tfrac_fork #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_tfrac_zero
+ 0#1{\xintiiopp\XINT_tfrac_P }%
+ 0-{\XINT_tfrac_P #1}%
+ \krof
+}%
+\def\XINT_tfrac_zero #1\Z { 0/1[0]}%
+\def\XINT_tfrac_P #1/#2\Z {\expandafter\XINT_rez_AB
+ \romannumeral0\xintiirem{#1}{#2}\Z {0}{#2}}%
+% \end{macrocode}
+% \subsection{\csh{xintTrunc}, \csh{xintiTrunc}}
+% \lverb|&
+% 1.2i release notes: ever since its inception this macro was stupid for a
+% decimal input: it did not handle it separately from the general fraction
+% case A/B[N] with B>1, hence ended up doing divisions by powers of ten. But
+% this meant that nesting \xintTrunc with itself was very inefficient.
+%
+% 1.2i version is better. However it still handles B>1, N<0 via adding zeros
+% to B and dividing with this extended B. A possibly more efficient approach
+% is implemented in \xintXTrunc, but its logic is more complicated, the code
+% is quite longer and making it f-expandable would not shorten it... I decided
+% for the time being to not complicate things here.
+% |
+% \begin{macrocode}
+\def\xintTrunc {\romannumeral0\xinttrunc }%
+\def\xintiTrunc {\romannumeral0\xintitrunc}%
+\def\xinttrunc #1{\expandafter\XINT_trunc\the\numexpr#1.\XINT_trunc_G}%
+\def\xintitrunc #1{\expandafter\XINT_trunc\the\numexpr#1.\XINT_itrunc_G}%
+\def\XINT_trunc #1.#2#3%
+{%
+ \expandafter\XINT_trunc_a\romannumeral0\XINT_infrac{#3}#1.#2%
+}%
+\def\XINT_trunc_a #1#2#3#4.#5%
+{%
+ \if0\XINT_Sgn#2\xint:\xint_dothis\XINT_trunc_zero\fi
+ \if1\XINT_is_One#3XY\xint_dothis\XINT_trunc_sp_b\fi
+ \xint_orthat\XINT_trunc_b #1+#4.{#2}{#3}#5#4.%
+}%
+\def\XINT_trunc_zero #1.#2.{ 0}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_trunc_b {\expandafter\XINT_trunc_B\the\numexpr}%
+\def\XINT_trunc_sp_b {\expandafter\XINT_trunc_sp_B\the\numexpr}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_trunc_B #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_trunc_C
+ -\XINT_trunc_D
+ \krof #1%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_trunc_sp_B #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_trunc_sp_C
+ -\XINT_trunc_sp_D
+ \krof #1%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_trunc_C -#1.#2#3%
+{%
+ \expandafter\XINT_trunc_CE
+ \romannumeral0\XINT_dsx_addzeros{#1}#3;.{#2}%
+}%
+\def\XINT_trunc_CE #1.#2{\XINT_trunc_E #2.{#1}}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_trunc_sp_C -#1.#2#3{\XINT_trunc_sp_Ca #2.#1.}%
+\def\XINT_trunc_sp_Ca #1%
+{%
+ \xint_UDsignfork
+ #1{\XINT_trunc_sp_Cb -}%
+ -{\XINT_trunc_sp_Cb \space#1}%
+ \krof
+}%
+\def\XINT_trunc_sp_Cb #1#2.#3.%
+{%
+ \expandafter\XINT_trunc_sp_Cc
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \romannumeral0\expandafter\XINT_split_fromright_a
+ \the\numexpr#3-\numexpr\XINT_length_loop
+ #2\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
+ .#2\xint_bye2345678\xint_bye..#1%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_trunc_sp_Cc #1%
+{%
+ \if.#1\xint_dothis{\XINT_trunc_sp_Cd 0.}\fi
+ \xint_orthat {\XINT_trunc_sp_Cd #1}%
+}%
+\def\XINT_trunc_sp_Cd #1.#2.#3%
+{%
+ \XINT_trunc_sp_F #3#1.%
+}%
+\def\XINT_trunc_D #1.#2%
+{%
+ \expandafter\XINT_trunc_E
+ \romannumeral0\XINT_dsx_addzeros {#1}#2;.%
+}%
+\def\XINT_trunc_sp_D #1.#2#3%
+{%
+ \expandafter\XINT_trunc_sp_E
+ \romannumeral0\XINT_dsx_addzeros {#1}#2;.%
+}%
+\def\XINT_trunc_E #1%
+{%
+ \xint_UDsignfork
+ #1{\XINT_trunc_F -}%
+ -{\XINT_trunc_F \space#1}%
+ \krof
+}%
+\def\XINT_trunc_sp_E #1%
+{%
+ \xint_UDsignfork
+ #1{\XINT_trunc_sp_F -}%
+ -{\XINT_trunc_sp_F\space#1}%
+ \krof
+}%
+\def\XINT_trunc_F #1#2.#3#4%
+ {\expandafter#4\romannumeral`&&@\expandafter\xint_firstoftwo
+ \romannumeral0\XINT_div_prepare {#3}{#2}.#1}%
+\def\XINT_trunc_sp_F #1#2.#3{#3#2.#1}%
+\def\XINT_itrunc_G #1#2.#3#4.{\if#10\xint_dothis{ 0}\fi\xint_orthat{#3#1}#2}%
+\def\XINT_trunc_G #1.#2#3.%
+{%
+ \expandafter\XINT_trunc_H
+ \the\numexpr\romannumeral0\xintlength {#1}-#3.#3.{#1}#2%
+}%
+\def\XINT_trunc_H #1.#2.%
+{%
+ \ifnum #1 > \xint_c_
+ \xint_afterfi {\XINT_trunc_Ha {#2}}%
+ \else
+ \xint_afterfi {\XINT_trunc_Hb {-#1}}% -0,--1,--2, ....
+ \fi
+}%
+\def\XINT_trunc_Ha{\expandafter\XINT_trunc_Haa\romannumeral0\xintdecsplit}%
+\def\XINT_trunc_Haa #1#2#3{#3#1.#2}%
+\def\XINT_trunc_Hb #1#2#3%
+{%
+ \expandafter #3\expandafter0\expandafter.%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \romannumeral\xintreplicate{#1}0#2%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintTTrunc}}
+% \lverb|1.1. Modified in 1.2i, it does simply \xintiTrunc0 with no
+% shortcut (the latter having been modified)
+%|
+% \begin{macrocode}
+\def\xintTTrunc {\romannumeral0\xintttrunc }%
+\def\xintttrunc {\xintitrunc\xint_c_}%
+% \end{macrocode}
+% \subsection{\cshnolabel{xintNum}}
+% \begin{macrocode}
+\let\xintnum \xintttrunc
+% \end{macrocode}
+% \subsection{\csh{xintRound}, \csh{xintiRound}}
+% \lverb|Modified in 1.2i.
+%
+% It benefits first of all from the faster \xintTrunc, particularly when the
+% input is already a decimal number (denominator B=1).
+%
+% And the rounding is now done in 1.2 style (with much delay, sorry), like of
+% the rewritten \xintInc and \xintDec.|
+% \begin{macrocode}
+\def\xintRound {\romannumeral0\xintround }%
+\def\xintiRound {\romannumeral0\xintiround }%
+\def\xintround #1{\expandafter\XINT_round\the\numexpr #1.\XINT_round_A}%
+\def\xintiround #1{\expandafter\XINT_round\the\numexpr #1.\XINT_iround_A}%
+\def\XINT_round #1.{\expandafter\XINT_round_aa\the\numexpr #1+\xint_c_i.#1.}%
+\def\XINT_round_aa #1.#2.#3#4%
+{%
+ \expandafter\XINT_round_a\romannumeral0\XINT_infrac{#4}#1.#3#2.%
+}%
+\def\XINT_round_a #1#2#3#4.%
+{%
+ \if0\XINT_Sgn#2\xint:\xint_dothis\XINT_trunc_zero\fi
+ \if1\XINT_is_One#3XY\xint_dothis\XINT_trunc_sp_b\fi
+ \xint_orthat\XINT_trunc_b #1+#4.{#2}{#3}%
+}%
+\def\XINT_round_A{\expandafter\XINT_trunc_G\romannumeral0\XINT_round_B}%
+\def\XINT_iround_A{\expandafter\XINT_itrunc_G\romannumeral0\XINT_round_B}%
+\def\XINT_round_B #1.%
+ {\XINT_dsrr #1\xint_bye\xint_Bye3456789\xint_bye/\xint_c_x\relax.}%
+% \end{macrocode}
+% \subsection{\csh{xintXTrunc}}
+% \lverb@1.09j [2014/01/06] This is completely expandable but not f-expandable.
+% Rewritten for 1.2i (2016/12/04):
+%
+% - no more use of \xintiloop from xinttools.sty
+% (replaced by \xintreplicate... from xintkernel.sty),
+%
+% - no more use in 0>N>-D case of a dummy control sequence name via
+% \csname...\endcsname
+%
+% - handles better the case of an input already a decimal number
+%
+% Need to transfer code comments into public dtx.
+% @
+% \begin{macrocode}
+\def\xintXTrunc #1%#2%
+{%
+ \expandafter\XINT_xtrunc_a
+ \the\numexpr #1\expandafter.\romannumeral0\xintraw
+}%
+\def\XINT_xtrunc_a #1.% ?? faire autre chose
+{%
+ \expandafter\XINT_xtrunc_b\the\numexpr\ifnum#1<\xint_c_i \xint_c_i-\fi #1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_b #1.#2{\XINT_xtrunc_c #2{#1}}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_c #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_xtrunc_zero
+ 0#1{-\XINT_xtrunc_d {}}%
+ 0-{\XINT_xtrunc_d #1}%
+ \krof
+}%[
+\def\XINT_xtrunc_zero #1#2]{0.\romannumeral\xintreplicate{#1}0}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_d #1#2#3/#4[#5]%
+{%
+ \XINT_xtrunc_prepare_a#4\R\R\R\R\R\R\R\R {10}0000001\W
+ !{#4};{#5}{#2}{#1#3}%
+}%
+\def\XINT_xtrunc_prepare_a #1#2#3#4#5#6#7#8#9%
+{%
+ \xint_gob_til_R #9\XINT_xtrunc_prepare_small\R
+ \XINT_xtrunc_prepare_b #9%
+}%
+\def\XINT_xtrunc_prepare_small\R #1!#2;%
+{%
+ \ifcase #2
+ \or\expandafter\XINT_xtrunc_BisOne
+ \or\expandafter\XINT_xtrunc_BisTwo
+ \or
+ \or\expandafter\XINT_xtrunc_BisFour
+ \or\expandafter\XINT_xtrunc_BisFive
+ \or
+ \or
+ \or\expandafter\XINT_xtrunc_BisEight
+ \fi\XINT_xtrunc_BisSmall {#2}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_BisOne\XINT_xtrunc_BisSmall #1#2#3#4%
+ {\XINT_xtrunc_sp_e {#2}{#4}{#3}}%
+\def\XINT_xtrunc_BisTwo\XINT_xtrunc_BisSmall #1#2#3#4%
+{%
+ \expandafter\XINT_xtrunc_sp_e\expandafter
+ {\the\numexpr #2-\xint_c_i\expandafter}\expandafter
+ {\romannumeral0\xintiimul 5{#4}}{#3}%
+}%
+\def\XINT_xtrunc_BisFour\XINT_xtrunc_BisSmall #1#2#3#4%
+{%
+ \expandafter\XINT_xtrunc_sp_e\expandafter
+ {\the\numexpr #2-\xint_c_ii\expandafter}\expandafter
+ {\romannumeral0\xintiimul {25}{#4}}{#3}%
+}%
+\def\XINT_xtrunc_BisFive\XINT_xtrunc_BisSmall #1#2#3#4%
+{%
+ \expandafter\XINT_xtrunc_sp_e\expandafter
+ {\the\numexpr #2-\xint_c_i\expandafter}\expandafter
+ {\romannumeral0\xintdouble {#4}}{#3}%
+}%
+\def\XINT_xtrunc_BisEight\XINT_xtrunc_BisSmall #1#2#3#4%
+{%
+ \expandafter\XINT_xtrunc_sp_e\expandafter
+ {\the\numexpr #2-\xint_c_iii\expandafter}\expandafter
+ {\romannumeral0\xintiimul {125}{#4}}{#3}%
+}%
+\def\XINT_xtrunc_BisSmall #1%
+{%
+ \expandafter\XINT_xtrunc_e\expandafter
+ {\expandafter\XINT_xtrunc_small_a
+ \the\numexpr #1/\xint_c_ii\expandafter
+ .\the\numexpr \xint_c_x^viii+#1!}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_small_a #1.#2!#3%
+{%
+ \expandafter\XINT_div_small_b\the\numexpr #1\expandafter
+ \xint:\the\numexpr #2\expandafter!%
+ \romannumeral0\XINT_div_small_ba #3\R\R\R\R\R\R\R\R{10}0000001\W
+ #3\XINT_sepbyviii_Z_end 2345678\relax
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_prepare_b
+ {\expandafter\XINT_xtrunc_prepare_c\romannumeral0\XINT_zeroes_forviii }%
+\def\XINT_xtrunc_prepare_c #1!%
+{%
+ \XINT_xtrunc_prepare_d #1.00000000!{#1}%
+}%
+\def\XINT_xtrunc_prepare_d #1#2#3#4#5#6#7#8#9%
+{%
+ \expandafter\XINT_xtrunc_prepare_e
+ \xint_gob_til_dot #1#2#3#4#5#6#7#8#9!%
+}%
+\def\XINT_xtrunc_prepare_e #1!#2!#3#4%
+{%
+ \XINT_xtrunc_prepare_f #4#3\X {#1}{#3}%
+}%
+\def\XINT_xtrunc_prepare_f #1#2#3#4#5#6#7#8#9\X
+{%
+ \expandafter\XINT_xtrunc_prepare_g\expandafter
+ \XINT_div_prepare_g
+ \the\numexpr #1#2#3#4#5#6#7#8+\xint_c_i\expandafter
+ \xint:\the\numexpr (#1#2#3#4#5#6#7#8+\xint_c_i)/\xint_c_ii\expandafter
+ \xint:\the\numexpr #1#2#3#4#5#6#7#8\expandafter
+ \xint:\romannumeral0\XINT_sepandrev_andcount
+ #1#2#3#4#5#6#7#8#9\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_i
+ \R\xint:\xint_c_xii \R\xint:\xint_c_x \R\xint:\xint_c_viii \R\xint:\xint_c_vi
+ \R\xint:\xint_c_iv \R\xint:\xint_c_ii \R\xint:\xint_c_\W
+ \X
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_prepare_g #1;{\XINT_xtrunc_e {#1}}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_e #1#2%
+{%
+ \ifnum #2<\xint_c_
+ \expandafter\XINT_xtrunc_I
+ \else
+ \expandafter\XINT_xtrunc_II
+ \fi #2\xint:{#1}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_I -#1\xint:#2#3#4%
+{%
+ \expandafter\XINT_xtrunc_I_a\romannumeral0#2{#4}{#2}{#1}{#3}%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_I_a #1#2#3#4#5%
+{%
+ \expandafter\XINT_xtrunc_I_b\the\numexpr #4-#5\xint:#4\xint:{#5}{#2}{#3}{#1}%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_I_b #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_xtrunc_IA_c
+ -\XINT_xtrunc_IB_c
+ \krof #1%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_IA_c -#1\xint:#2\xint:#3#4#5#6%
+{%
+ \expandafter\XINT_xtrunc_IA_d
+ \the\numexpr#2-\xintLength{#6}\xint:{#6}%
+ \expandafter\XINT_xtrunc_IA_xd
+ \the\numexpr (#1+\xint_c_ii^v)/\xint_c_ii^vi-\xint_c_i\xint:#1\xint:{#5}{#4}%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_IA_d #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_xtrunc_IAA_e
+ -\XINT_xtrunc_IAB_e
+ \krof #1%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_IAA_e -#1\xint:#2%
+{%
+ \romannumeral0\XINT_split_fromleft
+ #1.#2\xint_gobble_i\xint_bye2345678\xint_bye..%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_IAB_e #1\xint:#2%
+{%
+ 0.\romannumeral\XINT_rep#1\endcsname0#2%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_IA_xd #1\xint:#2\xint:%
+{%
+ \expandafter\XINT_xtrunc_IA_xe\the\numexpr #2-\xint_c_ii^vi*#1\xint:#1\xint:%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_IA_xe #1\xint:#2\xint:#3#4%
+{%
+ \XINT_xtrunc_loop {#2}{#4}{#3}{#1}%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_IB_c #1\xint:#2\xint:#3#4#5#6%
+{%
+ \expandafter\XINT_xtrunc_IB_d
+ \romannumeral0\XINT_split_xfork #1.#6\xint_bye2345678\xint_bye..{#3}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_IB_d #1.#2.#3%
+{%
+ \expandafter\XINT_xtrunc_IA_d\the\numexpr#3-\xintLength {#1}\xint:{#1}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_II #1\xint:%
+{%
+ \expandafter\XINT_xtrunc_II_a\romannumeral\xintreplicate{#1}0\xint:%
+}%
+\def\XINT_xtrunc_II_a #1\xint:#2#3#4%
+{%
+ \expandafter\XINT_xtrunc_II_b
+ \the\numexpr (#3+\xint_c_ii^v)/\xint_c_ii^vi-\xint_c_i\expandafter\xint:%
+ \the\numexpr #3\expandafter\xint:\romannumeral0#2{#4#1}{#2}%
+}%
+\def\XINT_xtrunc_II_b #1\xint:#2\xint:%
+{%
+ \expandafter\XINT_xtrunc_II_c\the\numexpr #2-\xint_c_ii^vi*#1\xint:#1\xint:%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_II_c #1\xint:#2\xint:#3#4#5%
+{%
+ #3.\XINT_xtrunc_loop {#2}{#4}{#5}{#1}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_loop #1%
+{%
+ \ifnum #1=\xint_c_ \expandafter\XINT_xtrunc_transition\fi
+ \expandafter\XINT_xtrunc_loop_a\the\numexpr #1-\xint_c_i\xint:%
+}%
+\def\XINT_xtrunc_loop_a #1\xint:#2#3%
+{%
+ \expandafter\XINT_xtrunc_loop_b\romannumeral0#3%
+ {#20000000000000000000000000000000000000000000000000000000000000000}%
+ {#1}{#3}%
+}%
+\def\XINT_xtrunc_loop_b #1#2#3%
+{%
+ \romannumeral\xintreplicate{\xint_c_ii^vi-\xintLength{#1}}0#1%
+ \XINT_xtrunc_loop {#3}{#2}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_transition
+ \expandafter\XINT_xtrunc_loop_a\the\numexpr #1\xint:#2#3#4%
+{%
+ \ifnum #4=\xint_c_ \expandafter\xint_gobble_vi\fi
+ \expandafter\XINT_xtrunc_finish\expandafter
+ {\romannumeral0\XINT_dsx_addzeros{#4}#2;}{#3}{#4}%
+}%
+\def\XINT_xtrunc_finish #1#2%
+{%
+ \expandafter\XINT_xtrunc_finish_a\romannumeral0#2{#1}%
+}%
+\def\XINT_xtrunc_finish_a #1#2#3%
+{%
+ \romannumeral\xintreplicate{#3-\xintLength{#1}}0#1%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_sp_e #1%
+{%
+ \ifnum #1<\xint_c_
+ \expandafter\XINT_xtrunc_sp_I
+ \else
+ \expandafter\XINT_xtrunc_sp_II
+ \fi #1\xint:%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_sp_I -#1\xint:#2#3%
+{%
+ \expandafter\XINT_xtrunc_sp_I_a\the\numexpr #1-#3\xint:#1\xint:{#3}{#2}%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_sp_I_a #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_xtrunc_sp_IA_b
+ -\XINT_xtrunc_sp_IB_b
+ \krof #1%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_sp_IA_b -#1\xint:#2\xint:#3#4%
+{%
+ \expandafter\XINT_xtrunc_sp_IA_c
+ \the\numexpr#2-\xintLength{#4}\xint:{#4}\romannumeral\XINT_rep#1\endcsname0%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_sp_IA_c #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_xtrunc_sp_IAA
+ -\XINT_xtrunc_sp_IAB
+ \krof #1%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_sp_IAA -#1\xint:#2%
+{%
+ \romannumeral0\XINT_split_fromleft
+ #1.#2\xint_gobble_i\xint_bye2345678\xint_bye..%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_sp_IAB #1\xint:#2%
+{%
+ 0.\romannumeral\XINT_rep#1\endcsname0#2%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_sp_IB_b #1\xint:#2\xint:#3#4%
+{%
+ \expandafter\XINT_xtrunc_sp_IB_c
+ \romannumeral0\XINT_split_xfork #1.#4\xint_bye2345678\xint_bye..{#3}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_xtrunc_sp_IB_c #1.#2.#3%
+{%
+ \expandafter\XINT_xtrunc_sp_IA_c\the\numexpr#3-\xintLength {#1}\xint:{#1}%
+}%
+% \end{macrocode}
+% \lverb@&
+% @
+% \begin{macrocode}
+\def\XINT_xtrunc_sp_II #1\xint:#2#3%
+{%
+ #2\romannumeral\XINT_rep#1\endcsname0.\romannumeral\XINT_rep#3\endcsname0%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintDigits}}
+% \lverb|The mathchardef used to be called \XINT_digits, but for reasons
+% originating in \xintNewExpr (and now obsolete), release 1.09a uses
+% \XINTdigits without underscore.|
+% \begin{macrocode}
+\mathchardef\XINTdigits 16
+\def\xintDigits #1#2%
+ {\afterassignment \xint_gobble_i \mathchardef\XINTdigits=}%
+\def\xinttheDigits {\number\XINTdigits }%
+% \end{macrocode}
+% \subsection{\csh{xintAdd}}
+% \lverb|Big change at 1.3: a/b+c/d uses lcm(b,d) as denominator.|
+% \begin{macrocode}
+\def\xintAdd {\romannumeral0\xintadd }%
+\def\xintadd #1{\expandafter\XINT_fadd\romannumeral0\xintraw {#1}}%
+\def\XINT_fadd #1{\xint_gob_til_zero #1\XINT_fadd_Azero 0\XINT_fadd_a #1}%
+\def\XINT_fadd_Azero #1]{\xintraw }%
+\def\XINT_fadd_a #1/#2[#3]#4%
+ {\expandafter\XINT_fadd_b\romannumeral0\xintraw {#4}{#3}{#1}{#2}}%
+\def\XINT_fadd_b #1{\xint_gob_til_zero #1\XINT_fadd_Bzero 0\XINT_fadd_c #1}%
+\def\XINT_fadd_Bzero #1]#2#3#4{ #3/#4[#2]}%
+\def\XINT_fadd_c #1/#2[#3]#4%
+{%
+ \expandafter\XINT_fadd_Aa\the\numexpr #4-#3.{#3}{#4}{#1}{#2}%
+}%
+\def\XINT_fadd_Aa #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_fadd_B
+ 0#1\XINT_fadd_Bb
+ 0-\XINT_fadd_Ba
+ \krof #1%
+}%
+\def\XINT_fadd_B #1.#2#3#4#5#6#7{\XINT_fadd_C {#4}{#5}{#7}{#6}[#3]}%
+\def\XINT_fadd_Ba #1.#2#3#4#5#6#7%
+{%
+ \expandafter\XINT_fadd_C\expandafter
+ {\romannumeral0\XINT_dsx_addzeros {#1}#6;}%
+ {#7}{#5}{#4}[#2]%
+}%
+\def\XINT_fadd_Bb -#1.#2#3#4#5#6#7%
+{%
+ \expandafter\XINT_fadd_C\expandafter
+ {\romannumeral0\XINT_dsx_addzeros {#1}#4;}%
+ {#5}{#7}{#6}[#3]%
+}%
+\def\XINT_fadd_iszero #1[#2]{ 0/1[0]}% ou [#2] originel?
+\def\XINT_fadd_C #1#2#3%
+{%
+ \expandafter\XINT_fadd_D_b
+ \romannumeral0\XINT_div_prepare{#2}{#3}{#2}{#2}{#3}{#1}%
+}%
+% \end{macrocode}
+% \lverb|Basically a clone of the \XINT_irr_loop_a loop. I should modify the
+% output of \XINT_div_prepare perhaps to be optimized for checking if
+% remainder vanishes.|
+% \begin{macrocode}
+\def\XINT_fadd_D_a #1#2%
+{%
+ \expandafter\XINT_fadd_D_b
+ \romannumeral0\XINT_div_prepare {#1}{#2}{#1}%
+}%
+\def\XINT_fadd_D_b #1#2{\XINT_fadd_D_c #2\Z}%
+\def\XINT_fadd_D_c #1#2\Z
+{%
+ \xint_gob_til_zero #1\XINT_fadd_D_exit0\XINT_fadd_D_a {#1#2}%
+}%
+\def\XINT_fadd_D_exit0\XINT_fadd_D_a #1#2#3%
+{%
+ \expandafter\XINT_fadd_E
+ \romannumeral0\xintiiquo {#3}{#2}.{#2}%
+}%
+\def\XINT_fadd_E #1.#2#3%
+{%
+ \expandafter\XINT_fadd_F
+ \romannumeral0\xintiimul{#1}{#3}.{\xintiiQuo{#3}{#2}}{#1}%
+}%
+\def\XINT_fadd_F #1.#2#3#4#5%
+{%
+ \expandafter\XINT_fadd_G
+ \romannumeral0\xintiiadd{\xintiiMul{#2}{#4}}{\xintiiMul{#3}{#5}}/#1%
+}%
+\def\XINT_fadd_G #1{%
+\def\XINT_fadd_G ##1{\if0##1\expandafter\XINT_fadd_iszero\fi#1##1}%
+}\XINT_fadd_G{ }%
+% \end{macrocode}
+% \subsection{\csh{xintSub}}
+% \lverb|Since 1.3 will use least common multiple of denominators.|
+% \begin{macrocode}
+\def\xintSub {\romannumeral0\xintsub }%
+\def\xintsub #1{\expandafter\XINT_fsub\romannumeral0\xintraw {#1}}%
+\def\XINT_fsub #1{\xint_gob_til_zero #1\XINT_fsub_Azero 0\XINT_fsub_a #1}%
+\def\XINT_fsub_Azero #1]{\xintopp }%
+\def\XINT_fsub_a #1/#2[#3]#4%
+ {\expandafter\XINT_fsub_b\romannumeral0\xintraw {#4}{#3}{#1}{#2}}%
+\def\XINT_fsub_b #1{\xint_UDzerominusfork
+ #1-\XINT_fadd_Bzero
+ 0#1\XINT_fadd_c
+ 0-{\XINT_fadd_c -#1}%
+ \krof }%
+% \end{macrocode}
+% \subsection{\csh{xintSum}}
+% \lverb|There was (not documented anymore since 1.09d, 2013/10/22) a macro
+% \xintSumExpr, but it has been deleted at 1.2l.
+%
+% Empty items are not accepted by this macro.|
+% \begin{macrocode}
+\def\xintSum {\romannumeral0\xintsum }%
+\def\xintsum #1{\expandafter\XINT_fsumexpr\romannumeral`&&@#1\xint:}%
+\def\XINT_fsumexpr {\XINT_fsum_loop_a {0/1[0]}}%
+\def\XINT_fsum_loop_a #1#2%
+{%
+ \expandafter\XINT_fsum_loop_b \romannumeral`&&@#2\xint:{#1}%
+}%
+\def\XINT_fsum_loop_b #1%
+{%
+ \xint_gob_til_xint: #1\XINT_fsum_finished\xint:\XINT_fsum_loop_c #1%
+}%
+\def\XINT_fsum_loop_c #1\xint:#2%
+{%
+ \expandafter\XINT_fsum_loop_a\expandafter{\romannumeral0\xintadd {#2}{#1}}%
+}%
+\def\XINT_fsum_finished #1\xint:\xint:#2{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintMul}}
+% \begin{macrocode}
+\def\xintMul {\romannumeral0\xintmul }%
+\def\xintmul #1{\expandafter\XINT_fmul\romannumeral0\xintraw {#1}.}%
+\def\XINT_fmul #1{\xint_gob_til_zero #1\XINT_fmul_zero 0\XINT_fmul_a #1}%
+\def\XINT_fmul_a #1[#2].#3%
+ {\expandafter\XINT_fmul_b\romannumeral0\xintraw {#3}#1[#2.]}%
+\def\XINT_fmul_b #1{\xint_gob_til_zero #1\XINT_fmul_zero 0\XINT_fmul_c #1}%
+\def\XINT_fmul_c #1/#2[#3]#4/#5[#6.]%
+{%
+ \expandafter\XINT_fmul_d
+ \expandafter{\the\numexpr #3+#6\expandafter}%
+ \expandafter{\romannumeral0\xintiimul {#5}{#2}}%
+ {\romannumeral0\xintiimul {#4}{#1}}%
+}%
+\def\XINT_fmul_d #1#2#3%
+{%
+ \expandafter \XINT_fmul_e \expandafter{#3}{#1}{#2}%
+}%
+\def\XINT_fmul_e #1#2{\XINT_outfrac {#2}{#1}}%
+\def\XINT_fmul_zero #1.#2{ 0/1[0]}%
+% \end{macrocode}
+% \subsection{\csh{xintSqr}}
+% \lverb|1.1 modifs comme xintMul.
+%
+% |
+% \begin{macrocode}
+\def\xintSqr {\romannumeral0\xintsqr }%
+\def\xintsqr #1{\expandafter\XINT_fsqr\romannumeral0\xintraw {#1}}%
+\def\XINT_fsqr #1{\xint_gob_til_zero #1\XINT_fsqr_zero 0\XINT_fsqr_a #1}%
+\def\XINT_fsqr_a #1/#2[#3]%
+{%
+ \expandafter\XINT_fsqr_b
+ \expandafter{\the\numexpr #3+#3\expandafter}%
+ \expandafter{\romannumeral0\xintiisqr {#2}}%
+ {\romannumeral0\xintiisqr {#1}}%
+}%
+\def\XINT_fsqr_b #1#2#3{\expandafter \XINT_fmul_e \expandafter{#3}{#1}{#2}}%
+\def\XINT_fsqr_zero #1]{ 0/1[0]}%
+% \end{macrocode}
+% \subsection{\csh{xintPow}}
+% \lverb|&
+% 1.2f: to be coherent with the "i" convention \xintiPow should parse also its
+% exponent via \xintNum when xintfrac.sty is loaded. This was not the case so
+% far. Cependant le problème est que le fait d'appliquer \xintNum rend
+% impossible certains inputs qui auraient pu être gérès par \numexpr. Le
+% \numexpr externe est ici pour intercepter trop grand input.
+% |
+% \begin{macrocode}
+\def\xintipow #1#2%
+{%
+ \expandafter\xint_pow\the\numexpr \xintNum{#2}\expandafter
+ .\romannumeral0\xintnum{#1}\xint:
+}%
+\def\xintPow {\romannumeral0\xintpow }%
+\def\xintpow #1%
+{%
+ \expandafter\XINT_fpow\expandafter {\romannumeral0\XINT_infrac {#1}}%
+}%
+\def\XINT_fpow #1#2%
+{%
+ \expandafter\XINT_fpow_fork\the\numexpr \xintNum{#2}\relax\Z #1%
+}%
+\def\XINT_fpow_fork #1#2\Z
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_fpow_zero
+ 0#1\XINT_fpow_neg
+ 0-{\XINT_fpow_pos #1}%
+ \krof
+ {#2}%
+}%
+\def\XINT_fpow_zero #1#2#3#4{ 1/1[0]}%
+\def\XINT_fpow_pos #1#2#3#4#5%
+{%
+ \expandafter\XINT_fpow_pos_A\expandafter
+ {\the\numexpr #1#2*#3\expandafter}\expandafter
+ {\romannumeral0\xintiipow {#5}{#1#2}}%
+ {\romannumeral0\xintiipow {#4}{#1#2}}%
+}%
+\def\XINT_fpow_neg #1#2#3#4%
+{%
+ \expandafter\XINT_fpow_pos_A\expandafter
+ {\the\numexpr -#1*#2\expandafter}\expandafter
+ {\romannumeral0\xintiipow {#3}{#1}}%
+ {\romannumeral0\xintiipow {#4}{#1}}%
+}%
+\def\XINT_fpow_pos_A #1#2#3%
+{%
+ \expandafter\XINT_fpow_pos_B\expandafter {#3}{#1}{#2}%
+}%
+\def\XINT_fpow_pos_B #1#2{\XINT_outfrac {#2}{#1}}%
+% \end{macrocode}
+% \subsection{\csh{xintFac}}
+% \lverb|Factorial coefficients: variant which can be chained with other
+% xintfrac macros. \xintiFac deprecated at 1.2o and removed at 1.3; \xintFac
+% used by xintexpr.sty.|
+% \begin{macrocode}
+\def\xintFac {\romannumeral0\xintfac}%
+\def\xintfac #1{\expandafter\XINT_fac_fork\the\numexpr\xintNum{#1}.[0]}%
+% \end{macrocode}
+% \subsection{\csh{xintBinomial}}
+% \lverb|1.2f. Binomial coefficients. \xintiBinomial deprecated at 1.2o and
+% removed at 1.3;
+% \xintBinomial needed by xintexpr.sty.|
+% \begin{macrocode}
+\def\xintBinomial {\romannumeral0\xintbinomial}%
+\def\xintbinomial #1#2%
+{%
+ \expandafter\XINT_binom_pre
+ \the\numexpr\xintNum{#1}\expandafter.\the\numexpr\xintNum{#2}.[0]%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintPFactorial}}
+% \lverb|1.2f. Partial factorial. For needs of xintexpr.sty.|
+% \begin{macrocode}
+\def\xintipfactorial #1#2%
+{%
+ \expandafter\XINT_pfac_fork
+ \the\numexpr\xintNum{#1}\expandafter.\the\numexpr\xintNum{#2}.%
+}%
+\def\xintPFactorial {\romannumeral0\xintpfactorial}%
+\def\xintpfactorial #1#2%
+{%
+ \expandafter\XINT_pfac_fork
+ \the\numexpr\xintNum{#1}\expandafter.\the\numexpr\xintNum{#2}.[0]%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintPrd}}
+% \lverb|There was (not documented anymore since 1.09d, 2013/10/22) a macro
+% \xintPrdExpr, but it has been deleted at 1.2l
+% |
+% \begin{macrocode}
+\def\xintPrd {\romannumeral0\xintprd }%
+\def\xintprd #1{\expandafter\XINT_fprdexpr \romannumeral`&&@#1\xint:}%
+\def\XINT_fprdexpr {\XINT_fprod_loop_a {1/1[0]}}%
+\def\XINT_fprod_loop_a #1#2%
+{%
+ \expandafter\XINT_fprod_loop_b \romannumeral`&&@#2\xint:{#1}%
+}%
+\def\XINT_fprod_loop_b #1%
+{%
+ \xint_gob_til_xint: #1\XINT_fprod_finished\xint:\XINT_fprod_loop_c #1%
+}%
+\def\XINT_fprod_loop_c #1\xint:#2%
+{%
+ \expandafter\XINT_fprod_loop_a\expandafter{\romannumeral0\xintmul {#1}{#2}}%
+}%
+\def\XINT_fprod_finished#1\xint:\xint:#2{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintDiv}}
+% \begin{macrocode}
+\def\xintDiv {\romannumeral0\xintdiv }%
+\def\xintdiv #1%
+{%
+ \expandafter\XINT_fdiv\expandafter {\romannumeral0\XINT_infrac {#1}}%
+}%
+\def\XINT_fdiv #1#2%
+ {\expandafter\XINT_fdiv_A\romannumeral0\XINT_infrac {#2}#1}%
+\def\XINT_fdiv_A #1#2#3#4#5#6%
+{%
+ \expandafter\XINT_fdiv_B
+ \expandafter{\the\numexpr #4-#1\expandafter}%
+ \expandafter{\romannumeral0\xintiimul {#2}{#6}}%
+ {\romannumeral0\xintiimul {#3}{#5}}%
+}%
+\def\XINT_fdiv_B #1#2#3%
+{%
+ \expandafter\XINT_fdiv_C
+ \expandafter{#3}{#1}{#2}%
+}%
+\def\XINT_fdiv_C #1#2{\XINT_outfrac {#2}{#1}}%
+% \end{macrocode}
+% \subsection{\csh{xintDivFloor}}
+% \lverb|1.1. Changed at 1.2p to not append /1[0] ending but rather output a
+% big integer in strict format, like \xintDivTrunc and \xintDivRound.|
+% \begin{macrocode}
+\def\xintDivFloor {\romannumeral0\xintdivfloor }%
+\def\xintdivfloor #1#2{\xintifloor{\xintDiv {#1}{#2}}}%
+% \end{macrocode}
+% \subsection{\csh{xintDivTrunc}}
+% \lverb|1.1. \xintttrunc rather than \xintitrunc0 in 1.1a|
+% \begin{macrocode}
+\def\xintDivTrunc {\romannumeral0\xintdivtrunc }%
+\def\xintdivtrunc #1#2{\xintttrunc {\xintDiv {#1}{#2}}}%
+% \end{macrocode}
+% \subsection{\csh{xintDivRound}}
+% \lverb|1.1|
+% \begin{macrocode}
+\def\xintDivRound {\romannumeral0\xintdivround }%
+\def\xintdivround #1#2{\xintiround 0{\xintDiv {#1}{#2}}}%
+% \end{macrocode}
+% \subsection{\csh{xintModTrunc}}
+% \lverb|1.1. \xintModTrunc {q1}{q2} computes q1 - q2*t(q1/q2) with t(q1/q2)
+% equal to the truncated division of two fractions q1 and q2.
+%
+% Its former name, prior to 1.2p, was \xintMod.
+%
+% At 1.3, uses least common multiple denominator, like \xintMod (next).|
+% \begin{macrocode}
+\def\xintModTrunc {\romannumeral0\xintmodtrunc }%
+\def\xintmodtrunc #1{\expandafter\XINT_modtrunc_a\romannumeral0\xintraw{#1}.}%
+\def\XINT_modtrunc_a #1#2.#3%
+ {\expandafter\XINT_modtrunc_b\expandafter #1\romannumeral0\xintraw{#3}#2.}%
+\def\XINT_modtrunc_b #1#2% #1 de A, #2 de B.
+{%
+ \if0#2\xint_dothis{\XINT_modtrunc_divbyzero #1#2}\fi
+ \if0#1\xint_dothis\XINT_modtrunc_aiszero\fi
+ \if-#2\xint_dothis{\XINT_modtrunc_bneg #1}\fi
+ \xint_orthat{\XINT_modtrunc_bpos #1#2}%
+}%
+\def\XINT_modtrunc_divbyzero #1#2[#3]#4.%
+{%
+ \XINT_signalcondition{DivisionByZero}{Division by #2[#3] of #1#4}{}{0/1[0]}%
+}%
+\def\XINT_modtrunc_aiszero #1.{ 0/1[0]}%
+\def\XINT_modtrunc_bneg #1%
+{%
+ \xint_UDsignfork
+ #1{\xintiiopp\XINT_modtrunc_pos {}}%
+ -{\XINT_modtrunc_pos #1}%
+ \krof
+}%
+\def\XINT_modtrunc_bpos #1%
+{%
+ \xint_UDsignfork
+ #1{\xintiiopp\XINT_modtrunc_pos {}}%
+ -{\XINT_modtrunc_pos #1}%
+ \krof
+}%
+% \end{macrocode}
+% \lverb|Attention. This crucially uses that xint's \xintiiE{x}{e} is defined
+% to return x unchanged if e is negative (and x extended by e zeroes if e >=
+% 0).|
+% \begin{macrocode}
+\def\XINT_modtrunc_pos #1#2/#3[#4]#5/#6[#7].%
+{%
+ \expandafter\XINT_modtrunc_pos_a
+ \the\numexpr\ifnum#7>#4 #4\else #7\fi\expandafter.%
+ \romannumeral0\expandafter\XINT_mod_D_b
+ \romannumeral0\XINT_div_prepare{#3}{#6}{#3}{#3}{#6}%
+ {#1#5}{#7-#4}{#2}{#4-#7}%
+}%
+\def\XINT_modtrunc_pos_a #1.#2#3#4{\xintiirem {#3}{#4}/#2[#1]}%
+% \end{macrocode}
+% \subsection{\csh{xintDivMod}}
+% \lverb|1.2p. \xintDivMod{q1}{q2} outputs {floor(q1/q2)}{q1 - q2*floor(q1/q2)}.
+% Attention that it relies on \xintiiE{x}{e} returning x if e < 0.
+%
+% Modified (like \xintAdd and \xintSub) at 1.3 to use a l.c.m for final
+% denominator of the "mod" part.|
+% \begin{macrocode}
+\def\xintDivMod {\romannumeral0\xintdivmod }%
+\def\xintdivmod #1{\expandafter\XINT_divmod_a\romannumeral0\xintraw{#1}.}%
+\def\XINT_divmod_a #1#2.#3%
+ {\expandafter\XINT_divmod_b\expandafter #1\romannumeral0\xintraw{#3}#2.}%
+\def\XINT_divmod_b #1#2% #1 de A, #2 de B.
+{%
+ \if0#2\xint_dothis{\XINT_divmod_divbyzero #1#2}\fi
+ \if0#1\xint_dothis\XINT_divmod_aiszero\fi
+ \if-#2\xint_dothis{\XINT_divmod_bneg #1}\fi
+ \xint_orthat{\XINT_divmod_bpos #1#2}%
+}%
+\def\XINT_divmod_divbyzero #1#2[#3]#4.%
+{%
+ \XINT_signalcondition{DivisionByZero}{Division by #2[#3] of #1#4}{}%
+ {{0}{0/1[0]}}% à revoir...
+}%
+\def\XINT_divmod_aiszero #1.{{0}{0/1[0]}}%
+\def\XINT_divmod_bneg #1% f // -g = (-f) // g, f % -g = - ((-f) % g)
+{%
+ \expandafter\XINT_divmod_bneg_finish
+ \romannumeral0\xint_UDsignfork
+ #1{\XINT_divmod_bpos {}}%
+ -{\XINT_divmod_bpos {-#1}}%
+ \krof
+}%
+\def\XINT_divmod_bneg_finish#1#2%
+{%
+ \expandafter\xint_exchangetwo_keepbraces\expandafter
+ {\romannumeral0\xintiiopp#2}{#1}%
+}%
+\def\XINT_divmod_bpos #1#2/#3[#4]#5/#6[#7].%
+{%
+ \expandafter\XINT_divmod_bpos_a
+ \the\numexpr\ifnum#7>#4 #4\else #7\fi\expandafter.%
+ \romannumeral0\expandafter\XINT_mod_D_b
+ \romannumeral0\XINT_div_prepare{#3}{#6}{#3}{#3}{#6}%
+ {#1#5}{#7-#4}{#2}{#4-#7}%
+}%
+\def\XINT_divmod_bpos_a #1.#2#3#4%
+{%
+ \expandafter\XINT_divmod_bpos_finish
+ \romannumeral0\xintiidivision{#3}{#4}{/#2[#1]}%
+}%
+\def\XINT_divmod_bpos_finish #1#2#3{{#1}{#2#3}}%
+% \end{macrocode}
+% \subsection{\csh{xintMod}}
+% \lverb|1.2p. \xintMod{q1}{q2} computes q1 - q2*floor(q1/q2). Attention that
+% it relies on \xintiiE{x}{e} returning x if e < 0.
+%
+% Prior to 1.2p, that macro had the meaning now attributed to \xintModTrunc.
+%
+% Modified (like \xintAdd and \xintSub) at 1.3 to use a l.c.m for final
+% denominator.|
+% \begin{macrocode}
+\def\xintMod {\romannumeral0\xintmod }%
+\def\xintmod #1{\expandafter\XINT_mod_a\romannumeral0\xintraw{#1}.}%
+\def\XINT_mod_a #1#2.#3%
+ {\expandafter\XINT_mod_b\expandafter #1\romannumeral0\xintraw{#3}#2.}%
+\def\XINT_mod_b #1#2% #1 de A, #2 de B.
+{%
+ \if0#2\xint_dothis{\XINT_mod_divbyzero #1#2}\fi
+ \if0#1\xint_dothis\XINT_mod_aiszero\fi
+ \if-#2\xint_dothis{\XINT_mod_bneg #1}\fi
+ \xint_orthat{\XINT_mod_bpos #1#2}%
+}%
+% \end{macrocode}
+% \lverb|Attention to not move ModTrunc code beyond that point.|
+% \begin{macrocode}
+\let\XINT_mod_divbyzero\XINT_modtrunc_divbyzero
+\let\XINT_mod_aiszero \XINT_modtrunc_aiszero
+\def\XINT_mod_bneg #1% f % -g = - ((-f) % g), for g > 0
+{%
+ \xintiiopp\xint_UDsignfork
+ #1{\XINT_mod_bpos {}}%
+ -{\XINT_mod_bpos {-#1}}%
+ \krof
+}%
+\def\XINT_mod_bpos #1#2/#3[#4]#5/#6[#7].%
+{%
+ \expandafter\XINT_mod_bpos_a
+ \the\numexpr\ifnum#7>#4 #4\else #7\fi\expandafter.%
+ \romannumeral0\expandafter\XINT_mod_D_b
+ \romannumeral0\XINT_div_prepare{#3}{#6}{#3}{#3}{#6}%
+ {#1#5}{#7-#4}{#2}{#4-#7}%
+}%
+\def\XINT_mod_D_a #1#2%
+{%
+ \expandafter\XINT_mod_D_b
+ \romannumeral0\XINT_div_prepare {#1}{#2}{#1}%
+}%
+\def\XINT_mod_D_b #1#2{\XINT_mod_D_c #2\Z}%
+\def\XINT_mod_D_c #1#2\Z
+{%
+ \xint_gob_til_zero #1\XINT_mod_D_exit0\XINT_mod_D_a {#1#2}%
+}%
+\def\XINT_mod_D_exit0\XINT_mod_D_a #1#2#3%
+{%
+ \expandafter\XINT_mod_E
+ \romannumeral0\xintiiquo {#3}{#2}.{#2}%
+}%
+\def\XINT_mod_E #1.#2#3%
+{%
+ \expandafter\XINT_mod_F
+ \romannumeral0\xintiimul{#1}{#3}.{\xintiiQuo{#3}{#2}}{#1}%
+}%
+\def\XINT_mod_F #1.#2#3#4#5#6#7%
+{%
+ {#1}{\xintiiE{\xintiiMul{#4}{#3}}{#5}}%
+ {\xintiiE{\xintiiMul{#6}{#2}}{#7}}%
+}%
+\def\XINT_mod_bpos_a #1.#2#3#4{\xintiirem {#3}{#4}/#2[#1]}%
+% \end{macrocode}
+% \subsection{\csh{xintIsOne}}
+% \lverb|New with 1.09a. Could be more efficient. For fractions with big
+% powers of tens, it is better to use \xintCmp{f}{1}. Restyled in 1.09i.|
+% \begin{macrocode}
+\def\xintIsOne {\romannumeral0\xintisone }%
+\def\xintisone #1{\expandafter\XINT_fracisone
+ \romannumeral0\xintrawwithzeros{#1}\Z }%
+\def\XINT_fracisone #1/#2\Z
+ {\if0\xintiiCmp {#1}{#2}\xint_afterfi{ 1}\else\xint_afterfi{ 0}\fi}%
+% \end{macrocode}
+% \subsection{\csh{xintGeq}}
+% \begin{macrocode}
+\def\xintGeq {\romannumeral0\xintgeq }%
+\def\xintgeq #1%
+{%
+ \expandafter\XINT_fgeq\expandafter {\romannumeral0\xintabs {#1}}%
+}%
+\def\XINT_fgeq #1#2%
+{%
+ \expandafter\XINT_fgeq_A \romannumeral0\xintabs {#2}#1%
+}%
+\def\XINT_fgeq_A #1%
+{%
+ \xint_gob_til_zero #1\XINT_fgeq_Zii 0%
+ \XINT_fgeq_B #1%
+}%
+\def\XINT_fgeq_Zii 0\XINT_fgeq_B #1[#2]#3[#4]{ 1}%
+\def\XINT_fgeq_B #1/#2[#3]#4#5/#6[#7]%
+{%
+ \xint_gob_til_zero #4\XINT_fgeq_Zi 0%
+ \expandafter\XINT_fgeq_C\expandafter
+ {\the\numexpr #7-#3\expandafter}\expandafter
+ {\romannumeral0\xintiimul {#4#5}{#2}}%
+ {\romannumeral0\xintiimul {#6}{#1}}%
+}%
+\def\XINT_fgeq_Zi 0#1#2#3#4#5#6#7{ 0}%
+\def\XINT_fgeq_C #1#2#3%
+{%
+ \expandafter\XINT_fgeq_D\expandafter
+ {#3}{#1}{#2}%
+}%
+\def\XINT_fgeq_D #1#2#3%
+{%
+ \expandafter\XINT_cntSgnFork\romannumeral`&&@\expandafter\XINT_cntSgn
+ \the\numexpr #2+\xintLength{#3}-\xintLength{#1}\relax\xint:
+ { 0}{\XINT_fgeq_E #2\Z {#3}{#1}}{ 1}%
+}%
+\def\XINT_fgeq_E #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_fgeq_Fd
+ -{\XINT_fgeq_Fn #1}%
+ \krof
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_fgeq_Fd #1\Z #2#3%
+{%
+ \expandafter\XINT_fgeq_Fe
+ \romannumeral0\XINT_dsx_addzeros {#1}#3;\xint:#2\xint:
+}%
+\def\XINT_fgeq_Fe #1\xint:#2#3\xint:{\XINT_geq_plusplus #2#1\xint:#3\xint:}%
+\def\XINT_fgeq_Fn #1\Z #2#3%
+{%
+ \expandafter\XINT_fgeq_Fo
+ \romannumeral0\XINT_dsx_addzeros {#1}#2;\xint:#3\xint:
+}%
+\def\XINT_fgeq_Fo #1#2\xint:#3\xint:{\XINT_geq_plusplus #1#3\xint:#2\xint:}%
+% \end{macrocode}
+% \subsection{\csh{xintMax}}
+% \begin{macrocode}
+\def\xintMax {\romannumeral0\xintmax }%
+\def\xintmax #1%
+{%
+ \expandafter\XINT_fmax\expandafter {\romannumeral0\xintraw {#1}}%
+}%
+\def\XINT_fmax #1#2%
+{%
+ \expandafter\XINT_fmax_A\romannumeral0\xintraw {#2}#1%
+}%
+\def\XINT_fmax_A #1#2/#3[#4]#5#6/#7[#8]%
+{%
+ \xint_UDsignsfork
+ #1#5\XINT_fmax_minusminus
+ -#5\XINT_fmax_firstneg
+ #1-\XINT_fmax_secondneg
+ --\XINT_fmax_nonneg_a
+ \krof
+ #1#5{#2/#3[#4]}{#6/#7[#8]}%
+}%
+\def\XINT_fmax_minusminus --%
+ {\expandafter-\romannumeral0\XINT_fmin_nonneg_b }%
+\def\XINT_fmax_firstneg #1-#2#3{ #1#2}%
+\def\XINT_fmax_secondneg -#1#2#3{ #1#3}%
+\def\XINT_fmax_nonneg_a #1#2#3#4%
+{%
+ \XINT_fmax_nonneg_b {#1#3}{#2#4}%
+}%
+\def\XINT_fmax_nonneg_b #1#2%
+{%
+ \if0\romannumeral0\XINT_fgeq_A #1#2%
+ \xint_afterfi{ #1}%
+ \else \xint_afterfi{ #2}%
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintMaxof}}
+% \lverb|1.2l protects \xintMaxof against items with non terminated
+% \the\numexpr expressions.
+%
+% The macro is not compatible with an empty list.|
+% \begin{macrocode}
+\def\xintMaxof {\romannumeral0\xintmaxof }%
+\def\xintmaxof #1{\expandafter\XINT_maxof_a\romannumeral`&&@#1\xint:}%
+\def\XINT_maxof_a #1{\expandafter\XINT_maxof_b\romannumeral0\xintraw{#1}!}%
+\def\XINT_maxof_b #1!#2%
+ {\expandafter\XINT_maxof_c\romannumeral`&&@#2!{#1}!}%
+\def\XINT_maxof_c #1%
+ {\xint_gob_til_xint: #1\XINT_maxof_e\xint:\XINT_maxof_d #1}%
+\def\XINT_maxof_d #1!%
+ {\expandafter\XINT_maxof_b\romannumeral0\xintmax {#1}}%
+\def\XINT_maxof_e #1!#2!{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintMin}}
+% \begin{macrocode}
+\def\xintMin {\romannumeral0\xintmin }%
+\def\xintmin #1%
+{%
+ \expandafter\XINT_fmin\expandafter {\romannumeral0\xintraw {#1}}%
+}%
+\def\XINT_fmin #1#2%
+{%
+ \expandafter\XINT_fmin_A\romannumeral0\xintraw {#2}#1%
+}%
+\def\XINT_fmin_A #1#2/#3[#4]#5#6/#7[#8]%
+{%
+ \xint_UDsignsfork
+ #1#5\XINT_fmin_minusminus
+ -#5\XINT_fmin_firstneg
+ #1-\XINT_fmin_secondneg
+ --\XINT_fmin_nonneg_a
+ \krof
+ #1#5{#2/#3[#4]}{#6/#7[#8]}%
+}%
+\def\XINT_fmin_minusminus --%
+ {\expandafter-\romannumeral0\XINT_fmax_nonneg_b }%
+\def\XINT_fmin_firstneg #1-#2#3{ -#3}%
+\def\XINT_fmin_secondneg -#1#2#3{ -#2}%
+\def\XINT_fmin_nonneg_a #1#2#3#4%
+{%
+ \XINT_fmin_nonneg_b {#1#3}{#2#4}%
+}%
+\def\XINT_fmin_nonneg_b #1#2%
+{%
+ \if0\romannumeral0\XINT_fgeq_A #1#2%
+ \xint_afterfi{ #2}%
+ \else \xint_afterfi{ #1}%
+ \fi
+}%
+% \end{macrocode}
+% \subsection{\csh{xintMinof}}
+% \lverb|1.2l protects \xintMinof against items with non terminated
+% \the\numexpr expressions.
+%
+% The macro is not compatible with an empty list.|
+% \begin{macrocode}
+\def\xintMinof {\romannumeral0\xintminof }%
+\def\xintminof #1{\expandafter\XINT_minof_a\romannumeral`&&@#1\xint:}%
+\def\XINT_minof_a #1{\expandafter\XINT_minof_b\romannumeral0\xintraw{#1}!}%
+\def\XINT_minof_b #1!#2%
+ {\expandafter\XINT_minof_c\romannumeral`&&@#2!{#1}!}%
+\def\XINT_minof_c #1%
+ {\xint_gob_til_xint: #1\XINT_minof_e\xint:\XINT_minof_d #1}%
+\def\XINT_minof_d #1!%
+ {\expandafter\XINT_minof_b\romannumeral0\xintmin {#1}}%
+\def\XINT_minof_e #1!#2!{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintCmp}}
+% \begin{macrocode}
+\def\xintCmp {\romannumeral0\xintcmp }%
+\def\xintcmp #1%
+{%
+ \expandafter\XINT_fcmp\expandafter {\romannumeral0\xintraw {#1}}%
+}%
+\def\XINT_fcmp #1#2%
+{%
+ \expandafter\XINT_fcmp_A\romannumeral0\xintraw {#2}#1%
+}%
+\def\XINT_fcmp_A #1#2/#3[#4]#5#6/#7[#8]%
+{%
+ \xint_UDsignsfork
+ #1#5\XINT_fcmp_minusminus
+ -#5\XINT_fcmp_firstneg
+ #1-\XINT_fcmp_secondneg
+ --\XINT_fcmp_nonneg_a
+ \krof
+ #1#5{#2/#3[#4]}{#6/#7[#8]}%
+}%
+\def\XINT_fcmp_minusminus --#1#2{\XINT_fcmp_B #2#1}%
+\def\XINT_fcmp_firstneg #1-#2#3{ -1}%
+\def\XINT_fcmp_secondneg -#1#2#3{ 1}%
+\def\XINT_fcmp_nonneg_a #1#2%
+{%
+ \xint_UDzerosfork
+ #1#2\XINT_fcmp_zerozero
+ 0#2\XINT_fcmp_firstzero
+ #10\XINT_fcmp_secondzero
+ 00\XINT_fcmp_pos
+ \krof
+ #1#2%
+}%
+\def\XINT_fcmp_zerozero #1#2#3#4{ 0}%
+\def\XINT_fcmp_firstzero #1#2#3#4{ -1}%
+\def\XINT_fcmp_secondzero #1#2#3#4{ 1}%
+\def\XINT_fcmp_pos #1#2#3#4%
+{%
+ \XINT_fcmp_B #1#3#2#4%
+}%
+\def\XINT_fcmp_B #1/#2[#3]#4/#5[#6]%
+{%
+ \expandafter\XINT_fcmp_C\expandafter
+ {\the\numexpr #6-#3\expandafter}\expandafter
+ {\romannumeral0\xintiimul {#4}{#2}}%
+ {\romannumeral0\xintiimul {#5}{#1}}%
+}%
+\def\XINT_fcmp_C #1#2#3%
+{%
+ \expandafter\XINT_fcmp_D\expandafter
+ {#3}{#1}{#2}%
+}%
+\def\XINT_fcmp_D #1#2#3%
+{%
+ \expandafter\XINT_cntSgnFork\romannumeral`&&@\expandafter\XINT_cntSgn
+ \the\numexpr #2+\xintLength{#3}-\xintLength{#1}\relax\xint:
+ { -1}{\XINT_fcmp_E #2\Z {#3}{#1}}{ 1}%
+}%
+\def\XINT_fcmp_E #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_fcmp_Fd
+ -{\XINT_fcmp_Fn #1}%
+ \krof
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_fcmp_Fd #1\Z #2#3%
+{%
+ \expandafter\XINT_fcmp_Fe
+ \romannumeral0\XINT_dsx_addzeros {#1}#3;\xint:#2\xint:
+}%
+\def\XINT_fcmp_Fe #1\xint:#2#3\xint:{\XINT_cmp_plusplus #2#1\xint:#3\xint:}%
+\def\XINT_fcmp_Fn #1\Z #2#3%
+{%
+ \expandafter\XINT_fcmp_Fo
+ \romannumeral0\XINT_dsx_addzeros {#1}#2;\xint:#3\xint:
+}%
+\def\XINT_fcmp_Fo #1#2\xint:#3\xint:{\XINT_cmp_plusplus #1#3\xint:#2\xint:}%
+% \end{macrocode}
+% \subsection{\csh{xintAbs}}
+% \begin{macrocode}
+\def\xintAbs {\romannumeral0\xintabs }%
+\def\xintabs #1{\expandafter\XINT_abs\romannumeral0\xintraw {#1}}%
+% \end{macrocode}
+% \subsection{\csh{xintOpp}}
+% \begin{macrocode}
+\def\xintOpp {\romannumeral0\xintopp }%
+\def\xintopp #1{\expandafter\XINT_opp\romannumeral0\xintraw {#1}}%
+% \end{macrocode}
+% \subsection{\csh{xintInv}}
+% \changed{1.3d}{}
+% \begin{macrocode}
+\def\xintInv {\romannumeral0\xintinv }%
+\def\xintinv #1{\expandafter\XINT_inv\romannumeral0\xintraw {#1}}%
+\def\XINT_inv #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_inv_iszero
+ 0#1\XINT_inv_a
+ 0-{\XINT_inv_a {}}%
+ \krof #1%
+}%
+\def\XINT_inv_iszero #1]%
+ {\XINT_signalcondition{DivisionByZero}{Division of 1 by zero (#1])}{}{0/1[0]}}%
+\def\XINT_inv_a #1#2/#3[#4#5]%
+{%
+ \xint_UDzerominusfork
+ #4-\XINT_inv_expiszero
+ 0#4\XINT_inv_b
+ 0-{\XINT_inv_b -#4}%
+ \krof #5.{#1#3/#2}%
+}%
+\def\XINT_inv_expiszero #1.#2{ #2[0]}%
+\def\XINT_inv_b #1.#2{ #2[#1]}%
+% \end{macrocode}
+% \subsection{\csh{xintSgn}}
+% \begin{macrocode}
+\def\xintSgn {\romannumeral0\xintsgn }%
+\def\xintsgn #1{\expandafter\XINT_sgn\romannumeral0\xintraw {#1}\xint:}%
+% \end{macrocode}
+% \subsection{Floating point macros}
+%
+% For a long time the float routines dating back to releases |1.07/1.08a|
+% (May-June 2013) were not modified.
+%
+% Since |1.2f| (March 2016) the four operations first round their arguments to
+% |\xinttheDigits|-floats (or |P|-floats), not (|\xinttheDigits+2|)-floats or
+% (|P+2|)-floats as was the case with earlier releases.
+%
+% The four operations addition, subtraction, multiplication, division have
+% always produced the correct rounding of the theoretical exact value to |P|
+% or |\xinttheDigits| digits when the inputs are decimal numbers with at most
+% |P| digits, and arbitrary decimal exponent part.
+%
+% From |1.08a| to |1.2j|, |\xintFloat| (and |\XINTinFloat| which is used to
+% parse inputs to other float macros) handled a fractional input |A/B| via an
+% initial replacement to |A'/B'| where |A'| and |B'| were |A| and |B|
+% truncated to |Q+2| digits (where asked-for precision is |Q|), and then they
+% correctly rounded |A'/B'| to |Q| digits. But this meant that this rounding of
+% the input could differ (by up to one unit in the last place) from the
+% correct rounding of the original |A/B| to the asked-for number of
+% digits (which until |1.2f| in uses as auxiliary to the macros for the basic
+% operations was 2 more than the prevailing precision).
+%
+% Since |1.2k| all inputs are correctly rounded to the asked-for number of
+% digits (this was, I think, the case in the |1.07| release -- there are no
+% code comments -- but was, afaicr, not very efficiently done, and this is why
+% the |1.08a| release opeted for truncation of the numerator and denominator.)
+%
+% Notice that in float expressions, the |/| is treated as operator, hence the
+% above discussion makes a difference only for the special input form
+% |qfloat(A/B)| or for an |\xintexpr A/B\relax| embedded in the float
+% expression, with |A| or |B| having more digits than the prevailing float
+% precision.
+%
+% \begin{framed}
+% Internally there is no inner representation of |P|-floats as such !!!!!
+%
+% The input parser will again compute the length of the mantissa on each use
+% !!! This is obviously something that must be improved upon before
+% implementation of higher functions.
+%
+% Currently, special tricks are used to quickly recognize inputs having no
+% denominators, or fractions whose numerators and denominators are not too
+% long compared to the target precision |P|, and in particular |P|-floats or
+% quotients of two such.
+%
+% Another long-standing issue is that float multiplication will first
+% compute the |2P| or |2P-1| digits of the exact product, and then round it
+% to |P| digits. This is sub-optimal for large |P| particularly as the
+% multiplication algorithm is basically the schoolbook one, hence
+% \emph{worse} than quadratic in the \TeX\ implementation which has extra
+% cost of fetching long sequences of tokens.
+% \end{framed}
+%
+%
+% \subsection{\csh{xintFloat}}
+% \lverb|&
+% 1.2f and 1.2g brought some refactoring which resulted in faster treatment of
+% decimal inputs. 1.2i dropped use of some old routines dating back to pre 1.2
+% era in favor of more modern \xintDSRr for rounding. Then 1.2k improves
+% again the handling of denominators B with few digits.
+%
+% But the main change with 1.2k is a complete rewrite of the B>1 case in
+% order to achieve again correct rounding in all cases.
+%
+% The original version from 1.07 (May 2013) computed the exact rounding
+% to P digits for all inputs. But from 1.08 on (June 2013), the macro handled
+% A/B input by first truncating both A and B to at most P+2 digits. This meant
+% that decimal input (arbitrarily long, with scientific part) was correctly
+% rounded, but in case of fractional input there could be up to 0.6 unit in
+% the last place difference of the produced rounding to the input, hence the
+% output could differ from the correct rounding.
+%
+% Example with 16 digits (the default): \xintFloat {1/17597472569900621233}$newline
+% with xintfrac 1.07: 5.682634230727187e-20$newline
+% with xintfrac 1.08b--1.2j: 5.682634230727188e-20$newline
+% with xintfrac 1.2k: 5.682634230727187e-20$newline
+% The exact value is 5.682634230727187499924124...e-20, showing that 1.07 and
+% 1.2k
+% produce the correct rounding.
+%
+% Currently the code ends in a more costly branch in about 1 case among 500,
+% where it does some extra operations (a multiplication in particular). There
+% is a free parameter delta (here set at 4), I have yet to make some numerical
+% explorations, to see if it could be favorable to set it to a higher value
+% (with delta=5, there is only 1 exceptional case in 5000, etc...).
+%
+% I have always hesitated about the policy of printing 10.00...0 in case of
+% rounding upwards to the next power of ten. Already since 1.2f \XINTinFloat
+% always produced a mantissa with exactly P digits (except for the zero
+% value). Starting with 1.2k, \xintFloat drops this habit of printing
+% 10.00..0 in such cases. Side note: the rounding-up detection worked when the
+% input A/B was with numerator A and denominator B having each less than P+2
+% digits, or with B=1, else, it could happen that the output was a power of
+% ten but not detected to be a rounding up of the original fraction. The value
+% was ok, but printed 1.0...0eN with P-1 zeroes, not 10.0...0e(N-1).
+%
+% I decided it was not worth the effort to enhance the algorithm to detect
+% with 100$% fiability all cases of rounding up to next
+% power of ten, hence 1.2k dropped this.
+%
+% To avoid duplication of code, and any extra burden on \XINTinFloat, which is
+% the macro used internally by the float macros for parsing their inputs, we
+% simply make now \xintFloat a wrapper of \XINTinFloat.|
+% \begin{macrocode}
+\def\xintFloat {\romannumeral0\xintfloat }%
+\def\xintfloat #1{\XINT_float_chkopt #1\xint:}%
+\def\XINT_float_chkopt #1%
+{%
+ \ifx [#1\expandafter\XINT_float_opt
+ \else\expandafter\XINT_float_noopt
+ \fi #1%
+}%
+\def\XINT_float_noopt #1\xint:%
+{%
+ \expandafter\XINT_float_post
+ \romannumeral0\XINTinfloat[\XINTdigits]{#1}\XINTdigits.%
+}%
+\def\XINT_float_opt [\xint:#1]%
+{%
+ \expandafter\XINT_float_opt_a\the\numexpr #1.%
+}%
+\def\XINT_float_opt_a #1.#2%
+{%
+ \expandafter\XINT_float_post
+ \romannumeral0\XINTinfloat[#1]{#2}#1.%
+}%
+\def\XINT_float_post #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_float_zero
+ 0#1\XINT_float_neg
+ 0-\XINT_float_pos
+ \krof #1%
+}%[
+\def\XINT_float_zero #1]#2.{ 0.e0}%
+\def\XINT_float_neg-{\expandafter-\romannumeral0\XINT_float_pos}%
+\def\XINT_float_pos #1#2[#3]#4.%
+{%
+ \expandafter\XINT_float_pos_done\the\numexpr#3+#4-\xint_c_i.#1.#2;%
+}%
+\def\XINT_float_pos_done #1.#2;{ #2e#1}%
+% \end{macrocode}
+% \subsection{\csh{XINTinFloat}, \csh{XINTinFloatS}, \csh{XINTiLogTen}}
+% \lverb|&
+% This routine is like \xintFloat but produces an output of the shape A[N]
+% which is then parsed faster as input to other float macros.
+% Float operations in \xintfloatexpr...\relax use internally this format.
+%
+% It must be used in form \XINTinFloat[P]{f}: the optional [P] is
+% mandatory.
+%
+% Since 1.2f, the mantissa always has exactly P digits even in case of
+% rounding up to next power of ten. This simplifies other routines.
+%
+% 1.2g added a variant \XINTinFloatS which, in case of decimal input with less
+% than the asked for precision P will not add extra zeros to the mantissa. For
+% example it may output 2[0] even if P=500, rather than the canonical
+% representation 200...000[-499]. This is how \xintFloatMul and \xintFloatDiv
+% parse their inputs, which speeds-up follow-up processing. But \xintFloatAdd
+% and \xintFloatSub still use \XINTinFloat for parsing their inputs; anyway
+% this will have to be changed again when inner structure will carry upfront
+% at least the length of mantissa as data.
+%
+% Each time \XINTinFloat is called it at least computes a length. Naturally if
+% we had some format for floats that would be dispensed of...$newline
+% something like
+% <letterP><length of mantissa>.mantissa.exponent, etc... not yet.
+%
+% Since 1.2k, \XINTinFloat always correctly rounds its argument, even if it
+% is a fraction with very big numerator and denominator. See the discussion of
+% \xintFloat.
+%
+% 1.3e adds \XINTiLogTen.
+% |
+% \begin{macrocode}
+\def\XINTinFloat {\romannumeral0\XINTinfloat }%
+\def\XINTinfloat
+ {\expandafter\XINT_infloat_clean\romannumeral0\XINT_infloat}%
+% \end{macrocode}
+% \lverb|Attention que ici le fait que l'on grabbe #1 est important car il
+% pourrait y avoir un zéro (en particulier dans le cas où input est nul).|
+% \begin{macrocode}
+\def\XINT_infloat_clean #1%
+ {\if #1!\xint_dothis\XINT_infloat_clean_a\fi\xint_orthat{ }#1}%
+% \end{macrocode}
+% \lverb|Ici on ajoute les zeros pour faire exactement avec P chiffres.
+% Car le #1 = P - L avec L la longueur de #2, (ou de abs(#2), ici le #2 peut
+% avoir un signe) qui est < P|
+% \begin{macrocode}
+\def\XINT_infloat_clean_a !#1.#2[#3]%
+{%
+ \expandafter\XINT_infloat_done
+ \the\numexpr #3-#1\expandafter.%
+ \romannumeral0\XINT_dsx_addzeros {#1}#2;;%
+}%
+\def\XINT_infloat_done #1.#2;{ #2[#1]}%
+% \end{macrocode}
+% \lverb|variant which allows output with shorter mantissas.|
+% \begin{macrocode}
+\def\XINTinFloatS {\romannumeral0\XINTinfloatS}%
+\def\XINTinfloatS
+ {\expandafter\XINT_infloatS_clean\romannumeral0\XINT_infloat}%
+\def\XINT_infloatS_clean #1%
+ {\if #1!\xint_dothis\XINT_infloatS_clean_a\fi\xint_orthat{ }#1}%
+\def\XINT_infloatS_clean_a !#1.{ }%
+% \end{macrocode}
+% \lverb|1.3e ajoute \XINTiLogTen. Le comportement pour un input nul est non
+% encore finalisé. Il changera lorsque NaN, +Inf, -Inf existeront.|
+% \begin{macrocode}
+\def\XINTFloatiLogTen {\the\numexpr\XINTfloatilogten}%
+\def\XINTfloatilogten [#1]#2%
+ {\expandafter\XINT_floatilogten\romannumeral0\XINT_infloat[#1]{#2}#1.}%
+\def\XINT_floatilogten #1{%
+ \if #10\xint_dothis\XINT_floatilogten_z\fi
+ \if #1!\xint_dothis\XINT_floatilogten_a\fi
+ \xint_orthat\XINT_floatilogten_b #1%
+}%
+\def\XINT_floatilogten_z 0[0]#1.{-"7FFF8000\relax}%
+\def\XINT_floatilogten_a !#1.#2[#3]#4.{#3-#1+#4-1\relax}%
+\def\XINT_floatilogten_b #1[#2]#3.{#2+#3-1\relax}%
+% \end{macrocode}
+% \lverb|début de la routine proprement dite,
+% l'argument optionnel est obligatoire.|
+% \begin{macrocode}
+\def\XINT_infloat [#1]#2%
+{%
+ \expandafter\XINT_infloat_a\the\numexpr #1\expandafter.%
+ \romannumeral0\XINT_infrac {#2}%
+}%
+% \end{macrocode}
+% \lverb| #1=P, #2=n, #3=A, #4=B.|
+% \begin{macrocode}
+\def\XINT_infloat_a #1.#2#3#4%
+{%
+% \end{macrocode}
+% \lverb|micro boost au lieu d'utiliser \XINT_isOne{#4}, mais pas bon style.|
+% \begin{macrocode}
+ \if1\XINT_is_One#4XY%
+ \expandafter\XINT_infloat_sp
+ \else\expandafter\XINT_infloat_fork
+ \fi #3.{#1}{#2}{#4}%
+}%
+% \end{macrocode}
+% \lverb|Special quick treatment of B=1 case (1.2f then again 1.2g.)$newline
+% maintenant: A.{P}{N}{1}
+% Il est possible que A soit nul.
+% |
+% \begin{macrocode}
+\def\XINT_infloat_sp #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_infloat_spzero
+ 0#1\XINT_infloat_spneg
+ 0-\XINT_infloat_sppos
+ \krof #1%
+}%
+% \end{macrocode}
+% \lverb|Attention surtout pas 0/1[0] ici.|
+% \begin{macrocode}
+\def\XINT_infloat_spzero 0.#1#2#3{ 0[0]}%
+\def\XINT_infloat_spneg-%
+ {\expandafter\XINT_infloat_spnegend\romannumeral0\XINT_infloat_sppos}%
+\def\XINT_infloat_spnegend #1%
+ {\if#1!\expandafter\XINT_infloat_spneg_needzeros\fi -#1}%
+\def\XINT_infloat_spneg_needzeros -!#1.{!#1.-}%
+% \end{macrocode}
+% \lverb|in: A.{P}{N}{1}$newline
+% out: P-L.A.P.N.|
+% \begin{macrocode}
+\def\XINT_infloat_sppos #1.#2#3#4%
+{%
+ \expandafter\XINT_infloat_sp_b\the\numexpr#2-\xintLength{#1}.#1.#2.#3.%
+}%
+% \end{macrocode}
+% \lverb|#1= P-L. Si c'est positif ou nul il faut retrancher #1 à l'exposant, et
+% ajouter autant de zéros. On regarde premier token.
+% P-L.A.P.N.|
+% \begin{macrocode}
+\def\XINT_infloat_sp_b #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_infloat_sp_quick
+ 0#1\XINT_infloat_sp_c
+ 0-\XINT_infloat_sp_needzeros
+ \krof #1%
+}%
+% \end{macrocode}
+% \lverb|Ici P=L. Le cas usuel dans \xintfloatexpr.|
+% \begin{macrocode}
+\def\XINT_infloat_sp_quick 0.#1.#2.#3.{ #1[#3]}%
+% \end{macrocode}
+% \lverb|Ici #1=P-L est >0. L'exposant sera N-(P-L). #2=A. #3=P. #4=N.$newline
+% 18 mars 2016. En fait dans certains contextes il est sous-optimal d'ajouter les
+% zéros. Par exemple quand c'est appelé par la multiplication ou la division,
+% c'est idiot de convertir 2 en 200000...00000[-499].
+% Donc je redéfinis addzeros en needzeroes. Si on appelle sous la forme
+% \XINTinFloatS, on ne fait pas l'addition de zeros.|
+% \begin{macrocode}
+\def\XINT_infloat_sp_needzeros #1.#2.#3.#4.{!#1.#2[#4]}%
+% \end{macrocode}
+% \lverb|L-P=#1.A=#2#3.P=#4.N=#5.$newline
+% Ici P<L. Il va falloir arrondir. Attention si on va à la puissance de 10
+% suivante. En #1 on a L-P qui est >0. L'exposant final sera N+L-P,
+% sauf dans le cas spécial, il sera alors N+L-P+1. L'ajustement final
+% est fait par \XINT_infloat_Y.|
+% \begin{macrocode}
+\def\XINT_infloat_sp_c -#1.#2#3.#4.#5.%
+{%
+ \expandafter\XINT_infloat_Y
+ \the\numexpr #5+#1\expandafter.%
+ \romannumeral0\expandafter\XINT_infloat_sp_round
+ \romannumeral0\XINT_split_fromleft
+ (\xint_c_i+#4).#2#3\xint_bye2345678\xint_bye..#2%
+}%
+\def\XINT_infloat_sp_round #1.#2.%
+{%
+ \XINT_dsrr#1\xint_bye\xint_Bye3456789\xint_bye/\xint_c_x\relax.%
+}%
+% \end{macrocode}
+% \lverb|General branch for A/B with B>1 inputs. It achieves correct rounding
+% always since 1.2k (done January 2, 2017.) This branch is never taken for A=0
+% because \XINT_infrac will have returned B=1 then.|
+% \begin{macrocode}
+\def\XINT_infloat_fork #1%
+{%
+ \xint_UDsignfork
+ #1\XINT_infloat_J
+ -\XINT_infloat_K
+ \krof #1%
+}%
+\def\XINT_infloat_J-{\expandafter-\romannumeral0\XINT_infloat_K }%
+% \end{macrocode}
+% \lverb?A.{P}{n}{B} avec B>1.?
+% \begin{macrocode}
+\def\XINT_infloat_K #1.#2%
+{%
+ \expandafter\XINT_infloat_L
+ \the\numexpr\xintLength{#1}\expandafter.\the\numexpr #2+\xint_c_iv.{#1}{#2}%
+}%
+% \end{macrocode}
+% \lverb?|A|.P+4.{A}{P}{n}{B}. We check if A already has length
+% <= P+4.?
+% \begin{macrocode}
+\def\XINT_infloat_L #1.#2.%
+{%
+ \ifnum #1>#2
+ \expandafter\XINT_infloat_Ma
+ \else
+ \expandafter\XINT_infloat_Mb
+ \fi #1.#2.%
+}%
+% \end{macrocode}
+% \lverb?|A|.P+4.{A}{P}{n}{B}. We will keep only the first P+4
+% digits of A, denoted A'' in what follows.
+%
+% output: u=-0.A''.junk.P+4.|A|.{A}{P}{n}{B}?
+% \begin{macrocode}
+\def\XINT_infloat_Ma #1.#2.#3%
+{%
+ \expandafter\XINT_infloat_MtoN\expandafter-\expandafter0\expandafter.%
+ \romannumeral0\XINT_split_fromleft#2.#3\xint_bye2345678\xint_bye..%
+ #2.#1.{#3}%
+}%
+% \end{macrocode}
+% \lverb?|A|.P+4.{A}{P}{n}{B}.$newline
+% Here A is short. We set u = P+4-|A|, and A''=A (A' = 10^u A)
+%
+% output: u.A''..P+4.|A|.{A}{P}{n}{B}?
+% \begin{macrocode}
+\def\XINT_infloat_Mb #1.#2.#3%
+{%
+ \expandafter\XINT_infloat_MtoN\the\numexpr#2-#1.%
+ #3..#2.#1.{#3}%
+}%
+% \end{macrocode}
+% \lverb?input u.A''.junk.P+4.|A|.{A}{P}{n}{B}$newline
+% output |B|.P+4.{B}u.A''.P.|A|.n.{A}{B}?
+% \begin{macrocode}
+\def\XINT_infloat_MtoN #1.#2.#3.#4.#5.#6#7#8#9%
+{%
+ \expandafter\XINT_infloat_N
+ \the\numexpr\xintLength{#9}.#4.{#9}#1.#2.#7.#5.#8.{#6}{#9}%
+}%
+\def\XINT_infloat_N #1.#2.%
+{%
+ \ifnum #1>#2
+ \expandafter\XINT_infloat_Oa
+ \else
+ \expandafter\XINT_infloat_Ob
+ \fi #1.#2.%
+}%
+% \end{macrocode}
+% \lverb?input |B|.P+4.{B}u.A''.P.|A|.n.{A}{B}$newline
+% output v=-0.B''.junk.|B|.u.A''.P.|A|.n.{A}{B}?
+% \begin{macrocode}
+\def\XINT_infloat_Oa #1.#2.#3%
+{%
+ \expandafter\XINT_infloat_P\expandafter-\expandafter0\expandafter.%
+ \romannumeral0\XINT_split_fromleft#2.#3\xint_bye2345678\xint_bye..%
+ #1.%
+}%
+% \end{macrocode}
+% \lverb?output v=P+4-|B|>=0.B''.junk.|B|.u.A''.P.|A|.n.{A}{B}?
+% \begin{macrocode}
+\def\XINT_infloat_Ob #1.#2.#3%
+{%
+ \expandafter\XINT_infloat_P\the\numexpr#2-#1.#3..#1.%
+}%
+% \end{macrocode}
+% \lverb?input v.B''.junk.|B|.u.A''.P.|A|.n.{A}{B}$newline
+% output Q1.P.|B|.|A|.n.{A}{B}$newline
+% Q1 = division euclidienne de A''.10^{u-v+P+3} par B''.
+%
+% Special detection of cases with A and B both having length at most P+4: this
+% will happen when called from \xintFloatDiv as A and B (produced then via
+% \XINTinFloatS) will have at most P digits. We then only need integer division
+% with P+1 extra zeros, not P+3.?
+% \begin{macrocode}
+\def\XINT_infloat_P #1#2.#3.#4.#5.#6#7.#8.#9.%
+{%
+ \csname XINT_infloat_Q\if-#1\else\if-#6\else q\fi\fi\expandafter\endcsname
+ \romannumeral0\xintiiquo
+ {\romannumeral0\XINT_dsx_addzerosnofuss
+ {#6#7-#1#2+#9+\xint_c_iii\if-#1\else\if-#6\else-\xint_c_ii\fi\fi}#8;}%
+ {#3}.#9.#5.%
+}%
+% \end{macrocode}
+% \lverb?«quick» branch.?
+% \begin{macrocode}
+\def\XINT_infloat_Qq #1.#2.%
+{%
+ \expandafter\XINT_infloat_Rq
+ \romannumeral0\XINT_split_fromleft#2.#1\xint_bye2345678\xint_bye..#2.%
+}%
+\def\XINT_infloat_Rq #1.#2#3.%
+{%
+ \ifnum#2<\xint_c_v
+ \expandafter\XINT_infloat_SEq
+ \else\expandafter\XINT_infloat_SUp
+ \fi
+ {\if.#3.\xint_c_\else\xint_c_i\fi}#1.%
+}%
+% \end{macrocode}
+% \lverb?standard branch which will have to handle undecided rounding, if too
+% close to a mid-value.?
+% \begin{macrocode}
+\def\XINT_infloat_Q #1.#2.%
+{%
+ \expandafter\XINT_infloat_R
+ \romannumeral0\XINT_split_fromleft#2.#1\xint_bye2345678\xint_bye..#2.%
+}%
+\def\XINT_infloat_R #1.#2#3#4#5.%
+{%
+ \if.#5.\expandafter\XINT_infloat_Sa\else\expandafter\XINT_infloat_Sb\fi
+ #2#3#4#5.#1.%
+}%
+% \end{macrocode}
+% \lverb?trailing digits.Q.P.|B|.|A|.n.{A}{B}$newline
+% #1=trailing digits (they may have leading zeros.)?
+% \begin{macrocode}
+\def\XINT_infloat_Sa #1.%
+{%
+ \ifnum#1>500 \xint_dothis\XINT_infloat_SUp\fi
+ \ifnum#1<499 \xint_dothis\XINT_infloat_SEq\fi
+ \xint_orthat\XINT_infloat_X\xint_c_
+}%
+\def\XINT_infloat_Sb #1.%
+{%
+ \ifnum#1>5009 \xint_dothis\XINT_infloat_SUp\fi
+ \ifnum#1<4990 \xint_dothis\XINT_infloat_SEq\fi
+ \xint_orthat\XINT_infloat_X\xint_c_i
+}%
+% \end{macrocode}
+% \lverb?epsilon #2=Q.#3=P.#4=|B|.#5=|A|.#6=n.{A}{B}$newline
+% exposant final est n+|A|-|B|-P+epsilon?
+% \begin{macrocode}
+\def\XINT_infloat_SEq #1#2.#3.#4.#5.#6.#7#8%
+{%
+ \expandafter\XINT_infloat_SY
+ \the\numexpr #6+#5-#4-#3+#1.#2.%
+}%
+\def\XINT_infloat_SY #1.#2.{ #2[#1]}%
+% \end{macrocode}
+% \lverb?initial digit #2 put aside to check for case of rounding up to
+% next power of ten, which will need adjustment of mantissa and exponent.?
+% \begin{macrocode}
+\def\XINT_infloat_SUp #1#2#3.#4.#5.#6.#7.#8#9%
+{%
+ \expandafter\XINT_infloat_Y
+ \the\numexpr#7+#6-#5-#4+#1\expandafter.%
+ \romannumeral0\xintinc{#2#3}.#2%
+}%
+% \end{macrocode}
+% \lverb?epsilon Q.P.|B|.|A|.n.{A}{B}$newline
+%
+% \xintDSH{-x}{U} multiplies U by 10^x. When x is negative, this means
+% it truncates (i.e. it drops the last -x digits).
+%
+% We don't try to optimize too much macro calls here, the odds are 2 per 1000
+% for this branch to be taken. Perhaps in future I will use higher free
+% parameter d, which currently is set at 4.
+%
+% #1=epsilon, #2#3=Q, #4=P, #5=|B|, #6=|A|, #7=n, #8=A, #9=B?
+% \begin{macrocode}
+\def\XINT_infloat_X #1#2#3.#4.#5.#6.#7.#8#9%
+{%
+ \expandafter\XINT_infloat_Y
+ \the\numexpr #7+#6-#5-#4+#1\expandafter.%
+ \romannumeral`&&@\romannumeral0\xintiiiflt
+ {\xintDSH{#6-#5-#4+#1}{\xintDouble{#8}}}%
+ {\xintiiMul{\xintInc{\xintDouble{#2#3}}}{#9}}%
+ \xint_firstofone
+ \xintinc{#2#3}.#2%
+}%
+% \end{macrocode}
+% \lverb?check for rounding up to next power of ten.?
+% \begin{macrocode}
+\def\XINT_infloat_Y #1{%
+\def\XINT_infloat_Y ##1.##2##3.##4%
+{%
+ \if##49\if##21\expandafter\expandafter\expandafter\XINT_infloat_Z\fi\fi
+ #1##2##3[##1]%
+}}\XINT_infloat_Y{ }%
+% \end{macrocode}
+% \lverb?#1=1, #2=0.?
+% \begin{macrocode}
+\def\XINT_infloat_Z #1#2#3[#4]%
+{%
+ \expandafter\XINT_infloat_ZZ\the\numexpr#4+\xint_c_i.#3.%
+}%
+\def\XINT_infloat_ZZ #1.#2.{ 1#2[#1]}%
+% \end{macrocode}
+% \subsection{\csh{xintPFloat}}
+% \lverb|1.1. This is a prettifying printing macro for floats.
+%
+%
+% The macro applies one simple rule: x.yz...eN will drop scientific notation in
+% favor of pure decimal notation if -5<=N<=5. This is the default behaviour of
+% Maple. The N here is as produced on output by \xintFloat.
+%
+% Special case: the zero value is printed 0. (with a dot)
+%
+% The coding got simpler with 1.2k as its \xintFloat always produces
+% a mantissa with exactly P digits (no more 10.0...0eN annoying exception).
+%
+% |
+% \begin{macrocode}
+\def\xintPFloat {\romannumeral0\xintpfloat }%
+\def\xintpfloat #1{\XINT_pfloat_chkopt #1\xint:}%
+\def\XINT_pfloat_chkopt #1%
+{%
+ \ifx [#1\expandafter\XINT_pfloat_opt
+ \else\expandafter\XINT_pfloat_noopt
+ \fi #1%
+}%
+\def\XINT_pfloat_noopt #1\xint:%
+{%
+ \expandafter\XINT_pfloat_a
+ \romannumeral0\xintfloat [\XINTdigits]{#1};\XINTdigits.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_pfloat_opt [\xint:#1]%
+{%
+ \expandafter\XINT_pfloat_opt_a \the\numexpr #1.%
+}%
+\def\XINT_pfloat_opt_a #1.#2%
+{%
+ \expandafter\XINT_pfloat_a\romannumeral0\xintfloat [#1]{#2};#1.%
+}%
+\def\XINT_pfloat_a #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_pfloat_zero
+ 0#1\XINT_pfloat_neg
+ 0-\XINT_pfloat_pos
+ \krof #1%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_pfloat_zero #1;#2.{ 0.}%
+\def\XINT_pfloat_neg-{\expandafter-\romannumeral0\XINT_pfloat_pos }%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_pfloat_pos #1.#2e#3;#4.%
+{%
+ \ifnum #3>\xint_c_v \xint_dothis\XINT_pfloat_no\fi
+ \ifnum #3<-\xint_c_v \xint_dothis\XINT_pfloat_no\fi
+ \ifnum #3<\xint_c_ \xint_dothis\XINT_pfloat_N\fi
+ \ifnum #3>\numexpr #4-\xint_c_i\relax \xint_dothis\XINT_pfloat_Ps\fi
+ \xint_orthat\XINT_pfloat_P #1#2e#3;%
+}%
+\def\XINT_pfloat_no #1#2;{ #1.#2}%
+% \end{macrocode}
+% \lverb|This is all simpler coded, now that 1.2k's \xintFloat always
+% outputs a mantissa with exactly one digits before decimal mark always.
+% |
+% \begin{macrocode}
+\def\XINT_pfloat_N #1e-#2;%
+{%
+ \csname XINT_pfloat_N_\romannumeral#2\endcsname #1%
+}%
+\def\XINT_pfloat_N_i { 0.}%
+\def\XINT_pfloat_N_ii { 0.0}%
+\def\XINT_pfloat_N_iii{ 0.00}%
+\def\XINT_pfloat_N_iv { 0.000}%
+\def\XINT_pfloat_N_v { 0.0000}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_pfloat_P #1e#2;%
+{%
+ \csname XINT_pfloat_P_\romannumeral#2\endcsname #1%
+}%
+\def\XINT_pfloat_P_ #1{ #1.}%
+\def\XINT_pfloat_P_i #1#2{ #1#2.}%
+\def\XINT_pfloat_P_ii #1#2#3{ #1#2#3.}%
+\def\XINT_pfloat_P_iii#1#2#3#4{ #1#2#3#4.}%
+\def\XINT_pfloat_P_iv #1#2#3#4#5{ #1#2#3#4#5.}%
+\def\XINT_pfloat_P_v #1#2#3#4#5#6{ #1#2#3#4#5#6.}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_pfloat_Ps #1e#2;%
+{%
+ \csname XINT_pfloat_Ps\romannumeral#2\endcsname #100000;%
+}%
+\def\XINT_pfloat_Psi #1#2#3;{ #1#2.}%
+\def\XINT_pfloat_Psii #1#2#3#4;{ #1#2#3.}%
+\def\XINT_pfloat_Psiii#1#2#3#4#5;{ #1#2#3#4.}%
+\def\XINT_pfloat_Psiv #1#2#3#4#5#6;{ #1#2#3#4#5.}%
+\def\XINT_pfloat_Psv #1#2#3#4#5#6#7;{ #1#2#3#4#5#6.}%
+% \end{macrocode}
+% \subsection{\csh{XINTinFloatFracdigits}}
+% \lverb|1.09i, for frac function in \xintfloatexpr. This version computes
+% exactly from the input the fractional part and then only converts it
+% into a float with the asked-for number of digits. I will have to think
+% it again some day, certainly.
+%
+% 1.1 removes optional argument for which there was anyhow no interface, for
+% technical reasons having to do with \xintNewExpr.
+%
+% 1.1a renames the macro as \XINTinFloatFracdigits (from \XINTinFloatFrac) to
+% be synchronous with the \XINTinFloatSqrt and \XINTinFloat habits related to
+% \xintNewExpr problems.
+%
+% Note to myself: I still have to rethink the whole thing about what is the best
+% to do, the initial way of going through \xinttfrac was just a first
+% implementation.|
+% \begin{macrocode}
+\def\XINTinFloatFracdigits {\romannumeral0\XINTinfloatfracdigits }%
+\def\XINTinfloatfracdigits #1%
+{%
+ \expandafter\XINT_infloatfracdg_a\expandafter {\romannumeral0\xinttfrac{#1}}%
+}%
+\def\XINT_infloatfracdg_a {\XINTinfloat [\XINTdigits]}%
+% \end{macrocode}
+% \subsection{\csh{xintFloatAdd}, \csh{XINTinFloatAdd}}
+% \lverb|First included in release 1.07.
+%
+% 1.09ka improved a bit the efficiency. However the add, sub, mul, div
+% routines were provisory and supposed to be revised soon.
+%
+% Which didn't happen until 1.2f. Now, the inputs are first rounded to P
+% digits, not P+2 as earlier.
+%
+%
+%|
+% \begin{macrocode}
+\def\xintFloatAdd {\romannumeral0\xintfloatadd }%
+\def\xintfloatadd #1{\XINT_fladd_chkopt \xintfloat #1\xint:}%
+\def\XINTinFloatAdd {\romannumeral0\XINTinfloatadd }%
+\def\XINTinfloatadd #1{\XINT_fladd_chkopt \XINTinfloatS #1\xint:}%
+\def\XINT_fladd_chkopt #1#2%
+{%
+ \ifx [#2\expandafter\XINT_fladd_opt
+ \else\expandafter\XINT_fladd_noopt
+ \fi #1#2%
+}%
+\def\XINT_fladd_noopt #1#2\xint:#3%
+{%
+ #1[\XINTdigits]%
+ {\expandafter\XINT_FL_add_a
+ \romannumeral0\XINTinfloat[\XINTdigits]{#2}\XINTdigits.{#3}}%
+}%
+\def\XINT_fladd_opt #1[\xint:#2]%#3#4%
+{%
+ \expandafter\XINT_fladd_opt_a\the\numexpr #2.#1%
+}%
+\def\XINT_fladd_opt_a #1.#2#3#4%
+{%
+ #2[#1]{\expandafter\XINT_FL_add_a\romannumeral0\XINTinfloat[#1]{#3}#1.{#4}}%
+}%
+\def\XINT_FL_add_a #1%
+{%
+ \xint_gob_til_zero #1\XINT_FL_add_zero 0\XINT_FL_add_b #1%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_FL_add_zero #1.#2{#2}%[[
+\def\XINT_FL_add_b #1]#2.#3%
+{%
+ \expandafter\XINT_FL_add_c\romannumeral0\XINTinfloat[#2]{#3}#2.#1]%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_FL_add_c #1%
+{%
+ \xint_gob_til_zero #1\XINT_FL_add_zero 0\XINT_FL_add_d #1%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_FL_add_d #1[#2]#3.#4[#5]%
+{%
+ \ifnum\numexpr #2-#3-#5>\xint_c_\xint_dothis\xint_firstoftwo\fi
+ \ifnum\numexpr #5-#3-#2>\xint_c_\xint_dothis\xint_secondoftwo\fi
+ \xint_orthat\xintAdd {#1[#2]}{#4[#5]}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFloatSub}, \csh{XINTinFloatSub}}
+% \lverb|First done 1.07.
+%
+% Starting with 1.2f the arguments undergo an intial rounding to the target
+% precision P not P+2.|
+%
+% \begin{macrocode}
+\def\xintFloatSub {\romannumeral0\xintfloatsub }%
+\def\xintfloatsub #1{\XINT_flsub_chkopt \xintfloat #1\xint:}%
+\def\XINTinFloatSub {\romannumeral0\XINTinfloatsub }%
+\def\XINTinfloatsub #1{\XINT_flsub_chkopt \XINTinfloatS #1\xint:}%
+\def\XINT_flsub_chkopt #1#2%
+{%
+ \ifx [#2\expandafter\XINT_flsub_opt
+ \else\expandafter\XINT_flsub_noopt
+ \fi #1#2%
+}%
+\def\XINT_flsub_noopt #1#2\xint:#3%
+{%
+ #1[\XINTdigits]%
+ {\expandafter\XINT_FL_add_a
+ \romannumeral0\XINTinfloat[\XINTdigits]{#2}\XINTdigits.{\xintOpp{#3}}}%
+}%
+\def\XINT_flsub_opt #1[\xint:#2]%#3#4%
+{%
+ \expandafter\XINT_flsub_opt_a\the\numexpr #2.#1%
+}%
+\def\XINT_flsub_opt_a #1.#2#3#4%
+{%
+ #2[#1]{\expandafter\XINT_FL_add_a\romannumeral0\XINTinfloat[#1]{#3}#1.{\xintOpp{#4}}}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFloatMul}, \csh{XINTinFloatMul}}
+% \lverb|1.07.
+%
+% Starting with 1.2f the arguments are rounded to the target precision P not
+% P+2.
+%
+% 1.2g handles the inputs via \XINTinFloatS which will be more efficient when
+% the precision is large and the input is for example a small constant like 2.
+%
+% 1.2k does a micro improvement to the way the macro passes over control
+% to its output routine (former version used a higher level \xintE causing
+% some extra un-needed processing with two calls to \XINT_infrac where
+% one was amply enough).|
+% \begin{macrocode}
+\def\xintFloatMul {\romannumeral0\xintfloatmul }%
+\def\xintfloatmul #1{\XINT_flmul_chkopt \xintfloat #1\xint:}%
+\def\XINTinFloatMul {\romannumeral0\XINTinfloatmul }%
+\def\XINTinfloatmul #1{\XINT_flmul_chkopt \XINTinfloatS #1\xint:}%
+\def\XINT_flmul_chkopt #1#2%
+{%
+ \ifx [#2\expandafter\XINT_flmul_opt
+ \else\expandafter\XINT_flmul_noopt
+ \fi #1#2%
+}%
+\def\XINT_flmul_noopt #1#2\xint:#3%
+{%
+ #1[\XINTdigits]%
+ {\expandafter\XINT_FL_mul_a
+ \romannumeral0\XINTinfloatS[\XINTdigits]{#2}\XINTdigits.{#3}}%
+}%
+\def\XINT_flmul_opt #1[\xint:#2]%#3#4%
+{%
+ \expandafter\XINT_flmul_opt_a\the\numexpr #2.#1%
+}%
+\def\XINT_flmul_opt_a #1.#2#3#4%
+{%
+ #2[#1]{\expandafter\XINT_FL_mul_a\romannumeral0\XINTinfloatS[#1]{#3}#1.{#4}}%
+}%
+\def\XINT_FL_mul_a #1[#2]#3.#4%
+{%
+ \expandafter\XINT_FL_mul_b\romannumeral0\XINTinfloatS[#3]{#4}#1[#2]%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_FL_mul_b #1[#2]#3[#4]{\xintiiMul{#3}{#1}/1[#4+#2]}%
+% \end{macrocode}
+% \subsection{\csh{XINTinFloatInv}}
+% \lverb|Added belatedly at 1.3e, to support inv() function. We use Short
+% output, for rare inv(\xintexpr 1/3\relax) case. I need to think the whole
+% thing out at some later date.|
+% \begin{macrocode}
+\def\XINTinFloatInv#1{\XINTinFloatS[\XINTdigits]{\xintInv{#1}}}%
+% \end{macrocode}
+% \subsection{\csh{xintFloatDiv}, \csh{XINTinFloatDiv}}
+% \lverb|1.07.
+%
+% Starting with 1.2f the arguments are rounded to the target precision P not
+% P+2.
+%
+% 1.2g handles the inputs via \XINTinFloatS which will be more efficient when
+% the precision is large and the input is for example a small constant like 2.
+%
+% The actual rounding of the quotient is handled via \xintfloat (or
+% \XINTinfloatS).
+%
+% 1.2k does the same kind of improvement in \XINT_FL_div_b as for
+% multiplication: earlier code was unnecessarily high level.
+% |
+% \begin{macrocode}
+\def\xintFloatDiv {\romannumeral0\xintfloatdiv }%
+\def\xintfloatdiv #1{\XINT_fldiv_chkopt \xintfloat #1\xint:}%
+\def\XINTinFloatDiv {\romannumeral0\XINTinfloatdiv }%
+\def\XINTinfloatdiv #1{\XINT_fldiv_chkopt \XINTinfloatS #1\xint:}%
+\def\XINT_fldiv_chkopt #1#2%
+{%
+ \ifx [#2\expandafter\XINT_fldiv_opt
+ \else\expandafter\XINT_fldiv_noopt
+ \fi #1#2%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_fldiv_noopt #1#2\xint:#3%
+{%
+ #1[\XINTdigits]%
+ {\expandafter\XINT_FL_div_a
+ \romannumeral0\XINTinfloatS[\XINTdigits]{#3}\XINTdigits.{#2}}%
+}%
+\def\XINT_fldiv_opt #1[\xint:#2]%#3#4%
+{%
+ \expandafter\XINT_fldiv_opt_a\the\numexpr #2.#1%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_fldiv_opt_a #1.#2#3#4%
+{%
+ #2[#1]{\expandafter\XINT_FL_div_a\romannumeral0\XINTinfloatS[#1]{#4}#1.{#3}}%
+}%
+\def\XINT_FL_div_a #1[#2]#3.#4%
+{%
+ \expandafter\XINT_FL_div_b\romannumeral0\XINTinfloatS[#3]{#4}/#1e#2%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_FL_div_b #1[#2]{#1e#2}%
+% \end{macrocode}
+% \subsection{\csh{xintFloatPow}, \csh{XINTinFloatPow}}
+% \lverb|1.07: initial version. 1.09j has re-organized the core loop.
+%
+% 2015/12/07. I have hesitated to map ^ in expressions to \xintFloatPow rather
+% than \xintFloatPower. But for 1.234567890123456 to the power 2145678912 with
+% P=16, using Pow rather than Power seems to bring only about 5$char37 $space
+% gain.
+%
+% This routine requires the exponent x to be compatible with \numexpr parsing.
+%
+% 1.2f has rewritten the code for better efficiency. Also, now the argument A
+% for A^x is first rounded to P digits before switching to the increased
+% working precision (which depends upon x).
+%
+% |
+% \begin{macrocode}
+\def\xintFloatPow {\romannumeral0\xintfloatpow}%
+\def\xintfloatpow #1{\XINT_flpow_chkopt \xintfloat #1\xint:}%
+\def\XINTinFloatPow {\romannumeral0\XINTinfloatpow }%
+\def\XINTinfloatpow #1{\XINT_flpow_chkopt \XINTinfloatS #1\xint:}%
+\def\XINT_flpow_chkopt #1#2%
+{%
+ \ifx [#2\expandafter\XINT_flpow_opt
+ \else\expandafter\XINT_flpow_noopt
+ \fi
+ #1#2%
+}%
+\def\XINT_flpow_noopt #1#2\xint:#3%
+{%
+ \expandafter\XINT_flpow_checkB_a
+ \the\numexpr #3.\XINTdigits.{#2}{#1[\XINTdigits]}%
+}%
+\def\XINT_flpow_opt #1[\xint:#2]%
+{%
+ \expandafter\XINT_flpow_opt_a\the\numexpr #2.#1%
+}%
+\def\XINT_flpow_opt_a #1.#2#3#4%
+{%
+ \expandafter\XINT_flpow_checkB_a\the\numexpr #4.#1.{#3}{#2[#1]}%
+}%
+\def\XINT_flpow_checkB_a #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_flpow_BisZero
+ 0#1{\XINT_flpow_checkB_b -}%
+ 0-{\XINT_flpow_checkB_b {}#1}%
+ \krof
+}%
+\def\XINT_flpow_BisZero .#1.#2#3{#3{1[0]}}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flpow_checkB_b #1#2.#3.%
+{%
+ \expandafter\XINT_flpow_checkB_c
+ \the\numexpr\xintLength{#2}+\xint_c_iii.#3.#2.{#1}%
+}%
+% \end{macrocode}
+% \begin{macrocode}
+\def\XINT_flpow_checkB_c #1.#2.%
+{%
+ \expandafter\XINT_flpow_checkB_d\the\numexpr#1+#2.#1.#2.%
+}%
+% \end{macrocode}
+% \lverb|&
+%
+% 1.2f rounds input to P digits, first.
+% |
+% \begin{macrocode}
+\def\XINT_flpow_checkB_d #1.#2.#3.#4.#5#6%
+{%
+ \expandafter \XINT_flpow_aa
+ \romannumeral0\XINTinfloat [#3]{#6}{#2}{#1}{#4}{#5}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flpow_aa #1[#2]#3%
+{%
+ \expandafter\XINT_flpow_ab\the\numexpr #2-#3\expandafter.%
+ \romannumeral\XINT_rep #3\endcsname0.#1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flpow_ab #1.#2.#3.{\XINT_flpow_a #3#2[#1]}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flpow_a #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_flpow_zero
+ 0#1{\XINT_flpow_b \iftrue}%
+ 0-{\XINT_flpow_b \iffalse#1}%
+ \krof
+}%
+\def\XINT_flpow_zero #1[#2]#3#4#5#6%
+{%
+ #6{\if 1#51\xint_dothis {0[0]}\fi
+ \xint_orthat
+ {\XINT_signalcondition{DivisionByZero}{0 to the power #4}{}{0[0]}}%
+ }%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flpow_b #1#2[#3]#4#5%
+{%
+ \XINT_flpow_loopI #5.#3.#2.#4.{#1\ifodd #5 \xint_c_i\fi\fi}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flpow_truncate #1.#2.#3.%
+{%
+ \expandafter\XINT_flpow_truncate_a
+ \romannumeral0\XINT_split_fromleft
+ #3.#2\xint_bye2345678\xint_bye..#1.#3.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flpow_truncate_a #1.#2.#3.{#3+\xintLength{#2}.#1.}%
+\def\XINT_flpow_loopI #1.%
+{%
+ \ifnum #1=\xint_c_i\expandafter\XINT_flpow_ItoIII\fi
+ \ifodd #1
+ \expandafter\XINT_flpow_loopI_odd
+ \else
+ \expandafter\XINT_flpow_loopI_even
+ \fi
+ #1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flpow_ItoIII\ifodd #1\fi #2.#3.#4.#5.#6%
+{%
+ \expandafter\XINT_flpow_III\the\numexpr #6+\xint_c_.#3.#4.#5.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flpow_loopI_even #1.#2.#3.%#4.%
+{%
+ \expandafter\XINT_flpow_loopI
+ \the\numexpr #1/\xint_c_ii\expandafter.%
+ \the\numexpr\expandafter\XINT_flpow_truncate
+ \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.%
+}%
+\def\XINT_flpow_loopI_odd #1.#2.#3.#4.%
+{%
+ \expandafter\XINT_flpow_loopII
+ \the\numexpr #1/\xint_c_ii-\xint_c_i\expandafter.%
+ \the\numexpr\expandafter\XINT_flpow_truncate
+ \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.#4.#2.#3.%
+}%
+\def\XINT_flpow_loopII #1.%
+{%
+ \ifnum #1 = \xint_c_i\expandafter\XINT_flpow_IItoIII\fi
+ \ifodd #1
+ \expandafter\XINT_flpow_loopII_odd
+ \else
+ \expandafter\XINT_flpow_loopII_even
+ \fi
+ #1.%
+}%
+\def\XINT_flpow_loopII_even #1.#2.#3.%#4.%
+{%
+ \expandafter\XINT_flpow_loopII
+ \the\numexpr #1/\xint_c_ii\expandafter.%
+ \the\numexpr\expandafter\XINT_flpow_truncate
+ \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.%
+}%
+\def\XINT_flpow_loopII_odd #1.#2.#3.#4.#5.#6.%
+{%
+ \expandafter\XINT_flpow_loopII_odda
+ \the\numexpr\expandafter\XINT_flpow_truncate
+ \the\numexpr#2+#5\expandafter.\romannumeral0\xintiimul{#3}{#6}.#4.%
+ #1.#2.#3.%
+}%
+\def\XINT_flpow_loopII_odda #1.#2.#3.#4.#5.#6.%
+{%
+ \expandafter\XINT_flpow_loopII
+ \the\numexpr #4/\xint_c_ii-\xint_c_i\expandafter.%
+ \the\numexpr\expandafter\XINT_flpow_truncate
+ \the\numexpr\xint_c_ii*#5\expandafter.\romannumeral0\xintiisqr{#6}.#3.%
+ #1.#2.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flpow_IItoIII\ifodd #1\fi #2.#3.#4.#5.#6.#7.#8%
+{%
+ \expandafter\XINT_flpow_III\the\numexpr #8+\xint_c_\expandafter.%
+ \the\numexpr\expandafter\XINT_flpow_truncate
+ \the\numexpr#3+#6\expandafter.\romannumeral0\xintiimul{#4}{#7}.#5.%
+}%
+% \end{macrocode}
+% \lverb|This ending is common with \xintFloatPower.
+%
+% In the case of negative exponent we need to inverse the Q-digits mantissa.
+% This requires no special attention now as 1.2k's \xintFloat does correct
+% rounding of fractions hence it is easy to bound the total error. It can be
+% checked that the algorithm after final rounding to the target precision
+% computes a value Z whose distance to the exact theoretical will be less than
+% 0.52 ulp(Z) (and worst cases can only be slightly worse than 0.51 ulp(Z)).
+%
+% In the case of the half-integer exponent (only via the expression
+% interface,) the computation (which proceeds via \XINTinFloatPowerH) ends
+% with a square root. This square root extraction is done with 3 guard digits
+% (the power operations were done with more.) Then the value is rounded to the
+% target precision. There is thus this rounding to 3 guard digits (in the case
+% of negative exponent the reciprocal is computed before the square-root),
+% then the square root is (computed with exact rounding for these 3 guard
+% digits), and then there is the final rounding of this to the target
+% precision. The total error (for positive as well as negative exponent) has
+% been estimated to at worst possibly exceed slightly 0.5125 ulp(Z), and at
+% any rate it is less than 0.52 ulp(Z).|
+% \begin{macrocode}
+\def\XINT_flpow_III #1.#2.#3.#4.#5%
+{%
+ \expandafter\XINT_flpow_IIIend
+ \xint_UDsignfork
+ #5{{1/#3[-#2]}}%
+ -{{#3[#2]}}%
+ \krof #1%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flpow_IIIend #1#2#3%
+ {#3{\if#21\xint_afterfi{\expandafter-\romannumeral`&&@}\fi#1}}%
+% \end{macrocode}
+% \subsection{\csh{xintFloatPower}, \csh{XINTinFloatPower}}
+% \lverb|1.07. The core loop has been re-organized in 1.09j for some slight
+% efficiency gain. The exponent B is given to \xintNum. The ^ in expressions
+% is mapped to this routine.
+%
+% Same modifications as in \xintFloatPow for 1.2f.
+%
+% 1.2f adds a special private macro for allowing half-integral exponents for
+% use with ^ within \xintfloatexpr. The exponent will be first truncated to
+% either an integer or an half-integer. The macro is not for general use.
+%
+% 1.2k does anew this 1.2f handling of half-integer exponents for the
+% \xintfloatexpr parser: with 1.2f's code
+% the final square-root extraction was applied to a value already rounded to
+% the target precision, unneedlessly losing precision.
+% |
+% \begin{macrocode}
+\def\xintFloatPower {\romannumeral0\xintfloatpower}%
+\def\xintfloatpower #1{\XINT_flpower_chkopt \xintfloat #1\xint:}%
+\def\XINTinFloatPower {\romannumeral0\XINTinfloatpower }%
+\def\XINTinfloatpower #1{\XINT_flpower_chkopt \XINTinfloatS #1\xint:}%
+% \end{macrocode}
+% \lverb|First the special macro for use by the expression parser which checks
+% if one raises to an half-integer exponent. This is always with \XINTdigits
+% precision. Rewritten for 1.2k in order for the final square root to keep
+% three guard digits.
+%
+% We have to be careful that exponent #2 is not constrained by TeX bound. And
+% we must allow fractions. The 1.2k variant does a rounding to nearest integer
+% of half-integer, 1.2f did a truncation rather (this is done after truncation
+% of #2 to fixed point with one digit after mark.) We try to recognize quickly
+% the case of integer exponent, for speed, but there is overhead of going
+% through \xintiTrunc1.|
+% \begin{macrocode}
+\def\XINTinFloatPowerH {\romannumeral0\XINTinfloatpowerh }%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINTinfloatpowerh #1#2%
+{%
+ \expandafter\XINT_flpowerh_a\romannumeral0\xintitrunc1{#2};%
+ \XINTdigits.{#1}{\XINTinfloatS[\XINTdigits]}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flpowerh_a #1;%
+{%
+ \if0\xintLDg{#1}\expandafter\XINT_flpowerh_int
+ \else\expandafter\XINT_flpowerh_b
+ \fi #1.%
+}%
+\def\XINT_flpowerh_int #1%
+{%
+ \if0#1\expandafter\XINT_flpower_BisZero
+ \else\expandafter\XINT_flpowerh_i
+ \fi #1%
+}%
+\def\XINT_flpowerh_i #10.{\expandafter\XINT_flpower_checkB_a#1.}%
+\def\XINT_flpowerh_b #1.%
+{%
+ \expandafter\XINT_flpowerh_c\romannumeral0\xintdsrr{\xintDouble{#1}}.%
+}%
+\def\XINT_flpowerh_c #1.%
+{%
+ \ifodd\xintLDg{#1} %<- intentional space
+ \expandafter\XINT_flpowerh_d\else\expandafter\XINT_flpowerh_e
+ \fi #1.%
+}%
+\def\XINT_flpowerh_d #1.\XINTdigits.#2#3%
+{%
+ \XINT_flpower_checkB_a #1.\XINTdigits.{#2}\XINT_flpowerh_finish
+}%
+\def\XINT_flpowerh_finish #1%
+ {\XINTinfloatS[\XINTdigits]{\XINTinFloatSqrt[\XINTdigits+\xint_c_iii]{#1}}}%
+\def\XINT_flpowerh_e #1.%
+ {\expandafter\XINT_flpower_checkB_a\romannumeral0\xinthalf{#1}.}%
+% \end{macrocode}
+% \lverb|Start of macro. Check for optional argument.|
+% \begin{macrocode}
+\def\XINT_flpower_chkopt #1#2%
+{%
+ \ifx [#2\expandafter\XINT_flpower_opt
+ \else\expandafter\XINT_flpower_noopt
+ \fi
+ #1#2%
+}%
+\def\XINT_flpower_noopt #1#2\xint:#3%
+{%
+ \expandafter\XINT_flpower_checkB_a
+ \romannumeral0\xintnum{#3}.\XINTdigits.{#2}{#1[\XINTdigits]}%
+}%
+\def\XINT_flpower_opt #1[\xint:#2]%
+{%
+ \expandafter\XINT_flpower_opt_a\the\numexpr #2.#1%
+}%
+\def\XINT_flpower_opt_a #1.#2#3#4%
+{%
+ \expandafter\XINT_flpower_checkB_a
+ \romannumeral0\xintnum{#4}.#1.{#3}{#2[#1]}%
+}%
+\def\XINT_flpower_checkB_a #1%
+{%
+ \xint_UDzerominusfork
+ #1-{\XINT_flpower_BisZero 0}%
+ 0#1{\XINT_flpower_checkB_b -}%
+ 0-{\XINT_flpower_checkB_b {}#1}%
+ \krof
+}%
+\def\XINT_flpower_BisZero 0.#1.#2#3{#3{1[0]}}%
+\def\XINT_flpower_checkB_b #1#2.#3.%
+{%
+ \expandafter\XINT_flpower_checkB_c
+ \the\numexpr\xintLength{#2}+\xint_c_iii.#3.#2.{#1}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flpower_checkB_c #1.#2.%
+{%
+ \expandafter\XINT_flpower_checkB_d\the\numexpr#1+#2.#1.#2.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flpower_checkB_d #1.#2.#3.#4.#5#6%
+{%
+ \expandafter \XINT_flpower_aa
+ \romannumeral0\XINTinfloat [#3]{#6}{#2}{#1}{#4}{#5}%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flpower_aa #1[#2]#3%
+{%
+ \expandafter\XINT_flpower_ab\the\numexpr #2-#3\expandafter.%
+ \romannumeral\XINT_rep #3\endcsname0.#1.%
+}%
+\def\XINT_flpower_ab #1.#2.#3.{\XINT_flpower_a #3#2[#1]}%
+\def\XINT_flpower_a #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_flpow_zero
+ 0#1{\XINT_flpower_b \iftrue}%
+ 0-{\XINT_flpower_b \iffalse#1}%
+ \krof
+}%
+\def\XINT_flpower_b #1#2[#3]#4#5%
+{%
+ \XINT_flpower_loopI #5.#3.#2.#4.{#1\xintiiOdd{#5}\fi}%
+}%
+\def\XINT_flpower_loopI #1.%
+{%
+ \if1\XINT_isOne {#1}\xint_dothis\XINT_flpower_ItoIII\fi
+ \ifodd\xintLDg{#1} %<- intentional space
+ \xint_dothis{\expandafter\XINT_flpower_loopI_odd}\fi
+ \xint_orthat{\expandafter\XINT_flpower_loopI_even}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \romannumeral0\XINT_half
+ #1\xint_bye\xint_Bye345678\xint_bye
+ *\xint_c_v+\xint_c_v)/\xint_c_x-\xint_c_i\relax.%
+}%
+\def\XINT_flpower_ItoIII #1.#2.#3.#4.#5%
+{%
+ \expandafter\XINT_flpow_III\the\numexpr #5+\xint_c_.#2.#3.#4.%
+}%
+\def\XINT_flpower_loopI_even #1.#2.#3.#4.%
+{%
+ \expandafter\XINT_flpower_toloopI
+ \the\numexpr\expandafter\XINT_flpow_truncate
+ \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.#4.#1.%
+}%
+\def\XINT_flpower_toloopI #1.#2.#3.#4.{\XINT_flpower_loopI #4.#1.#2.#3.}%
+\def\XINT_flpower_loopI_odd #1.#2.#3.#4.%
+{%
+ \expandafter\XINT_flpower_toloopII
+ \the\numexpr\expandafter\XINT_flpow_truncate
+ \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.#4.%
+ #1.#2.#3.%
+}%
+\def\XINT_flpower_toloopII #1.#2.#3.#4.{\XINT_flpower_loopII #4.#1.#2.#3.}%
+\def\XINT_flpower_loopII #1.%
+{%
+ \if1\XINT_isOne{#1}\xint_dothis\XINT_flpower_IItoIII\fi
+ \ifodd\xintLDg{#1} %<- intentional space
+ \xint_dothis{\expandafter\XINT_flpower_loopII_odd}\fi
+ \xint_orthat{\expandafter\XINT_flpower_loopII_even}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+ \romannumeral0\XINT_half#1\xint_bye\xint_Bye345678\xint_bye
+ *\xint_c_v+\xint_c_v)/\xint_c_x-\xint_c_i\relax.%
+}%
+\def\XINT_flpower_loopII_even #1.#2.#3.#4.%
+{%
+ \expandafter\XINT_flpower_toloopII
+ \the\numexpr\expandafter\XINT_flpow_truncate
+ \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.#4.#1.%
+}%
+\def\XINT_flpower_loopII_odd #1.#2.#3.#4.#5.#6.%
+{%
+ \expandafter\XINT_flpower_loopII_odda
+ \the\numexpr\expandafter\XINT_flpow_truncate
+ \the\numexpr#2+#5\expandafter.\romannumeral0\xintiimul{#3}{#6}.#4.%
+ #1.#2.#3.%
+}%
+\def\XINT_flpower_loopII_odda #1.#2.#3.#4.#5.#6.%
+{%
+ \expandafter\XINT_flpower_toloopII
+ \the\numexpr\expandafter\XINT_flpow_truncate
+ \the\numexpr\xint_c_ii*#5\expandafter.\romannumeral0\xintiisqr{#6}.#3.%
+ #4.#1.#2.%
+}%
+\def\XINT_flpower_IItoIII #1.#2.#3.#4.#5.#6.#7%
+{%
+ \expandafter\XINT_flpow_III\the\numexpr #7+\xint_c_\expandafter.%
+ \the\numexpr\expandafter\XINT_flpow_truncate
+ \the\numexpr#2+#5\expandafter.\romannumeral0\xintiimul{#3}{#6}.#4.%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFloatFac}, \csh{XINTFloatFac}}
+% |Done at 1.2. At 1.3e \XINTinFloatFac outputs using \XINTinFloatS.|
+% \begin{macrocode}
+\def\xintFloatFac {\romannumeral0\xintfloatfac}%
+\def\xintfloatfac #1{\XINT_flfac_chkopt \xintfloat #1\xint:}%
+\def\XINTinFloatFac {\romannumeral0\XINTinfloatfac }%
+\def\XINTinfloatfac #1{\XINT_flfac_chkopt \XINTinfloatS #1\xint:}%
+\def\XINT_flfac_chkopt #1#2%
+{%
+ \ifx [#2\expandafter\XINT_flfac_opt
+ \else\expandafter\XINT_flfac_noopt
+ \fi
+ #1#2%
+}%
+\def\XINT_flfac_noopt #1#2\xint:
+{%
+ \expandafter\XINT_FL_fac_fork_a
+ \the\numexpr \xintNum{#2}.\xint_c_i \XINTdigits\XINT_FL_fac_out{#1[\XINTdigits]}%
+}%
+\def\XINT_flfac_opt #1[\xint:#2]%
+{%
+ \expandafter\XINT_flfac_opt_a\the\numexpr #2.#1%
+}%
+\def\XINT_flfac_opt_a #1.#2#3%
+{%
+ \expandafter\XINT_FL_fac_fork_a\the\numexpr \xintNum{#3}.\xint_c_i {#1}\XINT_FL_fac_out{#2[#1]}%
+}%
+\def\XINT_FL_fac_fork_a #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_FL_fac_iszero
+ 0#1\XINT_FL_fac_isneg
+ 0-{\XINT_FL_fac_fork_b #1}%
+ \krof
+}%
+\def\XINT_FL_fac_iszero #1.#2#3#4#5{#5{1[0]}}%
+% \end{macrocode}
+% \lverb|1.2f XINT_FL_fac_isneg returns 0, earlier versions used 1 here.|
+% \begin{macrocode}
+\def\XINT_FL_fac_isneg #1.#2#3#4#5%
+{%
+ #5{\XINT_signalcondition{InvalidOperation}
+ {Factorial of negative: (-#1)!}{}{0[0]}}%
+}%
+\def\XINT_FL_fac_fork_b #1.%
+{%
+ \ifnum #1>\xint_c_x^viii_mone\xint_dothis\XINT_FL_fac_toobig\fi
+ \ifnum #1>\xint_c_x^iv\xint_dothis\XINT_FL_fac_vbig \fi
+ \ifnum #1>465 \xint_dothis\XINT_FL_fac_big\fi
+ \ifnum #1>101 \xint_dothis\XINT_FL_fac_med\fi
+ \xint_orthat\XINT_FL_fac_small
+ #1.%
+}%
+\def\XINT_FL_fac_toobig #1.#2#3#4#5%
+{%
+ #5{\XINT_signalcondition{InvalidOperation}
+ {Factorial of too big: (#1)!}{}{0[0]}}%
+}%
+% \end{macrocode}
+% \lverb?Computations are done with Q blocks of eight digits. When a
+% multiplication has a carry, hence creates Q+1 blocks, the least significant
+% one is dropped. The goal is to compute an approximate value X' to the exact
+% value X, such that the final relative error (X-X')/X will be at most
+% 10^{-P-1} with P the desired precision. Then, when we round X' to X'' with P
+% significant digits, we can prove that the absolute error |X-X''| is bounded
+% (strictly) by 0.6 ulp(X''). (ulp= unit in the last (significant) place). Let
+% N be the number of such operations, the formula for Q deduces from the
+% previous explanations is that 8Q should be at least P+9+k, with k the number
+% of digits of N (in base 10). Note that 1.2 version used P+10+k, for 1.2f I
+% reduced to P+9+k. Also, k should be the number of digits of the number N of
+% multiplications done, hence for n<=10000 we can take N=n/2, or N/3, or N/4.
+% This is rounded above by numexpr and always an overestimate of the actual
+% number of approximate multiplications done (the first ones are exact).
+% (vérifier ce que je raconte, j'ai la flemme là).
+%
+% We then want ceil((P+k+n)/8). Using \numexpr rounding division
+% (ARRRRRGGGHHHH), if m is a positive integer, ceil(m/8) can be computed as
+% (m+3)/8. Thus with m=P+10+k, this gives Q<-(P+13+k)/8. The routine actually
+% computes 8(Q-1) for use in \XINT_FL_fac_addzeros.
+%
+% With 1.2f the formula is m=P+9+k, Q<-(P+12+k)/8, and we use now 4=12-8 rather
+% than the earlier 5=13-8. Whatever happens, the value computed in
+% \XINT_FL_fac_increaseP is at least 8. There will always be an extra block.
+%
+% Note: with Digits:=32; Maple gives for 200!:$bgroup$obeylines$obeyspaces$ttbfamily
+% > factorial(200.);
+% $indent 375
+% $indent 0.78865786736479050355236321393218 10
+% My 1.2f routine (and also 1.2) outputs:
+% $indent 7.8865786736479050355236321393219e374
+% and this is the correct rounding because for 40 digits it computes
+% $indent 7.886578673647905035523632139321850622951e374
+% $egroup
+% Maple's result (contrarily to xint) is thus not the correct rounding but
+% still it is less than 0.6 ulp wrong.
+% ?
+% \begin{macrocode}
+\def\XINT_FL_fac_vbig
+ {\expandafter\XINT_FL_fac_vbigloop_a
+ \the\numexpr \XINT_FL_fac_increaseP \xint_c_i }%
+\def\XINT_FL_fac_big
+ {\expandafter\XINT_FL_fac_bigloop_a
+ \the\numexpr \XINT_FL_fac_increaseP \xint_c_ii }%
+\def\XINT_FL_fac_med
+ {\expandafter\XINT_FL_fac_medloop_a
+ \the\numexpr \XINT_FL_fac_increaseP \xint_c_iii }%
+\def\XINT_FL_fac_small
+ {\expandafter\XINT_FL_fac_smallloop_a
+ \the\numexpr \XINT_FL_fac_increaseP \xint_c_iv }%
+\def\XINT_FL_fac_increaseP #1#2.#3#4%
+{%
+ #2\expandafter.\the\numexpr\xint_c_viii*%
+ ((\xint_c_iv+#4+\expandafter\XINT_FL_fac_countdigits
+ \the\numexpr #2/(#1*#3)\relax 87654321\Z)/\xint_c_viii).%
+}%
+\def\XINT_FL_fac_countdigits #1#2#3#4#5#6#7#8{\XINT_FL_fac_countdone }%
+\def\XINT_FL_fac_countdone #1#2\Z {#1}%
+\def\XINT_FL_fac_out #1;![#2]#3%
+ {#3{\romannumeral0\XINT_mul_out
+ #1;!1\R!1\R!1\R!1\R!%
+ 1\R!1\R!1\R!1\R!\W [#2]}}%
+\def\XINT_FL_fac_vbigloop_a #1.#2.%
+{%
+ \XINT_FL_fac_bigloop_a \xint_c_x^iv.#2.%
+ {\expandafter\XINT_FL_fac_vbigloop_loop\the\numexpr 100010001\expandafter.%
+ \the\numexpr \xint_c_x^viii+#1.}%
+}%
+\def\XINT_FL_fac_vbigloop_loop #1.#2.%
+{%
+ \ifnum #1>#2 \expandafter\XINT_FL_fac_loop_exit\fi
+ \expandafter\XINT_FL_fac_vbigloop_loop
+ \the\numexpr #1+\xint_c_i\expandafter.%
+ \the\numexpr #2\expandafter.\the\numexpr\XINT_FL_fac_mul #1!%
+}%
+\def\XINT_FL_fac_bigloop_a #1.%
+{%
+ \expandafter\XINT_FL_fac_bigloop_b \the\numexpr
+ #1+\xint_c_i-\xint_c_ii*((#1-464)/\xint_c_ii).#1.%
+}%
+\def\XINT_FL_fac_bigloop_b #1.#2.#3.%
+{%
+ \expandafter\XINT_FL_fac_medloop_a
+ \the\numexpr #1-\xint_c_i.#3.{\XINT_FL_fac_bigloop_loop #1.#2.}%
+}%
+\def\XINT_FL_fac_bigloop_loop #1.#2.%
+{%
+ \ifnum #1>#2 \expandafter\XINT_FL_fac_loop_exit\fi
+ \expandafter\XINT_FL_fac_bigloop_loop
+ \the\numexpr #1+\xint_c_ii\expandafter.%
+ \the\numexpr #2\expandafter.\the\numexpr\XINT_FL_fac_bigloop_mul #1!%
+}%
+\def\XINT_FL_fac_bigloop_mul #1!%
+{%
+ \expandafter\XINT_FL_fac_mul
+ \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!%
+}%
+\def\XINT_FL_fac_medloop_a #1.%
+{%
+ \expandafter\XINT_FL_fac_medloop_b
+ \the\numexpr #1+\xint_c_i-\xint_c_iii*((#1-100)/\xint_c_iii).#1.%
+}%
+\def\XINT_FL_fac_medloop_b #1.#2.#3.%
+{%
+ \expandafter\XINT_FL_fac_smallloop_a
+ \the\numexpr #1-\xint_c_i.#3.{\XINT_FL_fac_medloop_loop #1.#2.}%
+}%
+\def\XINT_FL_fac_medloop_loop #1.#2.%
+{%
+ \ifnum #1>#2 \expandafter\XINT_FL_fac_loop_exit\fi
+ \expandafter\XINT_FL_fac_medloop_loop
+ \the\numexpr #1+\xint_c_iii\expandafter.%
+ \the\numexpr #2\expandafter.\the\numexpr\XINT_FL_fac_medloop_mul #1!%
+}%
+\def\XINT_FL_fac_medloop_mul #1!%
+{%
+ \expandafter\XINT_FL_fac_mul
+ \the\numexpr
+ \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!%
+}%
+\def\XINT_FL_fac_smallloop_a #1.%
+{%
+ \csname
+ XINT_FL_fac_smallloop_\the\numexpr #1-\xint_c_iv*(#1/\xint_c_iv)\relax
+ \endcsname #1.%
+}%
+\expandafter\def\csname XINT_FL_fac_smallloop_1\endcsname #1.#2.%
+{%
+ \XINT_FL_fac_addzeros #2.100000001!.{2.#1.}{#2}%
+}%
+\expandafter\def\csname XINT_FL_fac_smallloop_-2\endcsname #1.#2.%
+{%
+ \XINT_FL_fac_addzeros #2.100000002!.{3.#1.}{#2}%
+}%
+\expandafter\def\csname XINT_FL_fac_smallloop_-1\endcsname #1.#2.%
+{%
+ \XINT_FL_fac_addzeros #2.100000006!.{4.#1.}{#2}%
+}%
+\expandafter\def\csname XINT_FL_fac_smallloop_0\endcsname #1.#2.%
+{%
+ \XINT_FL_fac_addzeros #2.100000024!.{5.#1.}{#2}%
+}%
+\def\XINT_FL_fac_addzeros #1.%
+{%
+ \ifnum #1=\xint_c_viii \expandafter\XINT_FL_fac_addzeros_exit\fi
+ \expandafter\XINT_FL_fac_addzeros
+ \the\numexpr #1-\xint_c_viii.100000000!%
+}%
+% \end{macrocode}
+% \lverb|We will manipulate by successive *small* multiplications Q blocks
+% 1<8d>!, terminated by 1;!. We need a custom small multiplication which
+% tells us when it has create a new block, and the least significant one
+% should be dropped.|
+% \begin{macrocode}
+\def\XINT_FL_fac_addzeros_exit #1.#2.#3#4{\XINT_FL_fac_smallloop_loop #3#21;![-#4]}%
+\def\XINT_FL_fac_smallloop_loop #1.#2.%
+{%
+ \ifnum #1>#2 \expandafter\XINT_FL_fac_loop_exit\fi
+ \expandafter\XINT_FL_fac_smallloop_loop
+ \the\numexpr #1+\xint_c_iv\expandafter.%
+ \the\numexpr #2\expandafter.\romannumeral0\XINT_FL_fac_smallloop_mul #1!%
+}%
+\def\XINT_FL_fac_smallloop_mul #1!%
+{%
+ \expandafter\XINT_FL_fac_mul
+ \the\numexpr
+ \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!%
+}%[[
+\def\XINT_FL_fac_loop_exit #1!#2]#3{#3#2]}%
+\def\XINT_FL_fac_mul 1#1!%
+ {\expandafter\XINT_FL_fac_mul_a\the\numexpr\XINT_FL_fac_smallmul 10!{#1}}%
+\def\XINT_FL_fac_mul_a #1-#2%
+{%
+ \if#21\xint_afterfi{\expandafter\space\xint_gob_til_exclam}\else
+ \expandafter\space\fi #11;!%
+}%
+\def\XINT_FL_fac_minimulwc_a #1#2#3#4#5!#6#7#8#9%
+{%
+ \XINT_FL_fac_minimulwc_b {#1#2#3#4}{#5}{#6#7#8#9}%
+}%
+\def\XINT_FL_fac_minimulwc_b #1#2#3#4!#5%
+{%
+ \expandafter\XINT_FL_fac_minimulwc_c
+ \the\numexpr \xint_c_x^ix+#5+#2*#4!{{#1}{#2}{#3}{#4}}%
+}%
+\def\XINT_FL_fac_minimulwc_c 1#1#2#3#4#5#6!#7%
+{%
+ \expandafter\XINT_FL_fac_minimulwc_d {#1#2#3#4#5}#7{#6}%
+}%
+\def\XINT_FL_fac_minimulwc_d #1#2#3#4#5%
+{%
+ \expandafter\XINT_FL_fac_minimulwc_e
+ \the\numexpr \xint_c_x^ix+#1+#2*#5+#3*#4!{#2}{#4}%
+}%
+\def\XINT_FL_fac_minimulwc_e 1#1#2#3#4#5#6!#7#8#9%
+{%
+ 1#6#9\expandafter!%
+ \the\numexpr\expandafter\XINT_FL_fac_smallmul
+ \the\numexpr \xint_c_x^viii+#1#2#3#4#5+#7*#8!%
+}%
+\def\XINT_FL_fac_smallmul 1#1!#21#3!%
+{%
+ \xint_gob_til_sc #3\XINT_FL_fac_smallmul_end;%
+ \XINT_FL_fac_minimulwc_a #2!#3!{#1}{#2}%
+}%
+% \end{macrocode}
+% \lverb|This is the crucial ending. I note that I used here an \ifnum test
+% rather than the gob_til_eightzeroes thing. Actually for eight digits there
+% is much less difference than for only four.
+%
+% The "carry" situation is marked by a final !-1 rather than !-2 for no-carry.
+% (a \numexpr muste be stopped, and leaving a - as delimiter is good as it
+% will not arise earlier.)|
+% \begin{macrocode}
+\def\XINT_FL_fac_smallmul_end;\XINT_FL_fac_minimulwc_a #1!;!#2#3[#4]%
+{%
+ \ifnum #2=\xint_c_
+ \expandafter\xint_firstoftwo\else
+ \expandafter\xint_secondoftwo
+ \fi
+ {-2\relax[#4]}%
+ {1#2\expandafter!\expandafter-\expandafter1\expandafter
+ [\the\numexpr #4+\xint_c_viii]}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFloatPFactorial}, \csh{XINTinFloatPFactorial}}
+% \lverb|2015/11/29 for 1.2f. Partial factorial pfactorial(a,b)=(a+1)...b,
+% only for non-negative integers with a<=b<10^8.
+%
+% 1.2h (2016/11/20) now avoids raising \xintError:OutOfRangePFac if the
+% condition 0<=a<=b<10^8 is violated. Same as for \xintiiPFactorial.|
+% \begin{macrocode}
+\def\xintFloatPFactorial {\romannumeral0\xintfloatpfactorial}%
+\def\xintfloatpfactorial #1{\XINT_flpfac_chkopt \xintfloat #1\xint:}%
+\def\XINTinFloatPFactorial {\romannumeral0\XINTinfloatpfactorial }%
+\def\XINTinfloatpfactorial #1{\XINT_flpfac_chkopt \XINTinfloat #1\xint:}%
+\def\XINT_flpfac_chkopt #1#2%
+{%
+ \ifx [#2\expandafter\XINT_flpfac_opt
+ \else\expandafter\XINT_flpfac_noopt
+ \fi
+ #1#2%
+}%
+\def\XINT_flpfac_noopt #1#2\xint:#3%
+{%
+ \expandafter\XINT_FL_pfac_fork
+ \the\numexpr \xintNum{#2}\expandafter.%
+ \the\numexpr \xintNum{#3}.\xint_c_i{\XINTdigits}{#1[\XINTdigits]}%
+}%
+\def\XINT_flpfac_opt #1[\xint:#2]%
+{%
+ \expandafter\XINT_flpfac_opt_b\the\numexpr #2.#1%
+}%
+\def\XINT_flpfac_opt_b #1.#2#3#4%
+{%
+ \expandafter\XINT_FL_pfac_fork
+ \the\numexpr \xintNum{#3}\expandafter.%
+ \the\numexpr \xintNum{#4}.\xint_c_i{#1}{#2[#1]}%
+}%
+\def\XINT_FL_pfac_fork #1#2.#3#4.%
+{%
+ \unless\ifnum #1#2<#3#4 \xint_dothis\XINT_FL_pfac_one\fi
+ \if-#3\xint_dothis\XINT_FL_pfac_neg \fi
+ \if-#1\xint_dothis\XINT_FL_pfac_zero\fi
+ \ifnum #3#4>\xint_c_x^viii_mone\xint_dothis\XINT_FL_pfac_outofrange\fi
+ \xint_orthat \XINT_FL_pfac_increaseP #1#2.#3#4.%
+}%
+\def\XINT_FL_pfac_outofrange #1.#2.#3#4#5%
+{%
+ #5{\XINT_signalcondition{InvalidOperation}
+ {pfactorial second arg too big: 99999999 < #2}{}{0[0]}}%
+}%
+\def\XINT_FL_pfac_one #1.#2.#3#4#5{#5{1[0]}}%
+\def\XINT_FL_pfac_zero #1.#2.#3#4#5{#5{0[0]}}%
+\def\XINT_FL_pfac_neg -#1.-#2.%
+{%
+ \ifnum #1>\xint_c_x^viii\xint_dothis\XINT_FL_pfac_outofrange\fi
+ \xint_orthat {%
+ \ifodd\numexpr#2-#1\relax\xint_afterfi{\expandafter-\romannumeral`&&@}\fi
+ \expandafter\XINT_FL_pfac_increaseP}%
+ \the\numexpr #2-\xint_c_i\expandafter.\the\numexpr#1-\xint_c_i.%
+}%
+% \end{macrocode}
+% \lverb|See the comments for \XINT_FL_pfac_increaseP. Case of b=a+1 should be
+% filtered out perhaps. We only needed here to copy the \xintPFactorial macros and
+% re-use \XINT_FL_fac_mul/\XINT_FL_fac_out. Had to modify a bit
+% \XINT_FL_pfac_addzeroes. We can enter here directly with #3 equal to specify
+% the precision (the calculated value before final rounding has a relative
+% error less than #3.10^{-#4-1}), and #5 would hold the macro doing the final
+% rounding (or truncating, if I make a FloatTrunc available) to a given number
+% of digits, possibly not #4. By default the #3 is 1, but FloatBinomial calls
+% it with #3=4.|
+% \begin{macrocode}
+\def\XINT_FL_pfac_increaseP #1.#2.#3#4%
+{%
+ \expandafter\XINT_FL_pfac_a
+ \the\numexpr \xint_c_viii*((\xint_c_iv+#4+\expandafter
+ \XINT_FL_fac_countdigits\the\numexpr (#2-#1-\xint_c_i)%
+ /\ifnum #2>\xint_c_x^iv #3\else(#3*\xint_c_ii)\fi\relax
+ 87654321\Z)/\xint_c_viii).#1.#2.%
+}%
+\def\XINT_FL_pfac_a #1.#2.#3.%
+{%
+ \expandafter\XINT_FL_pfac_b\the\numexpr \xint_c_i+#2\expandafter.%
+ \the\numexpr#3\expandafter.%
+ \romannumeral0\XINT_FL_pfac_addzeroes #1.100000001!1;![-#1]%
+}%
+\def\XINT_FL_pfac_addzeroes #1.%
+{%
+ \ifnum #1=\xint_c_viii \expandafter\XINT_FL_pfac_addzeroes_exit\fi
+ \expandafter\XINT_FL_pfac_addzeroes\the\numexpr #1-\xint_c_viii.100000000!%
+}%
+\def\XINT_FL_pfac_addzeroes_exit #1.{ }%
+\def\XINT_FL_pfac_b #1.%
+{%
+ \ifnum #1>9999 \xint_dothis\XINT_FL_pfac_vbigloop \fi
+ \ifnum #1>463 \xint_dothis\XINT_FL_pfac_bigloop \fi
+ \ifnum #1>98 \xint_dothis\XINT_FL_pfac_medloop \fi
+ \xint_orthat\XINT_FL_pfac_smallloop #1.%
+}%
+\def\XINT_FL_pfac_smallloop #1.#2.%
+{%
+ \ifcase\numexpr #2-#1\relax
+ \expandafter\XINT_FL_pfac_end_
+ \or \expandafter\XINT_FL_pfac_end_i
+ \or \expandafter\XINT_FL_pfac_end_ii
+ \or \expandafter\XINT_FL_pfac_end_iii
+ \else\expandafter\XINT_FL_pfac_smallloop_a
+ \fi #1.#2.%
+}%
+\def\XINT_FL_pfac_smallloop_a #1.#2.%
+{%
+ \expandafter\XINT_FL_pfac_smallloop_b
+ \the\numexpr #1+\xint_c_iv\expandafter.%
+ \the\numexpr #2\expandafter.%
+ \romannumeral0\expandafter\XINT_FL_fac_mul
+ \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!%
+}%
+\def\XINT_FL_pfac_smallloop_b #1.%
+{%
+ \ifnum #1>98 \expandafter\XINT_FL_pfac_medloop \else
+ \expandafter\XINT_FL_pfac_smallloop \fi #1.%
+}%
+\def\XINT_FL_pfac_medloop #1.#2.%
+{%
+ \ifcase\numexpr #2-#1\relax
+ \expandafter\XINT_FL_pfac_end_
+ \or \expandafter\XINT_FL_pfac_end_i
+ \or \expandafter\XINT_FL_pfac_end_ii
+ \else\expandafter\XINT_FL_pfac_medloop_a
+ \fi #1.#2.%
+}%
+\def\XINT_FL_pfac_medloop_a #1.#2.%
+{%
+ \expandafter\XINT_FL_pfac_medloop_b
+ \the\numexpr #1+\xint_c_iii\expandafter.%
+ \the\numexpr #2\expandafter.%
+ \romannumeral0\expandafter\XINT_FL_fac_mul
+ \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!%
+}%
+\def\XINT_FL_pfac_medloop_b #1.%
+{%
+ \ifnum #1>463 \expandafter\XINT_FL_pfac_bigloop \else
+ \expandafter\XINT_FL_pfac_medloop \fi #1.%
+}%
+\def\XINT_FL_pfac_bigloop #1.#2.%
+{%
+ \ifcase\numexpr #2-#1\relax
+ \expandafter\XINT_FL_pfac_end_
+ \or \expandafter\XINT_FL_pfac_end_i
+ \else\expandafter\XINT_FL_pfac_bigloop_a
+ \fi #1.#2.%
+}%
+\def\XINT_FL_pfac_bigloop_a #1.#2.%
+{%
+ \expandafter\XINT_FL_pfac_bigloop_b
+ \the\numexpr #1+\xint_c_ii\expandafter.%
+ \the\numexpr #2\expandafter.%
+ \romannumeral0\expandafter\XINT_FL_fac_mul
+ \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!%
+}%
+\def\XINT_FL_pfac_bigloop_b #1.%
+{%
+ \ifnum #1>9999 \expandafter\XINT_FL_pfac_vbigloop \else
+ \expandafter\XINT_FL_pfac_bigloop \fi #1.%
+}%
+\def\XINT_FL_pfac_vbigloop #1.#2.%
+{%
+ \ifnum #2=#1
+ \expandafter\XINT_FL_pfac_end_
+ \else\expandafter\XINT_FL_pfac_vbigloop_a
+ \fi #1.#2.%
+}%
+\def\XINT_FL_pfac_vbigloop_a #1.#2.%
+{%
+ \expandafter\XINT_FL_pfac_vbigloop
+ \the\numexpr #1+\xint_c_i\expandafter.%
+ \the\numexpr #2\expandafter.%
+ \romannumeral0\expandafter\XINT_FL_fac_mul
+ \the\numexpr\xint_c_x^viii+#1!%
+}%
+\def\XINT_FL_pfac_end_iii #1.#2.%
+{%
+ \expandafter\XINT_FL_fac_out
+ \romannumeral0\expandafter\XINT_FL_fac_mul
+ \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!%
+}%
+\def\XINT_FL_pfac_end_ii #1.#2.%
+{%
+ \expandafter\XINT_FL_fac_out
+ \romannumeral0\expandafter\XINT_FL_fac_mul
+ \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!%
+}%
+\def\XINT_FL_pfac_end_i #1.#2.%
+{%
+ \expandafter\XINT_FL_fac_out
+ \romannumeral0\expandafter\XINT_FL_fac_mul
+ \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!%
+}%
+\def\XINT_FL_pfac_end_ #1.#2.%
+{%
+ \expandafter\XINT_FL_fac_out
+ \romannumeral0\expandafter\XINT_FL_fac_mul
+ \the\numexpr \xint_c_x^viii+#1!%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFloatBinomial}, \csh{XINTinFloatBinomial}}
+% \lverb|1.2f. We compute binomial(x,y) as pfac(x-y,x)/y!, where the numerator
+% and denominator are computed with a relative error at most 4.10^{-P-2}, then
+% rounded (once I have a float truncation, I will use truncation rather) to
+% P+3 digits, and finally the quotient is correctly rounded to P digits. This
+% will guarantee that the exact value X differs from the computed one Y by at
+% most 0.6 ulp(Y). (2015/12/01).
+%
+% 2016/11/19 for 1.2h. As for \xintiiBinomial, hard to understand why last
+% year I coded this to raise an error if y<0 or y>x ! The question of the
+% Gamma function is for another occasion, here x and y must be (small)
+% integers.|
+% \begin{macrocode}
+\def\xintFloatBinomial {\romannumeral0\xintfloatbinomial}%
+\def\xintfloatbinomial #1{\XINT_flbinom_chkopt \xintfloat #1\xint:}%
+\def\XINTinFloatBinomial {\romannumeral0\XINTinfloatbinomial }%
+\def\XINTinfloatbinomial #1{\XINT_flbinom_chkopt \XINTinfloat #1\xint:}%
+\def\XINT_flbinom_chkopt #1#2%
+{%
+ \ifx [#2\expandafter\XINT_flbinom_opt
+ \else\expandafter\XINT_flbinom_noopt
+ \fi #1#2%
+}%
+\def\XINT_flbinom_noopt #1#2\xint:#3%
+{%
+ \expandafter\XINT_FL_binom_a
+ \the\numexpr\xintNum{#2}\expandafter.\the\numexpr\xintNum{#3}.\XINTdigits.#1%
+}%
+\def\XINT_flbinom_opt #1[\xint:#2]#3#4%
+{%
+ \expandafter\XINT_FL_binom_a
+ \the\numexpr\xintNum{#3}\expandafter.\the\numexpr\xintNum{#4}\expandafter.%
+ \the\numexpr #2.#1%
+}%
+\def\XINT_FL_binom_a #1.#2.%
+{%
+ \expandafter\XINT_FL_binom_fork \the\numexpr #1-#2.#2.#1.%
+}%
+\def\XINT_FL_binom_fork #1#2.#3#4.#5#6.%
+{%
+ \if-#5\xint_dothis \XINT_FL_binom_neg\fi
+ \if-#1\xint_dothis \XINT_FL_binom_zero\fi
+ \if-#3\xint_dothis \XINT_FL_binom_zero\fi
+ \if0#1\xint_dothis \XINT_FL_binom_one\fi
+ \if0#3\xint_dothis \XINT_FL_binom_one\fi
+ \ifnum #5#6>\xint_c_x^viii_mone \xint_dothis\XINT_FL_binom_toobig\fi
+ \ifnum #1#2>#3#4 \xint_dothis\XINT_FL_binom_ab \fi
+ \xint_orthat\XINT_FL_binom_aa
+ #1#2.#3#4.#5#6.%
+}%
+\def\XINT_FL_binom_neg #1.#2.#3.#4.#5%
+{%
+ #5[#4]{\XINT_signalcondition{InvalidOperation}
+ {binomial with first arg negative: #3}{}{0[0]}}%
+}%
+\def\XINT_FL_binom_toobig #1.#2.#3.#4.#5%
+{%
+ #5[#4]{\XINT_signalcondition{InvalidOperation}
+ {binomial with first arg too big: 99999999 < #3}{}{0[0]}}%
+}%
+\def\XINT_FL_binom_one #1.#2.#3.#4.#5{#5[#4]{1[0]}}%
+\def\XINT_FL_binom_zero #1.#2.#3.#4.#5{#5[#4]{0[0]}}%
+% \end{macrocode}
+% \begin{macrocode}
+\def\XINT_FL_binom_aa #1.#2.#3.#4.#5%
+{%
+ #5[#4]{\xintDiv{\XINT_FL_pfac_increaseP
+ #2.#3.\xint_c_iv{#4+\xint_c_i}{\XINTinfloat[#4+\xint_c_iii]}}%
+ {\XINT_FL_fac_fork_b
+ #1.\xint_c_iv{#4+\xint_c_i}\XINT_FL_fac_out{\XINTinfloat[#4+\xint_c_iii]}}}%
+}%
+\def\XINT_FL_binom_ab #1.#2.#3.#4.#5%
+{%
+ #5[#4]{\xintDiv{\XINT_FL_pfac_increaseP
+ #1.#3.\xint_c_iv{#4+\xint_c_i}{\XINTinfloat[#4+\xint_c_iii]}}%
+ {\XINT_FL_fac_fork_b
+ #2.\xint_c_iv{#4+\xint_c_i}\XINT_FL_fac_out{\XINTinfloat[#4+\xint_c_iii]}}}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFloatSqrt}, \csh{XINTinFloatSqrt}}
+% \lverb|First done for 1.08.
+%
+% The float version was developed at the same time as the integer one and even
+% a bit earlier. As a result the integer variant had some sub-optimal parts.
+% Anyway, for 1.2f I have rewritten the integer variant, and the float variant
+% delegates all preparatory wrok for it until the last step. In particular the
+% very low precisions are not penalized anymore from doing computations for at
+% least 17 or 18 digits. Both the large and small precisions give quite
+% shorter computation times.
+%
+% Also, after examining more closely the achieved precision I decided to
+% extend the float version in order for it to obtain the correct rounding (for
+% inputs already of at most P digits with P the precision) of the theoretical
+% exact value.
+%
+% Beyond about 500 digits of precision the efficiency decreases swiftly,
+% as is the case generally speaking with xintcore/xint/xintfrac arithmetic
+% macros.
+%
+% Final note: with 1.2f the input is always first rounded to P significant
+% places.
+%
+%
+% |
+% \begin{macrocode}
+\def\xintFloatSqrt {\romannumeral0\xintfloatsqrt }%
+\def\xintfloatsqrt #1{\XINT_flsqrt_chkopt \xintfloat #1\xint:}%
+\def\XINTinFloatSqrt {\romannumeral0\XINTinfloatsqrt }%
+\def\XINTinfloatsqrt #1{\XINT_flsqrt_chkopt \XINTinfloat #1\xint:}%
+\def\XINT_flsqrt_chkopt #1#2%
+{%
+ \ifx [#2\expandafter\XINT_flsqrt_opt
+ \else\expandafter\XINT_flsqrt_noopt
+ \fi #1#2%
+}%
+\def\XINT_flsqrt_noopt #1#2\xint:%
+{%
+ \expandafter\XINT_FL_sqrt_a
+ \romannumeral0\XINTinfloat[\XINTdigits]{#2}\XINTdigits.#1%
+}%
+\def\XINT_flsqrt_opt #1[\xint:#2]%#3%
+{%
+ \expandafter\XINT_flsqrt_opt_a\the\numexpr #2.#1%
+}%
+\def\XINT_flsqrt_opt_a #1.#2#3%
+{%
+ \expandafter\XINT_FL_sqrt_a\romannumeral0\XINTinfloat[#1]{#3}#1.#2%
+}%
+\def\XINT_FL_sqrt_a #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_FL_sqrt_iszero
+ 0#1\XINT_FL_sqrt_isneg
+ 0-{\XINT_FL_sqrt_pos #1}%
+ \krof
+}%[
+\def\XINT_FL_sqrt_iszero #1]#2.#3{#3[#2]{0[0]}}%
+\def\XINT_FL_sqrt_isneg #1]#2.#3%
+{%
+ #3[#2]{\XINT_signalcondition{InvalidOperation}
+ {Square root of negative: -#1]}{}{0[0]}}%
+}%
+% \end{macrocode}
+%\lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_FL_sqrt_pos #1[#2]#3.%
+{%
+ \expandafter\XINT_flsqrt
+ \the\numexpr #3\ifodd #2 \xint_dothis {+\xint_c_iii.(#2+\xint_c_i).0}\fi
+ \xint_orthat {+\xint_c_ii.#2.{}}#100.#3.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flsqrt #1.#2.%
+{%
+ \expandafter\XINT_flsqrt_a
+ \the\numexpr #2/\xint_c_ii-(#1-\xint_c_i)/\xint_c_ii.#1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flsqrt_a #1.#2.#3#4.#5.%
+{%
+ \expandafter\XINT_flsqrt_b
+ \the\numexpr (#2-\xint_c_i)/\xint_c_ii\expandafter.%
+ \romannumeral0\XINT_sqrt_start #2.#4#3.#5.#2.#4#3.#5.#1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flsqrt_b #1.#2#3%
+{%
+ \expandafter\XINT_flsqrt_c
+ \romannumeral0\xintiisub
+ {\XINT_dsx_addzeros {#1}#2;}%
+ {\xintiiDivRound{\XINT_dsx_addzeros {#1}#3;}%
+ {\XINT_dbl#2\xint_bye2345678\xint_bye*\xint_c_ii\relax}}.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flsqrt_c #1.#2.%
+{%
+ \expandafter\XINT_flsqrt_d
+ \romannumeral0\XINT_split_fromleft#2.#1\xint_bye2345678\xint_bye..%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flsqrt_d #1.#2#3.%
+{%
+ \ifnum #2=\xint_c_v
+ \expandafter\XINT_flsqrt_f\else\expandafter\XINT_flsqrt_finish\fi
+ #2#3.#1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flsqrt_finish #1#2.#3.#4.#5.#6.#7.#8{#8[#6]{#3#1[#7]}}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flsqrt_f 5#1.%
+ {\expandafter\XINT_flsqrt_g\romannumeral0\xintinum{#1}\relax.}%
+\def\XINT_flsqrt_g #1#2#3.{\if\relax#2\xint_dothis{\XINT_flsqrt_h #1}\fi
+ \xint_orthat{\XINT_flsqrt_finish 5.}}%
+\def\XINT_flsqrt_h #1{\ifnum #1<\xint_c_iii\xint_dothis{\XINT_flsqrt_again}\fi
+ \xint_orthat{\XINT_flsqrt_finish 5.}}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flsqrt_again #1.#2.%
+{%
+ \expandafter\XINT_flsqrt_again_a\the\numexpr #2+\xint_c_viii.%
+}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_flsqrt_again_a #1.#2.#3.%
+{%
+ \expandafter\XINT_flsqrt_b
+ \the\numexpr (#1-\xint_c_i)/\xint_c_ii\expandafter.%
+ \romannumeral0\XINT_sqrt_start #1.#200000000.#3.%
+ #1.#200000000.#3.%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFloatE}, \csh{XINTinFloatE}}
+% \lverb|1.07: The fraction is the first argument contrarily to \xintTrunc and
+% \xintRound.
+%
+% 1.2k had to rewrite this since there is no more a \XINT_float_a macro.
+% Attention about \XINTinFloatE: it is for use by xintexpr.sty, contrarily to
+% other \XINTinFloat<foo> macros it inserts itself the [\XINTdigits] thing,
+% and with value 0 it produces on output 0[N], not 0[0].
+% |
+% \begin{macrocode}
+\def\xintFloatE {\romannumeral0\xintfloate }%
+\def\xintfloate #1{\XINT_floate_chkopt #1\xint:}%
+\def\XINT_floate_chkopt #1%
+{%
+ \ifx [#1\expandafter\XINT_floate_opt
+ \else\expandafter\XINT_floate_noopt
+ \fi #1%
+}%
+\def\XINT_floate_noopt #1\xint:%
+{%
+ \expandafter\XINT_floate_post
+ \romannumeral0\XINTinfloat[\XINTdigits]{#1}\XINTdigits.%
+}%
+\def\XINT_floate_opt [\xint:#1]%
+{%
+ \expandafter\XINT_floate_opt_a\the\numexpr #1.%
+}%
+\def\XINT_floate_opt_a #1.#2%
+{%
+ \expandafter\XINT_floate_post
+ \romannumeral0\XINTinfloat[#1]{#2}#1.%
+}%
+\def\XINT_floate_post #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_floate_zero
+ 0#1\XINT_floate_neg
+ 0-\XINT_floate_pos
+ \krof #1%
+}%[
+\def\XINT_floate_zero #1]#2.#3{ 0.e0}%
+\def\XINT_floate_neg-{\expandafter-\romannumeral0\XINT_floate_pos}%
+% \end{macrocode}
+% \lverb|&
+% |
+% \begin{macrocode}
+\def\XINT_floate_pos #1#2[#3]#4.#5%
+{%
+ \expandafter\XINT_float_pos_done\the\numexpr#3+#4+#5-\xint_c_i.#1.#2;%
+}%
+\def\XINTinFloatE {\romannumeral0\XINTinfloate }%
+\def\XINTinfloate
+ {\expandafter\XINT_infloate\romannumeral0\XINTinfloat[\XINTdigits]}%
+\def\XINT_infloate #1[#2]#3%
+ {\expandafter\XINT_infloate_end\the\numexpr #3+#2.{#1}}%
+\def\XINT_infloate_end #1.#2{ #2[#1]}%
+% \end{macrocode}
+% \subsection{\csh{XINTinFloatMod}}
+% \lverb|1.1. Pour emploi dans xintexpr. Code shortened at 1.2p.|
+% \begin{macrocode}
+\def\XINTinFloatMod {\romannumeral0\XINTinfloatmod [\XINTdigits]}%
+\def\XINTinfloatmod [#1]#2#3%
+{%
+ \XINTinfloat[#1]{\xintMod
+ {\romannumeral0\XINTinfloat[#1]{#2}}%
+ {\romannumeral0\XINTinfloat[#1]{#3}}}%
+}%
+% \end{macrocode}
+% \subsection{\csh{XINTinFloatDivFloor}}
+% \lverb|1.2p. Formerly // and /: in \xintfloatexpr used \xintDivFloor and
+% \xintMod, hence did not round their operands to float precision beforehand.|
+% \begin{macrocode}
+\def\XINTinFloatDivFloor {\romannumeral0\XINTinfloatdivfloor [\XINTdigits]}%
+\def\XINTinfloatdivfloor [#1]#2#3%
+{%
+ \xintdivfloor
+ {\romannumeral0\XINTinfloat[#1]{#2}}%
+ {\romannumeral0\XINTinfloat[#1]{#3}}%
+}%
+% \end{macrocode}
+% \subsection{\csh{XINTinFloatDivMod}}
+% \lverb|1.2p. Pour emploi dans xintexpr, donc je ne prends pas la peine de
+% faire l'expansion du modulo, qui se produira dans le \csname.
+%
+% Hésitation sur le quotient, faut-il l'arrondir immédiatement ?
+% Finalement non, le produire comme un integer.|
+% \begin{macrocode}
+\def\XINTinFloatDivMod {\romannumeral0\XINTinfloatdivmod [\XINTdigits]}%
+\def\XINTinfloatdivmod [#1]#2#3%
+{%
+ \expandafter\XINT_infloatdivmod
+ \romannumeral0\xintdivmod
+ {\romannumeral0\XINTinfloat[#1]{#2}}%
+ {\romannumeral0\XINTinfloat[#1]{#3}}%
+ {#1}%
+}%
+\def\XINT_infloatdivmod #1#2#3{ #1,\XINTinFloat[#3]{#2}}%
+% \end{macrocode}
+% \subsection{\csh{xintifFloatInt}}
+% \lverb|1.3a for ifint() function in \xintfloatexpr.|
+% \begin{macrocode}
+\def\xintifFloatInt {\romannumeral0\xintiffloatint}%
+\def\xintiffloatint #1{\expandafter\XINT_iffloatint
+ \romannumeral0\xintrez{\XINTinFloat[\XINTdigits]{#1}}}%
+\def\XINT_iffloatint #1#2/1[#3]%
+{%
+ \if 0#1\xint_dothis\xint_stop_atfirstoftwo\fi
+ \ifnum#3<\xint_c_\xint_dothis\xint_stop_atsecondoftwo\fi
+ \xint_orthat\xint_stop_atfirstoftwo
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFloatIsInt}}
+% \lverb|1.3d for isint() function in \xintfloatexpr.|
+% \begin{macrocode}
+\def\xintFloatIsInt {\romannumeral0\xintfloatisint}%
+\def\xintfloatisint #1{\expandafter\XINT_iffloatint
+ \romannumeral0\xintrez{\XINTinFloat[\XINTdigits]{#1}}10}%
+% \end{macrocode}
+% \subsection{(WIP) \csh{XINTinRandomFloatS}, \csh{XINTinRandomFloatSdigits}}
+% \lverb|1.3b. Support for random() function.
+%
+% Thus as it is a priori only for xintexpr usage, it expands inside \csname
+% context, but as we need to get rid of initial zeros we use \xintRandomDigits
+% not \xintXRandomDigits (\expanded would have a use case here).
+%
+% And anyway as we want to be able to use random() in
+% \xintdeffunc/\xintNewExpr, it is good to have f-expandable macros, so we add
+% the small overhead to make it f-expandable.
+%
+% We don't have to be very efficient in removing leading zeroes, as there is
+% only 10$%
+% chance for each successive one. Besides we use (current) internal storage
+% format of the type A[N], where A is not required to be with \xintDigits
+% digits, so N will simply be -\xintDigits and needs no adjustment.
+%
+% In case we use in future with #1 something else than \xintDigits we do
+% the 0-(#1) construct.
+%
+% I had some qualms about doing a random float like this which means that
+% when there are leading zeros in the random digits the (virtual) mantissa
+% ends up with trailing zeros. That did not feel right but I checked random()
+% in Python (which of course uses radix 2), and indeed this is what happens
+% there.
+%
+% |
+% \begin{macrocode}
+\def\XINTinRandomFloatS{\romannumeral0\XINTinrandomfloatS}%
+\def\XINTinRandomFloatSdigits{\XINTinRandomFloatS[\XINTdigits]}%
+\def\XINTinrandomfloatS[#1]%
+{%
+ \expandafter\XINT_inrandomfloatS\the\numexpr\xint_c_-(#1)\xint:
+}%
+\def\XINT_inrandomfloatS-#1\xint:
+{%
+ \expandafter\XINT_inrandomfloatS_a
+ \romannumeral0\xintrandomdigits{#1}[-#1]%
+}%
+% \end{macrocode}
+% \lverb|We add one macro to handle a tiny bit faster 90% of cases, after all
+% we also use one extra macro for the completely improbable all 0 case.|
+% \begin{macrocode}
+\def\XINT_inrandomfloatS_a#1%
+{%
+ \if#10\xint_dothis{\XINT_inrandomfloatS_b}\fi
+ \xint_orthat{ #1}%
+}%[
+\def\XINT_inrandomfloatS_b#1%
+{%
+ \if#1[\xint_dothis{\XINT_inrandomfloatS_zero}\fi% ]
+ \if#10\xint_dothis{\XINT_inrandomfloatS_b}\fi
+ \xint_orthat{ #1}%
+}%[
+\def\XINT_inrandomfloatS_zero#1]{ 0[0]}%
+% \end{macrocode}
+% \subsection{(WIP) \csh{XINTinRandomFloatSixteen}}
+% \lverb|1.3b. Support for qrand() function.|
+% \begin{macrocode}
+\def\XINTinRandomFloatSixteen%
+{%
+ \romannumeral0\expandafter\XINT_inrandomfloatS_a
+ \romannumeral`&&@\expandafter\XINT_eightrandomdigits
+ \romannumeral`&&@\XINT_eightrandomdigits[-16]%
+}%
+\XINT_restorecatcodes_endinput%
+% \end{macrocode}
+% \StoreCodelineNo {xintfrac}
+% \cleardoublepage\let\xintfracnameUp\undefined
+%\gardesactifs
+%\let</xintfrac>\relax
+%\let<*xintseries>\gardesinactifs
+%</xintfrac>^^A---------------------------------------------------
+%<*xintseries>^^A-------------------------------------------------
+%^^A -*- coding: utf-8; mode: doctex; -*-
+% \clearpage\csname xintseriesnameUp\endcsname
+% \section{Package \xintseriesnameimp implementation}
+% \RaisedLabel{sec:seriesimp}
+%
+% \localtableofcontents
+%
+% The commenting is currently (\xintdocdate) very sparse.
+%
+% \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{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+ \catcode13=5 % ^^M
+ \endlinechar=13 %
+ \catcode123=1 % {
+ \catcode125=2 % }
+ \catcode64=11 % @
+ \catcode35=6 % #
+ \catcode44=12 % ,
+ \catcode45=12 % -
+ \catcode46=12 % .
+ \catcode58=12 % :
+ \let\z\endgroup
+ \expandafter\let\expandafter\x\csname ver@xintseries.sty\endcsname
+ \expandafter\let\expandafter\w\csname ver@xintfrac.sty\endcsname
+ \expandafter
+ \ifx\csname PackageInfo\endcsname\relax
+ \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}%
+ \else
+ \def\y#1#2{\PackageInfo{#1}{#2}}%
+ \fi
+ \expandafter
+ \ifx\csname numexpr\endcsname\relax
+ \y{xintseries}{\numexpr not available, aborting input}%
+ \aftergroup\endinput
+ \else
+ \ifx\x\relax % plain-TeX, first loading of xintseries.sty
+ \ifx\w\relax % but xintfrac.sty not yet loaded.
+ \def\z{\endgroup\input xintfrac.sty\relax}%
+ \fi
+ \else
+ \def\empty {}%
+ \ifx\x\empty % LaTeX, first loading,
+ % variable is initialized, but \ProvidesPackage not yet seen
+ \ifx\w\relax % xintfrac.sty not yet loaded.
+ \def\z{\endgroup\RequirePackage{xintfrac}}%
+ \fi
+ \else
+ \aftergroup\endinput % xintseries already loaded.
+ \fi
+ \fi
+ \fi
+\z%
+\XINTsetupcatcodes% defined in xintkernel.sty
+% \end{macrocode}
+% \subsection{Package identification}
+% \begin{macrocode}
+\XINT_providespackage
+\ProvidesPackage{xintseries}%
+ [2019/04/05 1.3e Expandable partial sums with xint package (JFB)]%
+% \end{macrocode}
+% \subsection{\csh{xintSeries}}
+% \begin{macrocode}
+\def\xintSeries {\romannumeral0\xintseries }%
+\def\xintseries #1#2%
+{%
+ \expandafter\XINT_series\expandafter
+ {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2}%
+}%
+\def\XINT_series #1#2#3%
+{%
+ \ifnum #2<#1
+ \xint_afterfi { 0/1[0]}%
+ \else
+ \xint_afterfi {\XINT_series_loop {#1}{0}{#2}{#3}}%
+ \fi
+}%
+\def\XINT_series_loop #1#2#3#4%
+{%
+ \ifnum #3>#1 \else \XINT_series_exit \fi
+ \expandafter\XINT_series_loop\expandafter
+ {\the\numexpr #1+1\expandafter }\expandafter
+ {\romannumeral0\xintadd {#2}{#4{#1}}}%
+ {#3}{#4}%
+}%
+\def\XINT_series_exit \fi #1#2#3#4#5#6#7#8%
+{%
+ \fi\xint_gobble_ii #6%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiSeries}}
+% \begin{macrocode}
+\def\xintiSeries {\romannumeral0\xintiseries }%
+\def\xintiseries #1#2%
+{%
+ \expandafter\XINT_iseries\expandafter
+ {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2}%
+}%
+\def\XINT_iseries #1#2#3%
+{%
+ \ifnum #2<#1
+ \xint_afterfi { 0}%
+ \else
+ \xint_afterfi {\XINT_iseries_loop {#1}{0}{#2}{#3}}%
+ \fi
+}%
+\def\XINT_iseries_loop #1#2#3#4%
+{%
+ \ifnum #3>#1 \else \XINT_iseries_exit \fi
+ \expandafter\XINT_iseries_loop\expandafter
+ {\the\numexpr #1+1\expandafter }\expandafter
+ {\romannumeral0\xintiiadd {#2}{#4{#1}}}%
+ {#3}{#4}%
+}%
+\def\XINT_iseries_exit \fi #1#2#3#4#5#6#7#8%
+{%
+ \fi\xint_gobble_ii #6%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintPowerSeries}}
+% \lverb|&
+% The 1.03 version was very lame and created a build-up of denominators.
+% (this was at a time \xintAdd always multiplied denominators, by the way)
+% The Horner scheme for polynomial evaluation is used in 1.04, this
+% cures the denominator problem and drastically improves the efficiency
+% of the macro.
+% Modified in 1.06 to give the indices first to a \numexpr rather than expanding
+% twice. I just use \the\numexpr and maintain the previous code after that.
+% 1.08a adds the forgotten optimization following that previous change.|
+% \begin{macrocode}
+\def\xintPowerSeries {\romannumeral0\xintpowerseries }%
+\def\xintpowerseries #1#2%
+{%
+ \expandafter\XINT_powseries\expandafter
+ {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2}%
+}%
+\def\XINT_powseries #1#2#3#4%
+{%
+ \ifnum #2<#1
+ \xint_afterfi { 0/1[0]}%
+ \else
+ \xint_afterfi
+ {\XINT_powseries_loop_i {#3{#2}}{#1}{#2}{#3}{#4}}%
+ \fi
+}%
+\def\XINT_powseries_loop_i #1#2#3#4#5%
+{%
+ \ifnum #3>#2 \else\XINT_powseries_exit_i\fi
+ \expandafter\XINT_powseries_loop_ii\expandafter
+ {\the\numexpr #3-1\expandafter}\expandafter
+ {\romannumeral0\xintmul {#1}{#5}}{#2}{#4}{#5}%
+}%
+\def\XINT_powseries_loop_ii #1#2#3#4%
+{%
+ \expandafter\XINT_powseries_loop_i\expandafter
+ {\romannumeral0\xintadd {#4{#1}}{#2}}{#3}{#1}{#4}%
+}%
+\def\XINT_powseries_exit_i\fi #1#2#3#4#5#6#7#8#9%
+{%
+ \fi \XINT_powseries_exit_ii #6{#7}%
+}%
+\def\XINT_powseries_exit_ii #1#2#3#4#5#6%
+{%
+ \xintmul{\xintPow {#5}{#6}}{#4}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintPowerSeriesX}}
+% \lverb|&
+% Same as \xintPowerSeries except for the initial expansion of the x parameter.
+% Modified in 1.06 to give the indices first to a \numexpr rather than expanding
+% twice. I just use \the\numexpr and maintain the previous code after that.
+% 1.08a adds the forgotten optimization following that previous change.|
+% \begin{macrocode}
+\def\xintPowerSeriesX {\romannumeral0\xintpowerseriesx }%
+\def\xintpowerseriesx #1#2%
+{%
+ \expandafter\XINT_powseriesx\expandafter
+ {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2}%
+}%
+\def\XINT_powseriesx #1#2#3#4%
+{%
+ \ifnum #2<#1
+ \xint_afterfi { 0/1[0]}%
+ \else
+ \xint_afterfi
+ {\expandafter\XINT_powseriesx_pre\expandafter
+ {\romannumeral`&&@#4}{#1}{#2}{#3}%
+ }%
+ \fi
+}%
+\def\XINT_powseriesx_pre #1#2#3#4%
+{%
+ \XINT_powseries_loop_i {#4{#3}}{#2}{#3}{#4}{#1}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintRationalSeries}}
+% \lverb|&
+% This computes F(a)+...+F(b) on the basis of the value of F(a) and the
+% ratios F(n)/F(n-1). As in \xintPowerSeries we use an iterative scheme which
+% has the great advantage to avoid denominator build-up. This makes exact
+% computations possible with exponential type series, which would be completely
+% inaccessible to \xintSeries.
+% #1=a, #2=b, #3=F(a), #4=ratio function
+% Modified in 1.06 to give the indices first to a \numexpr rather than expanding
+% twice. I just use \the\numexpr and maintain the previous code after that.
+% 1.08a adds the forgotten optimization following that previous change.|
+% \begin{macrocode}
+\def\xintRationalSeries {\romannumeral0\xintratseries }%
+\def\xintratseries #1#2%
+{%
+ \expandafter\XINT_ratseries\expandafter
+ {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2}%
+}%
+\def\XINT_ratseries #1#2#3#4%
+{%
+ \ifnum #2<#1
+ \xint_afterfi { 0/1[0]}%
+ \else
+ \xint_afterfi
+ {\XINT_ratseries_loop {#2}{1}{#1}{#4}{#3}}%
+ \fi
+}%
+\def\XINT_ratseries_loop #1#2#3#4%
+{%
+ \ifnum #1>#3 \else\XINT_ratseries_exit_i\fi
+ \expandafter\XINT_ratseries_loop\expandafter
+ {\the\numexpr #1-1\expandafter}\expandafter
+ {\romannumeral0\xintadd {1}{\xintMul {#2}{#4{#1}}}}{#3}{#4}%
+}%
+\def\XINT_ratseries_exit_i\fi #1#2#3#4#5#6#7#8%
+{%
+ \fi \XINT_ratseries_exit_ii #6%
+}%
+\def\XINT_ratseries_exit_ii #1#2#3#4#5%
+{%
+ \XINT_ratseries_exit_iii #5%
+}%
+\def\XINT_ratseries_exit_iii #1#2#3#4%
+{%
+ \xintmul{#2}{#4}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintRationalSeriesX}}
+% \lverb|&
+% a,b,initial,ratiofunction,x$\
+% This computes F(a,x)+...+F(b,x) on the basis of the value of F(a,x) and the
+% ratios F(n,x)/F(n-1,x). The argument x is first expanded and it is the value
+% resulting from this which is used then throughout. The initial term F(a,x)
+% must be defined as one-parameter macro which will be given x.
+% Modified in 1.06 to give the indices first to a \numexpr rather than expanding
+% twice. I just use \the\numexpr and maintain the previous code after that.
+% 1.08a adds the forgotten optimization following that previous change.|
+% \begin{macrocode}
+\def\xintRationalSeriesX {\romannumeral0\xintratseriesx }%
+\def\xintratseriesx #1#2%
+{%
+ \expandafter\XINT_ratseriesx\expandafter
+ {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2}%
+}%
+\def\XINT_ratseriesx #1#2#3#4#5%
+{%
+ \ifnum #2<#1
+ \xint_afterfi { 0/1[0]}%
+ \else
+ \xint_afterfi
+ {\expandafter\XINT_ratseriesx_pre\expandafter
+ {\romannumeral`&&@#5}{#2}{#1}{#4}{#3}%
+ }%
+ \fi
+}%
+\def\XINT_ratseriesx_pre #1#2#3#4#5%
+{%
+ \XINT_ratseries_loop {#2}{1}{#3}{#4{#1}}{#5{#1}}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFxPtPowerSeries}}
+% \lverb|&
+% I am not two happy with this piece of code. Will make it more economical
+% another day.
+% Modified in 1.06 to give the indices first to a \numexpr rather than expanding
+% twice. I just use \the\numexpr and maintain the previous code after that.
+% 1.08a: forgot last time some optimization from the change to \numexpr.|
+% \begin{macrocode}
+\def\xintFxPtPowerSeries {\romannumeral0\xintfxptpowerseries }%
+\def\xintfxptpowerseries #1#2%
+{%
+ \expandafter\XINT_fppowseries\expandafter
+ {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2}%
+}%
+\def\XINT_fppowseries #1#2#3#4#5%
+{%
+ \ifnum #2<#1
+ \xint_afterfi { 0}%
+ \else
+ \xint_afterfi
+ {\expandafter\XINT_fppowseries_loop_pre\expandafter
+ {\romannumeral0\xinttrunc {#5}{\xintPow {#4}{#1}}}%
+ {#1}{#4}{#2}{#3}{#5}%
+ }%
+ \fi
+}%
+\def\XINT_fppowseries_loop_pre #1#2#3#4#5#6%
+{%
+ \ifnum #4>#2 \else\XINT_fppowseries_dont_i \fi
+ \expandafter\XINT_fppowseries_loop_i\expandafter
+ {\the\numexpr #2+\xint_c_i\expandafter}\expandafter
+ {\romannumeral0\xintitrunc {#6}{\xintMul {#5{#2}}{#1}}}%
+ {#1}{#3}{#4}{#5}{#6}%
+}%
+\def\XINT_fppowseries_dont_i \fi\expandafter\XINT_fppowseries_loop_i
+ {\fi \expandafter\XINT_fppowseries_dont_ii }%
+\def\XINT_fppowseries_dont_ii #1#2#3#4#5#6#7{\xinttrunc {#7}{#2[-#7]}}%
+\def\XINT_fppowseries_loop_i #1#2#3#4#5#6#7%
+{%
+ \ifnum #5>#1 \else \XINT_fppowseries_exit_i \fi
+ \expandafter\XINT_fppowseries_loop_ii\expandafter
+ {\romannumeral0\xinttrunc {#7}{\xintMul {#3}{#4}}}%
+ {#1}{#4}{#2}{#5}{#6}{#7}%
+}%
+\def\XINT_fppowseries_loop_ii #1#2#3#4#5#6#7%
+{%
+ \expandafter\XINT_fppowseries_loop_i\expandafter
+ {\the\numexpr #2+\xint_c_i\expandafter}\expandafter
+ {\romannumeral0\xintiiadd {#4}{\xintiTrunc {#7}{\xintMul {#6{#2}}{#1}}}}%
+ {#1}{#3}{#5}{#6}{#7}%
+}%
+\def\XINT_fppowseries_exit_i\fi\expandafter\XINT_fppowseries_loop_ii
+ {\fi \expandafter\XINT_fppowseries_exit_ii }%
+\def\XINT_fppowseries_exit_ii #1#2#3#4#5#6#7%
+{%
+ \xinttrunc {#7}
+ {\xintiiadd {#4}{\xintiTrunc {#7}{\xintMul {#6{#2}}{#1}}}[-#7]}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFxPtPowerSeriesX}}
+% \lverb|&
+% a,b,coeff,x,D$\
+% Modified in 1.06 to give the indices first to a \numexpr rather than expanding
+% twice. I just use \the\numexpr and maintain the previous code after that.
+% 1.08a adds the forgotten optimization following that previous change.|
+% \begin{macrocode}
+\def\xintFxPtPowerSeriesX {\romannumeral0\xintfxptpowerseriesx }%
+\def\xintfxptpowerseriesx #1#2%
+{%
+ \expandafter\XINT_fppowseriesx\expandafter
+ {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2}%
+}%
+\def\XINT_fppowseriesx #1#2#3#4#5%
+{%
+ \ifnum #2<#1
+ \xint_afterfi { 0}%
+ \else
+ \xint_afterfi
+ {\expandafter \XINT_fppowseriesx_pre \expandafter
+ {\romannumeral`&&@#4}{#1}{#2}{#3}{#5}%
+ }%
+ \fi
+}%
+\def\XINT_fppowseriesx_pre #1#2#3#4#5%
+{%
+ \expandafter\XINT_fppowseries_loop_pre\expandafter
+ {\romannumeral0\xinttrunc {#5}{\xintPow {#1}{#2}}}%
+ {#2}{#1}{#3}{#4}{#5}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFloatPowerSeries}}
+% \lverb|1.08a. I still have to re-visit \xintFxPtPowerSeries; temporarily I
+% just adapted the code to the case of floats.|
+% \begin{macrocode}
+\def\xintFloatPowerSeries {\romannumeral0\xintfloatpowerseries }%
+\def\xintfloatpowerseries #1{\XINT_flpowseries_chkopt #1\xint:}%
+\def\XINT_flpowseries_chkopt #1%
+{%
+ \ifx [#1\expandafter\XINT_flpowseries_opt
+ \else\expandafter\XINT_flpowseries_noopt
+ \fi
+ #1%
+}%
+\def\XINT_flpowseries_noopt #1\xint:#2%
+{%
+ \expandafter\XINT_flpowseries\expandafter
+ {\the\numexpr #1\expandafter}\expandafter
+ {\the\numexpr #2}\XINTdigits
+}%
+\def\XINT_flpowseries_opt [\xint:#1]#2#3%
+{%
+ \expandafter\XINT_flpowseries\expandafter
+ {\the\numexpr #2\expandafter}\expandafter
+ {\the\numexpr #3\expandafter}{\the\numexpr #1}%
+}%
+\def\XINT_flpowseries #1#2#3#4#5%
+{%
+ \ifnum #2<#1
+ \xint_afterfi { 0.e0}%
+ \else
+ \xint_afterfi
+ {\expandafter\XINT_flpowseries_loop_pre\expandafter
+ {\romannumeral0\XINTinfloatpow [#3]{#5}{#1}}%
+ {#1}{#5}{#2}{#4}{#3}%
+ }%
+ \fi
+}%
+\def\XINT_flpowseries_loop_pre #1#2#3#4#5#6%
+{%
+ \ifnum #4>#2 \else\XINT_flpowseries_dont_i \fi
+ \expandafter\XINT_flpowseries_loop_i\expandafter
+ {\the\numexpr #2+\xint_c_i\expandafter}\expandafter
+ {\romannumeral0\XINTinfloatmul [#6]{#5{#2}}{#1}}%
+ {#1}{#3}{#4}{#5}{#6}%
+}%
+\def\XINT_flpowseries_dont_i \fi\expandafter\XINT_flpowseries_loop_i
+ {\fi \expandafter\XINT_flpowseries_dont_ii }%
+\def\XINT_flpowseries_dont_ii #1#2#3#4#5#6#7{\xintfloat [#7]{#2}}%
+\def\XINT_flpowseries_loop_i #1#2#3#4#5#6#7%
+{%
+ \ifnum #5>#1 \else \XINT_flpowseries_exit_i \fi
+ \expandafter\XINT_flpowseries_loop_ii\expandafter
+ {\romannumeral0\XINTinfloatmul [#7]{#3}{#4}}%
+ {#1}{#4}{#2}{#5}{#6}{#7}%
+}%
+\def\XINT_flpowseries_loop_ii #1#2#3#4#5#6#7%
+{%
+ \expandafter\XINT_flpowseries_loop_i\expandafter
+ {\the\numexpr #2+\xint_c_i\expandafter}\expandafter
+ {\romannumeral0\XINTinfloatadd [#7]{#4}%
+ {\XINTinfloatmul [#7]{#6{#2}}{#1}}}%
+ {#1}{#3}{#5}{#6}{#7}%
+}%
+\def\XINT_flpowseries_exit_i\fi\expandafter\XINT_flpowseries_loop_ii
+ {\fi \expandafter\XINT_flpowseries_exit_ii }%
+\def\XINT_flpowseries_exit_ii #1#2#3#4#5#6#7%
+{%
+ \xintfloatadd [#7]{#4}{\XINTinfloatmul [#7]{#6{#2}}{#1}}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFloatPowerSeriesX}}
+% \lverb|1.08a|
+% \begin{macrocode}
+\def\xintFloatPowerSeriesX {\romannumeral0\xintfloatpowerseriesx }%
+\def\xintfloatpowerseriesx #1{\XINT_flpowseriesx_chkopt #1\xint:}%
+\def\XINT_flpowseriesx_chkopt #1%
+{%
+ \ifx [#1\expandafter\XINT_flpowseriesx_opt
+ \else\expandafter\XINT_flpowseriesx_noopt
+ \fi
+ #1%
+}%
+\def\XINT_flpowseriesx_noopt #1\xint:#2%
+{%
+ \expandafter\XINT_flpowseriesx\expandafter
+ {\the\numexpr #1\expandafter}\expandafter
+ {\the\numexpr #2}\XINTdigits
+}%
+\def\XINT_flpowseriesx_opt [\xint:#1]#2#3%
+{%
+ \expandafter\XINT_flpowseriesx\expandafter
+ {\the\numexpr #2\expandafter}\expandafter
+ {\the\numexpr #3\expandafter}{\the\numexpr #1}%
+}%
+\def\XINT_flpowseriesx #1#2#3#4#5%
+{%
+ \ifnum #2<#1
+ \xint_afterfi { 0.e0}%
+ \else
+ \xint_afterfi
+ {\expandafter \XINT_flpowseriesx_pre \expandafter
+ {\romannumeral`&&@#5}{#1}{#2}{#4}{#3}%
+ }%
+ \fi
+}%
+\def\XINT_flpowseriesx_pre #1#2#3#4#5%
+{%
+ \expandafter\XINT_flpowseries_loop_pre\expandafter
+ {\romannumeral0\XINTinfloatpow [#5]{#1}{#2}}%
+ {#2}{#1}{#3}{#4}{#5}%
+}%
+\XINT_restorecatcodes_endinput%
+% \end{macrocode}
+% \StoreCodelineNo {xintseries}
+% \cleardoublepage\let\xintseriesnameUp\undefined
+%\gardesactifs
+%\let</xintseries>\relax
+%\let<*xintcfrac>\gardesinactifs
+%</xintseries>^^A-------------------------------------------------
+%<*xintcfrac>^^A--------------------------------------------------
+%^^A -*- coding: utf-8; mode: doctex; -*-
+% \clearpage\csname xintcfracnameUp\endcsname
+% \section{Package \xintcfracnameimp implementation}
+% \RaisedLabel{sec:cfracimp}
+%
+% \localtableofcontents
+%
+% The commenting is currently (\xintdocdate) very sparse. Release |1.09m|
+% (|2014/02/26|) has modified a few things: |\xintFtoCs| and
+% |\xintCntoCs| insert spaces after the commas, |\xintCstoF| and
+% |\xintCstoCv| authorize spaces in the input also before the commas,
+% |\xintCntoCs| does not brace the produced coefficients, new macros
+% |\xintFtoC|, |\xintCtoF|, |\xintCtoCv|, |\xintFGtoC|, and
+% |\xintGGCFrac|.
+%
+% There is partial dependency on \xinttoolsnameimp due to |\xintCstoF| and
+% |\xintCsToCv|.
+%
+% \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{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+ \catcode13=5 % ^^M
+ \endlinechar=13 %
+ \catcode123=1 % {
+ \catcode125=2 % }
+ \catcode64=11 % @
+ \catcode35=6 % #
+ \catcode44=12 % ,
+ \catcode45=12 % -
+ \catcode46=12 % .
+ \catcode58=12 % :
+ \let\z\endgroup
+ \expandafter\let\expandafter\x\csname ver@xintcfrac.sty\endcsname
+ \expandafter\let\expandafter\w\csname ver@xintfrac.sty\endcsname
+ \expandafter
+ \ifx\csname PackageInfo\endcsname\relax
+ \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}%
+ \else
+ \def\y#1#2{\PackageInfo{#1}{#2}}%
+ \fi
+ \expandafter
+ \ifx\csname numexpr\endcsname\relax
+ \y{xintcfrac}{\numexpr not available, aborting input}%
+ \aftergroup\endinput
+ \else
+ \ifx\x\relax % plain-TeX, first loading of xintcfrac.sty
+ \ifx\w\relax % but xintfrac.sty not yet loaded.
+ \def\z{\endgroup\input xintfrac.sty\relax}%
+ \fi
+ \else
+ \def\empty {}%
+ \ifx\x\empty % LaTeX, first loading,
+ % variable is initialized, but \ProvidesPackage not yet seen
+ \ifx\w\relax % xintfrac.sty not yet loaded.
+ \def\z{\endgroup\RequirePackage{xintfrac}}%
+ \fi
+ \else
+ \aftergroup\endinput % xintcfrac already loaded.
+ \fi
+ \fi
+ \fi
+\z%
+\XINTsetupcatcodes% defined in xintkernel.sty
+% \end{macrocode}
+% \subsection{Package identification}
+% \begin{macrocode}
+\XINT_providespackage
+\ProvidesPackage{xintcfrac}%
+ [2019/04/05 1.3e Expandable continued fractions with xint package (JFB)]%
+% \end{macrocode}
+% \subsection{\csh{xintCFrac}}
+% \begin{macrocode}
+\def\xintCFrac {\romannumeral0\xintcfrac }%
+\def\xintcfrac #1%
+{%
+ \XINT_cfrac_opt_a #1\xint:
+}%
+\def\XINT_cfrac_opt_a #1%
+{%
+ \ifx[#1\XINT_cfrac_opt_b\fi \XINT_cfrac_noopt #1%
+}%
+\def\XINT_cfrac_noopt #1\xint:
+{%
+ \expandafter\XINT_cfrac_A\romannumeral0\xintrawwithzeros {#1}\Z
+ \relax\relax
+}%
+\def\XINT_cfrac_opt_b\fi\XINT_cfrac_noopt [\xint:#1]%
+{%
+ \fi\csname XINT_cfrac_opt#1\endcsname
+}%
+\def\XINT_cfrac_optl #1%
+{%
+ \expandafter\XINT_cfrac_A\romannumeral0\xintrawwithzeros {#1}\Z
+ \relax\hfill
+}%
+\def\XINT_cfrac_optc #1%
+{%
+ \expandafter\XINT_cfrac_A\romannumeral0\xintrawwithzeros {#1}\Z
+ \relax\relax
+}%
+\def\XINT_cfrac_optr #1%
+{%
+ \expandafter\XINT_cfrac_A\romannumeral0\xintrawwithzeros {#1}\Z
+ \hfill\relax
+}%
+\def\XINT_cfrac_A #1/#2\Z
+{%
+ \expandafter\XINT_cfrac_B\romannumeral0\xintiidivision {#1}{#2}{#2}%
+}%
+\def\XINT_cfrac_B #1#2%
+{%
+ \XINT_cfrac_C #2\Z {#1}%
+}%
+\def\XINT_cfrac_C #1%
+{%
+ \xint_gob_til_zero #1\XINT_cfrac_integer 0\XINT_cfrac_D #1%
+}%
+\def\XINT_cfrac_integer 0\XINT_cfrac_D 0#1\Z #2#3#4#5{ #2}%
+\def\XINT_cfrac_D #1\Z #2#3{\XINT_cfrac_loop_a {#1}{#3}{#1}{{#2}}}%
+\def\XINT_cfrac_loop_a
+{%
+ \expandafter\XINT_cfrac_loop_d\romannumeral0\XINT_div_prepare
+}%
+\def\XINT_cfrac_loop_d #1#2%
+{%
+ \XINT_cfrac_loop_e #2.{#1}%
+}%
+\def\XINT_cfrac_loop_e #1%
+{%
+ \xint_gob_til_zero #1\xint_cfrac_loop_exit0\XINT_cfrac_loop_f #1%
+}%
+\def\XINT_cfrac_loop_f #1.#2#3#4%
+{%
+ \XINT_cfrac_loop_a {#1}{#3}{#1}{{#2}#4}%
+}%
+\def\xint_cfrac_loop_exit0\XINT_cfrac_loop_f #1.#2#3#4#5#6%
+ {\XINT_cfrac_T #5#6{#2}#4\Z }%
+\def\XINT_cfrac_T #1#2#3#4%
+{%
+ \xint_gob_til_Z #4\XINT_cfrac_end\Z\XINT_cfrac_T #1#2{#4+\cfrac{#11#2}{#3}}%
+}%
+\def\XINT_cfrac_end\Z\XINT_cfrac_T #1#2#3%
+{%
+ \XINT_cfrac_end_b #3%
+}%
+\def\XINT_cfrac_end_b \Z+\cfrac#1#2{ #2}%
+% \end{macrocode}
+% \subsection{\csh{xintGCFrac}}
+% \begin{macrocode}
+\def\xintGCFrac {\romannumeral0\xintgcfrac }%
+\def\xintgcfrac #1{\XINT_gcfrac_opt_a #1\xint:}%
+\def\XINT_gcfrac_opt_a #1%
+{%
+ \ifx[#1\XINT_gcfrac_opt_b\fi \XINT_gcfrac_noopt #1%
+}%
+\def\XINT_gcfrac_noopt #1\xint:%
+{%
+ \XINT_gcfrac #1+!/\relax\relax
+}%
+\def\XINT_gcfrac_opt_b\fi\XINT_gcfrac_noopt [\xint:#1]%
+{%
+ \fi\csname XINT_gcfrac_opt#1\endcsname
+}%
+\def\XINT_gcfrac_optl #1%
+{%
+ \XINT_gcfrac #1+!/\relax\hfill
+}%
+\def\XINT_gcfrac_optc #1%
+{%
+ \XINT_gcfrac #1+!/\relax\relax
+}%
+\def\XINT_gcfrac_optr #1%
+{%
+ \XINT_gcfrac #1+!/\hfill\relax
+}%
+\def\XINT_gcfrac
+{%
+ \expandafter\XINT_gcfrac_enter\romannumeral`&&@%
+}%
+\def\XINT_gcfrac_enter {\XINT_gcfrac_loop {}}%
+\def\XINT_gcfrac_loop #1#2+#3/%
+{%
+ \xint_gob_til_exclam #3\XINT_gcfrac_endloop!%
+ \XINT_gcfrac_loop {{#3}{#2}#1}%
+}%
+\def\XINT_gcfrac_endloop!\XINT_gcfrac_loop #1#2#3%
+{%
+ \XINT_gcfrac_T #2#3#1!!%
+}%
+\def\XINT_gcfrac_T #1#2#3#4{\XINT_gcfrac_U #1#2{\xintFrac{#4}}}%
+\def\XINT_gcfrac_U #1#2#3#4#5%
+{%
+ \xint_gob_til_exclam #5\XINT_gcfrac_end!\XINT_gcfrac_U
+ #1#2{\xintFrac{#5}%
+ \ifcase\xintSgn{#4}
+ +\or+\else-\fi
+ \cfrac{#1\xintFrac{\xintAbs{#4}}#2}{#3}}%
+}%
+\def\XINT_gcfrac_end!\XINT_gcfrac_U #1#2#3%
+{%
+ \XINT_gcfrac_end_b #3%
+}%
+\def\XINT_gcfrac_end_b #1\cfrac#2#3{ #3}%
+% \end{macrocode}
+% \subsection{\csh{xintGGCFrac}}
+% \lverb|New with 1.09m|
+% \begin{macrocode}
+\def\xintGGCFrac {\romannumeral0\xintggcfrac }%
+\def\xintggcfrac #1{\XINT_ggcfrac_opt_a #1\xint:}%
+\def\XINT_ggcfrac_opt_a #1%
+{%
+ \ifx[#1\XINT_ggcfrac_opt_b\fi \XINT_ggcfrac_noopt #1%
+}%
+\def\XINT_ggcfrac_noopt #1\xint:
+{%
+ \XINT_ggcfrac #1+!/\relax\relax
+}%
+\def\XINT_ggcfrac_opt_b\fi\XINT_ggcfrac_noopt [\xint:#1]%
+{%
+ \fi\csname XINT_ggcfrac_opt#1\endcsname
+}%
+\def\XINT_ggcfrac_optl #1%
+{%
+ \XINT_ggcfrac #1+!/\relax\hfill
+}%
+\def\XINT_ggcfrac_optc #1%
+{%
+ \XINT_ggcfrac #1+!/\relax\relax
+}%
+\def\XINT_ggcfrac_optr #1%
+{%
+ \XINT_ggcfrac #1+!/\hfill\relax
+}%
+\def\XINT_ggcfrac
+{%
+ \expandafter\XINT_ggcfrac_enter\romannumeral`&&@%
+}%
+\def\XINT_ggcfrac_enter {\XINT_ggcfrac_loop {}}%
+\def\XINT_ggcfrac_loop #1#2+#3/%
+{%
+ \xint_gob_til_exclam #3\XINT_ggcfrac_endloop!%
+ \XINT_ggcfrac_loop {{#3}{#2}#1}%
+}%
+\def\XINT_ggcfrac_endloop!\XINT_ggcfrac_loop #1#2#3%
+{%
+ \XINT_ggcfrac_T #2#3#1!!%
+}%
+\def\XINT_ggcfrac_T #1#2#3#4{\XINT_ggcfrac_U #1#2{#4}}%
+\def\XINT_ggcfrac_U #1#2#3#4#5%
+{%
+ \xint_gob_til_exclam #5\XINT_ggcfrac_end!\XINT_ggcfrac_U
+ #1#2{#5+\cfrac{#1#4#2}{#3}}%
+}%
+\def\XINT_ggcfrac_end!\XINT_ggcfrac_U #1#2#3%
+{%
+ \XINT_ggcfrac_end_b #3%
+}%
+\def\XINT_ggcfrac_end_b #1\cfrac#2#3{ #3}%
+% \end{macrocode}
+% \subsection{\csh{xintGCtoGCx}}
+% \begin{macrocode}
+\def\xintGCtoGCx {\romannumeral0\xintgctogcx }%
+\def\xintgctogcx #1#2#3%
+{%
+ \expandafter\XINT_gctgcx_start\expandafter {\romannumeral`&&@#3}{#1}{#2}%
+}%
+\def\XINT_gctgcx_start #1#2#3{\XINT_gctgcx_loop_a {}{#2}{#3}#1+!/}%
+\def\XINT_gctgcx_loop_a #1#2#3#4+#5/%
+{%
+ \xint_gob_til_exclam #5\XINT_gctgcx_end!%
+ \XINT_gctgcx_loop_b {#1{#4}}{#2{#5}#3}{#2}{#3}%
+}%
+\def\XINT_gctgcx_loop_b #1#2%
+{%
+ \XINT_gctgcx_loop_a {#1#2}%
+}%
+\def\XINT_gctgcx_end!\XINT_gctgcx_loop_b #1#2#3#4{ #1}%
+% \end{macrocode}
+% \subsection{\csh{xintFtoCs}}
+% \lverb|Modified in 1.09m: a space is added after the inserted commas.|
+% \begin{macrocode}
+\def\xintFtoCs {\romannumeral0\xintftocs }%
+\def\xintftocs #1%
+{%
+ \expandafter\XINT_ftc_A\romannumeral0\xintrawwithzeros {#1}\Z
+}%
+\def\XINT_ftc_A #1/#2\Z
+{%
+ \expandafter\XINT_ftc_B\romannumeral0\xintiidivision {#1}{#2}{#2}%
+}%
+\def\XINT_ftc_B #1#2%
+{%
+ \XINT_ftc_C #2.{#1}%
+}%
+\def\XINT_ftc_C #1%
+{%
+ \xint_gob_til_zero #1\XINT_ftc_integer 0\XINT_ftc_D #1%
+}%
+\def\XINT_ftc_integer 0\XINT_ftc_D 0#1.#2#3{ #2}%
+\def\XINT_ftc_D #1.#2#3{\XINT_ftc_loop_a {#1}{#3}{#1}{#2, }}% 1.09m adds a space
+\def\XINT_ftc_loop_a
+{%
+ \expandafter\XINT_ftc_loop_d\romannumeral0\XINT_div_prepare
+}%
+\def\XINT_ftc_loop_d #1#2%
+{%
+ \XINT_ftc_loop_e #2.{#1}%
+}%
+\def\XINT_ftc_loop_e #1%
+{%
+ \xint_gob_til_zero #1\xint_ftc_loop_exit0\XINT_ftc_loop_f #1%
+}%
+\def\XINT_ftc_loop_f #1.#2#3#4%
+{%
+ \XINT_ftc_loop_a {#1}{#3}{#1}{#4#2, }% 1.09m has an added space here
+}%
+\def\xint_ftc_loop_exit0\XINT_ftc_loop_f #1.#2#3#4{ #4#2}%
+% \end{macrocode}
+% \subsection{\csh{xintFtoCx}}
+% \begin{macrocode}
+\def\xintFtoCx {\romannumeral0\xintftocx }%
+\def\xintftocx #1#2%
+{%
+ \expandafter\XINT_ftcx_A\romannumeral0\xintrawwithzeros {#2}\Z {#1}%
+}%
+\def\XINT_ftcx_A #1/#2\Z
+{%
+ \expandafter\XINT_ftcx_B\romannumeral0\xintiidivision {#1}{#2}{#2}%
+}%
+\def\XINT_ftcx_B #1#2%
+{%
+ \XINT_ftcx_C #2.{#1}%
+}%
+\def\XINT_ftcx_C #1%
+{%
+ \xint_gob_til_zero #1\XINT_ftcx_integer 0\XINT_ftcx_D #1%
+}%
+\def\XINT_ftcx_integer 0\XINT_ftcx_D 0#1.#2#3#4{ #2}%
+\def\XINT_ftcx_D #1.#2#3#4{\XINT_ftcx_loop_a {#1}{#3}{#1}{{#2}#4}{#4}}%
+\def\XINT_ftcx_loop_a
+{%
+ \expandafter\XINT_ftcx_loop_d\romannumeral0\XINT_div_prepare
+}%
+\def\XINT_ftcx_loop_d #1#2%
+{%
+ \XINT_ftcx_loop_e #2.{#1}%
+}%
+\def\XINT_ftcx_loop_e #1%
+{%
+ \xint_gob_til_zero #1\xint_ftcx_loop_exit0\XINT_ftcx_loop_f #1%
+}%
+\def\XINT_ftcx_loop_f #1.#2#3#4#5%
+{%
+ \XINT_ftcx_loop_a {#1}{#3}{#1}{#4{#2}#5}{#5}%
+}%
+\def\xint_ftcx_loop_exit0\XINT_ftcx_loop_f #1.#2#3#4#5{ #4{#2}}%
+% \end{macrocode}
+% \subsection{\csh{xintFtoC}}
+% \lverb|New in 1.09m: this is the same as \xintFtoCx with empty separator. I
+% had temporarily during preparation of 1.09m removed braces from \xintFtoCx,
+% but I recalled later why that was useful (see doc), thus let's just here do
+% \xintFtoCx {}|
+% \begin{macrocode}
+\def\xintFtoC {\romannumeral0\xintftoc }%
+\def\xintftoc {\xintftocx {}}%
+% \end{macrocode}
+% \subsection{\csh{xintFtoGC}}
+% \begin{macrocode}
+\def\xintFtoGC {\romannumeral0\xintftogc }%
+\def\xintftogc {\xintftocx {+1/}}%
+% \end{macrocode}
+% \subsection{\csh{xintFGtoC}}
+% \lverb|New with 1.09m of 2014/02/26. Computes the common initial coefficients
+% for the two fractions f and g, and outputs them as a sequence of braced
+% items.|
+% \begin{macrocode}
+\def\xintFGtoC {\romannumeral0\xintfgtoc}%
+\def\xintfgtoc#1%
+{%
+ \expandafter\XINT_fgtc_a\romannumeral0\xintrawwithzeros {#1}\Z
+}%
+\def\XINT_fgtc_a #1/#2\Z #3%
+{%
+ \expandafter\XINT_fgtc_b\romannumeral0\xintrawwithzeros {#3}\Z #1/#2\Z { }%
+}%
+\def\XINT_fgtc_b #1/#2\Z
+{%
+ \expandafter\XINT_fgtc_c\romannumeral0\xintiidivision {#1}{#2}{#2}%
+}%
+\def\XINT_fgtc_c #1#2#3#4/#5\Z
+{%
+ \expandafter\XINT_fgtc_d\romannumeral0\xintiidivision
+ {#4}{#5}{#5}{#1}{#2}{#3}%
+}%
+\def\XINT_fgtc_d #1#2#3#4%#5#6#7%
+{%
+ \xintifEq {#1}{#4}{\XINT_fgtc_da {#1}{#2}{#3}{#4}}%
+ {\xint_thirdofthree}%
+}%
+\def\XINT_fgtc_da #1#2#3#4#5#6#7%
+{%
+ \XINT_fgtc_e {#2}{#5}{#3}{#6}{#7{#1}}%
+}%
+\def\XINT_fgtc_e #1%
+{%
+ \xintiiifZero {#1}{\expandafter\xint_firstofone\xint_gobble_iii}%
+ {\XINT_fgtc_f {#1}}%
+}%
+\def\XINT_fgtc_f #1#2%
+{%
+ \xintiiifZero {#2}{\xint_thirdofthree}{\XINT_fgtc_g {#1}{#2}}%
+}%
+\def\XINT_fgtc_g #1#2#3%
+{%
+ \expandafter\XINT_fgtc_h\romannumeral0\XINT_div_prepare {#1}{#3}{#1}{#2}%
+}%
+\def\XINT_fgtc_h #1#2#3#4#5%
+{%
+ \expandafter\XINT_fgtc_d\romannumeral0\XINT_div_prepare
+ {#4}{#5}{#4}{#1}{#2}{#3}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFtoCC}}
+% \begin{macrocode}
+\def\xintFtoCC {\romannumeral0\xintftocc }%
+\def\xintftocc #1%
+{%
+ \expandafter\XINT_ftcc_A\expandafter {\romannumeral0\xintrawwithzeros {#1}}%
+}%
+\def\XINT_ftcc_A #1%
+{%
+ \expandafter\XINT_ftcc_B
+ \romannumeral0\xintrawwithzeros {\xintAdd {1/2[0]}{#1[0]}}\Z {#1[0]}%
+}%
+\def\XINT_ftcc_B #1/#2\Z
+{%
+ \expandafter\XINT_ftcc_C\expandafter {\romannumeral0\xintiiquo {#1}{#2}}%
+}%
+\def\XINT_ftcc_C #1#2%
+{%
+ \expandafter\XINT_ftcc_D\romannumeral0\xintsub {#2}{#1}\Z {#1}%
+}%
+\def\XINT_ftcc_D #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_ftcc_integer
+ 0#1\XINT_ftcc_En
+ 0-{\XINT_ftcc_Ep #1}%
+ \krof
+}%
+\def\XINT_ftcc_Ep #1\Z #2%
+{%
+ \expandafter\XINT_ftcc_loop_a\expandafter
+ {\romannumeral0\xintdiv {1[0]}{#1}}{#2+1/}%
+}%
+\def\XINT_ftcc_En #1\Z #2%
+{%
+ \expandafter\XINT_ftcc_loop_a\expandafter
+ {\romannumeral0\xintdiv {1[0]}{#1}}{#2+-1/}%
+}%
+\def\XINT_ftcc_integer #1\Z #2{ #2}%
+\def\XINT_ftcc_loop_a #1%
+{%
+ \expandafter\XINT_ftcc_loop_b
+ \romannumeral0\xintrawwithzeros {\xintAdd {1/2[0]}{#1}}\Z {#1}%
+}%
+\def\XINT_ftcc_loop_b #1/#2\Z
+{%
+ \expandafter\XINT_ftcc_loop_c\expandafter
+ {\romannumeral0\xintiiquo {#1}{#2}}%
+}%
+\def\XINT_ftcc_loop_c #1#2%
+{%
+ \expandafter\XINT_ftcc_loop_d
+ \romannumeral0\xintsub {#2}{#1[0]}\Z {#1}%
+}%
+\def\XINT_ftcc_loop_d #1%
+{%
+ \xint_UDzerominusfork
+ #1-\XINT_ftcc_end
+ 0#1\XINT_ftcc_loop_N
+ 0-{\XINT_ftcc_loop_P #1}%
+ \krof
+}%
+\def\XINT_ftcc_end #1\Z #2#3{ #3#2}%
+\def\XINT_ftcc_loop_P #1\Z #2#3%
+{%
+ \expandafter\XINT_ftcc_loop_a\expandafter
+ {\romannumeral0\xintdiv {1[0]}{#1}}{#3#2+1/}%
+}%
+\def\XINT_ftcc_loop_N #1\Z #2#3%
+{%
+ \expandafter\XINT_ftcc_loop_a\expandafter
+ {\romannumeral0\xintdiv {1[0]}{#1}}{#3#2+-1/}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintCtoF}, \csh{xintCstoF}}
+% \lverb|1.09m uses \xintCSVtoList on the argument of \xintCstoF to allow
+% spaces also before the commas. And the original \xintCstoF code became the
+% one of the new \xintCtoF dealing with a braced rather than comma separated
+% list.|
+% \begin{macrocode}
+\def\xintCstoF {\romannumeral0\xintcstof }%
+\def\xintcstof #1%
+{%
+ \expandafter\XINT_ctf_prep \romannumeral0\xintcsvtolist{#1}!%
+}%
+\def\xintCtoF {\romannumeral0\xintctof }%
+\def\xintctof #1%
+{%
+ \expandafter\XINT_ctf_prep \romannumeral`&&@#1!%
+}%
+\def\XINT_ctf_prep
+{%
+ \XINT_ctf_loop_a 1001%
+}%
+\def\XINT_ctf_loop_a #1#2#3#4#5%
+{%
+ \xint_gob_til_exclam #5\XINT_ctf_end!%
+ \expandafter\XINT_ctf_loop_b
+ \romannumeral0\xintrawwithzeros {#5}.{#1}{#2}{#3}{#4}%
+}%
+\def\XINT_ctf_loop_b #1/#2.#3#4#5#6%
+{%
+ \expandafter\XINT_ctf_loop_c\expandafter
+ {\romannumeral0\XINT_mul_fork #2\xint:#4\xint:}%
+ {\romannumeral0\XINT_mul_fork #2\xint:#3\xint:}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\xint:#6\xint:}%
+ {\XINT_mul_fork #1\xint:#4\xint:}}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\xint:#5\xint:}%
+ {\XINT_mul_fork #1\xint:#3\xint:}}%
+}%
+\def\XINT_ctf_loop_c #1#2%
+{%
+ \expandafter\XINT_ctf_loop_d\expandafter {\expandafter{#2}{#1}}%
+}%
+\def\XINT_ctf_loop_d #1#2%
+{%
+ \expandafter\XINT_ctf_loop_e\expandafter {\expandafter{#2}#1}%
+}%
+\def\XINT_ctf_loop_e #1#2%
+{%
+ \expandafter\XINT_ctf_loop_a\expandafter{#2}#1%
+}%
+\def\XINT_ctf_end #1.#2#3#4#5{\xintrawwithzeros {#2/#3}}% 1.09b removes [0]
+% \end{macrocode}
+% \subsection{\csh{xintiCstoF}}
+% \begin{macrocode}
+\def\xintiCstoF {\romannumeral0\xinticstof }%
+\def\xinticstof #1%
+{%
+ \expandafter\XINT_icstf_prep \romannumeral`&&@#1,!,%
+}%
+\def\XINT_icstf_prep
+{%
+ \XINT_icstf_loop_a 1001%
+}%
+\def\XINT_icstf_loop_a #1#2#3#4#5,%
+{%
+ \xint_gob_til_exclam #5\XINT_icstf_end!%
+ \expandafter
+ \XINT_icstf_loop_b \romannumeral`&&@#5.{#1}{#2}{#3}{#4}%
+}%
+\def\XINT_icstf_loop_b #1.#2#3#4#5%
+{%
+ \expandafter\XINT_icstf_loop_c\expandafter
+ {\romannumeral0\xintiiadd {#5}{\XINT_mul_fork #1\xint:#3\xint:}}%
+ {\romannumeral0\xintiiadd {#4}{\XINT_mul_fork #1\xint:#2\xint:}}%
+ {#2}{#3}%
+}%
+\def\XINT_icstf_loop_c #1#2%
+{%
+ \expandafter\XINT_icstf_loop_a\expandafter {#2}{#1}%
+}%
+\def\XINT_icstf_end#1.#2#3#4#5{\xintrawwithzeros {#2/#3}}% 1.09b removes [0]
+% \end{macrocode}
+% \subsection{\csh{xintGCtoF}}
+% \begin{macrocode}
+\def\xintGCtoF {\romannumeral0\xintgctof }%
+\def\xintgctof #1%
+{%
+ \expandafter\XINT_gctf_prep \romannumeral`&&@#1+!/%
+}%
+\def\XINT_gctf_prep
+{%
+ \XINT_gctf_loop_a 1001%
+}%
+\def\XINT_gctf_loop_a #1#2#3#4#5+%
+{%
+ \expandafter\XINT_gctf_loop_b
+ \romannumeral0\xintrawwithzeros {#5}.{#1}{#2}{#3}{#4}%
+}%
+\def\XINT_gctf_loop_b #1/#2.#3#4#5#6%
+{%
+ \expandafter\XINT_gctf_loop_c\expandafter
+ {\romannumeral0\XINT_mul_fork #2\xint:#4\xint:}%
+ {\romannumeral0\XINT_mul_fork #2\xint:#3\xint:}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\xint:#6\xint:}%
+ {\XINT_mul_fork #1\xint:#4\xint:}}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\xint:#5\xint:}%
+ {\XINT_mul_fork #1\xint:#3\xint:}}%
+}%
+\def\XINT_gctf_loop_c #1#2%
+{%
+ \expandafter\XINT_gctf_loop_d\expandafter {\expandafter{#2}{#1}}%
+}%
+\def\XINT_gctf_loop_d #1#2%
+{%
+ \expandafter\XINT_gctf_loop_e\expandafter {\expandafter{#2}#1}%
+}%
+\def\XINT_gctf_loop_e #1#2%
+{%
+ \expandafter\XINT_gctf_loop_f\expandafter {\expandafter{#2}#1}%
+}%
+\def\XINT_gctf_loop_f #1#2/%
+{%
+ \xint_gob_til_exclam #2\XINT_gctf_end!%
+ \expandafter\XINT_gctf_loop_g
+ \romannumeral0\xintrawwithzeros {#2}.#1%
+}%
+\def\XINT_gctf_loop_g #1/#2.#3#4#5#6%
+{%
+ \expandafter\XINT_gctf_loop_h\expandafter
+ {\romannumeral0\XINT_mul_fork #1\xint:#6\xint:}%
+ {\romannumeral0\XINT_mul_fork #1\xint:#5\xint:}%
+ {\romannumeral0\XINT_mul_fork #2\xint:#4\xint:}%
+ {\romannumeral0\XINT_mul_fork #2\xint:#3\xint:}%
+}%
+\def\XINT_gctf_loop_h #1#2%
+{%
+ \expandafter\XINT_gctf_loop_i\expandafter {\expandafter{#2}{#1}}%
+}%
+\def\XINT_gctf_loop_i #1#2%
+{%
+ \expandafter\XINT_gctf_loop_j\expandafter {\expandafter{#2}#1}%
+}%
+\def\XINT_gctf_loop_j #1#2%
+{%
+ \expandafter\XINT_gctf_loop_a\expandafter {#2}#1%
+}%
+\def\XINT_gctf_end #1.#2#3#4#5{\xintrawwithzeros {#2/#3}}% 1.09b removes [0]
+% \end{macrocode}
+% \subsection{\csh{xintiGCtoF}}
+% \begin{macrocode}
+\def\xintiGCtoF {\romannumeral0\xintigctof }%
+\def\xintigctof #1%
+{%
+ \expandafter\XINT_igctf_prep \romannumeral`&&@#1+!/%
+}%
+\def\XINT_igctf_prep
+{%
+ \XINT_igctf_loop_a 1001%
+}%
+\def\XINT_igctf_loop_a #1#2#3#4#5+%
+{%
+ \expandafter\XINT_igctf_loop_b
+ \romannumeral`&&@#5.{#1}{#2}{#3}{#4}%
+}%
+\def\XINT_igctf_loop_b #1.#2#3#4#5%
+{%
+ \expandafter\XINT_igctf_loop_c\expandafter
+ {\romannumeral0\xintiiadd {#5}{\XINT_mul_fork #1\xint:#3\xint:}}%
+ {\romannumeral0\xintiiadd {#4}{\XINT_mul_fork #1\xint:#2\xint:}}%
+ {#2}{#3}%
+}%
+\def\XINT_igctf_loop_c #1#2%
+{%
+ \expandafter\XINT_igctf_loop_f\expandafter {\expandafter{#2}{#1}}%
+}%
+\def\XINT_igctf_loop_f #1#2#3#4/%
+{%
+ \xint_gob_til_exclam #4\XINT_igctf_end!%
+ \expandafter\XINT_igctf_loop_g
+ \romannumeral`&&@#4.{#2}{#3}#1%
+}%
+\def\XINT_igctf_loop_g #1.#2#3%
+{%
+ \expandafter\XINT_igctf_loop_h\expandafter
+ {\romannumeral0\XINT_mul_fork #1\xint:#3\xint:}%
+ {\romannumeral0\XINT_mul_fork #1\xint:#2\xint:}%
+}%
+\def\XINT_igctf_loop_h #1#2%
+{%
+ \expandafter\XINT_igctf_loop_i\expandafter {#2}{#1}%
+}%
+\def\XINT_igctf_loop_i #1#2#3#4%
+{%
+ \XINT_igctf_loop_a {#3}{#4}{#1}{#2}%
+}%
+\def\XINT_igctf_end #1.#2#3#4#5{\xintrawwithzeros {#4/#5}}% 1.09b removes [0]
+% \end{macrocode}
+% \subsection{\csh{xintCtoCv}, \csh{xintCstoCv}}
+% \lverb|1.09m uses \xintCSVtoList on the argument of \xintCstoCv to allow
+% spaces also before the commas. The original \xintCstoCv code became the
+% one of the new \xintCtoF dealing with a braced rather than comma separated
+% list.|
+% \begin{macrocode}
+\def\xintCstoCv {\romannumeral0\xintcstocv }%
+\def\xintcstocv #1%
+{%
+ \expandafter\XINT_ctcv_prep\romannumeral0\xintcsvtolist{#1}!%
+}%
+\def\xintCtoCv {\romannumeral0\xintctocv }%
+\def\xintctocv #1%
+{%
+ \expandafter\XINT_ctcv_prep\romannumeral`&&@#1!%
+}%
+\def\XINT_ctcv_prep
+{%
+ \XINT_ctcv_loop_a {}1001%
+}%
+\def\XINT_ctcv_loop_a #1#2#3#4#5#6%
+{%
+ \xint_gob_til_exclam #6\XINT_ctcv_end!%
+ \expandafter\XINT_ctcv_loop_b
+ \romannumeral0\xintrawwithzeros {#6}.{#2}{#3}{#4}{#5}{#1}%
+}%
+\def\XINT_ctcv_loop_b #1/#2.#3#4#5#6%
+{%
+ \expandafter\XINT_ctcv_loop_c\expandafter
+ {\romannumeral0\XINT_mul_fork #2\xint:#4\xint:}%
+ {\romannumeral0\XINT_mul_fork #2\xint:#3\xint:}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\xint:#6\xint:}%
+ {\XINT_mul_fork #1\xint:#4\xint:}}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\xint:#5\xint:}%
+ {\XINT_mul_fork #1\xint:#3\xint:}}%
+}%
+\def\XINT_ctcv_loop_c #1#2%
+{%
+ \expandafter\XINT_ctcv_loop_d\expandafter {\expandafter{#2}{#1}}%
+}%
+\def\XINT_ctcv_loop_d #1#2%
+{%
+ \expandafter\XINT_ctcv_loop_e\expandafter {\expandafter{#2}#1}%
+}%
+\def\XINT_ctcv_loop_e #1#2%
+{%
+ \expandafter\XINT_ctcv_loop_f\expandafter{#2}#1%
+}%
+\def\XINT_ctcv_loop_f #1#2#3#4#5%
+{%
+ \expandafter\XINT_ctcv_loop_g\expandafter
+ {\romannumeral0\xintrawwithzeros {#1/#2}}{#5}{#1}{#2}{#3}{#4}%
+}%
+\def\XINT_ctcv_loop_g #1#2{\XINT_ctcv_loop_a {#2{#1}}}% 1.09b removes [0]
+\def\XINT_ctcv_end #1.#2#3#4#5#6{ #6}%
+% \end{macrocode}
+% \subsection{\csh{xintiCstoCv}}
+% \begin{macrocode}
+\def\xintiCstoCv {\romannumeral0\xinticstocv }%
+\def\xinticstocv #1%
+{%
+ \expandafter\XINT_icstcv_prep \romannumeral`&&@#1,!,%
+}%
+\def\XINT_icstcv_prep
+{%
+ \XINT_icstcv_loop_a {}1001%
+}%
+\def\XINT_icstcv_loop_a #1#2#3#4#5#6,%
+{%
+ \xint_gob_til_exclam #6\XINT_icstcv_end!%
+ \expandafter
+ \XINT_icstcv_loop_b \romannumeral`&&@#6.{#2}{#3}{#4}{#5}{#1}%
+}%
+\def\XINT_icstcv_loop_b #1.#2#3#4#5%
+{%
+ \expandafter\XINT_icstcv_loop_c\expandafter
+ {\romannumeral0\xintiiadd {#5}{\XINT_mul_fork #1\xint:#3\xint:}}%
+ {\romannumeral0\xintiiadd {#4}{\XINT_mul_fork #1\xint:#2\xint:}}%
+ {{#2}{#3}}%
+}%
+\def\XINT_icstcv_loop_c #1#2%
+{%
+ \expandafter\XINT_icstcv_loop_d\expandafter {#2}{#1}%
+}%
+\def\XINT_icstcv_loop_d #1#2%
+{%
+ \expandafter\XINT_icstcv_loop_e\expandafter
+ {\romannumeral0\xintrawwithzeros {#1/#2}}{{#1}{#2}}%
+}%
+\def\XINT_icstcv_loop_e #1#2#3#4{\XINT_icstcv_loop_a {#4{#1}}#2#3}%
+\def\XINT_icstcv_end #1.#2#3#4#5#6{ #6}% 1.09b removes [0]
+% \end{macrocode}
+% \subsection{\csh{xintGCtoCv}}
+% \begin{macrocode}
+\def\xintGCtoCv {\romannumeral0\xintgctocv }%
+\def\xintgctocv #1%
+{%
+ \expandafter\XINT_gctcv_prep \romannumeral`&&@#1+!/%
+}%
+\def\XINT_gctcv_prep
+{%
+ \XINT_gctcv_loop_a {}1001%
+}%
+\def\XINT_gctcv_loop_a #1#2#3#4#5#6+%
+{%
+ \expandafter\XINT_gctcv_loop_b
+ \romannumeral0\xintrawwithzeros {#6}.{#2}{#3}{#4}{#5}{#1}%
+}%
+\def\XINT_gctcv_loop_b #1/#2.#3#4#5#6%
+{%
+ \expandafter\XINT_gctcv_loop_c\expandafter
+ {\romannumeral0\XINT_mul_fork #2\xint:#4\xint:}%
+ {\romannumeral0\XINT_mul_fork #2\xint:#3\xint:}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\xint:#6\xint:}%
+ {\XINT_mul_fork #1\xint:#4\xint:}}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\xint:#5\xint:}%
+ {\XINT_mul_fork #1\xint:#3\xint:}}%
+}%
+\def\XINT_gctcv_loop_c #1#2%
+{%
+ \expandafter\XINT_gctcv_loop_d\expandafter {\expandafter{#2}{#1}}%
+}%
+\def\XINT_gctcv_loop_d #1#2%
+{%
+ \expandafter\XINT_gctcv_loop_e\expandafter {\expandafter{#2}{#1}}%
+}%
+\def\XINT_gctcv_loop_e #1#2%
+{%
+ \expandafter\XINT_gctcv_loop_f\expandafter {#2}#1%
+}%
+\def\XINT_gctcv_loop_f #1#2%
+{%
+ \expandafter\XINT_gctcv_loop_g\expandafter
+ {\romannumeral0\xintrawwithzeros {#1/#2}}{{#1}{#2}}%
+}%
+\def\XINT_gctcv_loop_g #1#2#3#4%
+{%
+ \XINT_gctcv_loop_h {#4{#1}}{#2#3}% 1.09b removes [0]
+}%
+\def\XINT_gctcv_loop_h #1#2#3/%
+{%
+ \xint_gob_til_exclam #3\XINT_gctcv_end!%
+ \expandafter\XINT_gctcv_loop_i
+ \romannumeral0\xintrawwithzeros {#3}.#2{#1}%
+}%
+\def\XINT_gctcv_loop_i #1/#2.#3#4#5#6%
+{%
+ \expandafter\XINT_gctcv_loop_j\expandafter
+ {\romannumeral0\XINT_mul_fork #1\xint:#6\xint:}%
+ {\romannumeral0\XINT_mul_fork #1\xint:#5\xint:}%
+ {\romannumeral0\XINT_mul_fork #2\xint:#4\xint:}%
+ {\romannumeral0\XINT_mul_fork #2\xint:#3\xint:}%
+}%
+\def\XINT_gctcv_loop_j #1#2%
+{%
+ \expandafter\XINT_gctcv_loop_k\expandafter {\expandafter{#2}{#1}}%
+}%
+\def\XINT_gctcv_loop_k #1#2%
+{%
+ \expandafter\XINT_gctcv_loop_l\expandafter {\expandafter{#2}#1}%
+}%
+\def\XINT_gctcv_loop_l #1#2%
+{%
+ \expandafter\XINT_gctcv_loop_m\expandafter {\expandafter{#2}#1}%
+}%
+\def\XINT_gctcv_loop_m #1#2{\XINT_gctcv_loop_a {#2}#1}%
+\def\XINT_gctcv_end #1.#2#3#4#5#6{ #6}%
+% \end{macrocode}
+% \subsection{\csh{xintiGCtoCv}}
+% \begin{macrocode}
+\def\xintiGCtoCv {\romannumeral0\xintigctocv }%
+\def\xintigctocv #1%
+{%
+ \expandafter\XINT_igctcv_prep \romannumeral`&&@#1+!/%
+}%
+\def\XINT_igctcv_prep
+{%
+ \XINT_igctcv_loop_a {}1001%
+}%
+\def\XINT_igctcv_loop_a #1#2#3#4#5#6+%
+{%
+ \expandafter\XINT_igctcv_loop_b
+ \romannumeral`&&@#6.{#2}{#3}{#4}{#5}{#1}%
+}%
+\def\XINT_igctcv_loop_b #1.#2#3#4#5%
+{%
+ \expandafter\XINT_igctcv_loop_c\expandafter
+ {\romannumeral0\xintiiadd {#5}{\XINT_mul_fork #1\xint:#3\xint:}}%
+ {\romannumeral0\xintiiadd {#4}{\XINT_mul_fork #1\xint:#2\xint:}}%
+ {{#2}{#3}}%
+}%
+\def\XINT_igctcv_loop_c #1#2%
+{%
+ \expandafter\XINT_igctcv_loop_f\expandafter {\expandafter{#2}{#1}}%
+}%
+\def\XINT_igctcv_loop_f #1#2#3#4/%
+{%
+ \xint_gob_til_exclam #4\XINT_igctcv_end_a!%
+ \expandafter\XINT_igctcv_loop_g
+ \romannumeral`&&@#4.#1#2{#3}%
+}%
+\def\XINT_igctcv_loop_g #1.#2#3#4#5%
+{%
+ \expandafter\XINT_igctcv_loop_h\expandafter
+ {\romannumeral0\XINT_mul_fork #1\xint:#5\xint:}%
+ {\romannumeral0\XINT_mul_fork #1\xint:#4\xint:}%
+ {{#2}{#3}}%
+}%
+\def\XINT_igctcv_loop_h #1#2%
+{%
+ \expandafter\XINT_igctcv_loop_i\expandafter {\expandafter{#2}{#1}}%
+}%
+\def\XINT_igctcv_loop_i #1#2{\XINT_igctcv_loop_k #2{#2#1}}%
+\def\XINT_igctcv_loop_k #1#2%
+{%
+ \expandafter\XINT_igctcv_loop_l\expandafter
+ {\romannumeral0\xintrawwithzeros {#1/#2}}%
+}%
+\def\XINT_igctcv_loop_l #1#2#3{\XINT_igctcv_loop_a {#3{#1}}#2}%1.09i removes [0]
+\def\XINT_igctcv_end_a #1.#2#3#4#5%
+{%
+ \expandafter\XINT_igctcv_end_b\expandafter
+ {\romannumeral0\xintrawwithzeros {#2/#3}}%
+}%
+\def\XINT_igctcv_end_b #1#2{ #2{#1}}% 1.09b removes [0]
+% \end{macrocode}
+% \subsection{\csh{xintFtoCv}}
+% \lverb|Still uses \xinticstocv \xintFtoCs rather than \xintctocv \xintFtoC.|
+% \begin{macrocode}
+\def\xintFtoCv {\romannumeral0\xintftocv }%
+\def\xintftocv #1%
+{%
+ \xinticstocv {\xintFtoCs {#1}}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintFtoCCv}}
+% \begin{macrocode}
+\def\xintFtoCCv {\romannumeral0\xintftoccv }%
+\def\xintftoccv #1%
+{%
+ \xintigctocv {\xintFtoCC {#1}}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintCntoF}}
+% \lverb|&
+% Modified in 1.06 to give the N first to a \numexpr rather than expanding
+% twice. I just use \the\numexpr and maintain the previous code after that.|
+% \begin{macrocode}
+\def\xintCntoF {\romannumeral0\xintcntof }%
+\def\xintcntof #1%
+{%
+ \expandafter\XINT_cntf\expandafter {\the\numexpr #1}%
+}%
+\def\XINT_cntf #1#2%
+{%
+ \ifnum #1>\xint_c_
+ \xint_afterfi {\expandafter\XINT_cntf_loop\expandafter
+ {\the\numexpr #1-1\expandafter}\expandafter
+ {\romannumeral`&&@#2{#1}}{#2}}%
+ \else
+ \xint_afterfi
+ {\ifnum #1=\xint_c_
+ \xint_afterfi {\expandafter\space \romannumeral`&&@#2{0}}%
+ \else \xint_afterfi { }% 1.09m now returns nothing.
+ \fi}%
+ \fi
+}%
+\def\XINT_cntf_loop #1#2#3%
+{%
+ \ifnum #1>\xint_c_ \else \XINT_cntf_exit \fi
+ \expandafter\XINT_cntf_loop\expandafter
+ {\the\numexpr #1-1\expandafter }\expandafter
+ {\romannumeral0\xintadd {\xintDiv {1[0]}{#2}}{#3{#1}}}%
+ {#3}%
+}%
+\def\XINT_cntf_exit \fi
+ \expandafter\XINT_cntf_loop\expandafter
+ #1\expandafter #2#3%
+{%
+ \fi\xint_gobble_ii #2%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintGCntoF}}
+% \lverb|Modified in 1.06 to give the N argument first to a \numexpr rather
+% than expanding twice. I just use \the\numexpr and maintain the previous code
+% after that.|
+% \begin{macrocode}
+\def\xintGCntoF {\romannumeral0\xintgcntof }%
+\def\xintgcntof #1%
+{%
+ \expandafter\XINT_gcntf\expandafter {\the\numexpr #1}%
+}%
+\def\XINT_gcntf #1#2#3%
+{%
+ \ifnum #1>\xint_c_
+ \xint_afterfi {\expandafter\XINT_gcntf_loop\expandafter
+ {\the\numexpr #1-1\expandafter}\expandafter
+ {\romannumeral`&&@#2{#1}}{#2}{#3}}%
+ \else
+ \xint_afterfi
+ {\ifnum #1=\xint_c_
+ \xint_afterfi {\expandafter\space\romannumeral`&&@#2{0}}%
+ \else \xint_afterfi { }% 1.09m now returns nothing rather than 0/1[0]
+ \fi}%
+ \fi
+}%
+\def\XINT_gcntf_loop #1#2#3#4%
+{%
+ \ifnum #1>\xint_c_ \else \XINT_gcntf_exit \fi
+ \expandafter\XINT_gcntf_loop\expandafter
+ {\the\numexpr #1-1\expandafter }\expandafter
+ {\romannumeral0\xintadd {\xintDiv {#4{#1}}{#2}}{#3{#1}}}%
+ {#3}{#4}%
+}%
+\def\XINT_gcntf_exit \fi
+ \expandafter\XINT_gcntf_loop\expandafter
+ #1\expandafter #2#3#4%
+{%
+ \fi\xint_gobble_ii #2%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintCntoCs}}
+% \lverb|Modified in 1.09m: added spaces after the commas in the produced list.
+% Moreover the coefficients are not braced anymore. A slight induced limitation
+% is that the macro argument should not contain some explicit comma (cf.
+% \XINT_cntcs_exit_b), hence \xintCntoCs {\macro,} with \def\macro,#1{<stuff>}
+% would crash. Not a very serious limitation, I believe. |
+% \begin{macrocode}
+\def\xintCntoCs {\romannumeral0\xintcntocs }%
+\def\xintcntocs #1%
+{%
+ \expandafter\XINT_cntcs\expandafter {\the\numexpr #1}%
+}%
+\def\XINT_cntcs #1#2%
+{%
+ \ifnum #1<0
+ \xint_afterfi { }% 1.09i: a 0/1[0] was here, now the macro returns nothing
+ \else
+ \xint_afterfi {\expandafter\XINT_cntcs_loop\expandafter
+ {\the\numexpr #1-\xint_c_i\expandafter}\expandafter
+ {\romannumeral`&&@#2{#1}}{#2}}% produced coeff not braced
+ \fi
+}%
+\def\XINT_cntcs_loop #1#2#3%
+{%
+ \ifnum #1>-\xint_c_i \else \XINT_cntcs_exit \fi
+ \expandafter\XINT_cntcs_loop\expandafter
+ {\the\numexpr #1-\xint_c_i\expandafter}\expandafter
+ {\romannumeral`&&@#3{#1}, #2}{#3}% space added, 1.09m
+}%
+\def\XINT_cntcs_exit \fi
+ \expandafter\XINT_cntcs_loop\expandafter
+ #1\expandafter #2#3%
+{%
+ \fi\XINT_cntcs_exit_b #2%
+}%
+\def\XINT_cntcs_exit_b #1,{}% romannumeral stopping space already there
+% \end{macrocode}
+% \subsection{\csh{xintCntoGC}}
+% \lverb|&
+% Modified in 1.06 to give the N first to a \numexpr rather than expanding
+% twice. I just use \the\numexpr and maintain the previous code after that.
+%
+% 1.09m maintains the braces, as the coeff are allowed to be fraction and the
+% slash can not be naked in the GC format, contrarily to what happens in
+% \xintCntoCs. Also the separators given to \xintGCtoGCx may then fetch the
+% coefficients as argument, as they are braced.|
+% \begin{macrocode}
+\def\xintCntoGC {\romannumeral0\xintcntogc }%
+\def\xintcntogc #1%
+{%
+ \expandafter\XINT_cntgc\expandafter {\the\numexpr #1}%
+}%
+\def\XINT_cntgc #1#2%
+{%
+ \ifnum #1<0
+ \xint_afterfi { }% 1.09i there was as strange 0/1[0] here, removed
+ \else
+ \xint_afterfi {\expandafter\XINT_cntgc_loop\expandafter
+ {\the\numexpr #1-\xint_c_i\expandafter}\expandafter
+ {\expandafter{\romannumeral`&&@#2{#1}}}{#2}}%
+ \fi
+}%
+\def\XINT_cntgc_loop #1#2#3%
+{%
+ \ifnum #1>-\xint_c_i \else \XINT_cntgc_exit \fi
+ \expandafter\XINT_cntgc_loop\expandafter
+ {\the\numexpr #1-\xint_c_i\expandafter }\expandafter
+ {\expandafter{\romannumeral`&&@#3{#1}}+1/#2}{#3}%
+}%
+\def\XINT_cntgc_exit \fi
+ \expandafter\XINT_cntgc_loop\expandafter
+ #1\expandafter #2#3%
+{%
+ \fi\XINT_cntgc_exit_b #2%
+}%
+\def\XINT_cntgc_exit_b #1+1/{ }%
+% \end{macrocode}
+% \subsection{\csh{xintGCntoGC}}
+% \lverb|&
+% Modified in 1.06 to give the N first to a \numexpr rather than expanding
+% twice. I just use \the\numexpr and maintain the previous code after that.|
+% \begin{macrocode}
+\def\xintGCntoGC {\romannumeral0\xintgcntogc }%
+\def\xintgcntogc #1%
+{%
+ \expandafter\XINT_gcntgc\expandafter {\the\numexpr #1}%
+}%
+\def\XINT_gcntgc #1#2#3%
+{%
+ \ifnum #1<0
+ \xint_afterfi { }% 1.09i now returns nothing
+ \else
+ \xint_afterfi {\expandafter\XINT_gcntgc_loop\expandafter
+ {\the\numexpr #1-\xint_c_i\expandafter}\expandafter
+ {\expandafter{\romannumeral`&&@#2{#1}}}{#2}{#3}}%
+ \fi
+}%
+\def\XINT_gcntgc_loop #1#2#3#4%
+{%
+ \ifnum #1>-\xint_c_i \else \XINT_gcntgc_exit \fi
+ \expandafter\XINT_gcntgc_loop_b\expandafter
+ {\expandafter{\romannumeral`&&@#4{#1}}/#2}{#3{#1}}{#1}{#3}{#4}%
+}%
+\def\XINT_gcntgc_loop_b #1#2#3%
+{%
+ \expandafter\XINT_gcntgc_loop\expandafter
+ {\the\numexpr #3-\xint_c_i \expandafter}\expandafter
+ {\expandafter{\romannumeral`&&@#2}+#1}%
+}%
+\def\XINT_gcntgc_exit \fi
+ \expandafter\XINT_gcntgc_loop_b\expandafter #1#2#3#4#5%
+{%
+ \fi\XINT_gcntgc_exit_b #1%
+}%
+\def\XINT_gcntgc_exit_b #1/{ }%
+% \end{macrocode}
+% \subsection{\csh{xintCstoGC}}
+% \begin{macrocode}
+\def\xintCstoGC {\romannumeral0\xintcstogc }%
+\def\xintcstogc #1%
+{%
+ \expandafter\XINT_cstc_prep \romannumeral`&&@#1,!,%
+}%
+\def\XINT_cstc_prep #1,{\XINT_cstc_loop_a {{#1}}}%
+\def\XINT_cstc_loop_a #1#2,%
+{%
+ \xint_gob_til_exclam #2\XINT_cstc_end!%
+ \XINT_cstc_loop_b {#1}{#2}%
+}%
+\def\XINT_cstc_loop_b #1#2{\XINT_cstc_loop_a {#1+1/{#2}}}%
+\def\XINT_cstc_end!\XINT_cstc_loop_b #1#2{ #1}%
+% \end{macrocode}
+% \subsection{\csh{xintGCtoGC}}
+% \begin{macrocode}
+\def\xintGCtoGC {\romannumeral0\xintgctogc }%
+\def\xintgctogc #1%
+{%
+ \expandafter\XINT_gctgc_start \romannumeral`&&@#1+!/%
+}%
+\def\XINT_gctgc_start {\XINT_gctgc_loop_a {}}%
+\def\XINT_gctgc_loop_a #1#2+#3/%
+{%
+ \xint_gob_til_exclam #3\XINT_gctgc_end!%
+ \expandafter\XINT_gctgc_loop_b\expandafter
+ {\romannumeral`&&@#2}{#3}{#1}%
+}%
+\def\XINT_gctgc_loop_b #1#2%
+{%
+ \expandafter\XINT_gctgc_loop_c\expandafter
+ {\romannumeral`&&@#2}{#1}%
+}%
+\def\XINT_gctgc_loop_c #1#2#3%
+{%
+ \XINT_gctgc_loop_a {#3{#2}+{#1}/}%
+}%
+\def\XINT_gctgc_end!\expandafter\XINT_gctgc_loop_b
+{%
+ \expandafter\XINT_gctgc_end_b
+}%
+\def\XINT_gctgc_end_b #1#2#3{ #3{#1}}%
+\XINT_restorecatcodes_endinput%
+% \end{macrocode}
+% \StoreCodelineNo {xintcfrac}
+% \cleardoublepage\let\xintcfracnameUp\undefined
+%\gardesactifs
+%\let</xintcfrac>\relax
+%\let<*xintexpr>\gardesinactifs
+%</xintcfrac>^^A--------------------------------------------------
+%<*xintexpr>^^A---------------------------------------------------
+%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*-
+% \clearpage\csname xintexprnameUp\endcsname
+% \section{Package \xintexprnameimp implementation}
+% \RaisedLabel{sec:exprimp}
+% \etocarticlestylenomarks
+% \etocstandardlines
+% \etocsetnexttocdepth {subsection}
+%
+% \localtableofcontents
+%
+% \etocsettocstyle{}{}
+%
+% This is release \expandafter|\xintbndlversion| of
+% \expandafter|\expandafter[\xintbndldate]|.
+%
+% \subsection{Old comments}
+%
+% These general comments were last updated at the end of the |1.09x| series in
+% 2014. The principles remain in place to this day but refer to
+% \href{http://www.ctan.org/pkg/xint/CHANGES.html}{CHANGES.html} for some
+% significant evolutions since.
+%
+% The first version was released in June 2013. I was greatly helped in this task
+% of writing an expandable parser of infix operations by the comments provided
+% in |l3fp-parse.dtx| (in its version as available in April-May 2013). One will
+% recognize in particular the idea of the `until' macros; I have not looked into
+% the actual |l3fp| code beyond the very useful comments provided in its
+% documentation.
+%
+% A main worry was that my data has no a priori bound on its size; to keep the
+% code reasonably efficient, I experimented with a technique of storing and
+% retrieving data expandably as \emph{names} of control sequences. Intermediate
+% computation results are stored as control sequences |\.=a/b[n]|.
+%
+%
+% Roughly speaking, the parser mechanism is as follows: at any given time the
+% last found ``operator'' has its associated |until| macro awaiting some news
+% from the token flow; first |getnext| expands forward in the hope to construct
+% some number, which may come from a parenthesized sub-expression, from some
+% braced material, or from a digit by digit scan. After this number has been
+% formed the next operator is looked for by the |getop| macro. Once |getop| has
+% finished its job, |until| is presented with three tokens: the first one is the
+% precedence level of the new found operator (which may be an end of expression
+% marker), the second is the operator character token (earlier versions had here
+% already some macro name, but in order to keep as much common code to expr and
+% floatexpr common as possible, this was modified) of the new found operator, and
+% the third one is the newly found number (which was encountered just before the
+% new operator).
+%
+% The |until| macro of the earlier operator examines the precedence level of the
+% new found one, and either executes the earlier operator (in the case of a
+% binary operation, with the found number and a previously stored one) or it
+% delays execution, giving the hand to the |until| macro of the operator having
+% been found of higher precedence.
+%
+% A minus sign acting as prefix gets converted into a (unary) operator
+% inheriting the precedence level of the previous operator.
+%
+% Once the end of the expression is found (it has to be marked by a |\relax|)
+% the final result is output as four tokens (five tokens since |1.09j|) the
+% first one a catcode 11 exclamation mark, the second one an error generating
+% macro, the third one is a protection mechanism, the fourth one a printing
+% macro and the fifth is |\.=a/b[n]|. The prefix |\xintthe| makes the output
+% printable by killing the first three tokens.
+%
+%
+% \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{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+ \catcode13=5 % ^^M
+ \endlinechar=13 %
+ \catcode123=1 % {
+ \catcode125=2 % }
+ \catcode64=11 % @
+ \catcode35=6 % #
+ \catcode44=12 % ,
+ \catcode45=12 % -
+ \catcode46=12 % .
+ \catcode58=12 % :
+ \def\z {\endgroup}%
+ \expandafter\let\expandafter\x\csname ver@xintexpr.sty\endcsname
+ \expandafter\let\expandafter\w\csname ver@xintfrac.sty\endcsname
+ \expandafter\let\expandafter\t\csname ver@xinttools.sty\endcsname
+ \expandafter
+ \ifx\csname PackageInfo\endcsname\relax
+ \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}%
+ \else
+ \def\y#1#2{\PackageInfo{#1}{#2}}%
+ \fi
+ \expandafter
+ \ifx\csname numexpr\endcsname\relax
+ \y{xintexpr}{\numexpr not available, aborting input}%
+ \aftergroup\endinput
+ \else
+ \ifx\x\relax % plain-TeX, first loading of xintexpr.sty
+ \ifx\w\relax % but xintfrac.sty not yet loaded.
+ \expandafter\def\expandafter\z\expandafter
+ {\z\input xintfrac.sty\relax}%
+ \fi
+ \ifx\t\relax % but xinttools.sty not yet loaded.
+ \expandafter\def\expandafter\z\expandafter
+ {\z\input xinttools.sty\relax}%
+ \fi
+ \else
+ \def\empty {}%
+ \ifx\x\empty % LaTeX, first loading,
+ % variable is initialized, but \ProvidesPackage not yet seen
+ \ifx\w\relax % xintfrac.sty not yet loaded.
+ \expandafter\def\expandafter\z\expandafter
+ {\z\RequirePackage{xintfrac}}%
+ \fi
+ \ifx\t\relax % xinttools.sty not yet loaded.
+ \expandafter\def\expandafter\z\expandafter
+ {\z\RequirePackage{xinttools}}%
+ \fi
+ \else
+ \aftergroup\endinput % xintexpr already loaded.
+ \fi
+ \fi
+ \fi
+\z%
+\XINTsetupcatcodes%
+% \end{macrocode}
+% \subsection{Package identification}
+% \lverb|&
+% |
+% \begin{macrocode}
+\XINT_providespackage
+\ProvidesPackage{xintexpr}%
+ [2019/04/05 1.3e Expandable expression parser (JFB)]%
+\catcode`! 11
+\let\XINT_Cmp \xintiiCmp
+% \end{macrocode}
+% \subsection{\csh{xintexpr}, \csh{xintiexpr}, \csh{xintfloatexpr},
+% \csh{xintiiexpr}}
+% \lverb|ATTENTION! 1.3d renamed \xinteval to \xintexpro etc...|
+% \begin{macrocode}
+\def\xintexpr {\romannumeral0\xintexpro }%
+\def\xintiexpr {\romannumeral0\xintiexpro }%
+\def\xintfloatexpr {\romannumeral0\xintfloatexpro }%
+\def\xintiiexpr {\romannumeral0\xintiiexpro }%
+% \end{macrocode}
+% \subsection{\csh{xintexpro}, \csh{xintiiexpro}}
+% \lverb|ATTENTION! 1.3d renamed \xinteval to \xintexpro etc...|
+% \begin{macrocode}
+\def\xintexpro {\expandafter\XINT_expr_wrap\romannumeral0\xintbareeval }%
+\def\xintiiexpro {\expandafter\XINT_iiexpr_wrap\romannumeral0\xintbareiieval }%
+% \end{macrocode}
+% \subsection{\csh{xintiexpro}, \csh{xintfloatexpro}}
+% \lverb|Optional argument since 1.1.
+%
+% ATTENTION! 1.3d renamed \xinteval to \xintexpro etc...
+%
+% Some renaming of macros at 1.3e here.|
+% \begin{macrocode}
+\def\xintiexpro #1%
+{%
+ \ifx [#1\expandafter\XINT_iexpr_withopt\else\expandafter\XINT_iexpr_noopt
+ \fi #1%
+}%
+\def\XINT_iexpr_noopt
+{%
+ \expandafter\XINT_iexpr_preprint\expandafter 0%
+ \romannumeral0\xintbareeval
+}%
+\def\XINT_iexpr_withopt [#1]%
+{%
+ \expandafter\XINT_iexpr_preprint\expandafter
+ {\the\numexpr \xint_zapspaces #1 \xint_gobble_i\expandafter}%
+ \romannumeral0\xintbareeval
+}%
+\def\XINT_iexpr_preprint #1#2%
+{%
+ \expandafter\XINT_expr_wrap
+ \csname .=\xintRound::csv {#1}{\XINT_expr_unlock #2}\endcsname
+}%
+\def\xintfloatexpro #1%
+{%
+ \ifx [#1\expandafter\XINT_flexpr_withopt\else\expandafter\XINT_flexpr_noopt
+ \fi #1%
+}%
+\def\XINT_flexpr_noopt
+{%
+ \expandafter\XINT_flexpr_preprint\expandafter\xinttheDigits
+ \romannumeral0\xintbarefloateval
+}%
+\def\XINT_flexpr_withopt [#1]%
+{%
+ \expandafter\XINT_flexpr_preprint\expandafter
+ {\the\numexpr\xint_zapspaces #1 \xint_gobble_i\expandafter}%
+ \romannumeral0\xintbarefloateval
+}%
+\def\XINT_flexpr_preprint #1#2%
+{%
+ \expandafter\XINT_flexpr_wrap
+ \csname .;#1.=\XINTinFloat::csv {#1}{\XINT_expr_unlock #2}\endcsname
+}%
+% \end{macrocode}
+% \subsection{\csh{XINT_expr_wrap}, \csh{XINT_iiexpr_wrap}, \csh{XINT_flexpr_wrap}}
+% \lverb|1.3e removes some leading space tokens which served nothing. There is
+% no \XINT_iexpr_wrap, because \XINT_expr_wrap is used directly.|
+% \begin{macrocode}
+\def\XINT_expr_wrap {!\XINT_expr_usethe\XINT_protectii\XINT_expr_print}%
+\def\XINT_iiexpr_wrap {!\XINT_expr_usethe\XINT_protectii\XINT_iiexpr_print}%
+\def\XINT_flexpr_wrap {!\XINT_expr_usethe\XINT_protectii\XINT_flexpr_print}%
+% \end{macrocode}
+% \subsection{\csh{XINT_expr_usethe}, \csh{XINT_protectii}}
+% \begin{macrocode}
+\def\XINT_protectii #1{\noexpand\XINT_protectii\noexpand #1\noexpand }%
+\protected\def\XINT_expr_usethe\XINT_protectii {\xintError:missing_xintthe!}%
+% \end{macrocode}
+% \subsection{\csh{XINT_expr_print}, \csh{XINT_iiexpr_print}, \csh{XINT_flexpr_print}}
+% \begin{macrocode}
+\def\XINT_expr_print #1{\xintSPRaw::csv {\XINT_expr_unlock #1}}%
+\def\XINT_iiexpr_print #1{\xintCSV::csv {\XINT_expr_unlock #1}}%
+\def\XINT_flexpr_print #1%
+{%
+ \expandafter\xintPFloat::csv
+ \romannumeral`&&@\expandafter\XINT_expr_unlock_sp\string #1!%
+}%
+\def\XINT_expr_unlock_sp #1.;#2.=#3!{{#2}{#3}}%
+% \end{macrocode}
+% \subsection{\csh{xinttheexpr}, \csh{xinttheiexpr}, \csh{xintthefloatexpr},
+% \csh{xinttheiiexpr}}
+% \lverb|The reason why \xinttheiexpr et \xintthefloatexpr are handled
+% differently is that they admit an optional argument which acts via a custom
+% «printing» stage.|
+% \begin{macrocode}
+\def\xinttheexpr
+ {\romannumeral`&&@\expandafter\XINT_expr_print\romannumeral0\xintbareeval}%
+\def\xinttheiexpr
+ {\romannumeral`&&@\expandafter\xint_gobble_iii\romannumeral`&&@\xintiexpr}%
+\def\xintthefloatexpr
+ {\romannumeral`&&@\expandafter\xint_gobble_iii\romannumeral`&&@\xintfloatexpr}%
+\def\xinttheiiexpr
+ {\romannumeral`&&@\expandafter\XINT_iiexpr_print\romannumeral0\xintbareiieval}%
+% \end{macrocode}
+% \subsection{\csh{thexintexpr}, \csh{thexintiexpr}, \csh{thexintfloatexpr},
+% \csh{thexintiiexpr}}
+% \lverb|New with 1.2h. I have been for the last three years very strict
+% regarding macros with \xint or \XINT, but well.|
+% \begin{macrocode}
+\let\thexintexpr \xinttheexpr
+\let\thexintiexpr \xinttheiexpr
+\let\thexintfloatexpr\xintthefloatexpr
+\let\thexintiiexpr \xinttheiiexpr
+% \end{macrocode}
+% \subsection{\csh{xinteval}, \csh{xintieval}, \csh{xintfloateval},
+% \csh{xintiieval}}
+% \begin{macrocode}
+\def\xinteval #1%
+ {\romannumeral`&&@\expandafter\XINT_expr_print\romannumeral0\xintbareeval#1\relax}%
+\def\xintieval #1%
+ {\romannumeral`&&@\expandafter\xint_gobble_iii\romannumeral`&&@\xintiexpr#1\relax}%
+\def\xintfloateval #1%
+ {\romannumeral`&&@\expandafter\xint_gobble_iii\romannumeral`&&@\xintfloatexpr#1\relax}%
+\def\xintiieval #1%
+ {\romannumeral`&&@\expandafter\XINT_iiexpr_print\romannumeral0\xintbareiieval#1\relax}%
+% \end{macrocode}
+% \subsection{\csh{xintthe}}
+% \begin{macrocode}
+\def\xintthe #1{\romannumeral`&&@\expandafter\xint_gobble_iii\romannumeral`&&@#1}%
+% \end{macrocode}
+% \subsection{\csh{xintbareeval}, \csh{xintbarefloateval}, \csh{xintbareiieval}}
+% \begin{macrocode}
+\def\xintbareeval
+ {\expandafter\XINT_expr_until_end_a\romannumeral`&&@\XINT_expr_getnext }%
+\def\xintbarefloateval
+ {\expandafter\XINT_flexpr_until_end_a\romannumeral`&&@\XINT_expr_getnext }%
+\def\xintbareiieval
+ {\expandafter\XINT_iiexpr_until_end_a\romannumeral`&&@\XINT_expr_getnext }%
+% \end{macrocode}
+% \subsection{\csh{xintthebareeval}, \csh{xintthebarefloateval}, \csh{xintthebareiieval}}
+% \begin{macrocode}
+\def\xintthebareeval {\expandafter\XINT_expr_unlock\romannumeral0\xintbareeval}%
+\def\xintthebarefloateval {\expandafter\XINT_expr_unlock\romannumeral0\xintbarefloateval}%
+\def\xintthebareiieval {\expandafter\XINT_expr_unlock\romannumeral0\xintbareiieval}%
+% \end{macrocode}
+% \subsection{\csh{xintboolexpr}, \csh{XINT_boolexpr_print}, \csh{xinttheboolexpr},
+% \csh{thexintboolexpr}}
+% \lverb|ATTENTION! 1.3d renamed \xinteval to \xintexpro etc...|
+% \begin{macrocode}
+\def\xintboolexpr
+{%
+ \romannumeral0\expandafter\expandafter\expandafter
+ \XINT_boolexpr_done\expandafter\xint_gobble_iv\romannumeral0\xintexpro
+}%
+\def\XINT_boolexpr_done {!\XINT_expr_usethe\XINT_protectii\XINT_boolexpr_print}%
+\def\XINT_boolexpr_print #1{\xintIsTrue::csv {\XINT_expr_unlock #1}}%
+\def\xinttheboolexpr
+{%
+ \romannumeral`&&@\expandafter\expandafter\expandafter
+ \XINT_boolexpr_print\expandafter\xint_gobble_iv\romannumeral0\xintexpro
+}%
+\let\thexintboolexpr\xinttheboolexpr
+% \end{macrocode}
+% \subsection{\csh{xintifboolexpr}, \csh{xintifboolfloatexpr}, \csh{xintifbooliiexpr}}
+% \lverb|Do not work with comma separated expressions.|
+% \begin{macrocode}
+\def\xintifboolexpr #1{\romannumeral0\xintiiifnotzero {\xinttheexpr #1\relax}}%
+\def\xintifboolfloatexpr #1{\romannumeral0\xintiiifnotzero {\xintthefloatexpr #1\relax}}%
+\def\xintifbooliiexpr #1{\romannumeral0\xintiiifnotzero {\xinttheiiexpr #1\relax}}%
+% \end{macrocode}
+% \subsection{\csh{xintifsgnexpr}, \csh{xintifsgnfloatexpr}, \csh{xintifsgniiexpr}}
+% \changed{1.3d}{}
+% \lverb|Do not work with comma separated expressions.|
+% \begin{macrocode}
+\def\xintifsgnexpr #1{\romannumeral0\xintiiifsgn {\xinttheexpr #1\relax}}%
+\def\xintifsgnfloatexpr #1{\romannumeral0\xintiiifsgn {\xintthefloatexpr #1\relax}}%
+\def\xintifsgniiexpr #1{\romannumeral0\xintiiifsgn {\xinttheiiexpr #1\relax}}%
+% \end{macrocode}
+% \subsection{\csh{xintthecoords}}
+% \lverb|1.1 Wraps up an even number of comma separated items into pairs of
+% TikZ coordinates; for use in the following way:
+%
+% coordinates {\xintthecoords\xintfloatexpr ... \relax}
+%
+% The crazyness with the \csname and unlock is due to TikZ somewhat STRANGE
+% control of the TOTAL number of expansions which should not exceed the very low
+% value of 100 !! As we implemented \XINT_thecoords_b in an "inline" style for
+% efficiency, we need to hide its expansions.
+%
+% Not to be used as \xintthecoords\xintthefloatexpr, only as
+% \xintthecoords\xintfloatexpr (or \xintiexpr etc...). Perhaps \xintthecoords
+% could make an extra check, but one should not accustom users to too loose
+% requirements!|
+% \begin{macrocode}
+\def\xintthecoords #1{\romannumeral`&&@\expandafter\expandafter\expandafter
+ \XINT_thecoords_a
+ \expandafter\xint_gobble_iii\romannumeral0#1}%
+\def\XINT_thecoords_a #1#2% #1=print macro, indispensible for scientific notation
+ {\expandafter\XINT_expr_unlock\csname.=\expandafter\XINT_thecoords_b
+ \romannumeral`&&@#1#2,!,!,^\endcsname }%
+\def\XINT_thecoords_b #1#2,#3#4,%
+ {\xint_gob_til_! #3\XINT_thecoords_c ! (#1#2, #3#4)\XINT_thecoords_b }%
+\def\XINT_thecoords_c #1^{}%
+% \end{macrocode}
+% \subsection{Locking and unlocking}
+% \lverb|Some renaming and modifications here with release 1.2 to switch from
+% using chains of \romannumeral-`0 in order to gather numbers, possibly
+% hexadecimals, to using a \csname governed expansion. In this way no more
+% limit at 5000 digits, and besides this is a logical move because the
+% \xintexpr parser is already based on \csname...\endcsname storage of numbers
+% as one token.
+%
+% The limitation at 5000 digits didn't worry me too much because it was not
+% very realistic to launch computations with thousands of digits... such
+% computations are still slow with 1.2 but less so now. Chains or
+% \romannumeral are still used for the gathering of function names and other
+% stuff which I have half-forgotten because the parser does many things.
+%
+% In the earlier versions we used the lockscan macro after a chain of
+% \romannumeral-`0 had ended gathering digits; this uses has been replaced by
+% direct processing inside a \csname...\endcsname and the macro is kept only
+% for matters of dummy variables.
+%
+% Currently, the parsing of hexadecimal numbers needs two nested
+% \csname...\endcsname, first to gather the letters (possibly with a hexadecimal
+% fractional part), and in a second stage to apply \xintHexToDec to do the
+% actual conversion. This should be faster than updating on the fly the number
+% (which would be hard for the fraction part...).|
+% \begin{macrocode}
+\def\xint_gob_til_! #1!{}% ! with catcode 11
+\def\XINT_expr_lockscan#1{% not used for decimal numbers in xintexpr 1.2
+\def\XINT_expr_lockscan##1!{\expandafter#1\csname .=##1\endcsname}%
+}\XINT_expr_lockscan{ }%
+\def\XINT_expr_lockit#1{%
+\def\XINT_expr_lockit##1{\expandafter#1\csname .=##1\endcsname}%
+}\XINT_expr_lockit{ }%
+\def\XINT_expr_unlock_hex_in #1% expanded inside \csname..\endcsname
+ {\expandafter\XINT_expr_inhex\romannumeral`&&@\XINT_expr_unlock#1;}%
+\def\XINT_expr_inhex #1.#2#3;% expanded inside \csname..\endcsname
+{%
+ \if#2>%
+ \xintHexToDec{#1}%
+ \else
+ \xintiiMul{\xintiiPow{625}{\xintLength{#3}}}{\xintHexToDec{#1#3}}%
+ [\the\numexpr-4*\xintLength{#3}]%
+ \fi
+}%
+\def\XINT_expr_unlock {\expandafter\XINT_expr_unlock_a\string }%
+\def\XINT_expr_unlock_a #1.={}%
+\def\XINT_expr_unexpectedtoken {\xintError:ignored }%
+\let\XINT_expr_done\space
+% \end{macrocode}
+% \subsection{Hooks for the functioning of \cshnolabel{xintNewExpr} and
+% \cshnolabel{xintdeffunc}}
+% \lverb|This is new with 1.3. See \XINT_expr_redefinemacros.|
+% \begin{macrocode}
+\let\XINT:NEhook:one\empty
+\let\XINT:NEhook:two\empty
+\let\XINT:NEhook:csv\empty
+\def\XINT:NEhook:twosp #1,#2,!#3{#3{#1}{#2}}%
+% \end{macrocode}
+% \subsection{Macros handling csv lists on output (for \cshnolabel{XINT_expr_print} et
+% al. routines)}
+% \localtableofcontents
+% \lverb|Changed completely for 1.1, which adds the optional arguments to
+% \xintiexpr and \xintfloatexpr.|
+% \subsubsection{\csh{XINT_::_end}}
+% \lverb|Le mécanisme est le suivant, #2 est dans des accolades et commence par
+% ,<sp>. Donc le gobble se débarrasse du, et le <sp> après brace stripping
+% arrête un \romannumeral0 ou \romannumeral-`0|
+% \begin{macrocode}
+\def\XINT_::_end #1,#2{\xint_gobble_i #2}%
+% \end{macrocode}
+% \subsubsection{\csh{xintCSV::csv}}
+% \begin{macrocode}
+\def\xintCSV::csv #1{\expandafter\XINT_csv::_a\romannumeral`&&@#1,^,}%
+\def\XINT_csv::_a {\XINT_csv::_b {}}%
+\def\XINT_csv::_b #1#2,{\expandafter\XINT_csv::_c \romannumeral`&&@#2,{#1}}%
+\def\XINT_csv::_c #1{\if ^#1\expandafter\XINT_::_end\fi\XINT_csv::_d #1}%
+\def\XINT_csv::_d #1,#2{\XINT_csv::_b {#2, #1}}% possibly, item #1 is empty.
+% \end{macrocode}
+% \subsubsection{\csh{xintSPRaw}, \csh{xintSPRaw::csv}}
+% \begin{macrocode}
+\def\xintSPRaw {\romannumeral0\xintspraw }%
+\def\xintspraw #1{\expandafter\XINT_spraw\romannumeral`&&@#1[\W]}%
+\def\XINT_spraw #1[#2#3]{\xint_gob_til_W #2\XINT_spraw_a\W\XINT_spraw_p #1[#2#3]}%
+\def\XINT_spraw_a\W\XINT_spraw_p #1[\W]{ #1}%
+\def\XINT_spraw_p #1[\W]{\xintpraw {#1}}%
+\def\xintSPRaw::csv #1{\romannumeral0\expandafter\XINT_spraw::_a\romannumeral`&&@#1,^,}%
+\def\XINT_spraw::_a {\XINT_spraw::_b {}}%
+\def\XINT_spraw::_b #1#2,{\expandafter\XINT_spraw::_c \romannumeral`&&@#2,{#1}}%
+\def\XINT_spraw::_c #1{\if ,#1\xint_dothis\XINT_spraw::_e\fi
+ \if ^#1\xint_dothis\XINT_::_end\fi
+ \xint_orthat\XINT_spraw::_d #1}%
+\def\XINT_spraw::_d #1,{\expandafter\XINT_spraw::_e\romannumeral0\XINT_spraw #1[\W],}%
+\def\XINT_spraw::_e #1,#2{\XINT_spraw::_b {#2, #1}}%
+% \end{macrocode}
+% \subsubsection{\csh{xintIsTrue::csv}}
+% \begin{macrocode}
+\def\xintIsTrue::csv #1{\romannumeral0\expandafter\XINT_istrue::_a\romannumeral`&&@#1,^,}%
+\def\XINT_istrue::_a {\XINT_istrue::_b {}}%
+\def\XINT_istrue::_b #1#2,{\expandafter\XINT_istrue::_c \romannumeral`&&@#2,{#1}}%
+\def\XINT_istrue::_c #1{\if ,#1\xint_dothis\XINT_istrue::_e\fi
+ \if ^#1\xint_dothis\XINT_::_end\fi
+ \xint_orthat\XINT_istrue::_d #1}%
+\def\XINT_istrue::_d #1,{\expandafter\XINT_istrue::_e\romannumeral0\xintisnotzero {#1},}%
+\def\XINT_istrue::_e #1,#2{\XINT_istrue::_b {#2, #1}}%
+% \end{macrocode}
+% \subsubsection{\csh{xintRound::csv}}
+% \lverb|
+% 1.3e Emploi d'un point comme délimiteur. Dans le futur donner une signification
+% à un #1 négatif dans \XINT_round::_a ?
+% |
+% \begin{macrocode}
+\def\XINT_:::_end #1,#2#3{\xint_gobble_i #3}%
+\def\xintRound::csv #1#2{\romannumeral0\expandafter\XINT_round::_a
+ \the\numexpr#1\expandafter.\romannumeral`&&@#2,^,}%
+\def\XINT_round::_a #1.{\XINT_round::_b #1.{}}%
+\def\XINT_round::_b #1.#2#3,{\expandafter\XINT_round::_c \romannumeral`&&@#3,{#1}{#2}}%
+\def\XINT_round::_c #1{\if ,#1\xint_dothis\XINT_round::_e\fi
+ \if ^#1\xint_dothis\XINT_:::_end\fi
+ \xint_orthat\XINT_round::_d #1}%
+\def\XINT_round::_d #1,#2{%
+ \expandafter\XINT_round::_e\romannumeral0\ifnum#2>\xint_c_
+ \expandafter\xintround\else\expandafter\xintiround\fi {#2}{#1},{#2}}%
+\def\XINT_round::_e #1,#2#3{\XINT_round::_b #2.{#3, #1}}%
+% \end{macrocode}
+% \subsubsection{\csh{XINTinFloat::csv}}
+% \lverb|&
+% 1.3e adds support for a negative specifier (\XINT_infloat::_a inserted, by
+% luck formerly it started straight with \XINT_infloat::_b ...).
+%
+% |
+% \begin{macrocode}
+\def\XINTinFloat::csv #1#2{\romannumeral0\expandafter\XINT_infloat::_a
+ \the\numexpr #1\expandafter.\romannumeral`&&@#2,^,}%
+\def\XINT_infloat::_a #1#2.%
+ {\expandafter\XINT_infloat::_b\the\numexpr\if#1-\XINTdigits\fi#1#2.{}}%
+\def\XINT_infloat::_b #1.#2#3,{\XINT_infloat::_c #3,{#1}{#2}}%
+\def\XINT_infloat::_c #1{\if ,#1\xint_dothis\XINT_infloat::_e\fi
+ \if ^#1\xint_dothis\XINT_:::_end\fi
+ \xint_orthat\XINT_infloat::_d #1}%
+\def\XINT_infloat::_d #1,#2%
+ {\expandafter\XINT_infloat::_e\romannumeral0\XINTinfloat [#2]{#1},{#2}}%
+\def\XINT_infloat::_e #1,#2#3{\XINT_infloat::_b #2.{#3, #1}}%
+% \end{macrocode}
+% \subsubsection{\csh{xintPFloat::csv}}
+% \lverb|&
+% Also extended at 1.3e to handle negative optional specifier for digits
+% precision. This macro formats output.
+%
+% |
+% \begin{macrocode}
+\def\xintPFloat::csv #1#2{\romannumeral0\expandafter\XINT_pfloat::_a
+ \the\numexpr #1\expandafter.\romannumeral`&&@#2,^,}%
+\def\XINT_pfloat::_a #1#2.%
+ {\expandafter\XINT_pfloat::_b\the\numexpr\if#1-\XINTdigits\fi#1#2.{}}%
+\def\XINT_pfloat::_b #1.#2#3,{\expandafter\XINT_pfloat::_c \romannumeral`&&@#3,{#1}{#2}}%
+\def\XINT_pfloat::_c #1{\if ,#1\xint_dothis\XINT_pfloat::_e\fi
+ \if ^#1\xint_dothis\XINT_:::_end\fi
+ \xint_orthat\XINT_pfloat::_d #1}%
+\def\XINT_pfloat::_d #1,#2%
+ {\expandafter\XINT_pfloat::_e\romannumeral0\XINT_pfloat_opt [\xint:#2]{#1},{#2}}%
+\def\XINT_pfloat::_e #1,#2#3{\XINT_pfloat::_b #2.{#3, #1}}%
+% \end{macrocode}
+% \subsection{\csh{XINT_expr_getnext}: fetching some number then an operator}
+% \lverb|Big change in 1.1, no attempt to detect braced stuff anymore as the
+% [N] notation is implemented otherwise. Now, braces should not be used at
+% all; one level removed, then \romannumeral-`0 expansion.|
+% \begin{macrocode}
+\def\XINT_expr_getnext #1%
+{%
+ \expandafter\XINT_expr_getnext_a\romannumeral`&&@#1%
+}%
+\def\XINT_expr_getnext_a #1%
+{% screens out sub-expressions and \count or \dimen registers/variables
+ \xint_gob_til_! #1\XINT_expr_subexpr !% recall this ! has catcode 11
+ \ifcat\relax#1% \count or \numexpr etc... token or count, dimen, skip cs
+ \expandafter\XINT_expr_countetc
+ \else
+ \expandafter\expandafter\expandafter\XINT_expr_getnextfork\expandafter\string
+ \fi
+ #1%
+}%
+\def\XINT_expr_subexpr !#1\fi !{\expandafter\XINT_expr_getop\xint_gobble_iii }%
+% \end{macrocode}
+% \lverb|1.2 adds \ht, \dp, \wd and the eTeX font things.|
+% \begin{macrocode}
+\def\XINT_expr_countetc #1%
+{%
+ \ifx\count#1\else\ifx\dimen#1\else\ifx\numexpr#1\else\ifx\dimexpr#1\else
+ \ifx\skip#1\else\ifx\glueexpr#1\else\ifx\fontdimen#1\else\ifx\ht#1\else
+ \ifx\dp#1\else\ifx\wd#1\else\ifx\fontcharht#1\else\ifx\fontcharwd#1\else
+ \ifx\fontchardp#1\else\ifx\fontcharic#1\else
+ \XINT_expr_unpackvar
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \expandafter\XINT_expr_getnext\number #1%
+}%
+\def\XINT_expr_unpackvar\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \expandafter\XINT_expr_getnext\number #1%
+ {\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \expandafter\XINT_expr_getop\csname .=\number#1\endcsname }%
+\begingroup
+\lccode`*=`#
+\lowercase{\endgroup
+\def\XINT_expr_getnextfork #1{%
+ \if#1*\xint_dothis {\XINT_expr_scan_macropar *}\fi
+ \if#1[\xint_dothis {\xint_c_xviii ({}}\fi
+ \if#1+\xint_dothis \XINT_expr_getnext \fi
+ \if#1.\xint_dothis {\XINT_expr_startdec}\fi
+ \if#1-\xint_dothis -\fi
+ \if#1(\xint_dothis {\xint_c_xviii ({}}\fi
+ \xint_orthat {\XINT_expr_scan_nbr_or_func #1}%
+}}%
+\def\XINT_expr_scan_macropar #1#2{\expandafter\XINT_expr_getop\csname .=#1#2\endcsname }%
+% \end{macrocode}
+% \subsection{\csh{XINT_expr_scan_nbr_or_func}: the integer or decimal number or hexa-decimal number or
+% function name or variable name or special hacky things big parser}
+% \localtableofcontents
+% \lverb@1.2 release has replaced chains of \romannumeral-`0 by \csname
+% governed expansion. Thus there is no more the limit at about 5000 digits for
+% parsed numbers.
+%
+% In order to avoid having to lock and unlock in succession to handle the
+% scientific part and adjust the exponent according to the number of digits of
+% the decimal part, the parsing of this decimal part counts on the fly the
+% number of digits it encounters.
+%
+% There is some slight annoyance with \xintiiexpr which should never be given
+% a [n] inside its \csname.=<digits>\endcsname storage of numbers (because its
+% arithmetic uses the ii macros which know nothing about the [N] notation).
+% Hence if the parser has only seen digits when hitting something else than
+% the dot or e (or E), it will not insert a [0]. Thus we very slightly
+% compromise the efficiency of \xintexpr and \xintfloatexpr in order to be
+% able to share the same code with \xintiiexpr.
+%
+% Indeed, the parser at this location is completely common to all, it does not
+% know if it is working inside \xintexpr or \xintiiexpr. On the other hand if
+% a dot or a e (or E) is met, then the (common) parser has no scrupules ending
+% this number with a [n], this will provoke an error later if that was within
+% an \xintiiexpr, as soon as an arithmetic macro is used.
+%
+% As the gathered numbers have no spaces, no pluses, no minuses, the only
+% remaining issue is with leading zeroes, which are discarded on the fly. The
+% hexadecimal numbers leading zeroes are stripped in a second stage by the
+% \xintHexToDec macro.
+%
+% With 1.2, \xinttheexpr . \relax does not work anymore (it did in earlier
+% releases). There must be digits either before or after the decimal mark. Thus
+% both \xinttheexpr 1.\relax and \xinttheexpr .1\relax are legal.
+%
+% The ` syntax is here used for special constructs like `+`(..), `*`(..) where
+% + or * will be treated as functions. Current implementation picks only one
+% token (could have been braced stuff), here it will be + or *, and via
+% \XINT_expr_op_` this then becomes a suitable
+% \XINT_{expr|iiexpr|flexpr}_func_+ (or *). Documentation says to use
+% `+`(...), but `+(...) is also valid. The opening parenthesis must be there,
+% it is not allowed to come from expansion.@
+%
+% \begin{macrocode}
+\catcode96 11 % `
+\def\XINT_expr_scan_nbr_or_func #1% this #1 has necessarily here catcode 12
+{%(
+ \if )#1\xint_dothis \XINT_expr_gotnil \fi
+ \if "#1\xint_dothis \XINT_expr_scanhex_I\fi
+ \if `#1\xint_dothis {\XINT_expr_onliteral_`}\fi
+ \ifnum \xint_c_ix<1#1 \xint_dothis \XINT_expr_startint\fi
+ \xint_orthat \XINT_expr_scanfunc #1%
+}%
+\def\XINT_expr_gotnil{\expandafter\XINT_expr_getop\csname.= \endcsname}%
+\def\XINT_expr_onliteral_` #1#2#3({\xint_c_xviii `{#2}}%
+\catcode96 12 % `
+\def\XINT_expr_startint #1%
+{%
+ \if #10\expandafter\XINT_expr_gobz_a\else\XINT_expr_scanint_a\fi #1%
+}%
+\def\XINT_expr_scanint_a #1#2%
+ {\expandafter\XINT_expr_getop\csname.=#1%
+ \expandafter\XINT_expr_scanint_b\romannumeral`&&@#2}%
+\def\XINT_expr_gobz_a #1%
+ {\expandafter\XINT_expr_getop\csname.=%
+ \expandafter\XINT_expr_gobz_scanint_b\romannumeral`&&@#1}%
+\def\XINT_expr_startdec #1%
+ {\expandafter\XINT_expr_getop\csname.=%
+ \expandafter\XINT_expr_scandec_a\romannumeral`&&@#1}%
+% \end{macrocode}
+% \subsubsection{Integral part (skipping zeroes)}
+% \lverb|1.2 has modified the code to give highest priority to digits, the
+% accelerating impact is non-negligeable. I don't think the doubled \string is
+% a serious penalty.|
+% \begin{macrocode}
+\def\XINT_expr_scanint_b #1%
+{%
+ \ifcat \relax #1\expandafter\XINT_expr_scanint_endbycs\expandafter #1\fi
+ \ifnum\xint_c_ix<1\string#1 \else\expandafter\XINT_expr_scanint_c\fi
+ \string#1\XINT_expr_scanint_d
+}%
+\def\XINT_expr_scanint_d #1%
+{%
+ \expandafter\XINT_expr_scanint_b\romannumeral`&&@#1%
+}%
+\def\XINT_expr_scanint_endbycs#1#2\XINT_expr_scanint_d{\endcsname #1}%
+% \end{macrocode}
+% \lverb|With 1.2d the tacit multiplication in front of a variable name or
+% function name is now done with a higher precedence, intermediate between the
+% common one of * and / and the one of ^. Thus x/2y is like x/(2y), but x^2y
+% is like x^2*y and 2y! is not (2y)! but 2*y!.
+%
+% Finally, 1.2d has moved away from the _scan macros all the business of the
+% tacit multiplication in one unique place via \XINT_expr_getop. For this, the
+% ending token is not first given to \string as was done earlier before
+% handing over back control to \XINT_expr_getop. Earlier we had to identify
+% the catcode 11 ! signaling a sub-expression here. With no \string applied
+% we can do it in \XINT_expr_getop. As a corollary of this displacement,
+% parsing of big numbers should be a tiny bit faster now.
+%
+% Extended for 1.2l to ignore underscore character _ if encountered within
+% digits; so it can serve as separator for better readability.|
+% \begin{macrocode}
+\def\XINT_expr_scanint_c\string #1\XINT_expr_scanint_d
+{%
+ \if _#1\xint_dothis\XINT_expr_scanint_d\fi
+ \if e#1\xint_dothis{[\the\numexpr0\XINT_expr_scanexp_a +}\fi
+ \if E#1\xint_dothis{[\the\numexpr0\XINT_expr_scanexp_a +}\fi
+ \if .#1\xint_dothis{\XINT_expr_startdec_a .}\fi
+ \xint_orthat {\endcsname #1}%
+}%
+\def\XINT_expr_startdec_a .#1%
+{%
+ \expandafter\XINT_expr_scandec_a\romannumeral`&&@#1%
+}%
+\def\XINT_expr_scandec_a #1%
+{%
+ \if .#1\xint_dothis{\endcsname..}\fi
+ \xint_orthat {\XINT_expr_scandec_b 0.#1}%
+}%
+\def\XINT_expr_gobz_scanint_b #1%
+{%
+ \ifcat \relax #1\expandafter\XINT_expr_gobz_scanint_endbycs\expandafter #1\fi
+ \ifnum\xint_c_x<1\string#1 \else\expandafter\XINT_expr_gobz_scanint_c\fi
+ \string#1\XINT_expr_scanint_d
+}%
+\def\XINT_expr_gobz_scanint_endbycs#1#2\XINT_expr_scanint_d{0\endcsname #1}%
+\def\XINT_expr_gobz_scanint_c\string #1\XINT_expr_scanint_d
+{%
+ \if _#1\xint_dothis\XINT_expr_gobz_scanint_d\fi
+ \if e#1\xint_dothis{0[\the\numexpr0\XINT_expr_scanexp_a +}\fi
+ \if E#1\xint_dothis{0[\the\numexpr0\XINT_expr_scanexp_a +}\fi
+ \if .#1\xint_dothis{\XINT_expr_gobz_startdec_a .}\fi
+ \if 0#1\xint_dothis\XINT_expr_gobz_scanint_d\fi
+ \xint_orthat {0\endcsname #1}%
+}%
+\def\XINT_expr_gobz_scanint_d #1%
+{%
+ \expandafter\XINT_expr_gobz_scanint_b\romannumeral`&&@#1%
+}%
+\def\XINT_expr_gobz_startdec_a .#1%
+{%
+ \expandafter\XINT_expr_gobz_scandec_a\romannumeral`&&@#1%
+}%
+\def\XINT_expr_gobz_scandec_a #1%
+{%
+ \if .#1\xint_dothis{0\endcsname..}\fi
+ \xint_orthat {\XINT_expr_gobz_scandec_b 0.#1}%
+}%
+% \end{macrocode}
+% \subsubsection{Fractional part}
+% \lverb|Annoying duplication of code to allow 0. as input.
+%
+% 1.2a corrects a very bad bug in 1.2 \XINT_expr_gobz_scandec_b which should
+% have stripped leading zeroes in the fractional part but didn't; as a result
+% \xinttheexpr 0.01\relax returned 0 =:-((( Thanks to Kroum Tzanev who
+% reported the issue. Does it improve things if I say the bug was introduced
+% in 1.2, it wasn't present before ?|
+% \begin{macrocode}
+\def\XINT_expr_scandec_b #1.#2%
+{%
+ \ifcat \relax #2\expandafter\XINT_expr_scandec_endbycs\expandafter#2\fi
+ \ifnum\xint_c_ix<1\string#2 \else\expandafter\XINT_expr_scandec_c\fi
+ \string#2\expandafter\XINT_expr_scandec_d\the\numexpr #1-\xint_c_i.%
+}%
+\def\XINT_expr_scandec_endbycs #1#2\XINT_expr_scandec_d
+ \the\numexpr#3-\xint_c_i.{[#3]\endcsname #1}%
+\def\XINT_expr_scandec_d #1.#2%
+{%
+ \expandafter\XINT_expr_scandec_b
+ \the\numexpr #1\expandafter.\romannumeral`&&@#2%
+}%
+\def\XINT_expr_scandec_c\string #1#2\the\numexpr#3-\xint_c_i.%
+{%
+ \if _#1\xint_dothis{\XINT_expr_scandec_d#3.}\fi
+ \if e#1\xint_dothis{[\the\numexpr#3\XINT_expr_scanexp_a +}\fi
+ \if E#1\xint_dothis{[\the\numexpr#3\XINT_expr_scanexp_a +}\fi
+ \xint_orthat {[#3]\endcsname #1}%
+}%
+% \end{macrocode}
+% \begin{macrocode}
+\def\XINT_expr_gobz_scandec_b #1.#2%
+{%
+ \ifcat \relax #2\expandafter\XINT_expr_gobz_scandec_endbycs\expandafter#2\fi
+ \ifnum\xint_c_ix<1\string#2 \else\expandafter\XINT_expr_gobz_scandec_c\fi
+ \if0#2\expandafter\xint_firstoftwo\else\expandafter\xint_secondoftwo\fi
+ {\expandafter\XINT_expr_gobz_scandec_b}%
+ {\string#2\expandafter\XINT_expr_scandec_d}\the\numexpr#1-\xint_c_i.%
+}%
+% \end{macrocode}
+% \begin{macrocode}
+\def\XINT_expr_gobz_scandec_endbycs #1#2\xint_c_i.{0[0]\endcsname #1}%
+\def\XINT_expr_gobz_scandec_c\if0#1#2\fi #3\numexpr#4-\xint_c_i.%
+{%
+ \if _#1\xint_dothis{\XINT_expr_gobz_scandec_b #4.}\fi
+ \if e#1\xint_dothis{0[\the\numexpr0\XINT_expr_scanexp_a +}\fi
+ \if E#1\xint_dothis{0[\the\numexpr0\XINT_expr_scanexp_a +}\fi
+ \xint_orthat {0[0]\endcsname #1}%
+}%
+% \end{macrocode}
+% \subsubsection{Scientific notation}
+% \lverb|Some pluses and minuses are allowed at the start of the scientific
+% part, however not later, and no parenthesis.|
+% \begin{macrocode}
+\def\XINT_expr_scanexp_a #1#2%
+{%
+ #1\expandafter\XINT_expr_scanexp_b\romannumeral`&&@#2%
+}%
+\def\XINT_expr_scanexp_b #1%
+{%
+ \ifcat \relax #1\expandafter\XINT_expr_scanexp_endbycs\expandafter #1\fi
+ \ifnum\xint_c_ix<1\string#1 \else\expandafter\XINT_expr_scanexp_c\fi
+ \string#1\XINT_expr_scanexp_d
+}%
+\def\XINT_expr_scanexpr_endbycs#1#2\XINT_expr_scanexp_d {]\endcsname #1}%
+\def\XINT_expr_scanexp_d #1%
+{%
+ \expandafter\XINT_expr_scanexp_bb\romannumeral`&&@#1%
+}%
+\def\XINT_expr_scanexp_c\string #1\XINT_expr_scanexp_d
+{%
+ \if _#1\xint_dothis \XINT_expr_scanexp_d \fi
+ \if +#1\xint_dothis {\XINT_expr_scanexp_a +}\fi
+ \if -#1\xint_dothis {\XINT_expr_scanexp_a -}\fi
+ \xint_orthat {]\endcsname #1}%
+}%
+\def\XINT_expr_scanexp_bb #1%
+{%
+ \ifcat \relax #1\expandafter\XINT_expr_scanexp_endbycs_b\expandafter #1\fi
+ \ifnum\xint_c_ix<1\string#1 \else\expandafter\XINT_expr_scanexp_cb\fi
+ \string#1\XINT_expr_scanexp_db
+}%
+\def\XINT_expr_scanexp_endbycs_b#1#2\XINT_expr_scanexp_db {]\endcsname #1}%
+\def\XINT_expr_scanexp_db #1%
+{%
+ \expandafter\XINT_expr_scanexp_bb\romannumeral`&&@#1%
+}%
+\def\XINT_expr_scanexp_cb\string #1\XINT_expr_scanexp_db
+{%
+ \if _#1\xint_dothis\XINT_expr_scanexp_d\fi
+ \xint_orthat{]\endcsname #1}%
+}%
+% \end{macrocode}
+% \subsubsection{Hexadecimal numbers}
+% \lverb|1.2d has moved most of the handling of tacit multiplication to
+% \XINT_expr_getop, but we have to do some of it here, because we apply
+% \string before calling \XINT_expr_scanhexI_aa. I do not insert the *
+% in \XINT_expr_scanhexI_a, because it is its higher precedence variant which
+% will is expected, to do the same as when a non-hexadecimal number prefixes a
+% sub-expression. Tacit multiplication in front of variable or function names
+% will not work (because of this \string).
+%
+% Extended for 1.2l to ignore underscore character _ if encountered within
+% digits.|
+% \begin{macrocode}
+\def\XINT_expr_scanhex_I #1% #1="
+{%
+ \expandafter\XINT_expr_getop\csname.=\expandafter
+ \XINT_expr_unlock_hex_in\csname.=\XINT_expr_scanhexI_a
+}%
+\def\XINT_expr_scanhexI_a #1%
+{%
+ \ifcat #1\relax\xint_dothis{.>\endcsname\endcsname #1}\fi
+ \ifx !#1\xint_dothis{.>\endcsname\endcsname !}\fi
+ \xint_orthat {\expandafter\XINT_expr_scanhexI_aa\string #1}%
+}%
+\def\XINT_expr_scanhexI_aa #1%
+{%
+ \if\ifnum`#1>`/
+ \ifnum`#1>`9
+ \ifnum`#1>`@
+ \ifnum`#1>`F
+ 0\else1\fi\else0\fi\else1\fi\else0\fi 1%
+ \expandafter\XINT_expr_scanhexI_b
+ \else
+ \if _#1\xint_dothis{\expandafter\XINT_expr_scanhexI_bgob}\fi
+ \if .#1\xint_dothis{\expandafter\XINT_expr_scanhex_transition}\fi
+ \xint_orthat % gather what we got so far, leave catcode 12 #1 in stream
+ {\xint_afterfi {.>\endcsname\endcsname}}%
+ \fi
+ #1%
+}%
+\def\XINT_expr_scanhexI_b #1#2%
+{%
+ #1\expandafter\XINT_expr_scanhexI_a\romannumeral`&&@#2%
+}%
+\def\XINT_expr_scanhexI_bgob #1#2%
+{%
+ \expandafter\XINT_expr_scanhexI_a\romannumeral`&&@#2%
+}%
+\def\XINT_expr_scanhex_transition .#1%
+{%
+ \expandafter.\expandafter.\expandafter
+ \XINT_expr_scanhexII_a\romannumeral`&&@#1%
+}%
+\def\XINT_expr_scanhexII_a #1%
+{%
+ \ifcat #1\relax\xint_dothis{\endcsname\endcsname#1}\fi
+ \ifx !#1\xint_dothis{\endcsname\endcsname !}\fi
+ \xint_orthat {\expandafter\XINT_expr_scanhexII_aa\string #1}%
+}%
+\def\XINT_expr_scanhexII_aa #1%
+{%
+ \if\ifnum`#1>`/
+ \ifnum`#1>`9
+ \ifnum`#1>`@
+ \ifnum`#1>`F
+ 0\else1\fi\else0\fi\else1\fi\else0\fi 1%
+ \expandafter\XINT_expr_scanhexII_b
+ \else
+ \if _#1\xint_dothis{\expandafter\XINT_expr_scanhexII_bgob}\fi
+ \xint_orthat{\xint_afterfi {\endcsname\endcsname}}%
+ \fi
+ #1%
+}%
+\def\XINT_expr_scanhexII_b #1#2%
+{%
+ #1\expandafter\XINT_expr_scanhexII_a\romannumeral`&&@#2%
+}%
+\def\XINT_expr_scanhexII_bgob #1#2%
+{%
+ \expandafter\XINT_expr_scanhexII_a\romannumeral`&&@#2%
+}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_scanfunc}: parsing names of functions and variables}
+% \begin{macrocode}
+\def\XINT_expr_scanfunc
+{%
+ \expandafter\XINT_expr_func\romannumeral`&&@\XINT_expr_scanfunc_a
+}%
+\def\XINT_expr_scanfunc_a #1#2%
+{%
+ \expandafter #1\romannumeral`&&@\expandafter\XINT_expr_scanfunc_b\romannumeral`&&@#2%
+}%
+% \end{macrocode}
+% \lverb|This handles: 1) (indirectly) tacit multiplication by a variable in
+% front a of sub-expression, 2) (indirectly) tacit multiplication in front of
+% a \count etc..., 3) functions which are recognized via an encountered opening
+% parenthesis (but later this must be disambiguated from variables with tacit
+% multiplication) 4) 5) 6) 7) acceptable components of a variable or function
+% names: @, underscore, digits, letters (or chars of category code letter.)
+%
+% The short lived 1.2d which followed the even shorter lived 1.2c managed to
+% introduce a bug here as it removed the check for catcode 11 !, which must be
+% recognized if ! is not to be taken as part of a variable name. Don't know
+% what I was thinking, it was the time when I was moving the handling of tacit
+% mutliplication entirely to the \XINT_expr_getop side. Fixed in 1.2e.
+%
+% I almost decided to remove the \ifcat\relax test whose rôle is to avoid the
+% \string#1 to do something bad is the escape char is a digit! Perhaps I will
+% remove it at some point ! I truly almost did it, but also the case of no
+% escape char is a problem (\string\0, if \0 is a count ...)
+%
+% The (indirectly) above means that via \XINT_expr_func then \XINT_expr_op__
+% one goes back to \XINT_expr_getop then \XINT_expr_getop_b which is the
+% location where tacit multiplication is now centralized. This makes the
+% treatment of tacit multiplication for situations such as <variable>\count or
+% <variable>\xintexpr..\relax, perhaps a bit sub-optimal, but first the
+% variable name must be gathered, second the variable must expand to its
+% value.|
+% \begin{macrocode}
+\def\XINT_expr_scanfunc_b #1%
+{%
+ \ifx !#1\xint_dothis{(_}\fi
+ \ifcat \relax#1\xint_dothis{(_}\fi
+ \if (#1\xint_dothis{\xint_firstoftwo{(`}}\fi
+ \if @#1\xint_dothis \XINT_expr_scanfunc_a \fi
+ \if _#1\xint_dothis \XINT_expr_scanfunc_a \fi
+ \ifnum \xint_c_ix<1\string#1 \xint_dothis \XINT_expr_scanfunc_a \fi
+ \ifcat a#1\xint_dothis \XINT_expr_scanfunc_a \fi
+ \xint_orthat {(_}%
+ #1%
+}%
+% \end{macrocode}
+% \lverb@Comments written 2015/11/12: earlier there was an \ifcsname test for
+% checking if we had a variable in front of a (, for tacit multiplication for
+% example in x(y+z(x+w)) to work. But after I had implemented functions (that
+% was yesterday...), I had the problem if was impossible to re-declare a
+% variable name such as "f" as a function name. The problem is that here we
+% can not test if the function is available because we don't know if we are in
+% expr, iiexpr or floatexpr. The \xint_c_xviii causes all fetching operations
+% to stop and control is handed over to the routines which will be expr,
+% iiexpr ou floatexpr specific, i.e. the \XINT_{expr|iiexpr|flexpr}_op_{`|_}
+% which are invoked by the until_<op>_b macros earlier in the stream.
+% Functions may exist for one but not the two other parsers. Variables are
+% declared via one parser and usable in the others, but naturally \xintiiexpr
+% has its restrictions.
+%
+% Thinking about this again I decided to treat a priori cases such as x(...)
+% as functions, after having assigned to each variable a low-weight macro
+% which will convert this into _getop\.=<value of x>*(...). To activate that
+% macro at the right time I could for this exploit the "onliteral" intercept,
+% which is parser independent (1.2c).
+%
+% This led to me necessarily to rewrite partially the seq, add, mul, subs,
+% iter ... routines as now the variables fetch only one token. I think the
+% thing is more efficient.
+%
+% 1.2c had \def\XINT_expr_func #1(#2{\xint_c_xviii #2{#1}}
+%
+% In \XINT_expr_func the #2 is _ if #1 must be a variable name, or #2=` if #1
+% must be either a function name or possibly a variable name which will then
+% have to be followed by tacit multiplication before the opening parenthesis.
+%
+% The \xint_c_xviii is there because _op_` must know in which parser
+% it works. Dispendious for _. Hence I modify for 1.2d. @
+% \begin{macrocode}
+\def\XINT_expr_func #1(#2{\if _#2\xint_dothis\XINT_expr_op__\fi
+ \xint_orthat{\xint_c_xviii #2}{#1}}%
+% \end{macrocode}
+% \subsection{\csh{XINT_expr_getop}: finding the next operator or closing
+% parenthesis or end of expression}
+% \lverb|Release 1.1 implements multi-character operators.
+%
+% 1.2d adds tacit mutiplication also in front of variable or functions names
+% starting with a letter, not only a @ or a _ as was already the case. This is
+% for (x+y)z situations. It also applies higher precedence in cases like x/2y
+% or x/2@, or x/2max(3,5), or x/2\xintexpr 3\relax.
+%
+% In fact, finally I decide that all sorts of tacit multiplication will always
+% use the higher precedence.
+%
+% Indeed I hesitated somewhat: with the current code one does not know if
+% \XINT_expr_getop as invoked after a closing parenthesis or because a number
+% parsing ended, and I felt distinguishing the two was unneeded extra stuff.
+% This means cases like (a+b)/(c+d)(e+f) will first multiply the last two
+% parenthesized terms.
+%
+% The ! starting a sub-expression must be distinguished from the post-fix !
+% for factorial, thus we must not do a too early \string. In versions < 1.2c,
+% the catcode 11 ! had to be identified in all branches of the number or
+% function scans. Here it is simply treated as a special case of a letter.
+%
+% 1.2q adds tacit multiplication in cases such as (1+1)3 or 5!7!|
+% \begin{macrocode}
+\def\XINT_expr_getop #1#2% this #1 is the current locked computed value
+{%
+ \expandafter\XINT_expr_getop_a\expandafter #1\romannumeral`&&@#2%
+}%
+\catcode`* 11
+\def\XINT_expr_getop_a #1#2%
+{%
+ \ifx \relax #2\xint_dothis\xint_firstofthree\fi
+ \ifcat \relax #2\xint_dothis\xint_secondofthree\fi
+ \ifnum\xint_c_ix<1\string#2 \xint_dothis\xint_secondofthree\fi
+ \if _#2\xint_dothis \xint_secondofthree\fi
+ \if @#2\xint_dothis \xint_secondofthree\fi
+ \if (#2\xint_dothis \xint_secondofthree\fi
+ \ifcat a#2\xint_dothis \xint_secondofthree\fi
+ \xint_orthat \xint_thirdofthree
+ {\XINT_expr_foundend #1}%
+ {\XINT_expr_precedence_*** *#1#2}% tacit multiplication with higher precedence
+ {\expandafter\XINT_expr_getop_b \string#2#1}%
+}%
+\catcode`* 12
+\def\XINT_expr_foundend {\xint_c_ \relax }% \relax is a place holder here.
+% \end{macrocode}
+% \lverb|? is a very special operator with top precedence which will check if
+% the next token is another ?, while avoiding removing a brace pair from token
+% stream due to its syntax. Pre 1.1 releases used : rather than ??, but we
+% need : for Python like slices of lists.|
+% \begin{macrocode}
+\def\XINT_expr_getop_b #1%
+{%
+ \if '#1\xint_dothis{\XINT_expr_binopwrd }\fi
+ \if ?#1\xint_dothis{\XINT_expr_precedence_? ?}\fi
+ \xint_orthat {\XINT_expr_scanop_a #1}%
+}%
+\def\XINT_expr_binopwrd #1#2'{\expandafter\XINT_expr_foundop_a
+ \csname XINT_expr_itself_\xint_zapspaces #2 \xint_gobble_i\endcsname #1}%
+\def\XINT_expr_scanop_a #1#2#3%
+ {\expandafter\XINT_expr_scanop_b\expandafter #1\expandafter #2\romannumeral`&&@#3}%
+\def\XINT_expr_scanop_b #1#2#3%
+{%
+ \ifcat#3\relax\xint_dothis{\XINT_expr_foundop_a #1#2#3}\fi
+ \ifcsname XINT_expr_itself_#1#3\endcsname
+ \xint_dothis
+ {\expandafter\XINT_expr_scanop_c\csname XINT_expr_itself_#1#3\endcsname #2}\fi
+ \xint_orthat {\XINT_expr_foundop_a #1#2#3}%
+}%
+\def\XINT_expr_scanop_c #1#2#3%
+{%
+ \expandafter\XINT_expr_scanop_d\expandafter #1\expandafter #2\romannumeral`&&@#3%
+}%
+\def\XINT_expr_scanop_d #1#2#3%
+{%
+ \ifcat#3\relax \xint_dothis{\XINT_expr_foundop #1#2#3}\fi
+ \ifcsname XINT_expr_itself_#1#3\endcsname
+ \xint_dothis
+ {\expandafter\XINT_expr_scanop_c\csname XINT_expr_itself_#1#3\endcsname #2}\fi
+ \xint_orthat {\csname XINT_expr_precedence_#1\endcsname #1#2#3}%
+}%
+\def\XINT_expr_foundop_a #1%
+{%
+ \ifcsname XINT_expr_precedence_#1\endcsname
+ \csname XINT_expr_precedence_#1\expandafter\endcsname
+ \expandafter #1%
+ \else
+ \xint_afterfi{\XINT_expr_unknown_operator {#1}\XINT_expr_getop}%
+ \fi
+}%
+\def\XINT_expr_unknown_operator #1{\xintError:removed \xint_gobble_i {#1}}%
+\def\XINT_expr_foundop #1{\csname XINT_expr_precedence_#1\endcsname #1}%
+% \end{macrocode}
+% \subsection{Expansion spanning; opening and closing parentheses}
+% \lverb|Version 1.1 had a hack inside the until macros for handling the omit
+% and abort in iterations over dummy variables. This has been removed by
+% 1.2c, see the subsection where omit and abort are discussed.|
+%
+% \begin{macrocode}
+\catcode`) 11
+\def\XINT_tmpa #1#2#3#4%
+{%
+ \def#1##1%
+ {%
+ \xint_UDsignfork
+ ##1{\expandafter#1\romannumeral`&&@#3}%
+ -{#2##1}%
+ \krof
+ }%
+ \def#2##1##2%
+ {%
+ \ifcase ##1\expandafter\XINT_expr_done
+ \or\xint_afterfi{\XINT_expr_extra_)
+ \expandafter #1\romannumeral`&&@\XINT_expr_getop }%
+ \else
+ \xint_afterfi{\expandafter#1\romannumeral`&&@\csname XINT_#4_op_##2\endcsname }%
+ \fi
+ }%
+}%
+\def\XINT_expr_extra_) {\xintError:removed }%
+\xintFor #1 in {expr,flexpr,iiexpr} \do {%
+ \expandafter\XINT_tmpa
+ \csname XINT_#1_until_end_a\expandafter\endcsname
+ \csname XINT_#1_until_end_b\expandafter\endcsname
+ \csname XINT_#1_op_-vi\endcsname
+ {#1}%
+}%
+\def\XINT_tmpa #1#2#3#4#5#6%
+{%
+ \def #1##1{\expandafter #3\romannumeral`&&@\XINT_expr_getnext }%
+ \def #2{\expandafter #3\romannumeral`&&@\XINT_expr_getnext }%
+ \def #3##1{\xint_UDsignfork
+ ##1{\expandafter #3\romannumeral`&&@#5}%
+ -{#4##1}%
+ \krof }%
+ \def #4##1##2{\ifcase ##1\expandafter\XINT_expr_missing_)
+ \or \csname XINT_#6_op_##2\expandafter\endcsname
+ \else
+ \xint_afterfi{\expandafter #3\romannumeral`&&@\csname XINT_#6_op_##2\endcsname }%
+ \fi
+ }%
+}%
+\def\XINT_expr_missing_) {\xintError:inserted \xint_c_ \XINT_expr_done }%
+% \end{macrocode}
+% \lverb|We should be using until_( notation to stay synchronous with until_+,
+% until_* etc..., but I found that until_) was more telling.|
+% \begin{macrocode}
+\catcode`) 12
+\xintFor #1 in {expr,flexpr,iiexpr} \do {%
+ \expandafter\XINT_tmpa
+ \csname XINT_#1_op_(\expandafter\endcsname
+ \csname XINT_#1_oparen\expandafter\endcsname
+ \csname XINT_#1_until_)_a\expandafter\endcsname
+ \csname XINT_#1_until_)_b\expandafter\endcsname
+ \csname XINT_#1_op_-vi\endcsname
+ {#1}%
+}%
+\expandafter\let\csname XINT_expr_precedence_)\endcsname\xint_c_i
+% \end{macrocode}
+% \subsection{\textbar, \textbar\textbar, \&,
+% \&\&, <, >, =, ==, <=, >=, !=, +, \textendash,
+% \texorpdfstring{\protect\lowast}{*}, /, \textasciicircum,
+% \texorpdfstring{\protect\lowast\protect\lowast}{**}, //, /:, .., ..[, ]..,
+% ][, ][:, :], and ++ operators}
+% \localtableofcontents
+% \subsubsection{Square brackets for lists, the
+% !? for omit and abort, and the ++ postfix construct}
+% \lverb|This is all very clever and only need setting some suitable precedence
+% levels, if only I could understand what I did in 2014... just joking. Notice
+% that op_) macros are defined here in the \xintFor loop.
+%
+% There is some clever business going on here with the letter a for handling
+% constructs such as [3..5]*2 (I think...).
+%
+% 1.2c has replaced 1.1's private dealings with "^C" (which was done before
+% dummy variables got implemented) by use of "!?". See discussion of omit and
+% abort.
+% |
+% \begin{macrocode}
+\expandafter\let\csname XINT_expr_precedence_]\endcsname\xint_c_i
+\expandafter\let\csname XINT_expr_precedence_;\endcsname\xint_c_i
+\let\XINT_expr_precedence_a \xint_c_xviii
+\let\XINT_expr_precedence_!? \xint_c_ii
+\expandafter\let\csname XINT_expr_precedence_++)\endcsname \xint_c_i
+% \end{macrocode}
+% \lverb|Comments added 2015/11/13 Here we have in particular the mechanism
+% for post action on lists via op_] The precedence_] is the one of a closing
+% parenthesis. We need the closing parenthesis to do its job, hence we can not
+% define a op_]+ operator for example, as we want to assign it the precedence
+% of addition not the one of closing parenthesis. The trick I used in 1.1 was
+% to let the op_] insert the letter a, this letter exceptionnally also being a
+% legitimate operator, launch the _getop and let it find a a*, a+, a/, a-, a^,
+% a** operator standing for ]*, ]+, ]/, ]^, ]** postfix item by item list
+% operator. I thought I had in mind an example to show that having defined
+% op_a and precedence_a for the letter a caused a reduction in syntax for this
+% letter, but it seems I am lacking now an example.
+%
+% 2015/11/18: for 1.2d I accelerate \XINT_expr_op_] to jump over the
+% \XINT_expr_getop_a which now does tacit multiplications also in front of
+% letters, for reasons of things like, (x+y)z, hence it must not see the "a".
+% I could have used a catcode12 a possibly, but anyhow jumping straight to
+% \XINT_expr_scanop_a skips a few expansion steps (up to the potential price
+% of less conceptual programming if I change things in the future.)|
+% \begin{macrocode}
+\catcode`. 11 \catcode`= 11 \catcode`+ 11
+\xintFor #1 in {expr,flexpr,iiexpr} \do {%
+ \expandafter\let\csname XINT_#1_op_)\endcsname \XINT_expr_getop
+ \expandafter\let\csname XINT_#1_op_;\endcsname \space
+ \expandafter\def\csname XINT_#1_op_]\endcsname ##1{\XINT_expr_scanop_a a##1}%
+ \expandafter\let\csname XINT_#1_op_a\endcsname \XINT_expr_getop
+% \end{macrocode}
+% \lverb|1.1 2014/10/29 did \expandafter\.=+\xintiCeil which transformed it into
+% \romannumeral0\xinticeil, which seems a bit weird. This exploited the fact
+% that dummy variables macros could back then pick braced material (which in the
+% case at hand here ended being {\romannumeral0\xinticeil...} and were submitted
+% to two expansions. The result of this was to provide a not value which got
+% expanded only in the first loop of the :_A and following macros of seq,
+% iter, rseq, etc...
+%
+% Anyhow with 1.2c I have changed the implementation of dummy variables which
+% now need to fetch a single locked token, which they do not expand.
+%
+% The \xintiCeil appears a bit dispendious, but I need the starting value in a
+% \numexpr compatible form in the iteration loops.|
+% \begin{macrocode}
+ \expandafter\def\csname XINT_#1_op_++)\endcsname ##1##2\relax
+ {\expandafter\XINT_expr_foundend \expandafter
+ {\expandafter\.=+\csname .=\XINT:NEhook:one\xintiCeil{\XINT_expr_unlock ##1}\endcsname }}%
+}%
+\catcode`. 12 \catcode`= 12 \catcode`+ 12
+% \end{macrocode}
+% \lverb|1.2d adds the *** for tying via tacit multiplication, for example
+% x/2y. Actually I don't need the _itself mechanism for ***, only a precedence.|
+% \begin{macrocode}
+\catcode`& 12
+\xintFor* #1 in {{==}{<=}{>=}{!=}{&&}{||}{**}{//}{/:}{..}{..[}{].}{]..}%
+ {+[}{-[}{*[}{/[}{**[}{^[}{a+}{a-}{a*}{a/}{a**}{a^}%
+ {][}{][:}{:]}{!?}{++}{++)}}%{***}}
+ \do {\expandafter\def\csname XINT_expr_itself_#1\endcsname {#1}}%
+\catcode`& 7
+\expandafter\let\csname XINT_expr_precedence_***\endcsname \xint_c_viii
+% \end{macrocode}
+% \subsubsection{The \textbar, \&, xor, <, >, =, <=, >=, !=, //, /:, .., +,
+% \textendash, \texorpdfstring{\protect\lowast}{*}, /, \textasciicircum, ..[,
+% and ].. operators for expr, floatexpr and iiexpr operators}
+% \lverb|1.2d needed some room between /, * and ^. Hence precedence for ^
+% is now at 9|
+% \begin{macrocode}
+\def\XINT_expr_defbin_c #1#2#3#4#5#6#7#8#9%
+{%
+ \def #1##1% \XINT_expr_op_<op> ou flexpr ou iiexpr
+ {% keep value, get next number and operator, then do until
+ \expandafter #2\expandafter ##1%
+ \romannumeral`&&@\expandafter\XINT_expr_getnext }%
+ \def #2##1##2% \XINT_expr_until_<op>_a ou flexpr ou iiexpr
+ {\xint_UDsignfork ##2{\expandafter #2\expandafter ##1\romannumeral`&&@#4}%
+ -{#3##1##2}%
+ \krof }%
+ \def #3##1##2##3##4% \XINT_expr_until_<op>_b ou flexpr ou iiexpr
+ {% either execute next operation now, or first do next (possibly unary)
+ \ifnum ##2>#7%
+ \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@%
+ \csname XINT_#8_op_##3\endcsname {##4}}%
+ \else \xint_afterfi {\expandafter ##2\expandafter ##3%
+ \csname .=#9#6{\XINT_expr_unlock ##1}{\XINT_expr_unlock ##4}\endcsname }%
+ \fi }%
+ \let #7#5%
+}%
+\def\XINT_expr_defbin_b #1#2#3#4#5%
+{%
+ \expandafter\XINT_expr_defbin_c
+ \csname XINT_#1_op_#2\expandafter\endcsname
+ \csname XINT_#1_until_#2_a\expandafter\endcsname
+ \csname XINT_#1_until_#2_b\expandafter\endcsname
+ \csname XINT_#1_op_-#4\expandafter\endcsname
+ \csname xint_c_#3\expandafter\endcsname
+ \csname #5\expandafter\endcsname
+ \csname XINT_expr_precedence_#2\endcsname {#1}\XINT:NEhook:two
+}%
+\XINT_expr_defbin_b {expr} | {iii}{vi} {xintOR}%
+\XINT_expr_defbin_b {flexpr} | {iii}{vi} {xintOR}%
+\XINT_expr_defbin_b {iiexpr} | {iii}{vi} {xintOR}%
+\XINT_expr_defbin_b {expr} & {iv}{vi} {xintAND}%
+\XINT_expr_defbin_b {flexpr} & {iv}{vi} {xintAND}%
+\XINT_expr_defbin_b {iiexpr} & {iv}{vi} {xintAND}%
+\XINT_expr_defbin_b {expr} {xor}{iii}{vi} {xintXOR}%
+\XINT_expr_defbin_b {flexpr}{xor}{iii}{vi} {xintXOR}%
+\XINT_expr_defbin_b {iiexpr}{xor}{iii}{vi} {xintXOR}%
+\XINT_expr_defbin_b {expr} < {v}{vi} {xintLt}%
+\XINT_expr_defbin_b {flexpr} < {v}{vi} {xintLt}%
+\XINT_expr_defbin_b {iiexpr} < {v}{vi} {xintiiLt}%
+\XINT_expr_defbin_b {expr} > {v}{vi} {xintGt}%
+\XINT_expr_defbin_b {flexpr} > {v}{vi} {xintGt}%
+\XINT_expr_defbin_b {iiexpr} > {v}{vi} {xintiiGt}%
+\XINT_expr_defbin_b {expr} = {v}{vi} {xintEq}%
+\XINT_expr_defbin_b {flexpr} = {v}{vi} {xintEq}%
+\XINT_expr_defbin_b {iiexpr} = {v}{vi} {xintiiEq}%
+\XINT_expr_defbin_b {expr} {<=} {v}{vi} {xintLtorEq}%
+\XINT_expr_defbin_b {flexpr}{<=} {v}{vi} {xintLtorEq}%
+\XINT_expr_defbin_b {iiexpr}{<=} {v}{vi} {xintiiLtorEq}%
+\XINT_expr_defbin_b {expr} {>=} {v}{vi} {xintGtorEq}%
+\XINT_expr_defbin_b {flexpr}{>=} {v}{vi} {xintGtorEq}%
+\XINT_expr_defbin_b {iiexpr}{>=} {v}{vi} {xintiiGtorEq}%
+\XINT_expr_defbin_b {expr} {!=} {v}{vi} {xintNotEq}%
+\XINT_expr_defbin_b {flexpr}{!=} {v}{vi} {xintNotEq}%
+\XINT_expr_defbin_b {iiexpr}{!=} {v}{vi} {xintiiNotEq}%
+\XINT_expr_defbin_b {expr} {//} {vii}{vii}{xintDivFloor}% CHANGED IN 1.2p!
+\XINT_expr_defbin_b {flexpr}{//} {vii}{vii}{XINTinFloatDivFloor}% "
+\XINT_expr_defbin_b {iiexpr}{//} {vii}{vii}{xintiiDivFloor}% "
+\XINT_expr_defbin_b {expr} {/:} {vii}{vii}{xintMod}% "
+\XINT_expr_defbin_b {flexpr}{/:} {vii}{vii}{XINTinFloatMod}% "
+\XINT_expr_defbin_b {iiexpr}{/:} {vii}{vii}{xintiiMod}% "
+\XINT_expr_defbin_b {expr} + {vi}{vi} {xintAdd}%
+\XINT_expr_defbin_b {flexpr} + {vi}{vi} {XINTinFloatAdd}%
+\XINT_expr_defbin_b {iiexpr} + {vi}{vi} {xintiiAdd}%
+\XINT_expr_defbin_b {expr} - {vi}{vi} {xintSub}%
+\XINT_expr_defbin_b {flexpr} - {vi}{vi} {XINTinFloatSub}%
+\XINT_expr_defbin_b {iiexpr} - {vi}{vi} {xintiiSub}%
+\XINT_expr_defbin_b {expr} * {vii}{vii}{xintMul}%
+\XINT_expr_defbin_b {flexpr} * {vii}{vii}{XINTinFloatMul}%
+\XINT_expr_defbin_b {iiexpr} * {vii}{vii}{xintiiMul}%
+\XINT_expr_defbin_b {expr} / {vii}{vii}{xintDiv}%
+\XINT_expr_defbin_b {flexpr} / {vii}{vii}{XINTinFloatDiv}%
+\XINT_expr_defbin_b {iiexpr} / {vii}{vii}{xintiiDivRound}% CHANGED IN 1.1!
+\XINT_expr_defbin_b {expr} ^ {ix}{ix} {xintPow}%
+\XINT_expr_defbin_b {flexpr} ^ {ix}{ix} {XINTinFloatPowerH}%
+\XINT_expr_defbin_b {iiexpr} ^ {ix}{ix} {xintiiPow}%
+\XINT_expr_defbin_b {expr} {..[}{iii}{vi} {xintSeqA::csv}%
+\XINT_expr_defbin_b {flexpr}{..[}{iii}{vi} {XINTinFloatSeqA::csv}%
+\XINT_expr_defbin_b {iiexpr}{..[}{iii}{vi} {xintiiSeqA::csv}%
+\def\XINT_expr_defbin_b #1#2#3#4#5%
+{%
+ \expandafter\XINT_expr_defbin_c
+ \csname XINT_#1_op_#2\expandafter\endcsname
+ \csname XINT_#1_until_#2_a\expandafter\endcsname
+ \csname XINT_#1_until_#2_b\expandafter\endcsname
+ \csname XINT_#1_op_-#4\expandafter\endcsname
+ \csname xint_c_#3\expandafter\endcsname
+ \csname #5\expandafter\endcsname
+ \csname XINT_expr_precedence_#2\endcsname {#1}{}%
+}%
+\XINT_expr_defbin_b {expr} {..} {iii}{vi} {xintSeq::csv}%
+\XINT_expr_defbin_b {flexpr}{..} {iii}{vi} {xintSeq::csv}%
+\XINT_expr_defbin_b {iiexpr}{..} {iii}{vi} {xintiiSeq::csv}%
+\XINT_expr_defbin_b {expr} {]..}{iii}{vi} {xintSeqB::csv}%
+\XINT_expr_defbin_b {flexpr}{]..}{iii}{vi} {XINTinFloatSeqB::csv}%
+\XINT_expr_defbin_b {iiexpr}{]..}{iii}{vi} {xintiiSeqB::csv}%
+% \end{macrocode}
+% \subsubsection{The ]+, ]\textendash, ]\texorpdfstring{\protect\lowast}{*}, ]/, ]\textasciicircum, +[, \textendash[, \texorpdfstring{\protect\lowast}{*}[, /[, and \textasciicircum[ list
+% operators}
+% \paragraph{\csh{XINT_expr_binop_inline_b}}\par
+% \lverb|This handles acting on comma separated values (no need to bother
+% about spaces in this context; expansion in a \csname...\endcsname.|
+% \begin{macrocode}
+\def\XINT_expr_binop_inline#1%
+ {\XINT_expr_binop_inline_a{\expandafter\XINT:NEhook:two\expandafter#1}}%
+\def\XINT_expr_binop_inline_a
+ {\expandafter\xint_gobble_i\romannumeral`&&@\XINT_expr_binop_inline_b }%
+\def\XINT_expr_binop_inline_b #1#2,{\XINT_expr_binop_inline_c #2,{#1}}%
+\def\XINT_expr_binop_inline_c #1{%
+ \if ,#1\xint_dothis\XINT_expr_binop_inline_e\fi
+ \if ^#1\xint_dothis\XINT_expr_binop_inline_end\fi
+ \xint_orthat\XINT_expr_binop_inline_d #1}%
+\def\XINT_expr_binop_inline_d #1,#2{,#2{#1}\XINT_expr_binop_inline_b {#2}}%
+\def\XINT_expr_binop_inline_e #1,#2{,\XINT_expr_binop_inline_b {#2}}%
+\def\XINT_expr_binop_inline_end #1,#2{}%
+\def\XINT_expr_deflistopr_c #1#2#3#4#5#6#7#8%
+{%
+ \def #1##1% \XINT_expr_op_<op> ou flexpr ou iiexpr
+ {% keep value, get next number and operator, then do until
+ \expandafter #2\expandafter ##1%
+ \romannumeral`&&@\expandafter\XINT_expr_getnext }%
+ \def #2##1##2% \XINT_expr_until_<op>_a ou flexpr ou iiexpr
+ {\xint_UDsignfork ##2{\expandafter #2\expandafter ##1\romannumeral`&&@#4}%
+ -{#3##1##2}%
+ \krof }%
+ \def #3##1##2##3##4% \XINT_expr_until_<op>_b ou flexpr ou iiexpr
+ {% either execute next operation now, or first do next (possibly unary)
+ \ifnum ##2>#7%
+ \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@%
+ \csname XINT_#8_op_##3\endcsname {##4}}%
+ \else \xint_afterfi {\expandafter ##2\expandafter ##3%
+ \csname .=\expandafter\XINT_expr_binop_inline\expandafter
+ {\expandafter#6\expandafter\xint_exchangetwo_keepbraces\expandafter
+ {\expandafter\XINT_expr_unlock\expandafter ##4\expandafter}\expandafter}%
+ \romannumeral`&&@\XINT_expr_unlock ##1,^,\endcsname }%
+ \fi }%
+ \let #7#5%
+}%
+\def\XINT_expr_deflistopr_b #1#2#3#4%
+{%
+ \expandafter\XINT_expr_deflistopr_c
+ \csname XINT_#1_op_#2\expandafter\endcsname
+ \csname XINT_#1_until_#2_a\expandafter\endcsname
+ \csname XINT_#1_until_#2_b\expandafter\endcsname
+ \csname XINT_#1_op_-#3\expandafter\endcsname
+ \csname xint_c_#3\expandafter\endcsname
+ \csname #4\expandafter\endcsname
+ \csname XINT_expr_precedence_#2\endcsname {#1}%
+}%
+% \end{macrocode}
+% \lverb|This is for [x..y]*z syntax etc.... Attention that with 1.2d,
+% precedence level of ^ raised to ix to make room for ***.|
+% \begin{macrocode}
+\XINT_expr_deflistopr_b {expr} {a+}{vi} {xintAdd}%
+\XINT_expr_deflistopr_b {expr} {a-}{vi} {xintSub}%
+\XINT_expr_deflistopr_b {expr} {a*}{vii}{xintMul}%
+\XINT_expr_deflistopr_b {expr} {a/}{vii}{xintDiv}%
+\XINT_expr_deflistopr_b {expr} {a^}{ix} {xintPow}%
+\XINT_expr_deflistopr_b {iiexpr}{a+}{vi} {xintiiAdd}%
+\XINT_expr_deflistopr_b {iiexpr}{a-}{vi} {xintiiSub}%
+\XINT_expr_deflistopr_b {iiexpr}{a*}{vii}{xintiiMul}%
+\XINT_expr_deflistopr_b {iiexpr}{a/}{vii}{xintiiDivRound}%
+\XINT_expr_deflistopr_b {iiexpr}{a^}{ix} {xintiiPow}%
+\XINT_expr_deflistopr_b {flexpr}{a+}{vi} {XINTinFloatAdd}%
+\XINT_expr_deflistopr_b {flexpr}{a-}{vi} {XINTinFloatSub}%
+\XINT_expr_deflistopr_b {flexpr}{a*}{vii}{XINTinFloatMul}%
+\XINT_expr_deflistopr_b {flexpr}{a/}{vii}{XINTinFloatDiv}%
+\XINT_expr_deflistopr_b {flexpr}{a^}{ix} {XINTinFloatPowerH}%
+\def\XINT_expr_deflistopl_c #1#2#3#4#5#6#7%
+{%
+ \def #1##1{\expandafter#2\expandafter##1\romannumeral`&&@%
+ \expandafter #3\romannumeral`&&@\XINT_expr_getnext }%
+ \def #2##1##2##3##4%
+ {% either execute next operation now, or first do next (possibly unary)
+ \ifnum ##2>#6%
+ \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@%
+ \csname XINT_#7_op_##3\endcsname {##4}}%
+ \else \xint_afterfi {\expandafter ##2\expandafter ##3%
+ \csname .=\expandafter\XINT_expr_binop_inline\expandafter
+ {\expandafter#5\expandafter
+ {\expandafter\XINT_expr_unlock\expandafter ##1\expandafter}\expandafter}%
+ \romannumeral`&&@\XINT_expr_unlock ##4,^,\endcsname }%
+ \fi }%
+ \let #6#4%
+}%
+\def\XINT_expr_deflistopl_b #1#2#3#4%
+{%
+ \expandafter\XINT_expr_deflistopl_c
+ \csname XINT_#1_op_#2\expandafter\endcsname
+ \csname XINT_#1_until_#2\expandafter\endcsname
+ \csname XINT_#1_until_)_a\expandafter\endcsname
+ \csname xint_c_#3\expandafter\endcsname
+ \csname #4\expandafter\endcsname
+ \csname XINT_expr_precedence_#2\endcsname {#1}%
+}%
+% \end{macrocode}
+% \lverb|This is for z*[x..y] syntax etc...|
+% \begin{macrocode}
+\XINT_expr_deflistopl_b {expr} {+[}{vi} {xintAdd}%
+\XINT_expr_deflistopl_b {expr} {-[}{vi} {xintSub}%
+\XINT_expr_deflistopl_b {expr} {*[}{vii}{xintMul}%
+\XINT_expr_deflistopl_b {expr} {/[}{vii}{xintDiv}%
+\XINT_expr_deflistopl_b {expr} {^[}{ix} {xintPow}%
+\XINT_expr_deflistopl_b {iiexpr}{+[}{vi} {xintiiAdd}%
+\XINT_expr_deflistopl_b {iiexpr}{-[}{vi} {xintiiSub}%
+\XINT_expr_deflistopl_b {iiexpr}{*[}{vii}{xintiiMul}%
+\XINT_expr_deflistopl_b {iiexpr}{/[}{vii}{xintiiDivRound}%
+\XINT_expr_deflistopl_b {iiexpr}{^[}{ix} {xintiiPow}%
+\XINT_expr_deflistopl_b {flexpr}{+[}{vi} {XINTinFloatAdd}%
+\XINT_expr_deflistopl_b {flexpr}{-[}{vi} {XINTinFloatSub}%
+\XINT_expr_deflistopl_b {flexpr}{*[}{vii}{XINTinFloatMul}%
+\XINT_expr_deflistopl_b {flexpr}{/[}{vii}{XINTinFloatDiv}%
+\XINT_expr_deflistopl_b {flexpr}{^[}{ix} {XINTinFloatPowerH}%
+% \end{macrocode}
+% \subsubsection{The \textquotesingle and\textquotesingle, \textquotesingle
+% or\textquotesingle, \textquotesingle xor\textquotesingle, and
+% \textquotesingle mod\textquotesingle\ as infix operator words}
+% \begin{macrocode}
+\xintFor #1 in {and,or,xor,mod} \do {%
+ \expandafter\def\csname XINT_expr_itself_#1\endcsname {#1}}%
+\expandafter\let\csname XINT_expr_precedence_and\expandafter\endcsname
+ \csname XINT_expr_precedence_&\endcsname
+\expandafter\let\csname XINT_expr_precedence_or\expandafter\endcsname
+ \csname XINT_expr_precedence_|\endcsname
+\expandafter\let\csname XINT_expr_precedence_mod\expandafter\endcsname
+ \csname XINT_expr_precedence_/:\endcsname
+\xintFor #1 in {expr, flexpr, iiexpr} \do {%
+ \expandafter\let\csname XINT_#1_op_and\expandafter\endcsname
+ \csname XINT_#1_op_&\endcsname
+ \expandafter\let\csname XINT_#1_op_or\expandafter\endcsname
+ \csname XINT_#1_op_|\endcsname
+ \expandafter\let\csname XINT_#1_op_mod\expandafter\endcsname
+ \csname XINT_#1_op_/:\endcsname
+}%
+% \end{macrocode}
+% \subsubsection{The \textbar\textbar,
+% \&\&, \texorpdfstring{\protect\lowast\protect\lowast,
+% \protect\lowast\protect\lowast[, ]\protect\lowast\protect\lowast}{**, **[, ]**}{} operators as synonyms}
+% \begin{macrocode}
+\expandafter\let\csname XINT_expr_precedence_==\expandafter\endcsname
+ \csname XINT_expr_precedence_=\endcsname
+\expandafter\let\csname XINT_expr_precedence_&\string&\expandafter\endcsname
+ \csname XINT_expr_precedence_&\endcsname
+\expandafter\let\csname XINT_expr_precedence_||\expandafter\endcsname
+ \csname XINT_expr_precedence_|\endcsname
+\expandafter\let\csname XINT_expr_precedence_**\expandafter\endcsname
+ \csname XINT_expr_precedence_^\endcsname
+\expandafter\let\csname XINT_expr_precedence_a**\expandafter\endcsname
+ \csname XINT_expr_precedence_a^\endcsname
+\expandafter\let\csname XINT_expr_precedence_**[\expandafter\endcsname
+ \csname XINT_expr_precedence_^[\endcsname
+\xintFor #1 in {expr, flexpr, iiexpr} \do {%
+ \expandafter\let\csname XINT_#1_op_==\expandafter\endcsname
+ \csname XINT_#1_op_=\endcsname
+ \expandafter\let\csname XINT_#1_op_&\string&\expandafter\endcsname
+ \csname XINT_#1_op_&\endcsname
+ \expandafter\let\csname XINT_#1_op_||\expandafter\endcsname
+ \csname XINT_#1_op_|\endcsname
+ \expandafter\let\csname XINT_#1_op_**\expandafter\endcsname
+ \csname XINT_#1_op_^\endcsname
+ \expandafter\let\csname XINT_#1_op_a**\expandafter\endcsname
+ \csname XINT_#1_op_a^\endcsname
+ \expandafter\let\csname XINT_#1_op_**[\expandafter\endcsname
+ \csname XINT_#1_op_^[\endcsname
+}%
+% \end{macrocode}
+% \subsection{Macros for list selectors: [list][N], [list][:b], [list][a:], [list][a:b]}
+% \localtableofcontents
+%
+% \lverb|Python slicing was first implemented for 1.1 (27 octobre 2014). But
+% it used \xintCSVtoList and \xintListWithSep{,} to convert back and forth to
+% token lists for use of \xintKeep, \xintTrim, \xintNthElt. Not very
+% efficient! Also [list][a:b] was Python like but not [list][N] which counted
+% items starting at one, and returned the length for N=0.
+%
+% Release 1.2g changed this so [list][N] now counts starting at zero and
+% len(list) computes the number of items. Also 1.2g had its own f-expandable
+% macros handling directly the comma separated lists. They are located into
+% $xinttoolsnameimp.sty.
+%
+% 1.2j improved the $xinttoolsnameimp.sty macros and furthermore it made the
+% Python slicing in expressions a bit more efficient still by exploiting in
+% some cases that expansion happens in \csname...\endcsname and does not have
+% to be f-expandable. But the f-expandable variants must be kept for use by
+% \xintNewExpr and \xintdeffunc.
+% |
+% \begin{macrocode}
+\def\XINT_tmpa #1#2#3#4#5#6%
+{%
+ \def #1##1% \XINT_expr_op_][
+ {%
+ \expandafter #2\expandafter ##1\romannumeral`&&@\XINT_expr_getnext
+ }%
+ \def #2##1##2% \XINT_expr_until_][_a
+ {\xint_UDsignfork
+ ##2{\expandafter #2\expandafter ##1\romannumeral`&&@#4}%
+ -{#3##1##2}%
+ \krof }%
+ \def #3##1##2##3##4% \XINT_expr_until_][_b
+ {%
+ \ifnum ##2>#5%
+ \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@%
+ \csname XINT_#6_op_##3\endcsname {##4}}%
+ \else
+ \xint_afterfi
+ {\expandafter ##2\expandafter ##3\csname
+ .=\expandafter\xintListSel:x:csv % will be \xintListSel:f:csv in \xintNewExpr output
+ \romannumeral`&&@\XINT_expr_unlock ##4;% selector
+ \XINT_expr_unlock ##1;\endcsname % unlock already pre-positioned for \xintNewExpr
+ }%
+ \fi
+ }%
+ \let #5\xint_c_ii
+}%
+\xintFor #1 in {expr,flexpr,iiexpr} \do {%
+\expandafter\XINT_tmpa
+ \csname XINT_#1_op_][\expandafter\endcsname
+ \csname XINT_#1_until_][_a\expandafter\endcsname
+ \csname XINT_#1_until_][_b\expandafter\endcsname
+ \csname XINT_#1_op_-vi\expandafter\endcsname
+ \csname XINT_expr_precedence_][\endcsname {#1}%
+}%
+\def\XINT_tmpa #1#2#3#4#5#6%
+{%
+ \def #1##1% \XINT_expr_op_:
+ {%
+ \expandafter #2\expandafter ##1\romannumeral`&&@\XINT_expr_getnext
+ }%
+ \def #2##1##2% \XINT_expr_until_:_a
+ {\xint_UDsignfork
+ ##2{\expandafter #2\expandafter ##1\romannumeral`&&@#4}%
+ -{#3##1##2}%
+ \krof }%
+ \def #3##1##2##3##4% \XINT_expr_until_:_b
+ {%
+ \ifnum ##2>#5%
+ \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@%
+ \csname XINT_#6_op_##3\endcsname {##4}}%
+ \else
+ \xint_afterfi
+ {\expandafter ##2\expandafter ##3\csname
+ .=:\XINT:NEhook:one\xintNum{\XINT_expr_unlock ##1};%
+ \XINT:NEhook:one\xintNum{\XINT_expr_unlock ##4}%
+ \endcsname
+ }%
+ \fi
+ }%
+ \let #5\xint_c_iii
+}%
+\xintFor #1 in {expr,flexpr,iiexpr} \do {%
+\expandafter\XINT_tmpa
+ \csname XINT_#1_op_:\expandafter\endcsname
+ \csname XINT_#1_until_:_a\expandafter\endcsname
+ \csname XINT_#1_until_:_b\expandafter\endcsname
+ \csname XINT_#1_op_-vi\expandafter\endcsname
+ \csname XINT_expr_precedence_:\endcsname {#1}%
+}%
+\catcode`[ 11 \catcode`] 11
+\let\XINT_expr_precedence_:] \xint_c_iii
+\def\XINT_expr_op_:] #1%
+{%
+ \expandafter\xint_c_i\expandafter )%
+ \csname .=]\XINT:NEhook:one\xintNum{\XINT_expr_unlock #1}\endcsname
+}%
+\let\XINT_flexpr_op_:] \XINT_expr_op_:]
+\let\XINT_iiexpr_op_:] \XINT_expr_op_:]
+\let\XINT_expr_precedence_][: \xint_c_iii
+% \end{macrocode}
+% \lverb|At the end of the replacement text of \XINT_expr_op_][:, the : after
+% index 0 must be catcode 12, else will be mistaken for the start of variable
+% by expression parser (as <digits><variable> is allowed by the syntax and does
+% tacit multiplication).|
+% \begin{macrocode}
+\edef\XINT_expr_op_][: #1{\xint_c_ii\noexpand\XINT_expr_itself_][#10\string :}%
+\let\XINT_flexpr_op_][: \XINT_expr_op_][:
+\let\XINT_iiexpr_op_][: \XINT_expr_op_][:
+\catcode`[ 12 \catcode`] 12
+% \end{macrocode}
+% \subsubsection{\csh{xintListSel:x:csv}}
+% \lverb|1.2j. Because there is \xintKeep:x:csv which is faster than
+% \xintKeep:f:csv.|
+% \begin{macrocode}
+\def\xintListSel:x:csv #1%
+{%
+ \if ]\noexpand#1\xint_dothis\XINT_listsel:_s\fi
+ \if :\noexpand#1\xint_dothis\XINT_listxsel:_:\fi
+ \xint_orthat {\XINT_listsel:_nth #1}%
+}%
+\def\XINT_listsel:_s #1#2;#3;%
+{%
+ \if-#1\expandafter\xintKeep:f:csv\else\expandafter\xintTrim:f:csv\fi
+ {#1#2}{#3}%
+}%
+\def\XINT_listsel:_nth #1;#2;{\xintNthEltPy:f:csv {\xintNum{#1}}{#2}}%
+% \end{macrocode}
+% \lverb|\XINT_listsel:_nth and \XINT_listsel:_s located in \xintListSel:f:csv.|
+% \begin{macrocode}
+\def\XINT_listxsel:_: #1#2;#3#4;%
+{%
+ \xint_UDsignsfork
+ #1#3\XINT_listxsel:_N:N
+ #1-\XINT_listxsel:_N:P
+ -#3\XINT_listxsel:_P:N
+ --\XINT_listxsel:_P:P
+ \krof #1#2;#3#4;%
+}%
+\def\XINT_listxsel:_P:P #1;#2;#3;%
+{%
+ \unless\ifnum #1<#2 \expandafter\xint_gobble_iii\fi
+ \xintKeep:x:csv{#2-#1}{\xintTrim:f:csv{#1}{#3}}%
+}%
+\def\XINT_listxsel:_N:N #1;#2;#3;%
+{%
+ \expandafter\XINT_listxsel:_N:N_a
+ \the\numexpr #2-#1\expandafter;\the\numexpr#1+\xintLength:f:csv{#3};#3;%
+}%
+\def\XINT_listxsel:_N:N_a #1;#2;#3;%
+{%
+ \unless\ifnum #1>\xint_c_ \expandafter\xint_gobble_iii\fi
+ \xintKeep:x:csv{#1}{\xintTrim:f:csv{\ifnum#2<\xint_c_\xint_c_\else#2\fi}{#3}}%
+}%
+\def\XINT_listxsel:_N:P #1;#2;#3;{\expandafter\XINT_listxsel:_N:P_a
+ \the\numexpr #1+\xintLength:f:csv{#3};#2;#3;}%
+\def\XINT_listxsel:_N:P_a #1#2;%
+ {\if -#1\expandafter\XINT_listxsel:_O:P\fi\XINT_listxsel:_P:P #1#2;}%
+\def\XINT_listxsel:_O:P\XINT_listxsel:_P:P #1;{\XINT_listxsel:_P:P 0;}%
+\def\XINT_listxsel:_P:N #1;#2;#3;{\expandafter\XINT_listxsel:_P:N_a
+ \the\numexpr #2+\xintLength:f:csv{#3};#1;#3;}%
+\def\XINT_listxsel:_P:N_a #1#2;#3;%
+ {\if -#1\expandafter\XINT_listxsel:_P:O\fi\XINT_listxsel:_P:P #3;#1#2;}%
+\def\XINT_listxsel:_P:O\XINT_listxsel:_P:P #1;#2;{\XINT_listxsel:_P:P #1;0;}%
+% \end{macrocode}
+% \subsubsection{\csh{xintListSel:f:csv}}
+% \lverb|1.2g. Since 1.2j this is needed only for \xintNewExpr and user
+% defined functions. Some extras compared to \xintListSel:x:csv because things
+% may not yet have been expanded in the \xintNewExpr context.|
+% \begin{macrocode}
+\def\xintListSel:f:csv #1%
+{%
+ \if ]\noexpand#1\xint_dothis{\expandafter\XINT_listsel:_s\romannumeral`&&@}\fi
+ \if :\noexpand#1\xint_dothis{\XINT_listsel:_:}\fi
+ \xint_orthat {\XINT_listsel:_nth #1}%
+}%
+\def\XINT_listsel:_: #1;#2;%
+{%
+ \expandafter\XINT_listsel:_:a
+ \the\numexpr #1\expandafter;\the\numexpr #2\expandafter;\romannumeral`&&@%
+}%
+\def\XINT_listsel:_:a #1#2;#3#4;%
+{%
+ \xint_UDsignsfork
+ #1#3\XINT_listsel:_N:N
+ #1-\XINT_listsel:_N:P
+ -#3\XINT_listsel:_P:N
+ --\XINT_listsel:_P:P
+ \krof #1#2;#3#4;%
+}%
+\def\XINT_listsel:_P:P #1;#2;#3;%
+{%
+ \unless\ifnum #1<#2 \xint_afterfi{\expandafter\space\xint_gobble_iii}\fi
+ \xintKeep:f:csv{#2-#1}{\xintTrim:f:csv{#1}{#3}}%
+}%
+\def\XINT_listsel:_N:N #1;#2;#3;%
+{%
+ \unless\ifnum #1<#2 \expandafter\XINT_listsel:_N:N_abort\fi
+ \expandafter\XINT_listsel:_N:N_a
+ \the\numexpr#1+\xintLength:f:csv{#3}\expandafter;\the\numexpr#2-#1;#3;%
+}%
+\def\XINT_listsel:_N:N_abort #1;#2;#3;{ }%
+\def\XINT_listsel:_N:N_a #1;#2;#3;%
+{%
+ \xintKeep:f:csv{#2}{\xintTrim:f:csv{\ifnum#1<\xint_c_\xint_c_\else#1\fi}{#3}}%
+}%
+\def\XINT_listsel:_N:P #1;#2;#3;{\expandafter\XINT_listsel:_N:P_a
+ \the\numexpr #1+\xintLength:f:csv{#3};#2;#3;}%
+\def\XINT_listsel:_N:P_a #1#2;%
+ {\if -#1\expandafter\XINT_listsel:_O:P\fi\XINT_listsel:_P:P #1#2;}%
+\def\XINT_listsel:_O:P\XINT_listsel:_P:P #1;{\XINT_listsel:_P:P 0;}%
+\def\XINT_listsel:_P:N #1;#2;#3;{\expandafter\XINT_listsel:_P:N_a
+ \the\numexpr #2+\xintLength:f:csv{#3};#1;#3;}%
+\def\XINT_listsel:_P:N_a #1#2;#3;%
+ {\if -#1\expandafter\XINT_listsel:_P:O\fi\XINT_listsel:_P:P #3;#1#2;}%
+\def\XINT_listsel:_P:O\XINT_listsel:_P:P #1;#2;{\XINT_listsel:_P:P #1;0;}%
+% \end{macrocode}
+% \subsubsection{\csh{xintKeep:x:csv}}
+% \lverb|1.2j. This macro is used only with positive first argument.
+% |
+% \begin{macrocode}
+\def\xintKeep:x:csv #1#2%
+{%
+ \expandafter\xint_gobble_i
+ \romannumeral0\expandafter\XINT_keep:x:csv_pos
+ \the\numexpr #1\expandafter.\expandafter{\romannumeral`&&@#2}%
+}%
+\def\XINT_keep:x:csv_pos #1.#2%
+{%
+ \expandafter\XINT_keep:x:csv_loop\the\numexpr#1-\xint_c_viii.%
+ #2\xint_Bye,\xint_Bye,\xint_Bye,\xint_Bye,%
+ \xint_Bye,\xint_Bye,\xint_Bye,\xint_Bye,\xint_bye
+}%
+\def\XINT_keep:x:csv_loop #1%
+{%
+ \xint_gob_til_minus#1\XINT_keep:x:csv_finish-%
+ \XINT_keep:x:csv_loop_pickeight #1%
+}%
+\def\XINT_keep:x:csv_loop_pickeight #1.#2,#3,#4,#5,#6,#7,#8,#9,%
+{%
+ ,#2,#3,#4,#5,#6,#7,#8,#9%
+ \expandafter\XINT_keep:x:csv_loop\the\numexpr#1-\xint_c_viii.%
+}%
+\def\XINT_keep:x:csv_finish-\XINT_keep:x:csv_loop_pickeight -#1.%
+{%
+ \csname XINT_keep:x:csv_finish#1\endcsname
+}%
+\expandafter\def\csname XINT_keep:x:csv_finish1\endcsname
+ #1,#2,#3,#4,#5,#6,#7,{,#1,#2,#3,#4,#5,#6,#7\xint_Bye}%
+\expandafter\def\csname XINT_keep:x:csv_finish2\endcsname
+ #1,#2,#3,#4,#5,#6,{,#1,#2,#3,#4,#5,#6\xint_Bye}%
+\expandafter\def\csname XINT_keep:x:csv_finish3\endcsname
+ #1,#2,#3,#4,#5,{,#1,#2,#3,#4,#5\xint_Bye}%
+\expandafter\def\csname XINT_keep:x:csv_finish4\endcsname
+ #1,#2,#3,#4,{,#1,#2,#3,#4\xint_Bye}%
+\expandafter\def\csname XINT_keep:x:csv_finish5\endcsname
+ #1,#2,#3,{,#1,#2,#3\xint_Bye}%
+\expandafter\def\csname XINT_keep:x:csv_finish6\endcsname
+ #1,#2,{,#1,#2\xint_Bye}%
+\expandafter\def\csname XINT_keep:x:csv_finish7\endcsname
+ #1,{,#1\xint_Bye}%
+\expandafter\let\csname XINT_keep:x:csv_finish8\endcsname\xint_Bye
+% \end{macrocode}
+% \subsubsection{\cshnolabel{xintKeep:f:csv}}
+% \changed{1.2g}{} moved to \xinttoolsnameimp.
+% \subsubsection{\cshnolabel{xintTrim:f:csv}}
+% \changed{1.2g}{} moved to \xinttoolsnameimp.
+% \subsubsection{\cshnolabel{xintNthEltPy:f:csv}}
+% \changed{1.2g}{} moved to \xinttoolsnameimp.
+% \subsubsection{\cshnolabel{xintLength:f:csv}}
+% \changed{1.2g}{} moved to \xinttoolsnameimp.
+% \subsubsection{\cshnolabel{xintReverse:f:csv}}
+% \changed{1.2g}{} moved to \xinttoolsnameimp.
+%
+% \subsection{Macros for a..b list generation}
+% \localtableofcontents
+%
+% \lverb|Ne produit que des listes d'entiers inférieurs à la borne
+% de TeX ! mais sous la forme N/1[0] en ce qui concerne \xintSeq::csv.|
+%
+%\subsubsection{\csh{xintSeq::csv}}
+%\lverb|Commence par remplacer a par ceil(a) et b par floor(b) et renvoie
+% ensuite les entiers entre les deux, possiblement en décroissant, et
+% extrémités comprises. Si a=b est non entier en obtient donc ceil(a) et
+% floor(a). Ne renvoie jamais une liste vide.
+%
+% Note: le a..b dans \xintfloatexpr utilise cette routine.|
+% \begin{macrocode}
+\def\xintSeq::csv {\romannumeral0\xintseq::csv }%
+\def\xintseq::csv #1#2%
+{%
+ \expandafter\XINT_seq::csv\expandafter
+ {\the\numexpr \xintiCeil{#1}\expandafter}\expandafter
+ {\the\numexpr \xintiFloor{#2}}%
+}%
+\def\XINT_seq::csv #1#2%
+{%
+ \ifcase\ifnum #1=#2 0\else\ifnum #2>#1 1\else -1\fi\fi\space
+ \expandafter\XINT_seq::csv_z
+ \or
+ \expandafter\XINT_seq::csv_p
+ \else
+ \expandafter\XINT_seq::csv_n
+ \fi
+ {#2}{#1}%
+}%
+\def\XINT_seq::csv_z #1#2{ #1/1[0]}%
+\def\XINT_seq::csv_p #1#2%
+{%
+ \ifnum #1>#2
+ \expandafter\expandafter\expandafter\XINT_seq::csv_p
+ \else
+ \expandafter\XINT_seq::csv_e
+ \fi
+ \expandafter{\the\numexpr #1-\xint_c_i}{#2},#1/1[0]%
+}%
+\def\XINT_seq::csv_n #1#2%
+{%
+ \ifnum #1<#2
+ \expandafter\expandafter\expandafter\XINT_seq::csv_n
+ \else
+ \expandafter\XINT_seq::csv_e
+ \fi
+ \expandafter{\the\numexpr #1+\xint_c_i}{#2},#1/1[0]%
+}%
+\def\XINT_seq::csv_e #1,{ }%
+% \end{macrocode}
+%\subsubsection{\csh{xintiiSeq::csv}}
+% \begin{macrocode}
+\def\xintiiSeq::csv {\romannumeral0\xintiiseq::csv }%
+\def\xintiiseq::csv #1#2%
+{%
+ \expandafter\XINT_iiseq::csv\expandafter
+ {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2}%
+}%
+\def\XINT_iiseq::csv #1#2%
+{%
+ \ifcase\ifnum #1=#2 0\else\ifnum #2>#1 1\else -1\fi\fi\space
+ \expandafter\XINT_iiseq::csv_z
+ \or
+ \expandafter\XINT_iiseq::csv_p
+ \else
+ \expandafter\XINT_iiseq::csv_n
+ \fi
+ {#2}{#1}%
+}%
+\def\XINT_iiseq::csv_z #1#2{ #1}%
+\def\XINT_iiseq::csv_p #1#2%
+{%
+ \ifnum #1>#2
+ \expandafter\expandafter\expandafter\XINT_iiseq::csv_p
+ \else
+ \expandafter\XINT_seq::csv_e
+ \fi
+ \expandafter{\the\numexpr #1-\xint_c_i}{#2},#1%
+}%
+\def\XINT_iiseq::csv_n #1#2%
+{%
+ \ifnum #1<#2
+ \expandafter\expandafter\expandafter\XINT_iiseq::csv_n
+ \else
+ \expandafter\XINT_seq::csv_e
+ \fi
+ \expandafter{\the\numexpr #1+\xint_c_i}{#2},#1%
+}%
+\def\XINT_seq::csv_e #1,{ }%
+% \end{macrocode}
+%\subsection{Macros for a..[d]..b list generation}
+% \localtableofcontents
+%
+% \lverb|Contrarily to a..b which is limited to small integers, this works
+% with a, b, and d (big) fractions. It will produce a «nil» list, if a>b and
+% d<0 or a<b and d>0.|
+%
+%\subsubsection{\csh{xintSeqA::csv}, \csh{xintiiSeqA::csv}, \csh{XINTinFloatSeqA::csv}}
+%
+% \begin{macrocode}
+\def\xintSeqA::csv #1%
+ {\expandafter\XINT_seqa::csv\expandafter{\romannumeral0\xintraw {#1}}}%
+\def\XINT_seqa::csv #1#2{\expandafter\XINT_seqa::csv_a \romannumeral0\xintraw {#2};#1;}%
+\def\xintiiSeqA::csv #1{\expandafter\XINT_iiseqa::csv\expandafter{\romannumeral`&&@#1}}%
+\def\XINT_iiseqa::csv #1#2{\expandafter\XINT_seqa::csv_a\romannumeral`&&@#2;#1;}%
+\def\XINTinFloatSeqA::csv #1{\expandafter\XINT_flseqa::csv\expandafter
+ {\romannumeral0\XINTinfloat [\XINTdigits]{#1}}}%
+\def\XINT_flseqa::csv #1#2%
+ {\expandafter\XINT_seqa::csv_a\romannumeral0\XINTinfloat [\XINTdigits]{#2};#1;}%
+\def\XINT_seqa::csv_a #1{\xint_UDzerominusfork
+ #1-{z}%
+ 0#1{n}%
+ 0-{p}%
+ \krof #1}%
+% \end{macrocode}
+%\subsubsection{\csh{xintSeqB::csv}}
+% \lverb|With one year late documentation, let's just say, the #1 is
+% \XINT_expr_unlock\.=Ua;b; with U=z or n or p, a=step, b=start.|
+% \begin{macrocode}
+\def\xintSeqB::csv #1#2%
+ {\expandafter\XINT_seqb::csv \expandafter{\romannumeral0\xintraw{#2}}{#1}}%
+\def\XINT_seqb::csv #1#2{\expandafter\XINT_seqb::csv_a\romannumeral`&&@#2#1!}%
+\def\XINT_seqb::csv_a #1#2;#3;#4!{\expandafter\XINT_expr_seq_empty?
+ \romannumeral0\csname XINT_seqb::csv_#1\endcsname {#3}{#4}{#2}}%
+\def\XINT_seqb::csv_p #1#2#3%
+{%
+ \xintifCmp {#1}{#2}{,#1\expandafter\XINT_seqb::csv_p\expandafter}%
+ {,#1\xint_gobble_iii}{\xint_gobble_iii}%
+% \end{macrocode}
+% \lverb|\romannumeral0 stopped by \endcsname, XINT_expr_seq_empty? constructs
+% "nil".|
+% \begin{macrocode}
+ {\romannumeral0\xintadd {#3}{#1}}{#2}{#3}%
+}%
+\def\XINT_seqb::csv_n #1#2#3%
+{%
+ \xintifCmp {#1}{#2}{\xint_gobble_iii}{,#1\xint_gobble_iii}%
+ {,#1\expandafter\XINT_seqb::csv_n\expandafter}%
+ {\romannumeral0\xintadd {#3}{#1}}{#2}{#3}%
+}%
+\def\XINT_seqb::csv_z #1#2#3{,#1}%
+% \end{macrocode}
+%\subsubsection{\csh{xintiiSeqB::csv}}
+% \begin{macrocode}
+\def\xintiiSeqB::csv #1#2{\XINT_iiseqb::csv #1#2}%
+\def\XINT_iiseqb::csv #1#2#3#4%
+ {\expandafter\XINT_iiseqb::csv_a
+ \romannumeral`&&@\expandafter \XINT_expr_unlock\expandafter#2%
+ \romannumeral`&&@\XINT_expr_unlock #4!}%
+\def\XINT_iiseqb::csv_a #1#2;#3;#4!{\expandafter\XINT_expr_seq_empty?
+ \romannumeral`&&@\csname XINT_iiseqb::csv_#1\endcsname {#3}{#4}{#2}}%
+\def\XINT_iiseqb::csv_p #1#2#3%
+{%
+ \xintSgnFork{\XINT_Cmp {#1}{#2}}{,#1\expandafter\XINT_iiseqb::csv_p\expandafter}%
+ {,#1\xint_gobble_iii}{\xint_gobble_iii}%
+ {\romannumeral0\xintiiadd {#3}{#1}}{#2}{#3}%
+}%
+\def\XINT_iiseqb::csv_n #1#2#3%
+{%
+ \xintSgnFork{\XINT_Cmp {#1}{#2}}{\xint_gobble_iii}{,#1\xint_gobble_iii}%
+ {,#1\expandafter\XINT_iiseqb::csv_n\expandafter}%
+ {\romannumeral0\xintiiadd {#3}{#1}}{#2}{#3}%
+}%
+\def\XINT_iiseqb::csv_z #1#2#3{,#1}%
+% \end{macrocode}
+%\subsubsection{\csh{XINTinFloatSeqB::csv}}
+% \begin{macrocode}
+\def\XINTinFloatSeqB::csv #1#2{\expandafter\XINT_flseqb::csv \expandafter
+ {\romannumeral0\XINTinfloat [\XINTdigits]{#2}}{#1}}%
+\def\XINT_flseqb::csv #1#2{\expandafter\XINT_flseqb::csv_a\romannumeral`&&@#2#1!}%
+\def\XINT_flseqb::csv_a #1#2;#3;#4!{\expandafter\XINT_expr_seq_empty?
+ \romannumeral`&&@\csname XINT_flseqb::csv_#1\endcsname {#3}{#4}{#2}}%
+\def\XINT_flseqb::csv_p #1#2#3%
+{%
+ \xintifCmp {#1}{#2}{,#1\expandafter\XINT_flseqb::csv_p\expandafter}%
+ {,#1\xint_gobble_iii}{\xint_gobble_iii}%
+ {\romannumeral0\XINTinfloatadd {#3}{#1}}{#2}{#3}%
+}%
+\def\XINT_flseqb::csv_n #1#2#3%
+{%
+ \xintifCmp {#1}{#2}{\xint_gobble_iii}{,#1\xint_gobble_iii}%
+ {,#1\expandafter\XINT_flseqb::csv_n\expandafter}%
+ {\romannumeral0\XINTinfloatadd {#3}{#1}}{#2}{#3}%
+}%
+\def\XINT_flseqb::csv_z #1#2#3{,#1}%
+% \end{macrocode}
+% \subsection{The comma as binary operator}
+% \lverb|New with 1.09a. Suffices to set its precedence level to two.|
+% \begin{macrocode}
+\def\XINT_tmpa #1#2#3#4#5#6%
+{%
+ \def #1##1% \XINT_expr_op_,
+ {%
+ \expandafter #2\expandafter ##1\romannumeral`&&@\XINT_expr_getnext
+ }%
+ \def #2##1##2% \XINT_expr_until_,_a
+ {\xint_UDsignfork
+ ##2{\expandafter #2\expandafter ##1\romannumeral`&&@#4}%
+ -{#3##1##2}%
+ \krof }%
+ \def #3##1##2##3##4% \XINT_expr_until_,_b
+ {%
+ \ifnum ##2>\xint_c_ii
+ \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@%
+ \csname XINT_#6_op_##3\endcsname {##4}}%
+ \else
+ \xint_afterfi
+ {\expandafter ##2\expandafter ##3%
+ \csname .=\XINT_expr_unlock ##1,\XINT_expr_unlock ##4\endcsname }%
+ \fi
+ }%
+ \let #5\xint_c_ii
+}%
+\xintFor #1 in {expr,flexpr,iiexpr} \do {%
+\expandafter\XINT_tmpa
+ \csname XINT_#1_op_,\expandafter\endcsname
+ \csname XINT_#1_until_,_a\expandafter\endcsname
+ \csname XINT_#1_until_,_b\expandafter\endcsname
+ \csname XINT_#1_op_-vi\expandafter\endcsname
+ \csname XINT_expr_precedence_,\endcsname {#1}%
+}%
+% \end{macrocode}
+% \subsection{The minus as prefix operator of variable precedence level}
+% \lverb|Inherits the precedence level of the previous infix operator.|
+% \begin{macrocode}
+\def\XINT_tmpa #1#2#3%
+{%
+ \expandafter\XINT_tmpb
+ \csname XINT_#1_op_-#3\expandafter\endcsname
+ \csname XINT_#1_until_-#3_a\expandafter\endcsname
+ \csname XINT_#1_until_-#3_b\expandafter\endcsname
+ \csname xint_c_#3\endcsname {#1}#2%
+}%
+\def\XINT_tmpb #1#2#3#4#5#6%
+{%
+ \def #1% \XINT_expr_op_-<level>
+ {% get next number+operator then switch to _until macro
+ \expandafter #2\romannumeral`&&@\XINT_expr_getnext
+ }%
+ \def #2##1% \XINT_expr_until_-<l>_a
+ {\xint_UDsignfork
+ ##1{\expandafter #2\romannumeral`&&@#1}%
+ -{#3##1}%
+ \krof }%
+ \def #3##1##2##3% \XINT_expr_until_-<l>_b
+ {% _until tests precedence level with next op, executes now or postpones
+ \ifnum ##1>#4%
+ \xint_afterfi {\expandafter #2\romannumeral`&&@%
+ \csname XINT_#5_op_##2\endcsname {##3}}%
+ \else
+ \xint_afterfi {\expandafter ##1\expandafter ##2%
+ \csname .=%
+ \XINT:NEhook:one#6{\XINT_expr_unlock ##3}\endcsname }%
+ \fi
+ }%
+}%
+% \end{macrocode}
+% \lverb|1.2d needs precedence 8 for *** and 9 for ^. Earlier, precedence
+% level for ^ was only 8 but nevertheless the code did also "ix" here, which I
+% think was unneeded back then.|
+% \begin{macrocode}
+\xintApplyInline{\XINT_tmpa {expr}\xintOpp}{{vi}{vii}{viii}{ix}}%
+\xintApplyInline{\XINT_tmpa {flexpr}\xintOpp}{{vi}{vii}{viii}{ix}}%
+\xintApplyInline{\XINT_tmpa {iiexpr}\xintiiOpp}{{vi}{vii}{viii}{ix}}%
+% \end{macrocode}
+% \subsection{? as two-way and ?? as three-way conditionals with braced branches}
+% \lverb|In 1.1, I overload ? with ??, as : will be used for list extraction,
+% problem with (stuff)?{?(1)}{0} for example, one should put a space (stuff)?{
+% ?(1)}{0} will work. Small idiosyncrasy. (which has been removed in 1.2h,
+% there is no problem anymore with (test)?{?(1)}{0}, however (test)?{?}{!}(x)
+% is not accepted; but (test)?{?(x)}{!(x)} is or even with {?(}{!(}x).)
+%
+% syntax: ?{yes}{no} and ??{<0}{=0}{>0}.
+%
+% The difficulty is to recognize the second ? without removing braces as would
+% be the case with standard parsing of operators. Hence the ? operator is
+% intercepted in \XINT_expr_getop_b.
+%
+% 1.2h corrects a bug in \XINT_expr_op_? which in context like
+% (test)?{\foo}{bar} would provoke expansion of \foo, or also with
+% (test)?{}{bar} would result in an error. The fix also solves the
+% (test)?{?(1)}{0} issue mentioned above.
+% |
+% \begin{macrocode}
+\let\XINT_expr_precedence_? \xint_c_x
+\def\XINT_expr_op_? #1#2%
+ {\XINT_expr_op_?checka #2!\xint_bye\XINT_expr_op_?a #1{#2}}%
+\def\XINT_expr_op_?checka #1{\expandafter\XINT_expr_op_?checkb\detokenize{#1}}%
+\def\XINT_expr_op_?checkb #1{\if ?#1\expandafter\XINT_expr_op_?checkc
+ \else\expandafter\xint_bye\fi }%
+\def\XINT_expr_op_?checkc #1{\xint_gob_til_! #1\XINT_expr_op_?? !\xint_bye}%
+\def\XINT_expr_op_?a #1#2#3%
+{%
+ \xintiiifNotZero{\XINT_expr_unlock #1}{\XINT_expr_getnext #2}{\XINT_expr_getnext #3}%
+}%
+\let\XINT_flexpr_op_?\XINT_expr_op_?
+\let\XINT_iiexpr_op_?\XINT_expr_op_?
+\def\XINT_expr_op_?? !\xint_bye\xint_bye\XINT_expr_op_?a #1#2#3#4#5%
+{%
+ \xintiiifSgn {\XINT_expr_unlock #1}%
+ {\XINT_expr_getnext #3}{\XINT_expr_getnext #4}{\XINT_expr_getnext #5}%
+}%
+% \end{macrocode}
+% \subsection{! as postfix factorial operator}
+% \lverb|&
+% |
+% \begin{macrocode}
+\let\XINT_expr_precedence_! \xint_c_x
+\def\XINT_expr_op_! #1{\expandafter\XINT_expr_getop
+ \csname .=\XINT:NEhook:one\xintFac{\XINT_expr_unlock #1}\endcsname }%
+\def\XINT_flexpr_op_! #1{\expandafter\XINT_expr_getop
+ \csname .=\XINT:NEhook:one\XINTinFloatFac{\XINT_expr_unlock #1}\endcsname }%
+\def\XINT_iiexpr_op_! #1{\expandafter\XINT_expr_getop
+ \csname .=\XINT:NEhook:one\xintiiFac{\XINT_expr_unlock #1}\endcsname }%
+% \end{macrocode}
+% \subsection{The A/B[N] mechanism}
+% \lverb|Releases earlier than 1.1 required the use of braces around A/B[N]
+% input. The [N] is now implemented directly. *BUT* this uses a delimited macro!
+% thus N is not allowed to be itself an expression (I could add it...).
+% \xintE, \xintiiE, and \XINTinFloatE all put #2 in a \numexpr. But attention
+% to the fact that \numexpr stops at spaces separating digits:
+% \the\numexpr 3 + 7 9\relax gives 109\relax !! Hence we have to be
+% careful.
+%
+% \numexpr will not handle catcode 11 digits, but adding a \detokenize will
+% suddenly make illicit for N to rely on macro expansion.|
+%
+% \begin{macrocode}
+\catcode`[ 11
+\let\XINT_expr_precedence_[ \xint_c_vii
+\def\XINT_expr_op_[ #1#2]{\expandafter\XINT_expr_getop
+ \csname .=\xintE{\XINT_expr_unlock #1}%
+ {\xint_zapspaces #2 \xint_gobble_i}\endcsname}%
+\def\XINT_iiexpr_op_[ #1#2]{\expandafter\XINT_expr_getop
+ \csname .=\xintiiE{\XINT_expr_unlock #1}%
+ {\xint_zapspaces #2 \xint_gobble_i}\endcsname}%
+\def\XINT_flexpr_op_[ #1#2]{\expandafter\XINT_expr_getop
+ \csname .=\XINTinFloatE{\XINT_expr_unlock #1}%
+ {\xint_zapspaces #2 \xint_gobble_i}\endcsname}%
+\catcode`[ 12
+% \end{macrocode}
+% \subsection{\csh{XINT_expr_op_`} for recognizing functions}
+% \lverb|The "onliteral" intercepts is for bool, togl, protect, ... but also
+% for add, mul, seq, etc... Genuine functions have expr, iiexpr and
+% flexpr versions (or only one or two of the three).
+%
+% With 1.2c "onliteral" is also used to disambiguate variables from
+% functions. However as I use only a \ifcsname test, in order to be able to
+% re-define a variable as function, I move the check for being a function
+% first. Each variable name now has its onliteral_<name> associated macro
+% which is the new way tacit multiplication in front of a parenthesis is
+% implemented. This used to be decided much earlier at the time of
+% \XINT_expr_func.
+%
+% The advantage of our choices for 1.2c is that the same name can be used for
+% a variable or a function, the parser will apply the correct interpretation
+% which is decided by the presence or not of an opening parenthesis next.|
+% \begin{macrocode}
+\def\XINT_tmpa #1#2#3{%
+ \def #1##1%
+ {%
+ \ifcsname XINT_#3_func_##1\endcsname
+ \xint_dothis{\expandafter\expandafter
+ \csname XINT_#3_func_##1\endcsname\romannumeral`&&@#2}\fi
+ \ifcsname XINT_expr_onliteral_##1\endcsname
+ \xint_dothis{\csname XINT_expr_onliteral_##1\endcsname}\fi
+ \xint_orthat{\XINT_expr_unknown_function {##1}%
+ \expandafter\XINT_expr_func_unknown\romannumeral`&&@#2}%
+ }%
+}%
+\def\XINT_expr_unknown_function #1{\xintError:removed \xint_gobble_i {#1}}%
+\xintFor #1 in {expr,flexpr,iiexpr} \do {%
+ \expandafter\XINT_tmpa
+ \csname XINT_#1_op_`\expandafter\endcsname
+ \csname XINT_#1_oparen\endcsname
+ {#1}%
+}%
+\def\XINT_expr_func_unknown #1#2#3%
+ {\expandafter #1\expandafter #2\csname .=0\endcsname }%
+% \end{macrocode}
+% \subsection{The \csh{bool()}, \csh{togl()}, \csh{protect()} pseudo ``functions''}
+% \lverb|bool, togl and protect use delimited macros. They are not true
+% functions, they turn off the parser to gather their "variable".|
+% \begin{macrocode}
+\def\XINT_expr_onliteral_bool #1)%
+ {\expandafter\XINT_expr_getop\csname .=\xintBool{#1}\endcsname }%
+\def\XINT_expr_onliteral_togl #1)%
+ {\expandafter\XINT_expr_getop\csname .=\xintToggle{#1}\endcsname }%
+\def\XINT_expr_onliteral_protect #1)%
+ {\expandafter\XINT_expr_getop\csname .=\detokenize{#1}\endcsname }%
+% \end{macrocode}
+% \subsection{The \csh{break()} function}
+% \lverb|break is a true function, the parsing via expansion of the succeeding
+% material proceeded via _oparen macros as with any other function.|
+% \begin{macrocode}
+\def\XINT_expr_func_break #1#2#3%
+ {\expandafter #1\expandafter #2\csname.=?\romannumeral`&&@\XINT_expr_unlock #3\endcsname }%
+\let\XINT_flexpr_func_break \XINT_expr_func_break
+\let\XINT_iiexpr_func_break \XINT_expr_func_break
+% \end{macrocode}
+% \subsection{The \csh{qraw()}, \csh{qint()}, \csh{qfrac()}, and
+% \csh{qfloat()} ``functions''}
+%
+% \changed{1.2}{} adds |qint()|, |qfrac()|, |qfloat()|.
+%
+% \changed{1.3c}{} adds |qraw()|. Useful to limit impact on \TeX{} memory
+% from abuse of |\csname|'s storage when generating many comma separated
+% values from a loop.
+%
+% \changed{1.3e}{} |qfloat()| keeps a short mantissa if possible.
+%
+% \lverb|They allow the user to hand over quickly a big number to the parser,
+% spaces not immediately removed but should be harmless in general. The qraw()
+% does no post-processing at all apart complete expansion, useful for
+% comma-separated values, but must be obedient to (non really documented)
+% expected format. Each uses a delimited macro, the closing parenthesis can
+% not emerge from expansion.|
+% \begin{macrocode}
+\def\XINT_expr_onliteral_qint #1)%
+ {\expandafter\XINT_expr_getop\csname .=\xintiNum{#1}\endcsname }%
+\def\XINT_expr_onliteral_qfrac #1)%
+ {\expandafter\XINT_expr_getop\csname .=\xintRaw{#1}\endcsname }%
+\def\XINT_expr_onliteral_qfloat #1)%
+ {\expandafter\XINT_expr_getop\csname .=\XINTinFloatSdigits{#1}\endcsname }%
+\def\XINT_expr_onliteral_qraw #1)%
+ {\expandafter\XINT_expr_getop\csname .=#1\endcsname }%
+% \end{macrocode}
+% \subsection{The \csh{random()} and \csh{qrand()} ``functions''}
+% \lverb|1.3b. Function-like syntax but with no argument currently, so let's
+% use fast parsing which requires though the closing parenthesis to be
+% explicit.|
+% \begin{macrocode}
+\def\XINT_expr_onliteral_random #1)%
+ {\expandafter\XINT_expr_getop\csname .=\XINTinRandomFloatSdigits\endcsname }%
+\def\XINT_expr_onliteral_qrand #1)%
+ {\expandafter\XINT_expr_getop\csname .=\XINTinRandomFloatSixteen\endcsname }%
+% \end{macrocode}
+% \subsection{\csh{XINT_expr_op__} for recognizing variables}
+% \lverb|The 1.1 mechanism for \XINT_expr_var_<varname> has been
+% modified in 1.2c. The <varname> associated macro is now only expanded
+% once, not twice. We arrive here via \XINT_expr_func.|
+% \begin{macrocode}
+\def\XINT_expr_op__ #1% op__ with two _'s
+ {%
+ \ifcsname XINT_expr_var_#1\endcsname
+ \expandafter\xint_firstoftwo
+ \else
+ \expandafter\xint_secondoftwo
+ \fi
+ {\expandafter\expandafter\expandafter
+ \XINT_expr_getop\csname XINT_expr_var_#1\endcsname}%
+ {\XINT_expr_unknown_variable {#1}%
+ \expandafter\XINT_expr_getop\csname .=0\endcsname}%
+ }%
+\def\XINT_expr_unknown_variable #1{\xintError:removed \xint_gobble_i {#1}}%
+\let\XINT_flexpr_op__ \XINT_expr_op__
+\let\XINT_iiexpr_op__ \XINT_expr_op__
+% \end{macrocode}
+% \subsection{User defined variables: \csh{xintdefvar}, \csh{xintdefiivar},
+% \csh{xintdeffloatvar}}
+% \changed{1.1}{}
+%
+% \changed{1.2p}{2017/12/01} extends |\xintdefvar| et al.\@ to accept
+% simultaneous assignments to multiple variables.
+%
+% \changed{1.3c}{2018/06/17}
+% Use \csbxint{exprSafeCatcodes} (to palliate issue with
+% active semi-colon from Babel+French if in body of a \LaTeX{} document).
+%
+% And allow usage with both syntaxes |name:=expr;| or |name=expr;|. Also the
+% colon may have catcode 11, 12, or 13 with no issue.
+% Variable names may contain letters, digits, underscores, and must not start
+% with a digit. Names starting with |@| or an underscore are reserved.
+%
+% \begin{itemize}[nosep]
+% \item currently |@|, |@1|, |@2|, |@3|, and |@4| are reserved because they
+% have special meanings for use in iterations,
+% \item |@@|, |@@@|, |@@@@| are also reserved but
+% are technically functions, not variables: a user may possibly define |@@| as
+% a variable name, but if it is followed by parentheses, the function
+% interpretation will be applied (rather than the variable interpretation
+% followed by a tacit multiplication),
+% \item since |1.2l|, the underscore |_| may be used as separator of digits in
+% long numbers.
+% Hence a variable whose name starts with |_| will not play well with the
+% mechanism of tacit multiplication of variables by numbers: the underscore
+% will be removed from input stream by the number scanner, thus creating
+% an undefined or wrong variable name, or none at all if the variable
+% name was an initial |_| followed by digits.
+% \end{itemize}
+% \lverb|
+% |
+% \begin{macrocode}
+\catcode`* 11
+\def\XINT_expr_defvar_one #1#2%
+{%
+ \XINT_global
+ \expandafter\edef\csname XINT_expr_var_#1\endcsname
+ {\expandafter\noexpand#2}%
+ \XINT_global
+ \expandafter\edef\csname XINT_expr_onliteral_#1\endcsname
+ {\XINT_expr_precedence_*** *\expandafter\noexpand#2(}%
+ \ifxintverbose\xintMessage{xintexpr}{Info}
+ {Variable "#1" \ifxintglobaldefs globally \fi
+ defined with value \expandafter\XINT_expr_unlock#2.}%
+ \fi
+}%
+\catcode`* 12
+\catcode`~ 13
+\catcode`: 12
+\def\XINT_expr_defvar_getname #1:#2~{\endgroup
+ \def\XINT_defvar_tmpa{#1}\edef\XINT_defvar_tmpc{\xintCSVLength{#1}}}%
+\def\XINT_expr_defvar #1#2#3;%
+{%
+ \xintexprRestoreCatcodes
+% \end{macrocode}
+% \lverb|Maybe SafeCatcodes was without effect because the colon and the rest
+% are from some earlier macro definition. Give a safe definition to active
+% colon (even if in math mode with a math active colon..).|
+% \begin{macrocode}
+ \begingroup\lccode`~`: \lowercase{\let~}\empty
+ \edef\XINT_defvar_tmpa{#2}%
+ \edef\XINT_defvar_tmpa{\xint_zapspaces_o\XINT_defvar_tmpa}%
+ \expandafter\XINT_expr_defvar_getname
+ \detokenize\expandafter{\XINT_defvar_tmpa}:~%
+ \ifcase\XINT_defvar_tmpc\space
+ \xintMessage {xintexpr}{Warning}
+ {Aborting: not allowed to declare variable with empty name.}%
+ \or
+ \edef\XINT_defvar_tmpb{\romannumeral0#1#3\relax}%
+ \XINT_expr_defvar_one\XINT_defvar_tmpa\XINT_defvar_tmpb
+ \else
+ \edef\XINT_defvar_tmpb
+ {\expandafter\XINT_expr_unlock\romannumeral0#1#3\relax}%
+ \edef\XINT_defvar_tmpd{\xintCSVLength{\XINT_defvar_tmpb}}%
+ \ifnum\XINT_defvar_tmpc=\XINT_defvar_tmpd\space
+ \xintAssignArray\xintCSVtoList\XINT_defvar_tmpa\to\XINT_defvar_tmpvar
+ \xintAssignArray
+ \xintApply\XINT_expr_lockit{\xintCSVtoList\XINT_defvar_tmpb}%
+ \to\XINT_defvar_tmpval
+ \def\XINT_defvar_tmpd{1}%
+ \xintloop
+ \expandafter\XINT_expr_defvar_one
+ \csname XINT_defvar_tmpvar\XINT_defvar_tmpd\expandafter\endcsname
+ \csname XINT_defvar_tmpval\XINT_defvar_tmpd\endcsname
+ \ifnum\XINT_defvar_tmpd<\XINT_defvar_tmpc\space
+ \edef\XINT_defvar_tmpd{\the\numexpr\XINT_defvar_tmpd+1}%
+ \repeat
+ \xintRelaxArray\XINT_defvar_tmpvar
+ \xintRelaxArray\XINT_defvar_tmpval
+ \else
+ \xintMessage {xintexpr}{Warning}
+ {Aborting: mismatch between number of variables (\XINT_defvar_tmpc)
+ and number of values (\XINT_defvar_tmpd).}%
+ \fi
+ \fi
+}%
+\catcode`~ 3
+\catcode`: 11
+% \end{macrocode}
+% \lverb|This SafeCatcodes is mainly in the hope that semi-colon ending the
+% expression can still be sanitized.|
+% \begin{macrocode}
+\def\xintdefvar {\xintexprSafeCatcodes\xintdefvar_a}%
+\def\xintdefiivar {\xintexprSafeCatcodes\xintdefiivar_a}%
+\def\xintdeffloatvar {\xintexprSafeCatcodes\xintdeffloatvar_a}%
+\def\xintdefvar_a #1={\XINT_expr_defvar\xintbareeval {#1}}%
+\def\xintdefiivar_a #1={\XINT_expr_defvar\xintbareiieval {#1}}%
+\def\xintdeffloatvar_a #1={\XINT_expr_defvar\xintbarefloateval {#1}}%
+% \end{macrocode}
+% \subsection{\csh{xintunassignvar}}
+% \changed{1.2e}{}
+%
+% \changed{1.3d}{}
+% Embarrassingly I had for a long time a misunderstanding of |\ifcsname|
+% (let's blame its documentation) and I was not aware that it chooses FALSE
+% branch if tested control sequence has been |\let| to |\undefined|... So
+% earlier version didn't do the right thing (and had another bug: failure to
+% protect |\.=0| from expansion).
+%
+% The |\ifcsname| tests are done in \csbXINT{_expr_op__} and
+% \csbXINT{_expr_op_`}.
+% \begin{macrocode}
+\def\xintunassignvar #1{%
+ \edef\XINT_unvar_tmpa{#1}%
+ \edef\XINT_unvar_tmpa {\xint_zapspaces_o\XINT_unvar_tmpa}%
+ \ifcsname XINT_expr_var_\XINT_unvar_tmpa\endcsname
+ \ifnum\expandafter\xintLength\expandafter{\XINT_unvar_tmpa}=\@ne
+ \expandafter\xintnewdummy\XINT_unvar_tmpa
+ \else
+ \XINT_global\expandafter
+ \let\csname XINT_expr_var_\XINT_unvar_tmpa\endcsname\xint_undefined
+ \XINT_global\expandafter
+ \let\csname XINT_expr_onliteral_\XINT_unvar_tmpa\endcsname\xint_undefined
+ \ifxintverbose\xintMessage {xintexpr}{Info}
+ {Variable \XINT_unvar_tmpa\space has been
+ \ifxintglobaldefs globally \fi ``unassigned''.}%
+ \fi
+ \fi
+ \else
+ \xintMessage {xintexpr}{Warning}
+ {Error: there was no such variable \XINT_unvar_tmpa\space to unassign.}%
+ \fi
+}%
+% \end{macrocode}
+% \subsection{seq and the implementation of dummy variables}
+% \localtableofcontents
+% \lverb|All of seq, add, mul, rseq, etc... (actually all of the extensive
+% changes from xintexpr 1.09n to 1.1) was done around June 15-25th 2014, but the
+% problem is that I did not document the code enough, and I had a hard time
+% understanding in October what I had done in June. Despite the lesson, again
+% being short on time, I do not document enough my current understanding of the
+% innards of the beast...
+%
+% I added subs, and iter in October (also the [:n], [n:] list extractors),
+% proving I did at least understand a bit (or rather could imitate) my earlier
+% code (but don't ask me to explain \xintNewExpr !)
+%
+% The \XINT_expr_onliteral_seq_a parses: "expression, variable=list)"
+% (when it is called the opening ( has been swallowed, and it looks for
+% the ending one.) Both expression and list may themselves contain
+% parentheses and commas, we allow nesting. For example "x^2,x=1..10)",
+% at the end of seq_a we have {variable{expression}}{list}, in this
+% example {x{x^2}}{1..10}, or more complicated
+% "seq(add(y,y=1..x),x=1..10)" will work too. The variable is a single
+% lowercase Latin letter.
+%
+% The complications with \xint_c_xviii in seq_f is for the recurrent
+% thing that we don't know in what type of expressions we are, hence we
+% must move back up, with some loss of efficiency (superfluous check for
+% minus sign, etc...). But the code manages simultaneously expr, flexpr
+% and iiexpr.|
+%
+% \subsubsection{All letters usable as dummy variables, \csh{xintnewdummy}}
+% \lverb|The nil variable was introduced in 1.1 but isn't used under that
+% name. However macros handling a..[d]..b, or for seq with dummy variable
+% where omit has omitted everyting may in practice inject a nil value as
+% current number.
+%
+% 1.2c has changed the way variables are disambiguated from functions and for
+% this it has added here the definitions of \XINT_expr_onliteral_<name>.
+%
+% In 1.1 a letter variable say X was acting as a delimited macro looking for
+% !X{stuff} and then would expand the stuff inside a \csname.=...\endcsname. I
+% don't think I used the possibilities this opened and the 1.2c version has
+% stuff _already_ encapsulated thus a single token. Only one expansion, not
+% two is then needed in \XINT_expr_op__.
+%
+% I had to accordingly modify seq, add, mul and subs, but fortunately realized
+% that the @, @1, etc... variables for rseq, rrseq and iter already had been
+% defined in the way now also followed by the Latin letters as dummy
+% variables.
+%
+% The 1.2e \XINT_expr_makedummy was adjoined \xintnewdummy by
+% 1.2k for a public interface. It should not be used with multi-letter
+% argument. The add, mul, seq, etc... can only work with one-letter long dummy
+% variable. And this will almost certainly not change.
+%
+% Also 1.2e does the tacit multiplication x(stuff)->x*(stuff) in its higher
+% precedence form. Things are easy now that variables always fetch a single
+% already locked value \.=<number>.
+%
+% The tacit multiplication in case of the ``nil'' variable doesn't make much
+% sense but we do it anyhow.
+%
+% 1.3e stores earlier meaning for usage by xinttrig and xintlog with
+% \xintensuredummy and \xintrestoredummy as high-level interface.
+%
+% Do an \xintrestorevar, and patch \xintdefvar to always store previous
+% meaning?
+% |
+%
+% \begin{macrocode}
+\catcode`* 11
+\def\XINT_expr_makedummy #1%
+{%
+ \ifcsname XINT_expr_var_#1\endcsname
+ \XINT_global
+ \expandafter\let\csname XINT_expr_var_#1/old\expandafter\endcsname
+ \csname XINT_expr_var_#1\expandafter\endcsname
+ \fi
+ \ifcsname XINT_expr_onliteral_#1\endcsname
+ \XINT_global
+ \expandafter\let\csname XINT_expr_onliteral_#1/old\expandafter\endcsname
+ \csname XINT_expr_onliteral_#1\expandafter\endcsname
+ \fi
+ \XINT_global
+ \expandafter\def\csname XINT_expr_var_#1\endcsname ##1\relax !#1##2%
+ {##2##1\relax !#1##2}%
+ \XINT_global
+ \expandafter\def\csname XINT_expr_onliteral_#1\endcsname ##1\relax !#1##2%
+ {\XINT_expr_precedence_*** *##2(##1\relax !#1##2}%
+}%
+\xintApplyUnbraced \XINT_expr_makedummy {abcdefghijklmnopqrstuvwxyz}%
+\xintApplyUnbraced \XINT_expr_makedummy {ABCDEFGHIJKLMNOPQRSTUVWXYZ}%
+\def\xintnewdummy #1{%
+ \XINT_expr_makedummy{#1}%
+ \ifxintverbose\xintMessage {xintexpr}{Info}%
+ {#1 (with letter catcode) now
+ \ifxintglobaldefs globally \fi usable as dummy variable.}%
+ \fi
+}%
+\edef\XINT_expr_var_nil {\expandafter\noexpand\csname .= \endcsname}%
+\edef\XINT_expr_onliteral_nil
+ {\XINT_expr_precedence_*** *\expandafter\noexpand\csname .= \endcsname (}%
+\catcode`* 12
+% \end{macrocode}
+% \subsubsection{\cshn{xintensuredummy}, \cshn{xintrestorelettervar}}
+% \lverb|\xintensuredummy differs only in the informational message...
+% Attention that this is not meant to be nested.|
+% \begin{macrocode}
+\def\xintensuredummy #1{%
+ \XINT_expr_makedummy{#1}%
+ \ifxintverbose\xintMessage {xintexpr}{Info}%
+ {#1 (with letter catcode) now
+ \ifxintglobaldefs globally \fi usable as dummy variable.&&J
+ Use \string\xintrestoredummy{#1} to restore it to its former meaning.}%
+ \fi
+}%
+\def\xintrestorelettervar #1{%
+ \ifcsname XINT_expr_var_#1/old\endcsname
+ \XINT_global
+ \expandafter\let\csname XINT_expr_var_#1\expandafter\endcsname
+ \csname XINT_expr_var_#1/old\expandafter\endcsname
+ \fi
+ \ifcsname XINT_expr_onliteral_#1/old\endcsname
+ \XINT_global
+ \expandafter\let\csname XINT_expr_onliteral_#1\expandafter\endcsname
+ \csname XINT_expr_onliteral_#1/old\expandafter\endcsname
+ \fi
+ \ifxintverbose\xintMessage {xintexpr}{Info}%
+ {Character #1 (with letter catcode)
+ \ifxintglobaldefs globally \fi restored to its earlier status, if any.}%
+ \fi
+}%
+% \end{macrocode}
+% \subsubsection{\csh{omit()} and \csh{abort()}}
+% \lverb|& attention à ce & qui est de catcode 14 dans les \lverb
+% June 24 and 25, 2014.
+%
+% Added comments 2015/11/13:
+%
+% Et la documentation ? on n'y comprend plus rien. Trop
+% rusé.$newline
+% \def\XINT_expr_var_omit #1\relax !{1^C!{}{}{}\.=!\relax !}$newline
+% \def\XINT_expr_var_abort #1\relax !{1^C!{}{}{}\.=^\relax !}$newline
+% C'était accompagné de \XINT_expr_precedence_^C=0 et d'un hack au sein même
+% des macros until de plus bas niveau.
+%
+% Le mécanisme sioux était le suivant: ^C est déclaré comme un opérateur de
+% précédence nulle. Lorsque le parseur trouve un "omit" dans un seq ou autre,
+% il va insérer dans le stream \XINT_expr_getop suivi du texte de
+% remplacement. Donc ici on avait un 1 comme place holder, puis l'opérateur
+% ^C. Celui-ci étant de précédence zéro provoque la finalisation de tous les
+% calculs antérieurs dans le sous-bareeval. Mais j'ai dû hacker le until_end_b
+% (et le until_)_b) qui confronté à ^C, va se relancer à zéro, le getnext va
+% trouver le !{}{}{}\.=! et ensuite il y aura \relax, et le résultat sera \.=!
+% pour omit ou \.=^ pour abort. Les routines des boucles seq, iter, etc...
+% peuvent alors repérer le ! ou ^ et agir en conséquence (un long paragraphe
+% pour ne décrire que partiellement une ou deux lignes de codes...).
+%
+% Mais ^C a été fait alors que je n'avais pas encore les variables muettes. Je
+% dois trouver autre chose, car seq(2^C, C=1..5) est alors impossible. De
+% toute façon ce ^C était à usage interne uniquement.
+%
+% Il me faut un symbole d'opérateur qui ne rentre pas en conflit. Bon je vais
+% prendre !?. Ensuite au lieu de hacker until_end, il vaut mieux lui donner
+% précédence 2 (mais ça ne pourra pas marcher à l'intérieur de parenthèses il
+% faut d'abord les fermer manuellement) et lui associer un simplement un op
+% spécial. Je n'avais pas fait cela peut-être pour éviter d'avoir à définir
+% plusieurs macros. Le #1 dans la définition de \XINT_expr_op_!? est le
+% résultat de l'évaluation forcée précédente.
+%
+% Attention que les premier ! doiventt être de catcode 12 sinon ils
+% signalent une sous-expression qui déclenche une multiplication tacite.
+%
+% |
+% \begin{macrocode}
+\edef\XINT_expr_var_omit #1\relax !{1\string !?!\relax !}%
+\edef\XINT_expr_var_abort #1\relax !{1\string !?^\relax !}%
+\def\XINT_expr_op_!? #1#2\relax {\expandafter\XINT_expr_foundend\csname .=#2\endcsname}%
+\let\XINT_iiexpr_op_!? \XINT_expr_op_!?
+\let\XINT_flexpr_op_!? \XINT_expr_op_!?
+% \end{macrocode}
+% \subsubsection{The special variables @, @1, @2, @3, @4, @@, @@(1), \dots, @@@,
+% @@@(1), \dots for recursion}
+% \lverb|October 2014: I had completely forgotten what the @@@ etc... stuff
+% were supposed to do: this is for nesting recursions! (I was mad back in
+% June). @@(N) gives the Nth back, @@@(N) gives the Nth back of the higher
+% recursion!
+%
+% 1.2c adds the needed "onliteral" now that tacit multiplication between a
+% variable and a ( has a new mechanism. 1.2e does this tacit multiplication
+% with higher precedence.
+%
+% For the record, the ~ has catcode 3 in this code.|
+%
+% \begin{macrocode}
+\catcode`? 3 \catcode`* 11
+\def\XINT_expr_var_@ #1~#2{#2#1~#2}%
+\expandafter\let\csname XINT_expr_var_@1\endcsname \XINT_expr_var_@
+\expandafter\def\csname XINT_expr_var_@2\endcsname #1~#2#3{#3#1~#2#3}%
+\expandafter\def\csname XINT_expr_var_@3\endcsname #1~#2#3#4{#4#1~#2#3#4}%
+\expandafter\def\csname XINT_expr_var_@4\endcsname #1~#2#3#4#5{#5#1~#2#3#4#5}%
+\def\XINT_expr_onliteral_@ #1~#2{\XINT_expr_precedence_*** *#2(#1~#2}%
+\expandafter\let\csname XINT_expr_onliteral_@1\endcsname \XINT_expr_onliteral_@
+\expandafter\def\csname XINT_expr_onliteral_@2\endcsname #1~#2#3%
+ {\XINT_expr_precedence_*** *#3(#1~#2#3}%
+\expandafter\def\csname XINT_expr_onliteral_@3\endcsname #1~#2#3#4%
+ {\XINT_expr_precedence_*** *#4(#1~#2#3#4}%
+\expandafter\def\csname XINT_expr_onliteral_@4\endcsname #1~#2#3#4#5%
+ {\XINT_expr_precedence_*** *#5(#1~#2#3#4#5}%
+\catcode`* 12
+\def\XINT_expr_func_@@ #1#2#3#4~#5?%
+{%
+ \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand
+ {\xintNum{\XINT_expr_unlock#3}}{#5}#4~#5?%
+}%
+\def\XINT_expr_func_@@@ #1#2#3#4~#5~#6?%
+{%
+ \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand
+ {\xintNum{\XINT_expr_unlock#3}}{#6}#4~#5~#6?%
+}%
+\def\XINT_expr_func_@@@@ #1#2#3#4~#5~#6~#7?%
+{%
+ \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand
+ {\xintNum{\XINT_expr_unlock#3}}{#7}#4~#5~#6~#7?%
+}%
+\let\XINT_flexpr_func_@@\XINT_expr_func_@@
+\let\XINT_flexpr_func_@@@\XINT_expr_func_@@@
+\let\XINT_flexpr_func_@@@@\XINT_expr_func_@@@@
+\def\XINT_iiexpr_func_@@ #1#2#3#4~#5?%
+{%
+ \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand
+ {\XINT_expr_unlock#3}{#5}#4~#5?%
+}%
+\def\XINT_iiexpr_func_@@@ #1#2#3#4~#5~#6?%
+{%
+ \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand
+ {\XINT_expr_unlock#3}{#6}#4~#5~#6?%
+}%
+\def\XINT_iiexpr_func_@@@@ #1#2#3#4~#5~#6~#7?%
+{%
+ \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand
+ {\XINT_expr_unlock#3}{#7}#4~#5~#6~#7?%
+}%
+\catcode`? 11
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_onliteral_seq}}
+% \begin{macrocode}
+\def\XINT_expr_onliteral_seq
+ {\expandafter\XINT_expr_onliteral_seq_f\romannumeral`&&@\XINT_expr_onliteral_seq_a {}}%
+\def\XINT_expr_onliteral_seq_f #1#2{\xint_c_xviii `{seqx}#2)\relax #1}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_onliteral_seq_a}}
+% \begin{macrocode}
+\def\XINT_expr_onliteral_seq_a #1#2,%
+{%
+ \ifcase\XINT_isbalanced_a \relax #1#2(\xint_bye)\xint_bye
+ \expandafter\XINT_expr_onliteral_seq_c
+ \or\expandafter\XINT_expr_onliteral_seq_b
+ \else\expandafter\xintError:we_are_doomed
+ \fi {#1#2},%
+}%
+\def\XINT_expr_onliteral_seq_b #1,{\XINT_expr_onliteral_seq_a {#1,}}%
+\def\XINT_expr_onliteral_seq_c #1,#2#3% #3 pour absorber le =
+{%
+ \XINT_expr_onliteral_seq_d {#2{#1}}{}%
+}%
+\def\XINT_expr_onliteral_seq_d #1#2#3)%
+{%
+ \ifcase\XINT_isbalanced_a \relax #2#3(\xint_bye)\xint_bye
+ \or\expandafter\XINT_expr_onliteral_seq_e
+ \else\expandafter\xintError:we_are_doomed
+ \fi
+ {#1}{#2#3}%
+}%
+\def\XINT_expr_onliteral_seq_e #1#2{\XINT_expr_onliteral_seq_d {#1}{#2)}}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_isbalanced_a} for \cshnolabel{XINT_expr_onliteral_seq_a}}
+% \lverb|Expands to \xint_c_mone in case a closing ) had no opening ( matching
+% it, to \@ne if opening ) had no closing ) matching it, to \z@ if expression
+% was balanced.|
+% \begin{macrocode}
+% use as \XINT_isbalanced_a \relax #1(\xint_bye)\xint_bye
+\def\XINT_isbalanced_a #1({\XINT_isbalanced_b #1)\xint_bye }%
+\def\XINT_isbalanced_b #1)#2%
+ {\xint_bye #2\XINT_isbalanced_c\xint_bye\XINT_isbalanced_error }%
+% \end{macrocode}
+% \lverb|if #2 is not \xint_bye, a ) was found, but there was no (. Hence error -> -1|
+% \begin{macrocode}
+\def\XINT_isbalanced_error #1)\xint_bye {\xint_c_mone}%
+% \end{macrocode}
+% \lverb|#2 was \xint_bye, was there a ) in original #1?|
+% \begin{macrocode}
+\def\XINT_isbalanced_c\xint_bye\XINT_isbalanced_error #1%
+ {\xint_bye #1\XINT_isbalanced_yes\xint_bye\XINT_isbalanced_d #1}%
+% \end{macrocode}
+% \lverb|#1 is \xint_bye, there was never ( nor ) in original #1, hence OK.|
+% \begin{macrocode}
+\def\XINT_isbalanced_yes\xint_bye\XINT_isbalanced_d\xint_bye )\xint_bye {\xint_c_ }%
+% \end{macrocode}
+% \lverb|#1 is not \xint_bye, there was indeed a ( in original #1. We check if
+% we see a ). If we do, we then loop until no ( nor ) is to be found.|
+% \begin{macrocode}
+\def\XINT_isbalanced_d #1)#2%
+ {\xint_bye #2\XINT_isbalanced_no\xint_bye\XINT_isbalanced_a #1#2}%
+% \end{macrocode}
+% \lverb|#2 was \xint_bye, we did not find a closing ) in original #1. Error.|
+% \begin{macrocode}
+\def\XINT_isbalanced_no\xint_bye #1\xint_bye\xint_bye {\xint_c_i }%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_allexpr_func_seqx}}
+% \lverb|1.2c uses \xintthebareval, ... which strangely were not available at
+% 1.1 time. This spares some tokens from \XINT_expr_seq:_d and cousins. Also now
+% variables have changed their mode of operation they pick only one token which
+% must be an already encapsulated value.
+%
+% In \XINT_allexp_seqx, #2 is the list, evaluated and encapsulated, #3 is the
+% dummy variable, #4 is the expression to evaluate repeatedly.
+%
+% A special case is a list generated by <variable>++: then #2 is {\.=+\.=<start>}.|
+% \begin{macrocode}
+\def\XINT_expr_func_seqx #1#2{\XINT_allexpr_seqx \xintthebareeval }%
+\def\XINT_flexpr_func_seqx #1#2{\XINT_allexpr_seqx \xintthebarefloateval}%
+\def\XINT_iiexpr_func_seqx #1#2{\XINT_allexpr_seqx \xintthebareiieval }%
+\def\XINT_allexpr_seqx #1#2#3#4%
+{%
+ \expandafter \XINT_expr_getop
+ \csname .=\expandafter\XINT_expr_seq:_aa
+ \romannumeral`&&@\XINT_expr_unlock #2!{#1#4\relax !#3}\endcsname
+}%
+\def\XINT_expr_seq:_aa #1{\if +#1\expandafter\XINT_expr_seq:_A\else
+ \expandafter\XINT_expr_seq:_a\fi #1}%
+% \end{macrocode}
+% \subsubsection{Evaluation over list, \csh{XINT_expr_seq:_a} with break,
+% abort, omit}
+% \lverb|The #2 here is \...bareeval <expression>\relax !<variable name>. The #1
+% is a comma separated list of values to assign to the dummy variable. The
+% \XINT_expr_seq_empty? intervenes immediately after handling of firstvalue.
+%
+% 1.2c has rewritten to a large extent this and other similar loops because
+% the dummy variables now fetch a single encapsulated token (apart from a good
+% means to lose a few hours needlessly -- as I have had to rewrite and review
+% most everything, this change could make the thing more efficient if the same
+% variable is used many times in an expression, but we are talking
+% micro-seconds here anyhow.)|
+% \begin{macrocode}
+\def\XINT_expr_seq:_a #1!#2{\expandafter\XINT_expr_seq_empty?
+ \romannumeral0\XINT_expr_seq:_b {#2}#1,^,}%
+\def\XINT_expr_seq:_b #1#2#3,{%
+ \if ,#2\xint_dothis\XINT_expr_seq:_noop\fi
+ \if ^#2\xint_dothis\XINT_expr_seq:_end\fi
+ \xint_orthat{\expandafter\XINT_expr_seq:_c}\csname.=#2#3\endcsname {#1}%
+}%
+\def\XINT_expr_seq:_noop\csname.=,#1\endcsname #2{\XINT_expr_seq:_b {#2}#1,}%
+\def\XINT_expr_seq:_end \csname.=^\endcsname #1{}%
+\def\XINT_expr_seq:_c #1#2{\expandafter\XINT_expr_seq:_d\romannumeral`&&@#2#1{#2}}%
+\def\XINT_expr_seq:_d #1{\if #1^\xint_dothis\XINT_expr_seq:_abort\fi
+ \if #1?\xint_dothis\XINT_expr_seq:_break\fi
+ \if #1!\xint_dothis\XINT_expr_seq:_omit\fi
+ \xint_orthat{\XINT_expr_seq:_goon #1}}%
+\def\XINT_expr_seq:_abort #1!#2#3#4#5^,{}%
+\def\XINT_expr_seq:_break #1!#2#3#4#5^,{,#1}%
+\def\XINT_expr_seq:_omit #1!#2#3#4{\XINT_expr_seq:_b {#4}}%
+\def\XINT_expr_seq:_goon #1!#2#3#4{,#1\XINT_expr_seq:_b {#4}}%
+% \end{macrocode}
+% \lverb|If all is omitted or list is empty, _empty? will fetch within the ##1
+% a \endcsname token and construct "nil" via <space>\endcsname, if not ##1
+% will be a comma and the gobble will swallow the space token and the
+% extra \endcsname.|
+% \begin{macrocode}
+\def\XINT_expr_seq_empty? #1{%
+\def\XINT_expr_seq_empty? ##1{\if ,##1\expandafter\xint_gobble_i\fi #1\endcsname }}%
+\XINT_expr_seq_empty? { }%
+% \end{macrocode}
+% \subsubsection{Evaluation over ++ generated lists with \csh{XINT_expr_seq:_A}}
+% \lverb|This is for index lists generated by n++. The starting point will have
+% been replaced by its ceil (added: in fact with version 1.1. the ceil was not
+% yet evaluated, but _var_<letter> did an expansion of what they fetch). We use
+% \numexpr rather than \xintInc, hence the indexing is limited to small
+% integers.
+%
+% The 1.2c version of n++ produces a #1 here which is already a single
+% \.=<value> token.|
+% \begin{macrocode}
+\def\XINT_expr_seq:_A +#1!%
+ {\expandafter\XINT_expr_seq_empty?\romannumeral0\XINT_expr_seq:_D #1}%
+\def\XINT_expr_seq:_D #1#2{\expandafter\XINT_expr_seq:_E\romannumeral`&&@#2#1{#2}}%
+\def\XINT_expr_seq:_E #1{\if #1^\xint_dothis\XINT_expr_seq:_Abort\fi
+ \if #1?\xint_dothis\XINT_expr_seq:_Break\fi
+ \if #1!\xint_dothis\XINT_expr_seq:_Omit\fi
+ \xint_orthat{\XINT_expr_seq:_Goon #1}}%
+\def\XINT_expr_seq:_Abort #1!#2#3#4{}%
+\def\XINT_expr_seq:_Break #1!#2#3#4{,#1}%
+\def\XINT_expr_seq:_Omit #1!#2#3%
+ {\expandafter\XINT_expr_seq:_D
+ \csname.=\the\numexpr \XINT_expr_unlock#3+\xint_c_i\endcsname}%
+\def\XINT_expr_seq:_Goon #1!#2#3%
+ {,#1\expandafter\XINT_expr_seq:_D
+ \csname.=\the\numexpr \XINT_expr_unlock#3+\xint_c_i\endcsname}%
+% \end{macrocode}
+% \subsection{\csh{add()}, \csh{mul()}}
+% \lverb|1.2c uses more directly the \xintiiAdd etc... macros and has
+% opxadd/opxmul rather than a single opx. This is less conceptual as I use
+% explicitely the associated macro names for +, * but this makes other things
+% more efficient, and the code more readable.|
+% \begin{macrocode}
+\def\XINT_expr_onliteral_add
+ {\expandafter\XINT_expr_onliteral_add_f\romannumeral`&&@\XINT_expr_onliteral_seq_a {}}%
+\def\XINT_expr_onliteral_add_f #1#2{\xint_c_xviii `{opxadd}#2)\relax #1}%
+\def\XINT_expr_onliteral_mul
+ {\expandafter\XINT_expr_onliteral_mul_f\romannumeral`&&@\XINT_expr_onliteral_seq_a {}}%
+\def\XINT_expr_onliteral_mul_f #1#2{\xint_c_xviii `{opxmul}#2)\relax #1}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_func_opxadd}, \csh{XINT_flexpr_func_opxadd},
+% \csh{XINT_iiexpr_func_opxadd} and same for mul}
+% |modified 1.2c.|
+% \begin{macrocode}
+\def\XINT_expr_func_opxadd #1#2{\XINT_allexpr_opx \xintbareeval {\xintAdd 0}}%
+\def\XINT_flexpr_func_opxadd #1#2{\XINT_allexpr_opx \xintbarefloateval {\XINTinFloatAdd 0}}%
+\def\XINT_iiexpr_func_opxadd #1#2{\XINT_allexpr_opx \xintbareiieval {\xintiiAdd 0}}%
+\def\XINT_expr_func_opxmul #1#2{\XINT_allexpr_opx \xintbareeval {\xintMul 1}}%
+\def\XINT_flexpr_func_opxmul #1#2{\XINT_allexpr_opx \xintbarefloateval {\XINTinFloatMul 1}}%
+\def\XINT_iiexpr_func_opxmul #1#2{\XINT_allexpr_opx \xintbareiieval {\xintiiMul 1}}%
+% \end{macrocode}
+% \lverb|#1=bareeval etc, #2={Add0} ou {Mul1}, #3=liste encapsulée, #4=la variable, #5=expression|
+% \begin{macrocode}
+\def\XINT_allexpr_opx #1#2#3#4#5%
+{%
+ \expandafter\XINT_expr_getop
+ \csname.=\romannumeral`&&@\expandafter\XINT_expr_op:_a
+ \romannumeral`&&@\XINT_expr_unlock #3!{#1#5\relax !#4}{#2}\endcsname
+}%
+\def\XINT_expr_op:_a #1!#2#3{\XINT_expr_op:_b #3{#2}#1,^,}%
+% \end{macrocode}
+% \lverb|#2 in \XINT_expr_op:_b is the partial result of computation so far, not
+% locked. A noop with have #4=, and #5 the next item which we need to recover.
+% No need to be very efficient for that in op:_noop. In op:_d, #4 is \xintAdd or
+% similar.|
+% \begin{macrocode}
+\def\XINT_expr_op:_b #1#2#3#4#5,{%
+ \if ,#4\xint_dothis\XINT_expr_op:_noop\fi
+ \if ^#4\xint_dothis\XINT_expr_op:_end\fi
+ \xint_orthat{\expandafter\XINT_expr_op:_c}\csname.=#4#5\endcsname {#3}#1{#2}%
+}%
+\def\XINT_expr_op:_c #1#2#3#4%
+ {\expandafter\XINT_expr_op:_d\romannumeral0#2#1#3{#4}{#2}}%
+\def\XINT_expr_op:_d #1!#2#3#4#5%
+ {\expandafter\XINT_expr_op:_b\expandafter #4\expandafter
+ {\romannumeral`&&@\XINT:NEhook:two#4{\XINT_expr_unlock#1}{#5}}}%
+% \end{macrocode}
+% \lverb|The replacement text had expr_seq:_b rather than expr_op:_b due to a
+% left-over from copy-paste. This made add and mul fail with an empty range
+% for the variable (or "nil" in the list of values). Fixed in 1.2h.|
+% \begin{macrocode}
+\def\XINT_expr_op:_noop\csname.=,#1\endcsname #2#3#4{\XINT_expr_op:_b #3{#4}{#2}#1,}%
+\def\XINT_expr_op:_end \csname.=^\endcsname #1#2#3{#3}%
+% \end{macrocode}
+% \subsection{\csh{subs()}}
+% \lverb|Got simpler with 1.2c as now the dummy variable fetches an
+% already encapsulated value, which is anyhow the form in which we get
+% it.|
+% \begin{macrocode}
+\def\XINT_expr_onliteral_subs
+ {\expandafter\XINT_expr_onliteral_subs_f\romannumeral`&&@\XINT_expr_onliteral_seq_a {}}%
+\def\XINT_expr_onliteral_subs_f #1#2{\xint_c_xviii `{subx}#2)\relax #1}%
+\def\XINT_expr_func_subx #1#2{\XINT_allexpr_subx \xintbareeval }%
+\def\XINT_flexpr_func_subx #1#2{\XINT_allexpr_subx \xintbarefloateval}%
+\def\XINT_iiexpr_func_subx #1#2{\XINT_allexpr_subx \xintbareiieval }%
+\def\XINT_allexpr_subx #1#2#3#4% #2 is the value to assign to the dummy variable
+{% #3 is the dummy variable, #4 is the expression to evaluate
+ \expandafter\expandafter\expandafter\XINT_expr_getop
+ \expandafter\XINT_expr_subx:_end\romannumeral0#1#4\relax !#3#2%
+}%
+\def\XINT_expr_subx:_end #1!#2#3{#1}%
+% \end{macrocode}
+% \subsection{\csh{rseq()}}
+% \localtableofcontents
+%
+% \lverb|When func_rseq has its turn, initial segment has been scanned by
+% oparen, the ; mimicking the rôle of a closing parenthesis, and stopping
+% further expansion. Notice that the ; is discovered during standard parsing
+% mode, it may be for example {;} or arise from expansion as rseq does not use
+% a delimited macro to locate it.
+%
+% Here and in rrseq and iter, 1.2c adds also use of \xintthebareeval, etc...|
+% \begin{macrocode}
+\def\XINT_expr_func_rseq {\XINT_allexpr_rseq \xintbareeval \xintthebareeval }%
+\def\XINT_flexpr_func_rseq {\XINT_allexpr_rseq \xintbarefloateval \xintthebarefloateval }%
+\def\XINT_iiexpr_func_rseq {\XINT_allexpr_rseq \xintbareiieval \xintthebareiieval }%
+\def\XINT_allexpr_rseq #1#2#3%
+{%
+ \expandafter\XINT_expr_rseqx\expandafter #1\expandafter#2\expandafter
+ #3\romannumeral`&&@\XINT_expr_onliteral_seq_a {}%
+}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_rseqx}}
+% \lverb|The (#5) is for ++ mechanism which must have its closing parenthesis.|
+% \begin{macrocode}
+\def\XINT_expr_rseqx #1#2#3#4#5%
+{%
+ \expandafter\XINT_expr_rseqy\romannumeral0#1(#5)\relax #3#4#2%
+}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_rseqy}}
+% \lverb|#1=valeurs pour variable (locked),
+% #2=toutes les valeurs initiales (csv,locked),
+% #3=variable, #4=expr,
+% #5=\xintthebareeval ou \xintthebarefloateval ou \xintthebareiieval|
+% \begin{macrocode}
+\def\XINT_expr_rseqy #1#2#3#4#5%
+{%
+ \expandafter \XINT_expr_getop
+ \csname .=\XINT_expr_unlock #2%
+ \expandafter\XINT_expr_rseq:_aa
+ \romannumeral`&&@\XINT_expr_unlock #1!{#5#4\relax !#3}#2\endcsname
+}%
+\def\XINT_expr_rseq:_aa #1{\if +#1\expandafter\XINT_expr_rseq:_A\else
+ \expandafter\XINT_expr_rseq:_a\fi #1}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_rseq:_a} etc\dots}
+% \begin{macrocode}
+\def\XINT_expr_rseq:_a #1!#2#3{\XINT_expr_rseq:_b {#3}{#2}#1,^,}%
+\def\XINT_expr_rseq:_b #1#2#3#4,{%
+ \if ,#3\xint_dothis\XINT_expr_rseq:_noop\fi
+ \if ^#3\xint_dothis\XINT_expr_rseq:_end\fi
+ \xint_orthat{\expandafter\XINT_expr_rseq:_c}\csname.=#3#4\endcsname
+ {#1}{#2}%
+}%
+\def\XINT_expr_rseq:_noop\csname.=,#1\endcsname #2#3{\XINT_expr_rseq:_b {#2}{#3}#1,}%
+\def\XINT_expr_rseq:_end \csname.=^\endcsname #1#2{}%
+\def\XINT_expr_rseq:_c #1#2#3%
+ {\expandafter\XINT_expr_rseq:_d\romannumeral`&&@#3#1~#2{#3}}%
+\def\XINT_expr_rseq:_d #1{%
+ \if ^#1\xint_dothis\XINT_expr_rseq:_abort\fi
+ \if ?#1\xint_dothis\XINT_expr_rseq:_break\fi
+ \if !#1\xint_dothis\XINT_expr_rseq:_omit\fi
+ \xint_orthat{\XINT_expr_rseq:_goon #1}}%
+\def\XINT_expr_rseq:_goon #1!#2#3~#4#5{,#1\expandafter\XINT_expr_rseq:_b
+ \romannumeral0\XINT_expr_lockit {#1}{#5}}%
+\def\XINT_expr_rseq:_omit #1!#2#3~{\XINT_expr_rseq:_b }%
+\def\XINT_expr_rseq:_abort #1!#2#3~#4#5#6^,{}%
+\def\XINT_expr_rseq:_break #1!#2#3~#4#5#6^,{,#1}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_rseq:_A} etc\dots}
+% \lverb |n++ for rseq. With 1.2c dummy variables pick a single token.|
+% \begin{macrocode}
+\def\XINT_expr_rseq:_A +#1!#2#3{\XINT_expr_rseq:_D #1#3{#2}}%
+\def\XINT_expr_rseq:_D #1#2#3%
+ {\expandafter\XINT_expr_rseq:_E\romannumeral`&&@#3#1~#2{#3}}%
+\def\XINT_expr_rseq:_E #1{\if #1^\xint_dothis\XINT_expr_rseq:_Abort\fi
+ \if #1?\xint_dothis\XINT_expr_rseq:_Break\fi
+ \if #1!\xint_dothis\XINT_expr_rseq:_Omit\fi
+ \xint_orthat{\XINT_expr_rseq:_Goon #1}}%
+\def\XINT_expr_rseq:_Goon #1!#2#3~#4#5%
+ {,#1\expandafter\XINT_expr_rseq:_D
+ \csname.=\the\numexpr \XINT_expr_unlock#3+\xint_c_i\expandafter\endcsname
+ \romannumeral0\XINT_expr_lockit{#1}{#5}}%
+\def\XINT_expr_rseq:_Omit #1!#2#3~%#4#5%
+ {\expandafter\XINT_expr_rseq:_D
+ \csname.=\the\numexpr \XINT_expr_unlock#3+\xint_c_i\endcsname }%
+\def\XINT_expr_rseq:_Abort #1!#2#3~#4#5{}%
+\def\XINT_expr_rseq:_Break #1!#2#3~#4#5{,#1}%
+% \end{macrocode}
+% \subsection{\csh{iter()}}
+% \localtableofcontents
+%
+% \lverb|Prior to 1.2g, the iter keyword was what is now called iterr,
+% analogous with rrseq. Somehow I forgot an iter functioning like rseq
+% with the sole difference of printing only the last iteration. Both rseq and
+% iter work well with list selectors, as @ refers to the whole comma separated
+% sequence of the initial values. I have thus deliberately done the backwards
+% incompatible renaming of iter to iterr, and the new iter.|
+% \begin{macrocode}
+\def\XINT_expr_func_iter {\XINT_allexpr_iter \xintbareeval \xintthebareeval }%
+\def\XINT_flexpr_func_iter {\XINT_allexpr_iter \xintbarefloateval \xintthebarefloateval }%
+\def\XINT_iiexpr_func_iter {\XINT_allexpr_iter \xintbareiieval \xintthebareiieval }%
+\def\XINT_allexpr_iter #1#2#3%
+{%
+ \expandafter\XINT_expr_iterx\expandafter #1\expandafter#2\expandafter
+ #3\romannumeral`&&@\XINT_expr_onliteral_seq_a {}%
+}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_iterx}}
+% \lverb|The (#5) is for ++ mechanism which must have its closing parenthesis.|
+% \begin{macrocode}
+\def\XINT_expr_iterx #1#2#3#4#5%
+{%
+ \expandafter\XINT_expr_itery\romannumeral0#1(#5)\relax #3#4#2%
+}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_itery}}
+% \lverb|#1=valeurs pour variable (locked),
+% #2=toutes les valeurs initiales (csv,locked),
+% #3=variable, #4=expr,
+% #5=\xintthebareeval ou \xintthebarefloateval ou \xintthebareiieval|
+% \begin{macrocode}
+\def\XINT_expr_itery #1#2#3#4#5%
+{%
+ \expandafter \XINT_expr_getop
+ \csname .=%
+ \expandafter\XINT_expr_iter:_aa
+ \romannumeral`&&@\XINT_expr_unlock #1!{#5#4\relax !#3}#2\endcsname
+}%
+\def\XINT_expr_iter:_aa #1{\if +#1\expandafter\XINT_expr_iter:_A\else
+ \expandafter\XINT_expr_iter:_a\fi #1}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_iter:_a} etc\dots}
+% \begin{macrocode}
+\def\XINT_expr_iter:_a #1!#2#3{\XINT_expr_iter:_b {#3}{#2}#1,^,}%
+\def\XINT_expr_iter:_b #1#2#3#4,{%
+ \if ,#3\xint_dothis\XINT_expr_iter:_noop\fi
+ \if ^#3\xint_dothis\XINT_expr_iter:_end\fi
+ \xint_orthat{\expandafter\XINT_expr_iter:_c}%
+ \csname.=#3#4\endcsname {#1}{#2}%
+}%
+\def\XINT_expr_iter:_noop\csname.=,#1\endcsname #2#3{\XINT_expr_iter:_b {#2}{#3}#1,}%
+\def\XINT_expr_iter:_end \csname.=^\endcsname #1#2{\XINT_expr:_unlock #1}%
+\def\XINT_expr_iter:_c #1#2#3%
+ {\expandafter\XINT_expr_iter:_d\romannumeral`&&@#3#1~#2{#3}}%
+\def\XINT_expr_iter:_d #1{%
+ \if ^#1\xint_dothis\XINT_expr_iter:_abort\fi
+ \if ?#1\xint_dothis\XINT_expr_iter:_break\fi
+ \if !#1\xint_dothis\XINT_expr_iter:_omit\fi
+ \xint_orthat{\XINT_expr_iter:_goon #1}}%
+\def\XINT_expr_iter:_goon #1!#2#3~#4#5%
+ {\expandafter\XINT_expr_iter:_b\romannumeral0\XINT_expr_lockit {#1}{#5}}%
+\def\XINT_expr_iter:_omit #1!#2#3~{\XINT_expr_iter:_b }%
+\def\XINT_expr_iter:_abort #1!#2#3~#4#5#6^,{\XINT_expr_unlock #4}%
+\def\XINT_expr_iter:_break #1!#2#3~#4#5#6^,{#1}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_iter:_A} etc\dots}
+% \lverb |n++ for iter. With 1.2c dummy variables pick a single token.|
+% \begin{macrocode}
+\def\XINT_expr_iter:_A +#1!#2#3{\XINT_expr_iter:_D #1#3{#2}}%
+\def\XINT_expr_iter:_D #1#2#3%
+ {\expandafter\XINT_expr_iter:_E\romannumeral`&&@#3#1~#2{#3}}%
+\def\XINT_expr_iter:_E #1{\if #1^\xint_dothis\XINT_expr_iter:_Abort\fi
+ \if #1?\xint_dothis\XINT_expr_iter:_Break\fi
+ \if #1!\xint_dothis\XINT_expr_iter:_Omit\fi
+ \xint_orthat{\XINT_expr_iter:_Goon #1}}%
+\def\XINT_expr_iter:_Goon #1!#2#3~#4#5%
+ {\expandafter\XINT_expr_iter:_D
+ \csname.=\the\numexpr \XINT_expr_unlock#3+\xint_c_i\expandafter\endcsname
+ \romannumeral0\XINT_expr_lockit{#1}{#5}}%
+\def\XINT_expr_iter:_Omit #1!#2#3~%#4#5%
+ {\expandafter\XINT_expr_iter:_D
+ \csname.=\the\numexpr \XINT_expr_unlock#3+\xint_c_i\endcsname }%
+\def\XINT_expr_iter:_Abort #1!#2#3~#4#5{\XINT_expr:_unlock #4}%
+\def\XINT_expr_iter:_Break #1!#2#3~#4#5{#1}%
+% \end{macrocode}
+% \subsection{\csh{rrseq()}}
+% \localtableofcontents
+%
+% \lverb|When func_rrseq has its turn, initial segment has been scanned
+% by oparen, the ; mimicking the rôle of a closing parenthesis, and
+% stopping further expansion.|
+% \begin{macrocode}
+\def\XINT_expr_func_rrseq {\XINT_allexpr_rrseq \xintbareeval \xintthebareeval }%
+\def\XINT_flexpr_func_rrseq {\XINT_allexpr_rrseq \xintbarefloateval \xintthebarefloateval }%
+\def\XINT_iiexpr_func_rrseq {\XINT_allexpr_rrseq \xintbareiieval \xintthebareiieval }%
+\def\XINT_allexpr_rrseq #1#2#3%
+{%
+ \expandafter\XINT_expr_rrseqx\expandafter #1\expandafter#2\expandafter
+ #3\romannumeral`&&@\XINT_expr_onliteral_seq_a {}%
+}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_rrseqx}}
+% \lverb|The (#5) is for ++ mechanism which must have its closing parenthesis.|
+% \begin{macrocode}
+\def\XINT_expr_rrseqx #1#2#3#4#5%
+{%
+ \expandafter\XINT_expr_rrseqy\romannumeral0#1(#5)\expandafter\relax
+ \expandafter{\romannumeral0\xintapply \XINT_expr_lockit
+ {\xintRevWithBraces{\xintCSVtoListNonStripped{\XINT_expr_unlock #3}}}}%
+ #3#4#2%
+}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_rrseqy}}
+% \lverb|#1=valeurs pour variable (locked),
+% #2=initial values (reversed, one (braced) token each)
+% #3=toutes les valeurs initiales (csv,locked),
+% #4=variable, #5=expr,
+% #6=\xintthebareeval ou \xintthebarefloateval ou \xintthebareiieval|
+% \begin{macrocode}
+\def\XINT_expr_rrseqy #1#2#3#4#5#6%
+{%
+ \expandafter \XINT_expr_getop
+ \csname .=\XINT_expr_unlock #3%
+ \expandafter\XINT_expr_rrseq:_aa
+ \romannumeral`&&@\XINT_expr_unlock #1!{#6#5\relax !#4}{#2}\endcsname
+}%
+\def\XINT_expr_rrseq:_aa #1{\if +#1\expandafter\XINT_expr_rrseq:_A\else
+ \expandafter\XINT_expr_rrseq:_a\fi #1}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_rrseq:_a} etc\dots}
+% \lverb|Attention que ? a catcode 3 ici et dans iter.|
+% \begin{macrocode}
+\catcode`? 3
+\def\XINT_expr_rrseq:_a #1!#2#3{\XINT_expr_rrseq:_b {#3}{#2}#1,^,}%
+\def\XINT_expr_rrseq:_b #1#2#3#4,{%
+ \if ,#3\xint_dothis\XINT_expr_rrseq:_noop\fi
+ \if ^#3\xint_dothis\XINT_expr_rrseq:_end\fi
+ \xint_orthat{\expandafter\XINT_expr_rrseq:_c}\csname.=#3#4\endcsname
+ {#1}{#2}%
+}%
+\def\XINT_expr_rrseq:_noop\csname.=,#1\endcsname #2#3{\XINT_expr_rrseq:_b {#2}{#3}#1,}%
+\def\XINT_expr_rrseq:_end \csname.=^\endcsname #1#2{}%
+\def\XINT_expr_rrseq:_c #1#2#3%
+ {\expandafter\XINT_expr_rrseq:_d\romannumeral`&&@#3#1~#2?{#3}}%
+\def\XINT_expr_rrseq:_d #1{%
+ \if ^#1\xint_dothis\XINT_expr_rrseq:_abort\fi
+ \if ?#1\xint_dothis\XINT_expr_rrseq:_break\fi
+ \if !#1\xint_dothis\XINT_expr_rrseq:_omit\fi
+ \xint_orthat{\XINT_expr_rrseq:_goon #1}%
+}%
+\def\XINT_expr_rrseq:_goon #1!#2#3~#4?#5{,#1\expandafter\XINT_expr_rrseq:_b\expandafter
+ {\romannumeral0\xinttrim{-1}{\XINT_expr_lockit{#1}#4}}{#5}}%
+\def\XINT_expr_rrseq:_omit #1!#2#3~{\XINT_expr_rrseq:_b }%
+\def\XINT_expr_rrseq:_abort #1!#2#3~#4?#5#6^,{}%
+\def\XINT_expr_rrseq:_break #1!#2#3~#4?#5#6^,{,#1}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_rrseq:_A} etc\dots}
+% \lverb |n++ for rrseq. With 1.2C, the #1 in \XINT_expr_rrseq:_A is a single token.|
+% \begin{macrocode}
+\def\XINT_expr_rrseq:_A +#1!#2#3{\XINT_expr_rrseq:_D #1{#3}{#2}}%
+\def\XINT_expr_rrseq:_D #1#2#3%
+ {\expandafter\XINT_expr_rrseq:_E\romannumeral`&&@#3#1~#2?{#3}}%
+\def\XINT_expr_rrseq:_Goon #1!#2#3~#4?#5%
+ {,#1\expandafter\XINT_expr_rrseq:_D
+ \csname.=\the\numexpr \XINT_expr_unlock#3+\xint_c_i\expandafter\endcsname
+ \expandafter{\romannumeral0\xinttrim{-1}{\XINT_expr_lockit{#1}#4}}{#5}}%
+\def\XINT_expr_rrseq:_Omit #1!#2#3~%#4?#5%
+ {\expandafter\XINT_expr_rrseq:_D
+ \csname.=\the\numexpr \XINT_expr_unlock#3+\xint_c_i\endcsname}%
+\def\XINT_expr_rrseq:_Abort #1!#2#3~#4?#5{}%
+\def\XINT_expr_rrseq:_Break #1!#2#3~#4?#5{,#1}%
+\def\XINT_expr_rrseq:_E #1{\if #1^\xint_dothis\XINT_expr_rrseq:_Abort\fi
+ \if #1?\xint_dothis\XINT_expr_rrseq:_Break\fi
+ \if #1!\xint_dothis\XINT_expr_rrseq:_Omit\fi
+ \xint_orthat{\XINT_expr_rrseq:_Goon #1}}%
+% \end{macrocode}
+% \subsection{\csh{iterr()}}
+% \localtableofcontents
+% \begin{macrocode}
+\def\XINT_expr_func_iterr {\XINT_allexpr_iterr \xintbareeval \xintthebareeval }%
+\def\XINT_flexpr_func_iterr {\XINT_allexpr_iterr \xintbarefloateval \xintthebarefloateval }%
+\def\XINT_iiexpr_func_iterr {\XINT_allexpr_iterr \xintbareiieval \xintthebareiieval }%
+\def\XINT_allexpr_iterr #1#2#3%
+{%
+ \expandafter\XINT_expr_iterrx\expandafter #1\expandafter #2\expandafter
+ #3\romannumeral`&&@\XINT_expr_onliteral_seq_a {}%
+}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_iterrx}}
+% \lverb|The (#5) is for ++ mechanism which must have its closing parenthesis.|
+% \begin{macrocode}
+\def\XINT_expr_iterrx #1#2#3#4#5%
+{%
+ \expandafter\XINT_expr_iterry\romannumeral0#1(#5)\expandafter\relax
+ \expandafter{\romannumeral0\xintapply \XINT_expr_lockit
+ {\xintRevWithBraces{\xintCSVtoListNonStripped{\XINT_expr_unlock #3}}}}%
+ #3#4#2%
+}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_iterry}}
+% \lverb|#1=valeurs pour variable (locked),
+% #2=initial values (reversed, one (braced) token each)
+% #3=toutes les valeurs initiales (csv,locked),
+% #4=variable, #5=expr,
+% #6=\xintbareeval ou \xintbarefloateval ou \xintbareiieval|
+% \begin{macrocode}
+\def\XINT_expr_iterry #1#2#3#4#5#6%
+{%
+ \expandafter \XINT_expr_getop
+ \csname .=%
+ \expandafter\XINT_expr_iterr:_aa
+ \romannumeral`&&@\XINT_expr_unlock #1!{#6#5\relax !#4}{#2}\endcsname
+}%
+\def\XINT_expr_iterr:_aa #1{\if +#1\expandafter\XINT_expr_iterr:_A\else
+ \expandafter\XINT_expr_iterr:_a\fi #1}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_iterr:_a} etc\dots}
+% \begin{macrocode}
+\def\XINT_expr_iterr:_a #1!#2#3{\XINT_expr_iterr:_b {#3}{#2}#1,^,}%
+\def\XINT_expr_iterr:_b #1#2#3#4,{%
+ \if ,#3\xint_dothis\XINT_expr_iterr:_noop\fi
+ \if ^#3\xint_dothis\XINT_expr_iterr:_end\fi
+ \xint_orthat{\expandafter\XINT_expr_iterr:_c}%
+ \csname.=#3#4\endcsname {#1}{#2}%
+}%
+\def\XINT_expr_iterr:_noop\csname.=,#1\endcsname #2#3{\XINT_expr_iterr:_b {#2}{#3}#1,}%
+\def\XINT_expr_iterr:_end \csname.=^\endcsname #1#2%
+ {\expandafter\xint_gobble_i\romannumeral0\xintapplyunbraced
+ {,\XINT_expr:_unlock}{\xintReverseOrder{#1\space}}}%
+\def\XINT_expr_iterr:_c #1#2#3%
+ {\expandafter\XINT_expr_iterr:_d\romannumeral`&&@#3#1~#2?{#3}}%
+\def\XINT_expr_iterr:_d #1{%
+ \if ^#1\xint_dothis\XINT_expr_iterr:_abort\fi
+ \if ?#1\xint_dothis\XINT_expr_iterr:_break\fi
+ \if !#1\xint_dothis\XINT_expr_iterr:_omit\fi
+ \xint_orthat{\XINT_expr_iterr:_goon #1}%
+}%
+\def\XINT_expr_iterr:_goon #1!#2#3~#4?#5{\expandafter\XINT_expr_iterr:_b\expandafter
+ {\romannumeral0\xinttrim{-1}{\XINT_expr_lockit{#1}#4}}{#5}}%
+\def\XINT_expr_iterr:_omit #1!#2#3~{\XINT_expr_iterr:_b }%
+\def\XINT_expr_iterr:_abort #1!#2#3~#4?#5#6^,%
+ {\expandafter\xint_gobble_i\romannumeral0\xintapplyunbraced
+ {,\XINT_expr:_unlock}{\xintReverseOrder{#4\space}}}%
+\def\XINT_expr_iterr:_break #1!#2#3~#4?#5#6^,%
+ {\expandafter\xint_gobble_iv\romannumeral0\xintapplyunbraced
+ {,\XINT_expr:_unlock}{\xintReverseOrder{#4\space}},#1}%
+\def\XINT_expr:_unlock #1{\XINT_expr_unlock #1}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_iterr:_A} etc\dots}
+% \lverb |n++ for iterr. ? is of catcode 3 here.|
+% \begin{macrocode}
+\def\XINT_expr_iterr:_A +#1!#2#3{\XINT_expr_iterr:_D #1{#3}{#2}}%
+\def\XINT_expr_iterr:_D #1#2#3%
+ {\expandafter\XINT_expr_iterr:_E\romannumeral`&&@#3#1~#2?{#3}}%
+\def\XINT_expr_iterr:_Goon #1!#2#3~#4?#5%
+ {\expandafter\XINT_expr_iterr:_D
+ \csname.=\the\numexpr \XINT_expr_unlock#3+\xint_c_i\expandafter\endcsname
+ \expandafter{\romannumeral0\xinttrim{-1}{\XINT_expr_lockit{#1}#4}}{#5}}%
+\def\XINT_expr_iterr:_Omit #1!#2#3~%#4?#5%
+ {\expandafter\XINT_expr_iterr:_D
+ \csname.=\the\numexpr \XINT_expr_unlock#3+\xint_c_i\endcsname}%
+\def\XINT_expr_iterr:_Abort #1!#2#3~#4?#5%
+ {\expandafter\xint_gobble_i\romannumeral0\xintapplyunbraced
+ {,\XINT_expr:_unlock}{\xintReverseOrder{#4\space}}}%
+\def\XINT_expr_iterr:_Break #1!#2#3~#4?#5%
+ {\expandafter\xint_gobble_iv\romannumeral0\xintapplyunbraced
+ {,\XINT_expr:_unlock}{\xintReverseOrder{#4\space}},#1}%
+\def\XINT_expr_iterr:_E #1{\if #1^\xint_dothis\XINT_expr_iterr:_Abort\fi
+ \if #1?\xint_dothis\XINT_expr_iterr:_Break\fi
+ \if #1!\xint_dothis\XINT_expr_iterr:_Omit\fi
+ \xint_orthat{\XINT_expr_iterr:_Goon #1}}%
+\catcode`? 11
+% \end{macrocode}
+% \subsection{Macros handling csv lists for functions with multiple comma
+% separated arguments in expressions}
+% \localtableofcontents
+% \lverb|These macros are used inside \csname...\endcsname. These things
+% are not initiated by a \romannumeral in general, but in some cases they are,
+% especially when involved in an \xintNewExpr. They will then be protected
+% against expansion and expand only later in contexts governed by an
+% initial \romannumeral-`0. There each new item may need to be expanded, which
+% would not be the case in the use for the _func_ things.
+%
+% 1.2g adds (to be continued)|
+%
+% \subsubsection{\csh{xintANDof:csv}}
+% \lverb|1.09a. For use by \xintexpr inside \csname. 1.1, je remplace
+% ifTrueAelseB par iiNotZero pour des raisons d'optimisations.|
+% \begin{macrocode}
+\def\xintANDof:csv #1{\expandafter\XINT_andof:_a\romannumeral`&&@#1,,^}%
+\def\XINT_andof:_a #1{\if ,#1\expandafter\XINT_andof:_e
+ \else\expandafter\XINT_andof:_c\fi #1}%
+\def\XINT_andof:_c #1,{\xintiiifNotZero {#1}{\XINT_andof:_a}{\XINT_andof:_no}}%
+\def\XINT_andof:_no #1^{0}%
+\def\XINT_andof:_e #1^{1}% works with empty list
+% \end{macrocode}
+% \subsubsection{\csh{xintORof:csv}}
+% \lverb|1.09a. For use by \xintexpr.|
+% \begin{macrocode}
+\def\xintORof:csv #1{\expandafter\XINT_orof:_a\romannumeral`&&@#1,,^}%
+\def\XINT_orof:_a #1{\if ,#1\expandafter\XINT_orof:_e
+ \else\expandafter\XINT_orof:_c\fi #1}%
+\def\XINT_orof:_c #1,{\xintiiifNotZero{#1}{\XINT_orof:_yes}{\XINT_orof:_a}}%
+\def\XINT_orof:_yes #1^{1}%
+\def\XINT_orof:_e #1^{0}% works with empty list
+% \end{macrocode}
+% \subsubsection{\csh{xintXORof:csv}}
+% \lverb|1.09a. For use by \xintexpr (inside a \csname..\endcsname).|
+% \begin{macrocode}
+\def\xintXORof:csv #1{\expandafter\XINT_xorof:_a\expandafter 0\romannumeral`&&@#1,,^}%
+\def\XINT_xorof:_a #1#2,{\XINT_xorof:_b #2,#1}%
+\def\XINT_xorof:_b #1{\if ,#1\expandafter\XINT_xorof:_e
+ \else\expandafter\XINT_xorof:_c\fi #1}%
+\def\XINT_xorof:_c #1,#2%
+ {\xintiiifNotZero {#1}{\if #20\xint_afterfi{\XINT_xorof:_a 1}%
+ \else\xint_afterfi{\XINT_xorof:_a 0}\fi}%
+ {\XINT_xorof:_a #2}%
+ }%
+\def\XINT_xorof:_e ,#1#2^{#1}% allows empty list (then returns 0)
+% \end{macrocode}
+% \subsubsection{Generic csv routine (\csh{XINT_oncsv:_a})}
+% \lverb|1.1. generic routine. up to the loss of some efficiency, especially
+% for Sum:csv and Prod:csv, where \XINTinFloat will be done twice for each
+% argument.
+%
+% FIXME: DOCUMENT BETTER. HOW IS THIS CALLED? WHAT IS MEANING OF ARGUMENTS? IS
+% THERE ANY POST-PROCESSING OF FINAL RESULT?|
+% \begin{macrocode}
+\def\XINT_oncsv:_empty #1,^,#2{#2}%
+\def\XINT_oncsv:_end ^,#1#2#3#4{#1}%
+\def\XINT_oncsv:_a #1#2#3%
+ {\if ,#3\expandafter\XINT_oncsv:_empty\else\expandafter\XINT_oncsv:_b\fi #1#2#3}%
+\def\XINT_oncsv:_b #1#2#3,%
+ {\expandafter\XINT_oncsv:_c \expandafter{\romannumeral`&&@#2{#3}}#1#2}%
+\def\XINT_oncsv:_c #1#2#3#4,{\expandafter\XINT_oncsv:_d \romannumeral`&&@#4,{#1}#2#3}%
+\def\XINT_oncsv:_d #1%
+ {\if ^#1\expandafter\XINT_oncsv:_end\else\expandafter\XINT_oncsv:_e\fi #1}%
+\def\XINT_oncsv:_e #1,#2#3#4%
+ {\expandafter\XINT_oncsv:_c\expandafter {\romannumeral`&&@#3{#4{#1}}{#2}}#3#4}%
+% \end{macrocode}
+% \subsubsection{\csh{xintMaxof:csv}, \csh{xintiiMaxof:csv}}
+% \lverb|1.09i. Rewritten for 1.1. Compatible avec liste vide donnant valeur par
+% défaut. Pas compatible avec items manquants.
+% ah je m'aperçois au dernier moment que je n'ai pas en effet de \xintiiMax.
+% Je devrais le rajouter. En tout cas ici c'est uniquement pour xintiiexpr,
+% dans il faut bien sûr ne pas faire de xintNum, donc il faut un iimax.|
+% \begin{macrocode}
+\def\xintMaxof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintmax
+ \expandafter\xint_firstofone\romannumeral`&&@#1,^,{0/1[0]}}%
+\def\xintiiMaxof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintiimax
+ \expandafter\xint_firstofone\romannumeral`&&@#1,^,0}%
+% \end{macrocode}
+% \subsubsection{\csh{xintMinof:csv}, \csh{xintiiMinof:csv}}
+% \lverb|1.09i. Rewritten for 1.1. For use by \xintiiexpr.|
+% \begin{macrocode}
+\def\xintMinof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintmin
+ \expandafter\xint_firstofone\romannumeral`&&@#1,^,{0/1[0]}}%
+\def\xintiiMinof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintiimin
+ \expandafter\xint_firstofone\romannumeral`&&@#1,^,0}%
+% \end{macrocode}
+% \subsubsection{\csh{xintSum:csv}, \csh{xintiiSum:csv}}
+% \lverb|1.09a. Rewritten for 1.1. For use by \xintexpr.|
+% \begin{macrocode}
+\def\xintSum:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintadd
+ \expandafter\xint_firstofone\romannumeral`&&@#1,^,{0/1[0]}}%
+\def\xintiiSum:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintiiadd
+ \expandafter\xint_firstofone\romannumeral`&&@#1,^,0}%
+% \end{macrocode}
+% \subsubsection{\csh{xintPrd:csv}, \csh{xintiiPrd:csv}}
+% \lverb|1.09a. Rewritten for 1.1. For use by \xintexpr.|
+% \begin{macrocode}
+\def\xintPrd:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintmul
+ \expandafter\xint_firstofone\romannumeral`&&@#1,^,{1/1[0]}}%
+\def\xintiiPrd:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintiimul
+ \expandafter\xint_firstofone\romannumeral`&&@#1,^,1}%
+% \end{macrocode}
+% \subsubsection{\csh{xintGCDof:csv}, \csh{xintLCMof:csv}}
+% \changed{1.09a}{}
+% Non-integer arguments are replaced by integers as |\xintGCD| and |\xintLCM|
+% apply |\xintNum|.
+% \changed{1.1}{}
+% As with other "csv" macros, the (list) argument needs to be expanded in case
+% it arises within a macro created from \csbxint{NewExpr}.
+% \changed{1.3d}{}
+% No more usage of the integer-only \xintgcdnameimp macros, replaced by direct
+% coding here, in order to extend scope to fractions (and produce fractions).
+% Hesitation about allowing empty input, and what to return then.
+% \begin{macrocode}
+\def\xintGCDof:csv #1{\expandafter\XINT_gcdof:_a\romannumeral`&&@#1,^,{1/1[0]}}%
+\def\XINT_gcdof:_a #1%
+ {\if ,#1\expandafter\XINT_oncsv:_empty\else\expandafter\XINT_gcdof:_b\fi #1}%
+% \end{macrocode}
+% This abuses the way |\xintiiabs| works in order to avoid fetching whole
+% argument again.
+% \begin{macrocode}
+\def\XINT_gcdof:_b #1,%
+ {\expandafter\XINT_gcdof:_c\romannumeral0\xintiiabs#1\xint:}%
+\def\XINT_gcdof:_c #1\xint:#2,%
+ {\expandafter\XINT_gcdof:_d\romannumeral0\xintiiabs#2\xint:#1\xint:}%
+\def\XINT_gcdof:_d #1%
+ {\if ^#1\expandafter\XINT_gcdof:_end\else\expandafter\XINT_gcdof:_e\fi #1}%
+% \end{macrocode}
+% \lverb|\xintMod will apply \xintRaw on its arguments, and will output in
+% normalized format. But in exceptional case with a one-item or one item and
+% then zeros, the output is (absolute value of) this item, not necessarily in
+% A/B[N] format.|
+% \begin{macrocode}
+\def\XINT_gcdof:_e#1#2\xint:#3\xint:
+{%
+ \if0#1\expandafter\XINT_gcdof:_f\fi
+ \expandafter\XINT_gcdof:_e\romannumeral0\xintmod{#3}{#1#2}\xint:#1#2\xint:
+}%
+\def\XINT_gcdof:_f
+ \expandafter\XINT_gcdof:_e\romannumeral0\xintmod#1#2\xint:#3\xint:#4,%
+{%
+ \expandafter\XINT_gcdof:_d\romannumeral0\xintiiabs#4\xint:#1\xint:
+}%
+% \end{macrocode}
+% \lverb|As for others :csv macros here expansion in the case of \xintNewExpr
+% crafted macros is triggered by (an equivalent to) \romannumeral-`0. Else it
+% happens inside \csname...\endcsname, and there is no triggering
+% \romannumeral, attention to not leave a space upfront.|
+% \begin{macrocode}
+\def\XINT_gcdof:_end ^\xint:#1\xint:#2{#1}%
+% \end{macrocode}
+% \lverb|For least common multiple, we will use \xintInv, but this requires to
+% make sure fractional input is in raw format.|
+% \begin{macrocode}
+\def\xintLCMof:csv #1{\expandafter\XINT_lcmof:_a\romannumeral`&&@#1,^,{0/1[0]}}%
+\def\XINT_lcmof:_a #1%
+ {\if ,#1\expandafter\XINT_oncsv:_empty\else\expandafter\XINT_lcmof:_b\fi #1}%
+\def\XINT_lcmof:_b #1,%
+ {\expandafter\XINT_lcmof:_c\romannumeral0\xintiiabs\xintRaw{#1}\xint:}%
+\def\XINT_lcmof:_c #1{\if0#1\expandafter\XINT_lcmof:_zero\fi
+ \expandafter\XINT_lcmof:_d\romannumeral0\XINT_inv #1}%
+% \end{macrocode}
+% \lverb|We can do \xintiiabs^, but \xintiiabs\xintRaw{^} would throw
+% an error. So we need to delay applying \xintRaw to new item.|
+% \begin{macrocode}
+\def\XINT_lcmof:_d #1\xint:#2,%
+ {\expandafter\XINT_lcmof:_e\romannumeral0\xintiiabs#2\xint:#1\xint:}%
+\def\XINT_lcmof:_e #1%
+ {\if ^#1\expandafter\XINT_lcmof:_end\else\expandafter\XINT_lcmof:_f\fi #1}%
+% \end{macrocode}
+% \lverb|As soon as we hit against a zero item, the l.c.m is known to be zero
+% itself. Else we need to inverse it, but this requires full A/B[N] raw format,
+% hence the \xintraw.|
+% \begin{macrocode}
+\def\XINT_lcmof:_f#1#2\xint:
+{%
+ \if0#1\expandafter\XINT_lcmof:_zero\fi
+ \expandafter\XINT_lcmof:_g\romannumeral0\expandafter\XINT_inv
+ \romannumeral0\xintraw{#1#2}\xint:
+}%
+\def\XINT_lcmof:_g #1#2\xint:#3\xint:
+{%
+ \if0#1\expandafter\XINT_lcmof:_h\fi
+ \expandafter\XINT_lcmof:_g\romannumeral0\xintmod{#3}{#1#2}\xint:#1#2\xint:
+}%
+\def\XINT_lcmof:_h
+ \expandafter\XINT_lcmof:_g\romannumeral0\xintmod#1#2\xint:#3\xint:#4,%
+{%
+ \expandafter\XINT_lcmof:_e\romannumeral0\xintiiabs#4\xint:#1\xint:
+}%
+\def\XINT_lcmof:_zero #1^,#2{0/1[0]}%
+% \end{macrocode}
+% \lverb|We need this \romannumeral0 to remove the up-front space token which
+% will be left by \XINT_inv, in case of \csname..\endcsname expansion.|
+% \begin{macrocode}
+\def\XINT_lcmof:_end ^\xint:#1\xint:#2{\romannumeral0\XINT_inv #1}%
+% \end{macrocode}
+% \subsubsection{\csh{xintiiGCDof:csv}, \csh{xintiiLCMof:csv}}
+% \changed{1.1a}{}
+% For \csbxint{iiexpr}. Requires the \xintgcdnameimp provided macros.
+% \begin{macrocode}
+\def\xintiiGCDof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintiigcd
+ \expandafter\xint_firstofone\romannumeral`&&@#1,^,1}%
+\def\xintiiLCMof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintiilcm
+ \expandafter\xint_firstofone\romannumeral`&&@#1,^,0}%
+% \end{macrocode}
+% \subsubsection{\csh{XINTinFloatdigits}, \csh{XINTinFloatSqrtdigits},
+% \csh{XINTinFloatFacdigits}, \csh{XINTiLogTendigits}}
+% \lverb|For \xintNewExpr matters, mainly.
+%
+% At 1.3e I add \XINTinFloatSdigits and use it at various places. I also modified
+% \XINTinFloatFac to use S(hort) output format.
+%
+% Also added \XINTiLogTendigits|
+% \begin{macrocode}
+\def\XINTinFloatdigits {\XINTinFloat [\XINTdigits]}%
+\def\XINTinFloatSdigits {\XINTinFloatS [\XINTdigits]}%
+\def\XINTinFloatSqrtdigits {\XINTinFloatSqrt[\XINTdigits]}%
+\def\XINTinFloatFacdigits {\XINTinFloatFac [\XINTdigits]}%
+\def\XINTFloatiLogTendigits{\XINTFloatiLogTen[\XINTdigits]}%
+% \end{macrocode}
+% \subsubsection{\csh{XINTinFloatMaxof:csv}, \csh{XINTinFloatMinof:csv}}
+% \lverb|1.09a. Rewritten for 1.1. For use by \xintfloatexpr. Name changed in
+% 1.09h. Changed at 1.3e to use \XINTinFloatSdigits.|
+% \begin{macrocode}
+\def\XINTinFloatMaxof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintmax
+ \expandafter\XINTinFloatSdigits\romannumeral`&&@#1,^,{0[0]}}%
+\def\XINTinFloatMinof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintmin
+ \expandafter\XINTinFloatSdigits\romannumeral`&&@#1,^,{0[0]}}%
+% \end{macrocode}
+% \subsubsection{\csh{XINTinFloatSum:csv}, \csh{XINTinFloatPrd:csv}}
+% \lverb|1.09a. Rewritten for 1.1. For use by \xintfloatexpr. Modified at 1.3e
+% to use \XINTinFloatSdigits.|
+% \begin{macrocode}
+\def\XINTinFloatSum:csv #1{\expandafter\XINT_oncsv:_a\expandafter\XINTinfloatadd
+ \expandafter\XINTinFloatSdigits\romannumeral`&&@#1,^,{0[0]}}%
+\def\XINTinFloatPrd:csv #1{\expandafter\XINT_oncsv:_a\expandafter\XINTinfloatmul
+ \expandafter\XINTinFloatSdigits\romannumeral`&&@#1,^,{1[0]}}%
+% \end{macrocode}
+% \subsection{Auxiliary wrappers for function macros}
+% \begin{macrocode}
+\def\XINT:expr:one:and:opt #1,#2,#3!#4#5%
+{%
+ \if\relax#3\relax\expandafter\xint_firstoftwo\else
+ \expandafter\xint_secondoftwo\fi
+ {#4}{#5[\xintNum{#2}]}{#1}%
+}%
+\def\XINT:expr:tacitzeroifonearg #1,#2,#3!#4#5%
+{%
+ \if\relax#3\relax\expandafter\xint_firstoftwo\else
+ \expandafter\xint_secondoftwo\fi
+ {#4{0}}{#5{\xintNum{#2}}}{#1}%
+}%
+\def\XINT:iiexpr:tacitzeroifonearg #1,#2,#3!#4%
+{%
+ \if\relax#3\relax\expandafter\xint_firstoftwo\else
+ \expandafter\xint_secondoftwo\fi
+ {#4{0}}{#4{#2}}{#1}%
+}%
+\def\XINT:expr:totwo #1#2{#1,#2}%
+\def\XINT:expr:two:to:two #1,#2,!#3%
+{%
+ \expandafter\XINT:expr:totwo\romannumeral`&&@#3{#1}{#2}%
+}%
+\let\XINT:flexpr:two:to:two\XINT:expr:two:to:two
+\let\XINT:iiexpr:two:to:two\XINT:expr:two:to:two
+% \end{macrocode}
+% \def\auxiliarymacro#1{ \noexpand\cshn{#1()}}
+% \edef\zzz{The \xintListWithSep{, }{\xintApply\auxiliarymacro
+% {{num}{reduce}{preduce}{abs}{sgn}{frac}{floor}{ceil}{sqr}{sqrt}{sqrtr}{float}
+% {sfloat}{ilog10}{inv}{round}{trunc}{mod}{quo}{rem}{divmod}{gcd}{lcm}{max}{min}
+% {`+`}
+% {`*`}
+% {?}{!}{not}{all}{any}{xor}{if}{ifsgn}{ifint}{ifone}{even}{odd}{isint}{isone}
+% {first}{last}{len}{reversed}{factorial}{binomial}}}
+% and \noexpand\cshn{randrange()} functions}
+% \expandafter\subsection\expandafter{\zzz}
+% \begin{macrocode}
+\def\XINT_expr_func_num #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintNum{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_num\XINT_expr_func_num
+\let\XINT_iiexpr_func_num\XINT_expr_func_num
+\def\XINT_expr_func_reduce #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintIrr{\XINT_expr_unlock #3}[0]\endcsname
+}%
+\let\XINT_flexpr_func_reduce\XINT_expr_func_reduce
+\def\XINT_expr_func_preduce #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintPIrr{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_preduce\XINT_expr_func_preduce
+\def\XINT_expr_func_abs #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintAbs{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_abs\XINT_expr_func_abs
+\def\XINT_iiexpr_func_abs #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintiiAbs{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_sgn #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintSgn{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_sgn\XINT_expr_func_sgn
+\def\XINT_iiexpr_func_sgn #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintiiSgn{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_frac #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintTFrac{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_flexpr_func_frac #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\XINTinFloatFracdigits{\XINT_expr_unlock #3}\endcsname
+}%
+% \end{macrocode}
+% \lverb|no \XINT_iiexpr_func_frac|
+% \begin{macrocode}
+\def\XINT_expr_func_floor #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintFloor{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_floor\XINT_expr_func_floor
+% \end{macrocode}
+% \lverb|The floor and ceil functions in \xintiiexpr require protect(a/b) or,
+% better, \qfrac(a/b); else the / will be executed first and do an integer
+% rounded division.|
+% \begin{macrocode}
+\def\XINT_iiexpr_func_floor #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintiFloor{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_ceil #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintCeil{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_ceil\XINT_expr_func_ceil
+\def\XINT_iiexpr_func_ceil #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintiCeil{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_sqr #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintSqr{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINTinFloatSqr#1{\XINTinFloatMul{#1}{#1}}% revoir après
+\def\XINT_flexpr_func_sqr #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\XINTinFloatSqr{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_iiexpr_func_sqr #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintiiSqr{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_? #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintiiIsNotZero{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_? \XINT_expr_func_?
+\let\XINT_iiexpr_func_? \XINT_expr_func_?
+\def\XINT_expr_func_! #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintiiIsZero{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_! \XINT_expr_func_!
+\let\XINT_iiexpr_func_! \XINT_expr_func_!
+\def\XINT_expr_func_not #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintiiIsZero{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_not \XINT_expr_func_not
+\let\XINT_iiexpr_func_not \XINT_expr_func_not
+\def\XINT_expr_func_odd #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintOdd{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_odd\XINT_expr_func_odd
+\def\XINT_iiexpr_func_odd #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintiiOdd{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_even #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintEven{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_even\XINT_expr_func_even
+\def\XINT_iiexpr_func_even #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintiiEven{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_isint #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintIsInt{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_flexpr_func_isint #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintFloatIsInt{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_iiexpr_func_isint\XINT_expr_func_isint % ? perhaps rather always 1
+\def\XINT_expr_func_isone #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintIsOne{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_isone\XINT_expr_func_isone
+\def\XINT_iiexpr_func_isone #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintiiIsOne{\XINT_expr_unlock #3}\endcsname
+}%
+% REVOIR nuple
+\def\XINT_expr_func_nuple #1#2#3%
+ {\expandafter #1\expandafter #2\csname.=\XINT_expr_unlock #3\endcsname }%
+\let\XINT_flexpr_func_nuple\XINT_expr_func_nuple
+\let\XINT_iiexpr_func_nuple\XINT_expr_func_nuple
+\def\XINT_expr_func_factorial #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:expr:one:and:opt
+ \romannumeral`&&@\XINT_expr_unlock#3,,!\xintFac\XINTinFloatFac
+ \endcsname
+}%
+\def\XINT_flexpr_func_factorial #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:expr:one:and:opt
+ \romannumeral`&&@\XINT_expr_unlock#3,,!\XINTinFloatFacdigits\XINTinFloatFac
+ \endcsname
+}%
+\def\XINT_iiexpr_func_factorial #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintiiFac{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_sqrt #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:expr:one:and:opt
+ \romannumeral`&&@\XINT_expr_unlock#3,,!\XINTinFloatSqrtdigits\XINTinFloatSqrt
+ \endcsname
+}%
+\let\XINT_flexpr_func_sqrt\XINT_expr_func_sqrt
+\def\XINT_iiexpr_func_sqrt #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintiiSqrt{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_iiexpr_func_sqrtr #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintiiSqrtR{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_inv #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintInv{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_flexpr_func_inv #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\XINTinFloatInv{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_round #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:expr:tacitzeroifonearg
+ \romannumeral`&&@\XINT_expr_unlock #3,,!\xintiRound\xintRound
+ \endcsname
+}%
+\let\XINT_flexpr_func_round\XINT_expr_func_round
+\def\XINT_iiexpr_func_round #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:iiexpr:tacitzeroifonearg
+ \romannumeral`&&@\XINT_expr_unlock #3,,!\xintiRound
+ \endcsname
+}%
+\def\XINT_expr_func_trunc #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:expr:tacitzeroifonearg
+ \romannumeral`&&@\XINT_expr_unlock #3,,!\xintiTrunc\xintTrunc
+ \endcsname
+}%
+\let\XINT_flexpr_func_trunc\XINT_expr_func_trunc
+\def\XINT_iiexpr_func_trunc #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:iiexpr:tacitzeroifonearg
+ \romannumeral`&&@\XINT_expr_unlock #3,,!\xintiTrunc
+ \endcsname
+}%
+% \end{macrocode}
+% \lverb|Hesitation at 1.3e about using \XINTinFloatSdigits and \XINTinFloatS.
+% Finally I add a sfloat() function. It helps for xinttrig.sty.|
+% \begin{macrocode}
+\def\XINT_expr_func_float #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:expr:one:and:opt
+ \romannumeral`&&@\XINT_expr_unlock #3,,!\XINTinFloatdigits\XINTinFloat
+ \endcsname
+}%
+\let\XINT_flexpr_func_float\XINT_expr_func_float
+\def\XINT_expr_func_sfloat #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:expr:one:and:opt
+ \romannumeral`&&@\XINT_expr_unlock #3,,!\XINTinFloatSdigits\XINTinFloatS
+ \endcsname
+}%
+\let\XINT_flexpr_func_sfloat\XINT_expr_func_sfloat
+% \XINT_iiexpr_func_sfloat not defined
+\expandafter\def\csname XINT_expr_func_ilog10\endcsname #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:expr:one:and:opt
+ \romannumeral`&&@\XINT_expr_unlock #3,,!\xintiLogTen\XINTFloatiLogTen
+ \endcsname
+}%
+\expandafter\def\csname XINT_flexpr_func_ilog10\endcsname #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:expr:one:and:opt
+ \romannumeral`&&@\XINT_expr_unlock #3,,!\XINTFloatiLogTendigits\XINTFloatiLogTen
+ \endcsname
+}%
+\expandafter\def\csname XINT_iiexpr_func_ilog10\endcsname #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintiiLogTen{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_divmod #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:expr:two:to:two
+ \romannumeral`&&@\XINT_expr_unlock #3,!\xintDivMod
+ \endcsname
+}%
+% \end{macrocode}
+% \lverb|\XINTinFloatDivMod a un output déjà comma separated|
+% \begin{macrocode}
+\def\XINT_flexpr_func_divmod #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:NEhook:twosp
+ \romannumeral`&&@\XINT_expr_unlock #3,!\XINTinFloatDivMod
+ \endcsname
+}%
+\def\XINT_iiexpr_func_divmod #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:expr:two:to:two
+ \romannumeral`&&@\XINT_expr_unlock #3,!\xintiiDivMod
+ \endcsname
+}%
+\def\XINT_expr_func_mod #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:NEhook:twosp
+ \romannumeral`&&@\XINT_expr_unlock #3,!\xintMod
+ \endcsname
+}%
+\def\XINT_flexpr_func_mod #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:NEhook:twosp
+ \romannumeral`&&@\XINT_expr_unlock #3,!\XINTinFloatMod
+ \endcsname
+}%
+\def\XINT_iiexpr_func_mod #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:NEhook:twosp
+ \romannumeral`&&@\XINT_expr_unlock #3,!\xintiiMod
+ \endcsname
+}%
+\def\XINT_expr_func_binomial #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:NEhook:twosp
+ \romannumeral`&&@\XINT_expr_unlock #3,!\xintBinomial
+ \endcsname
+}%
+\def\XINT_flexpr_func_binomial #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:NEhook:twosp
+ \romannumeral`&&@\XINT_expr_unlock #3,!\XINTinFloatBinomial
+ \endcsname
+}%
+\def\XINT_iiexpr_func_binomial #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:NEhook:twosp
+ \romannumeral`&&@\XINT_expr_unlock #3,!\xintiiBinomial
+ \endcsname
+}%
+\def\XINT_expr_func_pfactorial #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:NEhook:twosp
+ \romannumeral`&&@\XINT_expr_unlock #3,!\xintPFactorial
+ \endcsname
+}%
+\def\XINT_flexpr_func_pfactorial #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:NEhook:twosp
+ \romannumeral`&&@\XINT_expr_unlock #3,!\XINTinFloatPFactorial
+ \endcsname
+}%
+\def\XINT_iiexpr_func_pfactorial #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:NEhook:twosp
+ \romannumeral`&&@\XINT_expr_unlock #3,!\xintiiPFactorial
+ \endcsname
+}%
+\def\XINT_expr_func_randrange #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:expr:randrange
+ \romannumeral`&&@\XINT_expr_unlock #3,,!%
+ \endcsname
+}%
+\let\XINT_flexpr_func_randrange\XINT_expr_func_randrange
+\def\XINT_iiexpr_func_randrange #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:iiexpr:randrange
+ \romannumeral`&&@\XINT_expr_unlock #3,,!%
+ \endcsname
+}%
+\def\XINT:expr:randrange #1,#2,#3!%
+{%
+ \if\relax#3\relax\expandafter\xint_firstoftwo\else
+ \expandafter\xint_secondoftwo\fi
+ {\xintiiRandRange{\XINT:NEhook:one\xintNum{#1}}}%
+ {\xintiiRandRangeAtoB{\XINT:NEhook:one\xintNum{#1}}%
+ {\XINT:NEhook:one\xintNum{#2}}}%
+}%
+\def\XINT:iiexpr:randrange #1,#2,#3!%
+{%
+ \if\relax#3\relax\expandafter\xint_firstoftwo\else
+ \expandafter\xint_secondoftwo\fi
+ {\xintiiRandRange{#1}}{\xintiiRandRangeAtoB{#1}{#2}}%
+}%
+\def\XINT_expr_func_quo #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:NEhook:twosp
+ \romannumeral`&&@\XINT_expr_unlock #3,!\xintiQuo
+ \endcsname
+}%
+\let\XINT_flexpr_func_quo\XINT_expr_func_quo
+\def\XINT_iiexpr_func_quo #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:NEhook:twosp
+ \romannumeral`&&@\XINT_expr_unlock #3,!\xintiiQuo
+ \endcsname
+}%
+\def\XINT_expr_func_rem #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:NEhook:twosp
+ \romannumeral`&&@\XINT_expr_unlock #3,!\xintiRem
+ \endcsname
+}%
+\let\XINT_flexpr_func_rem\XINT_expr_func_rem
+\def\XINT_iiexpr_func_rem #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:NEhook:twosp
+ \romannumeral`&&@\XINT_expr_unlock #3,!\xintiiRem
+ \endcsname
+}%
+\def\XINT_expr_func_gcd #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintGCDof:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_gcd\XINT_expr_func_gcd
+\def\XINT_iiexpr_func_gcd #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintiiGCDof:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_lcm #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintLCMof:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_lcm\XINT_expr_func_lcm
+\def\XINT_iiexpr_func_lcm #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintiiLCMof:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_max #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintMaxof:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_iiexpr_func_max #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintiiMaxof:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_flexpr_func_max #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\XINTinFloatMaxof:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_min #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintMinof:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_iiexpr_func_min #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintiiMinof:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_flexpr_func_min #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\XINTinFloatMinof:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\expandafter
+\def\csname XINT_expr_func_+\endcsname #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintSum:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\expandafter
+\def\csname XINT_flexpr_func_+\endcsname #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\XINTinFloatSum:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\expandafter
+\def\csname XINT_iiexpr_func_+\endcsname #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintiiSum:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\expandafter
+\def\csname XINT_expr_func_*\endcsname #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintPrd:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\expandafter
+\def\csname XINT_flexpr_func_*\endcsname #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\XINTinFloatPrd:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\expandafter
+\def\csname XINT_iiexpr_func_*\endcsname #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintiiPrd:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_all #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintANDof:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_all\XINT_expr_func_all
+\let\XINT_iiexpr_func_all\XINT_expr_func_all
+\def\XINT_expr_func_any #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintORof:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_any\XINT_expr_func_any
+\let\XINT_iiexpr_func_any\XINT_expr_func_any
+\def\XINT_expr_func_xor #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintXORof:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_xor\XINT_expr_func_xor
+\let\XINT_iiexpr_func_xor\XINT_expr_func_xor
+\def\XINT_expr_func_len #1#2#3%
+{%
+ \expandafter#1\expandafter#2\csname.=%
+ \XINT:NEhook:csv\xintLength:f:csv{\XINT_expr_unlock#3}\endcsname
+}%
+\let\XINT_flexpr_func_len \XINT_expr_func_len
+\let\XINT_iiexpr_func_len \XINT_expr_func_len
+% \end{macrocode}
+% \lverb|1.2k has \xintFirstItem:f:csv for improved
+% \xintNewExpr compatibility.|
+% \begin{macrocode}
+\def\XINT_expr_func_first #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintFirstItem:f:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_first\XINT_expr_func_first
+\let\XINT_iiexpr_func_first\XINT_expr_func_first
+% \end{macrocode}
+% \lverb|1.2k has \xintLastItem:f:csv for efficiency and improved
+% \xintNewExpr compatibility.|
+% \begin{macrocode}
+\def\XINT_expr_func_last #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintLastItem:f:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_last\XINT_expr_func_last
+\let\XINT_iiexpr_func_last\XINT_expr_func_last
+% \end{macrocode}
+% \lverb|1.2c I hesitated but left the function "reversed" from 1.1 with
+% this name, not "reverse". But the inner not public macro got renamed
+% into \xintReverse::csv. 1.2g opts for the name \xintReverse:f:csv, and
+% rewrites it for direct handling of csv lists. 2016/03/17.|
+% \begin{macrocode}
+\def\XINT_expr_func_reversed #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:csv\xintReverse:f:csv{\XINT_expr_unlock #3}\endcsname
+}%
+\let\XINT_flexpr_func_reversed\XINT_expr_func_reversed
+\let\XINT_iiexpr_func_reversed\XINT_expr_func_reversed
+\def\xintiiifNotZero: #1,#2,#3,{\xintiiifNotZero{#1}{#2}{#3}}%
+\def\XINT_expr_func_if #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\xintiiifNotZero:%
+ \romannumeral`&&@\XINT_expr_unlock #3,\endcsname
+}%
+\let\XINT_flexpr_func_if\XINT_expr_func_if
+\let\XINT_iiexpr_func_if\XINT_expr_func_if
+\def\xintifInt: #1,#2,#3,{\xintifInt{#1}{#2}{#3}}%
+\def\XINT_expr_func_ifint #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\xintifInt:%
+ \romannumeral`&&@\XINT_expr_unlock #3,\endcsname
+}%
+\let\XINT_iiexpr_func_ifint\XINT_expr_func_ifint
+\def\xintifFloatInt: #1,#2,#3,{\xintifFloatInt{#1}{#2}{#3}}%
+\def\XINT_flexpr_func_ifint #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\xintifFloatInt:%
+ \romannumeral`&&@\XINT_expr_unlock #3,\endcsname
+}%
+\def\xintifOne: #1,#2,#3,{\xintifOne{#1}{#2}{#3}}%
+\def\XINT_expr_func_ifone #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\xintifOne:%
+ \romannumeral`&&@\XINT_expr_unlock #3,\endcsname
+}%
+\let\XINT_flexpr_func_ifone\XINT_expr_func_ifone
+\def\xintiiifOne: #1,#2,#3,{\xintiiifOne{#1}{#2}{#3}}%
+\def\XINT_iiexpr_func_ifone #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\xintiiifOne:%
+ \romannumeral`&&@\XINT_expr_unlock #3,\endcsname
+}%
+\def\xintiiifSgn: #1,#2,#3,#4,{\xintiiifSgn{#1}{#2}{#3}{#4}}%
+\def\XINT_expr_func_ifsgn #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\xintiiifSgn:%
+ \romannumeral`&&@\XINT_expr_unlock #3,\endcsname
+}%
+\let\XINT_flexpr_func_ifsgn\XINT_expr_func_ifsgn
+\let\XINT_iiexpr_func_ifsgn\XINT_expr_func_ifsgn
+% \end{macrocode}
+% \subsection{f-expandable versions of the \cshnolabel{xintSeqB::csv} and alike
+% routines, for \cshnolabel{xintNewExpr}}
+% \localtableofcontents
+% \subsubsection{\csh{xintSeqB:f:csv}}
+% \lverb|Produces in f-expandable way. If the step is zero, gives empty result
+% except if start and end coincide.|
+% \begin{macrocode}
+\def\xintSeqB:f:csv #1#2%
+ {\expandafter\XINT_seqb:f:csv \expandafter{\romannumeral0\xintraw{#2}}{#1}}%
+\def\XINT_seqb:f:csv #1#2{\expandafter\XINT_seqb:f:csv_a\romannumeral`&&@#2#1!}%
+\def\XINT_seqb:f:csv_a #1#2;#3;#4!{%
+ \expandafter\xint_gobble_i\romannumeral`&&@%
+ \xintifCmp {#3}{#4}\XINT_seqb:f:csv_bl\XINT_seqb:f:csv_be\XINT_seqb:f:csv_bg
+ #1{#3}{#4}{}{#2}}%
+\def\XINT_seqb:f:csv_be #1#2#3#4#5{,#2}%
+\def\XINT_seqb:f:csv_bl #1{\if #1p\expandafter\XINT_seqb:f:csv_pa\else
+ \xint_afterfi{\expandafter,\xint_gobble_iv}\fi }%
+\def\XINT_seqb:f:csv_pa #1#2#3#4{\expandafter\XINT_seqb:f:csv_p\expandafter
+ {\romannumeral0\xintadd{#4}{#1}}{#2}{#3,#1}{#4}}%
+\def\XINT_seqb:f:csv_p #1#2%
+{%
+ \xintifCmp {#1}{#2}\XINT_seqb:f:csv_pa\XINT_seqb:f:csv_pb\XINT_seqb:f:csv_pc
+ {#1}{#2}%
+}%
+\def\XINT_seqb:f:csv_pb #1#2#3#4{#3,#1}%
+\def\XINT_seqb:f:csv_pc #1#2#3#4{#3}%
+\def\XINT_seqb:f:csv_bg #1{\if #1n\expandafter\XINT_seqb:f:csv_na\else
+ \xint_afterfi{\expandafter,\xint_gobble_iv}\fi }%
+\def\XINT_seqb:f:csv_na #1#2#3#4{\expandafter\XINT_seqb:f:csv_n\expandafter
+ {\romannumeral0\xintadd{#4}{#1}}{#2}{#3,#1}{#4}}%
+\def\XINT_seqb:f:csv_n #1#2%
+{%
+ \xintifCmp {#1}{#2}\XINT_seqb:f:csv_nc\XINT_seqb:f:csv_nb\XINT_seqb:f:csv_na
+ {#1}{#2}%
+}%
+\def\XINT_seqb:f:csv_nb #1#2#3#4{#3,#1}%
+\def\XINT_seqb:f:csv_nc #1#2#3#4{#3}%
+% \end{macrocode}
+%\subsubsection{\csh{xintiiSeqB:f:csv}}
+% \lverb|Produces in f-expandable way. If the step is zero, gives empty result
+% except if start and end coincide.
+%
+% 2015/11/11. I correct a typo dating back to release 1.1 (2014/10/29): the
+% macro name had a "b" rather than "B", hence was not functional (causing
+% \xintNewIIExpr to fail on inputs such as #1..[1]..#2).|
+% \begin{macrocode}
+\def\xintiiSeqB:f:csv #1#2%
+ {\expandafter\XINT_iiseqb:f:csv \expandafter{\romannumeral`&&@#2}{#1}}%
+\def\XINT_iiseqb:f:csv #1#2{\expandafter\XINT_iiseqb:f:csv_a\romannumeral`&&@#2#1!}%
+\def\XINT_iiseqb:f:csv_a #1#2;#3;#4!{%
+ \expandafter\xint_gobble_i\romannumeral`&&@%
+ \xintSgnFork{\XINT_Cmp {#3}{#4}}%
+ \XINT_iiseqb:f:csv_bl\XINT_seqb:f:csv_be\XINT_iiseqb:f:csv_bg
+ #1{#3}{#4}{}{#2}}%
+\def\XINT_iiseqb:f:csv_bl #1{\if #1p\expandafter\XINT_iiseqb:f:csv_pa\else
+ \xint_afterfi{\expandafter,\xint_gobble_iv}\fi }%
+\def\XINT_iiseqb:f:csv_pa #1#2#3#4{\expandafter\XINT_iiseqb:f:csv_p\expandafter
+ {\romannumeral0\xintiiadd{#4}{#1}}{#2}{#3,#1}{#4}}%
+\def\XINT_iiseqb:f:csv_p #1#2%
+{%
+ \xintSgnFork{\XINT_Cmp {#1}{#2}}%
+ \XINT_iiseqb:f:csv_pa\XINT_iiseqb:f:csv_pb\XINT_iiseqb:f:csv_pc {#1}{#2}%
+}%
+\def\XINT_iiseqb:f:csv_pb #1#2#3#4{#3,#1}%
+\def\XINT_iiseqb:f:csv_pc #1#2#3#4{#3}%
+\def\XINT_iiseqb:f:csv_bg #1{\if #1n\expandafter\XINT_iiseqb:f:csv_na\else
+ \xint_afterfi{\expandafter,\xint_gobble_iv}\fi }%
+\def\XINT_iiseqb:f:csv_na #1#2#3#4{\expandafter\XINT_iiseqb:f:csv_n\expandafter
+ {\romannumeral0\xintiiadd{#4}{#1}}{#2}{#3,#1}{#4}}%
+\def\XINT_iiseqb:f:csv_n #1#2%
+{%
+ \xintSgnFork{\XINT_Cmp {#1}{#2}}%
+ \XINT_seqb:f:csv_nc\XINT_seqb:f:csv_nb\XINT_iiseqb:f:csv_na {#1}{#2}%
+}%
+% \end{macrocode}
+%\subsubsection{\csh{XINTinFloatSeqB:f:csv}}
+% \lverb|Produces in f-expandable way. If the step is zero, gives empty result
+% except if start and end coincide. This is all for \xintNewExpr.|
+% \begin{macrocode}
+\def\XINTinFloatSeqB:f:csv #1#2{\expandafter\XINT_flseqb:f:csv \expandafter
+ {\romannumeral0\XINTinfloat [\XINTdigits]{#2}}{#1}}%
+\def\XINT_flseqb:f:csv #1#2{\expandafter\XINT_flseqb:f:csv_a\romannumeral`&&@#2#1!}%
+\def\XINT_flseqb:f:csv_a #1#2;#3;#4!{%
+ \expandafter\xint_gobble_i\romannumeral`&&@%
+ \xintifCmp {#3}{#4}\XINT_flseqb:f:csv_bl\XINT_seqb:f:csv_be\XINT_flseqb:f:csv_bg
+ #1{#3}{#4}{}{#2}}%
+\def\XINT_flseqb:f:csv_bl #1{\if #1p\expandafter\XINT_flseqb:f:csv_pa\else
+ \xint_afterfi{\expandafter,\xint_gobble_iv}\fi }%
+\def\XINT_flseqb:f:csv_pa #1#2#3#4{\expandafter\XINT_flseqb:f:csv_p\expandafter
+ {\romannumeral0\XINTinfloatadd{#4}{#1}}{#2}{#3,#1}{#4}}%
+\def\XINT_flseqb:f:csv_p #1#2%
+{%
+ \xintifCmp {#1}{#2}%
+ \XINT_flseqb:f:csv_pa\XINT_flseqb:f:csv_pb\XINT_flseqb:f:csv_pc {#1}{#2}%
+}%
+\def\XINT_flseqb:f:csv_pb #1#2#3#4{#3,#1}%
+\def\XINT_flseqb:f:csv_pc #1#2#3#4{#3}%
+\def\XINT_flseqb:f:csv_bg #1{\if #1n\expandafter\XINT_flseqb:f:csv_na\else
+ \xint_afterfi{\expandafter,\xint_gobble_iv}\fi }%
+\def\XINT_flseqb:f:csv_na #1#2#3#4{\expandafter\XINT_flseqb:f:csv_n\expandafter
+ {\romannumeral0\XINTinfloatadd{#4}{#1}}{#2}{#3,#1}{#4}}%
+\def\XINT_flseqb:f:csv_n #1#2%
+{%
+ \xintifCmp {#1}{#2}%
+ \XINT_seqb:f:csv_nc\XINT_seqb:f:csv_nb\XINT_flseqb:f:csv_na {#1}{#2}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintdeffunc}, \csh{xintdefiifunc},
+% \csh{xintdeffloatfunc}}
+%
+% \changed{1.2c}{2015/11/12}
+% \lverb|Note: it is possible to have same name assigned both to a variable
+% and a function: things such as add(f(f), f=1..10) are possible.|
+%
+% \changed{1.2f}{2016/03/08}
+% \lverb|Comma separated expressions allowed (formerly this required using
+% parenthesis \xintdeffunc foo(x,..):=(.., .., ..);|
+%
+% \changed{1.3c}{2018/06/17}
+% \lverb|Usage of \xintexprSafeCatcodes to be compatible with an active
+% semi-colon at time of use; the colon was not a problem (see ##3) already.|
+%
+% \begin{macrocode}
+\def\XINT_tmpa #1#2#3#4%
+{%
+ \def #1##1(##2)##3=##4;{%
+ \edef\XINT_deffunc_tmpa {##1}%
+ \edef\XINT_deffunc_tmpa {\xint_zapspaces_o \XINT_deffunc_tmpa}%
+ \def\XINT_deffunc_tmpb {0}%
+ \def\XINT_deffunc_tmpc {(##4)}%
+ \edef\XINT_deffunc_tmpd {##2}%
+ \ifnum\xintLength:f:csv{\XINT_deffunc_tmpd}>\xint_c_
+ \xintFor ####1 in {\XINT_deffunc_tmpd}\do
+ {\edef\XINT_deffunc_tmpb {\the\numexpr\XINT_deffunc_tmpb+\xint_c_i}%
+ \edef\XINT_deffunc_tmpc {subs(\unexpanded\expandafter{\XINT_deffunc_tmpc},%
+ ####1=################\XINT_deffunc_tmpb)}%
+ }%
+ \fi
+% \end{macrocode}
+% \lverb|Something like this must be done before the NewFunc, else recursive
+% definitions are impossible as the function will be unknown.|
+% \begin{macrocode}
+ \ifnum\XINT_deffunc_tmpb=\xint_c_
+ \expandafter\XINT_expr_defuserfunc_none\csname
+ \else
+ \expandafter\XINT_expr_defuserfunc\csname
+ \fi
+ XINT_#2_func_\XINT_deffunc_tmpa\expandafter\endcsname
+ \expandafter{\XINT_deffunc_tmpa}{#2}%
+ \expandafter#3\csname XINT_#2_userfunc_\XINT_deffunc_tmpa\endcsname
+ [\XINT_deffunc_tmpb]{\XINT_deffunc_tmpc}%
+ \ifxintverbose\xintMessage {xintexpr}{Info}
+ {Function \XINT_deffunc_tmpa\space for \string\xint #4 parser
+ associated to \string\XINT_#2_userfunc_\XINT_deffunc_tmpa\space
+ with \ifxintglobaldefs global \fi meaning \expandafter\meaning
+ \csname XINT_#2_userfunc_\XINT_deffunc_tmpa\endcsname}%
+ \fi
+ \xintexprRestoreCatcodes
+ }%
+}%
+\def\xintdeffunc {\xintexprSafeCatcodes\xintdeffunc_a}%
+\def\xintdefiifunc {\xintexprSafeCatcodes\xintdefiifunc_a}%
+\def\xintdeffloatfunc {\xintexprSafeCatcodes\xintdeffloatfunc_a}%
+\XINT_tmpa\xintdeffunc_a {expr} \XINT_NewFunc {expr}%
+\XINT_tmpa\xintdefiifunc_a {iiexpr}\XINT_NewIIFunc {iiexpr}%
+\XINT_tmpa\xintdeffloatfunc_a{flexpr}\XINT_NewFloatFunc{floatexpr}%
+\def\XINT_expr_defuserfunc #1#2#3%
+{%
+ \XINT_global
+ \def #1##1##2##3{\expandafter ##1\expandafter ##2%
+ \csname.=\XINT:expr:userfunc{#3}{#2}{\XINT_expr_unlock ##3}\endcsname
+ }%
+}%
+\def\XINT:expr:userfunc #1#2#3%
+{%
+ \csname XINT_#1_userfunc_#2\expandafter\endcsname
+ \romannumeral0\xintcsvtolistnonstripped{#3}%
+}%
+\def\XINT_expr_defuserfunc_none #1#2#3%
+{%
+ \XINT_global
+ \def #1##1##2##3{\expandafter ##1\expandafter ##2%
+ \csname.=\XINT:expr:userfunc:none{#3}{#2}\endcsname
+ }%
+}%
+\def\XINT:expr:userfunc:none #1#2{\csname XINT_#1_userfunc_#2\endcsname}%
+% \end{macrocode}
+% \subsection{\csh{xintdefefunc}, \csh{xintdefiiefunc}, \csh{xintdeffloatefunc}}
+% \lverb|Added at 1.3e. Please consider the whole business of \xintdeffunc,
+% \xintdefefunc, \xintNewExpr as somewhat like a work in progress, it is
+% complex indeed.|
+% \begin{macrocode}
+\def\XINT_tmpa #1#2#3#4%
+{%
+ \def #1##1(##2)##3=##4;{%
+ \edef\XINT_defefunc_tmpa {##1}%
+ \edef\XINT_defefunc_tmpa {\xint_zapspaces_o \XINT_defefunc_tmpa}%
+ \def\XINT_defefunc_tmpb {0}%
+ \def\XINT_defefunc_tmpc {(##4)}%
+ \edef\XINT_defefunc_tmpd {##2}%
+ \ifnum\xintLength:f:csv{\XINT_defefunc_tmpd}>\xint_c_
+ \xintFor ####1 in {\XINT_defefunc_tmpd}\do
+ {\edef\XINT_defefunc_tmpb {\the\numexpr\XINT_defefunc_tmpb+\xint_c_i}%
+ \edef\XINT_defefunc_tmpc {subs(\unexpanded\expandafter{\XINT_defefunc_tmpc},%
+ ####1=################\XINT_defefunc_tmpb)}%
+ }%
+ \fi
+% \end{macrocode}
+% \lverb|No recursivity allowed here with the function to be defined.|
+% \begin{macrocode}
+ \expandafter#3\csname XINT_#2_userefunc_\XINT_defefunc_tmpa\endcsname
+ [\XINT_defefunc_tmpb]{\XINT_defefunc_tmpc}%
+ \edef\XINT_defefunc_tmpd{\xintLength:f:csv
+ {\expandafter\meaning\csname
+ XINT_#2_userfunc_\XINT_defefunc_tmpa\endcsname}}%
+% \end{macrocode}
+% \lverb|We try to distinguish wheter the function is supposed to deliver only
+% one value or more than two. And we separate the cases of 0, 1 or 2 variables
+% which can be set-up a bit better for usage in other definitions, in
+% generator environments. But there are many shortcomings. I don't have a very
+% clear view of all the complex situation, in fact.
+% |
+% \begin{macrocode}
+ \ifcase\XINT_defefunc_tmpb\space
+ \expandafter\XINT_expr_defuserefunc_none\csname
+ \or
+% \ifnum\XINT_defefunc_tmpd=\xint_c_i
+ \expandafter\XINT_expr_defuserefunc_one\csname
+% \else
+% \expandafter\XINT_expr_defuserefunc_onetocsv\csname
+% \fi
+ \or
+% \ifnum\XINT_defefunc_tmpd=\xint_c_i
+ \expandafter\XINT_expr_defuserefunc_two\csname
+% \else
+% \expandafter\XINT_expr_defuserefunc_twotocsv\csname
+% \fi
+ \else
+% \ifnum\XINT_defefunc_tmpd=\xint_c_i
+ \expandafter\XINT_expr_defuserefunc_many\csname
+% \else
+% \expandafter\XINT_expr_defuserefunc_manytocsv\csname
+% \fi
+ \fi
+ XINT_#2_func_\XINT_defefunc_tmpa\expandafter\endcsname
+ \expandafter{\XINT_defefunc_tmpa}{#2}%
+ \ifxintverbose\xintMessage {xintexpr}{Info}
+ {Function \XINT_defefunc_tmpa\space for \string\xint #4 parser
+ associated to \string\XINT_#2_userefunc_\XINT_defefunc_tmpa\space
+ with \ifxintglobaldefs global \fi meaning \expandafter\meaning
+ \csname XINT_#2_userefunc_\XINT_defefunc_tmpa\endcsname}%
+ \fi
+ \xintexprRestoreCatcodes
+ }%
+}%
+\def\xintdefefunc {\xintexprSafeCatcodes\xintdefefunc_a}%
+\def\xintdefiiefunc {\xintexprSafeCatcodes\xintdefiiefunc_a}%
+\def\xintdeffloatefunc {\xintexprSafeCatcodes\xintdeffloatefunc_a}%
+\XINT_tmpa\xintdefefunc_a {expr} \XINT_NewFunc {expr}%
+\XINT_tmpa\xintdefiiefunc_a {iiexpr}\XINT_NewIIFunc {iiexpr}%
+\XINT_tmpa\xintdeffloatefunc_a{flexpr}\XINT_NewFloatFunc{floatexpr}%
+\def\XINT_expr_defuserefunc_none #1#2#3%
+{%
+ \expandafter\XINT_expr_defuserefunc_none_a
+ \csname XINT_#3_userefunc_#2\endcsname
+}%
+\def\XINT_expr_defuserefunc_none_a #1#2%
+{%
+ \XINT_global
+ \def #2##1##2##3{\expandafter ##1\expandafter ##2\csname.=#1\endcsname}%
+}%
+% \end{macrocode}
+% \lverb|Je définis une macro auxiliaire qui fait l'expansion mais tout cela
+% pour éviter le très léger overhead de \xintExpandArgs... c'est idiot et le
+% devient encore plus pour deux arguments. Mais c'est aussi dû à
+% \xintApply::csv que l'on veut utiliser commodément
+% dans \XINT:NE:userefunc:one_a.|
+% \begin{macrocode}
+\def\XINT_expr_defuserefunc_one #1#2#3%
+{%
+ \expandafter\XINT_expr_defuserefunc_one_a
+ \csname XINT_#3_userefunc_#2\expandafter\endcsname
+ \csname XINT_#3_userefunc:f_#2\endcsname #1{#2}{#3}%
+}%
+\def\XINT_expr_defuserefunc_one_a #1#2#3#4#5%
+{%
+ \XINT_global
+ \def #2##1{\expandafter#1\expandafter{\romannumeral`&&@##1}}%
+ \XINT_global
+ \def #3##1##2##3%
+ {%
+ \expandafter ##1\expandafter ##2%
+ \csname.=\XINT:expr:userefunc:one{#5}{#4}{\XINT_expr_unlock##3}\endcsname
+ }%
+}%
+\def\XINT:expr:userefunc:one #1#2#3%
+{%
+ \csname XINT_#1_userefunc_#2\expandafter\endcsname\expandafter
+ {\romannumeral`&&@#3}%
+}%
+\def\XINT_expr_defuserefunc_two #1#2#3%
+{%
+ \expandafter\XINT_expr_defuserefunc_two_a
+ \csname XINT_#3_userefunc:f_#2\endcsname #1{#2}{#3}%
+}%
+% \end{macrocode}
+% \lverb|Le fait que \xintExpandArgs demande que les arguments sont regroupés
+% explique pourquoi plus bas j'ai dû faire \XINT:NE:userefunc:two.
+%
+% \xintExpandArgs#1{{##1}{##2}}
+%
+% Mais bon finalement je rajouter encore un helper d'expansion. Que j'ai
+% peut-être d'ailleurs déjà... C'est un peu de l'abus la macro auxiliaire
+% userefunc:f pour chaque userefunc, mais je dois gérer le problème que les
+% noms de macros ici peuvent contenir des chiffres.
+%
+% Il y a de la perte dans le grabbing de l'argument qui aura lieu et qu'on
+% pourrait optimiser, mais je commence à sérieusement fatiguer pour 1.3e.|
+% \begin{macrocode}
+\def\XINT_expr_defuserefunc_two_a #1#2#3#4%
+{%
+ \XINT_global
+ \def #1##1##2{\xintExpandArgs{XINT_#4_userefunc_#3}{{##1}{##2}}}%
+ \XINT_global
+ \def #2##1##2##3%
+ {%
+ \expandafter ##1\expandafter ##2%
+ \csname.=\XINT:expr:userefunc:two{#4}{#3}{\XINT_expr_unlock##3}\endcsname
+ }%
+}%
+\def\XINT:expr:userefunc:two #1#2#3%
+{%
+ \expandafter\XINT:expr:userefunc:two_a
+ \csname XINT_#1_userefunc_#2\expandafter\endcsname
+ \romannumeral`&&@#3,%
+}%
+\def\XINT:expr:userefunc:two_a #1#2,#3,{#1{#2}{#3}}%
+% \end{macrocode}
+% \lverb|Paradoxically the general case is code faster. But this is explained
+% because we try to hook into special handlers for one or two variables (see
+% "Mysterious stuff" subsection in NewExpr.|
+% \begin{macrocode}
+\def\XINT_expr_defuserefunc_many #1#2#3%
+{%
+ \XINT_global
+ \def #1##1##2##3%
+ {%
+ \expandafter ##1\expandafter ##2%
+ \csname.=\XINT:expr:userefunc{#3}{#2}{\XINT_expr_unlock##3}\endcsname
+ }%
+}%
+\def\XINT:expr:userefunc #1#2#3%
+{%
+ \csname XINT_#1_userefunc_#2\expandafter\endcsname
+ \romannumeral0\xintcsvtolistnonstripped{#3}%
+}%
+% \end{macrocode}
+% \subsection{\csh{xintunassignexprfunc}, \csh{xintunassigniiexprfunc}, \csh{xintunassignfloatexprfunc}}
+% See the \csbxint{unassignvar} for the embarrassing explanations why I had
+% not done that earlier. A bit lazy here, no warning if undefining something
+% not defined, and attention no precaution respective built-in functions.
+% \begin{macrocode}
+\def\XINT_tmpa #1{\expandafter\def\csname xintunassign#1func\endcsname ##1{%
+ \edef\XINT_unfunc_tmpa{##1}%
+ \edef\XINT_unfunc_tmpa {\xint_zapspaces_o\XINT_unfunc_tmpa}%
+ \XINT_global\expandafter
+ \let\csname XINT_#1_func_\XINT_unfunc_tmpa\endcsname\xint_undefined
+ \XINT_global\expandafter
+ \let\csname XINT_#1_userfunc_\XINT_unfunc_tmpa\endcsname\xint_undefined
+ \XINT_global\expandafter
+ \let\csname XINT_#1_userefunc_\XINT_unfunc_tmpa\endcsname\xint_undefined
+ \ifxintverbose\xintMessage {xintexpr}{Info}
+ {Function \XINT_unfunc_tmpa\space for \string\xint #1 parser now
+ \ifxintglobaldefs globally \fi undefined.}%
+ \fi}}%
+\XINT_tmpa{expr}\XINT_tmpa{iiexpr}\XINT_tmpa{floatexpr}%
+% \end{macrocode}
+% \subsection{\csh{xintNewFunction}}
+% \lverb|1.2h (2016/11/20). Syntax is \xintNewFunction{<name>}[nb of
+% arguments]{expression with #1, #2,... as in \xintNewExpr}. This defines
+% a function for all three parsers but the expression parsing is delayed until
+% function execution. Hence the expression admits all constructs, contrarily
+% to \xintNewExpr or \xintdeffunc.
+%
+% |
+% \begin{macrocode}
+\def\XINT_expr_wrapit #1{\expandafter\XINT_expr_wrap\csname.=#1\endcsname}%
+\def\xintNewFunction #1#2[#3]#4%
+{%
+ \edef\XINT_newfunc_tmpa {#1}%
+ \edef\XINT_newfunc_tmpa {\xint_zapspaces_o \XINT_newfunc_tmpa}%
+ \def\XINT_newfunc_tmpb ##1##2##3##4##5##6##7##8##9{#4}%
+ \begingroup
+ \ifcase #3\relax
+ \toks0{}%
+ \or \toks0{##1}%
+ \or \toks0{##1##2}%
+ \or \toks0{##1##2##3}%
+ \or \toks0{##1##2##3##4}%
+ \or \toks0{##1##2##3##4##5}%
+ \or \toks0{##1##2##3##4##5##6}%
+ \or \toks0{##1##2##3##4##5##6##7}%
+ \or \toks0{##1##2##3##4##5##6##7##8}%
+ \else \toks0{##1##2##3##4##5##6##7##8##9}%
+ \fi
+ \expandafter
+ \endgroup\expandafter
+ \XINT_global\expandafter
+ \def\csname XINT_expr_macrofunc_\XINT_newfunc_tmpa\expandafter\endcsname
+ \the\toks0\expandafter{\XINT_newfunc_tmpb
+ {\XINT_expr_wrapit{##1}}{\XINT_expr_wrapit{##2}}{\XINT_expr_wrapit{##3}}%
+ {\XINT_expr_wrapit{##4}}{\XINT_expr_wrapit{##5}}{\XINT_expr_wrapit{##6}}%
+ {\XINT_expr_wrapit{##7}}{\XINT_expr_wrapit{##8}}{\XINT_expr_wrapit{##9}}}%
+ \expandafter\XINT_expr_newfunction
+ \csname XINT_expr_func_\XINT_newfunc_tmpa\expandafter\endcsname
+ \expandafter{\XINT_newfunc_tmpa}{eval}\xintbareeval
+ \expandafter\XINT_expr_newfunction
+ \csname XINT_iiexpr_func_\XINT_newfunc_tmpa\expandafter\endcsname
+ \expandafter{\XINT_newfunc_tmpa}{iieval}\xintbareiieval
+ \expandafter\XINT_expr_newfunction
+ \csname XINT_flexpr_func_\XINT_newfunc_tmpa\expandafter\endcsname
+ \expandafter{\XINT_newfunc_tmpa}{floateval}\xintbarefloateval
+ \ifxintverbose
+ \xintMessage {xintexpr}{Info}
+ {Function \XINT_newfunc_tmpa\space for the expression parsers is
+ associated to \string\XINT_expr_macrofunc_\XINT_newfunc_tmpa\space
+ with \ifxintglobaldefs global \fi meaning \expandafter\meaning
+ \csname XINT_expr_macrofunc_\XINT_newfunc_tmpa\endcsname}%
+ \fi
+}%
+\def\XINT_expr_newfunction #1#2#3#4%
+{%
+ \XINT_global
+ \def#1##1##2##3{\expandafter ##1\expandafter ##2\romannumeral0%
+ \XINT:expr:macrofunc{#4}{#3}{#2}{\XINT_expr_unlock##3}}%
+}%
+\def\XINT:expr:macrofunc #1#2#3#4%
+{%
+ #1\csname XINT_expr_macrofunc_#3\expandafter\endcsname
+ \romannumeral0\xintcsvtolistnonstripped{#4}\relax
+}%
+\catcode`~ 12
+\def\XINT:newexpr:macrofunc #1{%
+\def\XINT:newexpr:macrofunc ##1##2##3##4%
+{%
+ \expandafter#1\csname.=~XINT:newexpr:macrofunc:a{##2}{##3}%
+ {\xintCSVtoListNonStripped{##4}}\endcsname
+}%
+}\XINT:newexpr:macrofunc { }%
+\catcode`~ 3
+\def\XINT:newexpr:macrofunc:a #1#2#3%
+{%
+ \expandafter\XINT_expr_unlock\romannumeral0\csname xintbare#1\endcsname
+ \csname XINT_expr_macrofunc_#2\endcsname#3\relax
+}%
+% \end{macrocode}
+% \subsection{\csh{xintNewExpr}, \csh{xintNewIExpr}, \csh{xintNewFloatExpr},
+% \csh{xintNewIIExpr}}
+% \localtableofcontents
+% \lverb|&
+% There was an \xintNewExpr already in 1.07 from May 2013, which was
+% modified in September 2013 to work with the # macro parameter character,
+% and then refactored into a more powerful version in June 2014 for 1.1
+% release of 2014/10/28. List handling causes special
+% challenges, addressed by \xintApply::csv, \xintApply:::csv, ... next.
+%
+% Comments finally added 2015/12/11 (with later edits):
+%
+% The whole point is to expand completely macros when they have only numerical
+% arguments and to inhibit this expansion if not. This is done in a recursive
+% way: the catcode 12 ~ is used to register a macro name whose expansion must
+% be inhibited. Any argument itself starting with such a ~ will
+% force use of ~ for the macro which receives it.
+%
+% In this context the catcode 12 $$ is used to signal a "virtual
+% list" argument. It triggers insertion of \xintApply::csv or
+% \xintApply:::csv for delayed handling later. This succeeds into handling
+% inputs such as [#1..[#2]..#3][#4:#5]...
+%
+% A final
+% \scantokens converts the "~" prefixed names into real control sequences.
+%
+% For this whole mechanism we need to have everything expressed using
+% exclusively f-expandable macros. We avoid \csname...\endcsname like
+% construct, but if absolutely needed perhaps we will do it ultimately.
+%
+% For the iterating loops seq, iter, etc..., and dummy variables, we have no
+% macros to our disposal to handle the case where the list
+% of indices is not explicit. Moreover omit, abort, break can not work with
+% non numerical data. Thus the whole mechanism is currently not appicable to
+% them. It does work when the macro parameters (or variables for \xintdeffunc)
+% do not intervene in the list of values to iterate over. But we can not delay
+% expansion of dummy variables.
+%
+% Comments added 2018/02/28:
+%
+% At 1.3 of February 2018, there was important refactoring. Earlier,
+% \XINT_expr_redefinemacros was a very big macro which made aliases of the
+% dozens of macros (most from xintfrac and some defined especially by xintexpr
+% for acting on csv lists primarily) involved in the expression rendering and
+% then redefined them all to expand to their original selves only when applied
+% to purely numeric arguments. At 1.3 only very few such re-definitions are
+% made, as what is redefined are a limited number of core wrapper macros.
+%
+% Only when the original macros have one or two arguments is it examined if
+% they can expand immediately (this includes case of function having possibly
+% only one, or possibly two arguments). For macros applying to three or more
+% or an undefined number of arguments, we don't complicate matters into
+% checking if expansion is possible, and we delay that expansion
+% automatically (but if() and ifsgn() do check if first argument is numeric
+% and expand to suitable branch in that case).
+%
+% In particular any function defined by \xintdeffunc or \xintNewFunction (it
+% is then basically only a macro abstraction) when used in new function
+% definitions will never be expanded immediately, because the detection of
+% whether they are applied to only numerical data has not yet been added.
+% (this might be added in future).
+%
+% Some aspects of the 1.3 refactoring have made recursive definition via
+% \xintdeffunc possible (of course they always were via \xintNewFunction as
+% the latter is but a wrapper of a standard TeX macro definition, where
+% \xintexpr parsing is not at all involved).
+%
+% A somewhat complicated layer (not modified at 1.3) is devoted to making
+% possible the parsing of constructs such as [#1..[#2]..#3][#4:#5] or
+% [#1..#2]*#3 and it seems to work. At 1.3, even esoteric construct such as
+% [divmod(#1,#2)]*#3 is parsable by \xintNewExpr. (In \xintNewFloatExpr, don't
+% forget \empty token so that square brackets are not mistaken for optional
+% argument of \xintthefloatexpr; same for \xintdeffloatfunc.)
+%
+% Side note: I wonder if I really had a good idea to define these list
+% operations [..]*foo or foo^[...] which do not seem to occur in other
+% languages with the meanings I used. And they caused me lots of efforts for
+% support at \xintNewExpr level...
+%
+% The catcode 12 dollar sign is used to signal when a macro can not be
+% expanded but would produce a csv list. Furthermore some cases require
+% f-expandable macros as the original code expanding in \xintexpr is in
+% \csname context and did not need f-expandability.
+%
+% As mentioned above, currently syntax with dummy variables can not go through
+% where the values iterated over are not explicit; and omit, abort, break
+% mechanisms are not parsable with non purely numerical data, in part because
+% they are not implemented internally via pure f-expansion.
+% |
+% \subsubsection{\csh{xintApply::csv} and \csh{xintApply:::csv}}
+% \lverb|Serve in particular to support things such as
+%
+% \xintdeffunc foo(x):=seq(sqr(i), i=0..x);
+%
+% ... as far as I still understand what is going on here! The most complicated
+% is for list operations; many things involving sequences don't go through
+% \xintNewExpr, especially with functions of more than one variable.
+%
+% |
+% \begin{macrocode}
+\def\xintApply::csv #1#2%
+ {\expandafter\XINT_applyon::_a\expandafter {\romannumeral`&&@#2}{#1}}%
+\def\XINT_applyon::_a #1#2{\XINT_applyon::_b {#2}{}#1,,}%
+\def\XINT_applyon::_b #1#2#3,{\expandafter\XINT_applyon::_c \romannumeral`&&@#3,{#1}{#2}}%
+\def\XINT_applyon::_c #1{\if #1,\expandafter\XINT_applyon::_end
+ \else\expandafter\XINT_applyon::_d\fi #1}%
+\def\XINT_applyon::_d #1,#2{\expandafter\XINT_applyon::_e\romannumeral`&&@#2{#1},{#2}}%
+\def\XINT_applyon::_e #1,#2#3{\XINT_applyon::_b {#2}{#3, #1}}%
+\def\XINT_applyon::_end #1,#2#3{\xint_secondoftwo #3}%
+\def\xintApply:::csv #1#2#3%
+ {\expandafter\XINT_applyon:::_a\expandafter{\romannumeral`&&@#2}{#1}{#3}}%
+\def\XINT_applyon:::_a #1#2#3{\XINT_applyon:::_b {#2}{#3}{}#1,,}%
+\def\XINT_applyon:::_b #1#2#3#4,%
+ {\expandafter\XINT_applyon:::_c \romannumeral`&&@#4,{#1}{#2}{#3}}%
+\def\XINT_applyon:::_c #1{\if #1,\expandafter\XINT_applyon:::_end
+ \else\expandafter\XINT_applyon:::_d\fi #1}%
+\def\XINT_applyon:::_d #1,#2#3%
+ {\expandafter\XINT_applyon:::_e\expandafter
+ {\romannumeral`&&@\xintApply::csv {#2{#1}}{#3}},{#2}{#3}}%
+\def\XINT_applyon:::_e #1,#2#3#4{\XINT_applyon:::_b {#2}{#3}{#4, #1}}%
+\def\XINT_applyon:::_end #1,#2#3#4{\xint_secondoftwo #4}%
+% \end{macrocode}
+% \subsubsection{Mysterious stuff}
+% \lverb|~ and $$ of catcode 12 in what follows. There was some refactoring at
+% 1.3e, particulary \XINT:NE:userefunc was added.|
+% \begin{macrocode}
+\catcode`~ 12
+\catcode`$ 12 % $
+\def\xint_dfork #1$#2#3\krof {#2}% $
+\def\xint_ddfork #1$$#2#3\krof {#2}% $$
+\def\XINT:NE:RApply::csv #1#2#3#4%
+ {~xintApply::csv{~expandafter #2~xint_exchangetwo_keepbraces{#4}}{#3}}%
+\def\XINT:NE:LApply::csv #1#2#3{~xintApply::csv{#2{#3}}}%
+\def\XINT:NE:RLApply:::csv #1{~xintApply:::csv}%
+\def\XINT:NE:two#1{\XINT:NE:two_{#1}{\detokenize{#1}}}%
+\def\XINT:NE:two_#1#2#3#4%
+ {\expandafter\XINT:NE:two_a\romannumeral`&&@#4!{#3}{#1}{#2}}%
+\def\XINT:NE:two_a#1#2!#3#4#5%
+ {\expandafter\XINT:NE:two_b\romannumeral`&&@#3!#1{#4}{#5}{#1#2}}%
+\def\XINT:NE:two_b#1#2!#3#4#5{\XINT:NE:two_fork_dd#1#3{#4}{#5}{#1#2}}%
+\def\XINT:NE:two_fork_dd #1#2{%
+ \xint_ddfork
+ #1#2\XINT:NE:RLApply:::csv
+ #1$\XINT:NE:RApply::csv% $
+ $#2\XINT:NE:LApply::csv% $
+ $${\XINT:NE:two_fork_nn #1#2}% $$
+ \krof
+}%
+\def\XINT:NE:two_fork_nn #1#2#3#4{%
+ \if #1##\xint_dothis{#4}\fi
+ \if #1~\xint_dothis{#4}\fi
+ \if #2##\xint_dothis{#4}\fi
+ \if #2~\xint_dothis{#4}\fi
+ \xint_orthat{#3}%
+}%
+% \end{macrocode}
+% \lverb|Problème pour autoriser ici qu'une liste arrive comme argument qui
+% potentiellement en donnerait deux mais pour le moment on ne sait pas. Donc
+% j'impose le prérequis que \XINT:NE:twosp soit toujours suivi de deux items
+% exactement.
+%
+% Il y a eu des modifications à 1.3e car j'ai supprimé des choses que je ne
+% comprenais pas puis je les ai remises lorsque je comprenais mais sans doute
+% pas pareil (certains tests passent et pas avant) et ensuite je ne comprenais
+% plus à nouveau.|
+% \begin{macrocode}
+\def\XINT:NE:twosp#1#2,#3#4,!#5%
+{%
+ \XINT:NE:two_fork_dd#1#3{#5}{\detokenize{#5}}{#1#2}{#3#4}%
+}%
+\def\XINT:NE:one#1#2{\expandafter\XINT:NE:one_a\romannumeral`&&@#2!#1}%
+\def\XINT:NE:one_a#1#2!#3%
+{%
+ \if ###1\xint_dothis {\detokenize{#3}}\fi
+ \if ~#1\xint_dothis {\detokenize{#3}}\fi
+ \if $#1\xint_dothis {~xintApply::csv{\detokenize{#3}}}\fi %$
+ \xint_orthat #3{#1#2}%
+}%
+% \end{macrocode}
+% \lverb|\xintExpandArgs is defined in xinttools.sty (I don't recall why; not
+% for reasons internal to xint I guess). Attention here that user function
+% names may contain digits, so we don't use a \detokenize or ~ approach.|
+% \begin{macrocode}
+\def\XINT:NE:userfunc #1#2#3%
+ {~xintExpandArgs{XINT_#1_userfunc_#2}{\xintCSVtoListNonStripped{#3}}}%
+\def\XINT:NE:userfunc:none #1#2{~!{XINT_#1_userfunc_#2}}%
+% \end{macrocode}
+% \lverb|\XINT:NE:userefunc et al. added at 1.3e. For one and two I can not
+% use \XINT:NE:one due to possible digits in names. For more than two nothing
+% special done with mysterious "Apply" macros above.
+%
+% Should they ever use $ in
+% output? Je crois que j'ai des problèmes en particulier car j'utilise le most
+% liste dans plusieurs sens il y a en particulier la confusion possible pour
+% liste dans le sens restreint devant être géré par les opérations genre ]* ou
+% celui avec les seq() ou finalement la liste des arguments d'une fonction.
+%
+% When expansion of the user func can not happend on the spot, the version
+% which will be expanded later one must first expand its argument for
+% efficiency because the functions from \XINT_NewFunc do not do that and we
+% must thus have an auxiliary variant expanding its argument.|
+% \begin{macrocode}
+\def\XINT:NE:userefunc:one#1#2#3%
+ {\expandafter\XINT:NE:userefunc:one_a\romannumeral`&&@#3!{#1}{#2}}%
+\def\XINT:NE:userefunc:one_a#1#2!#3#4%
+{%
+ \if ###1\xint_dothis {~!{XINT_#3_userefunc:f_#4}}\fi
+ \if ~#1\xint_dothis {~!{XINT_#3_userefunc:f_#4}}\fi
+% \end{macrocode}
+% \lverb|Quickly checked this \csname presentation ok for \xintApply::csv.|
+% \begin{macrocode}
+ \if $#1\xint_dothis {~xintApply::csv~!{XINT_#3_userefunc:f_#4}}\fi %$
+ \xint_orthat {\csname XINT_#3_userefunc_#4\endcsname}%
+ {#1#2}%
+}%
+\def\XINT:NE:twosp#1#2,#3#4,!#5%
+{%
+ \XINT:NE:two_fork_dd#1#3{#5}{\detokenize{#5}}{#1#2}{#3#4}%
+}%
+\def\XINT:NE:userefunc:two#1#2#3%
+ {\expandafter\XINT:NE:userefunc:two_a\romannumeral`&&@#3,!{#1}{#2}}%
+% \end{macrocode}
+% \lverb|Je ne peux pas faire ~xintExpandArgs{XINT_#5_userefunc_#6} à cause du
+% fait que j'ai {#1#2}{#3#4} pas {{#1#2}{#3#4}} à cause de la première
+% branche, celle qui s'étend.|
+% \begin{macrocode}
+\def\XINT:NE:userefunc:two_a#1#2,#3#4,!#5#6%
+{%
+ \XINT:NE:two_fork_dd#1#3{\csname XINT_#5_userefunc_#6\endcsname}%
+ {~!{XINT_#5_userefunc:f_#6}}%
+ {#1#2}{#3#4}%
+}%
+\def\XINT:NE:userefunc#1#2#3%
+{%
+ \expandafter\XINT:NE:userefunc_a\romannumeral`&&@#3,2,3,4,5,6,7,8,9,!%
+ {#1}{#2}{#3}%
+}%
+\def\XINT:NE:userefunc_a#1#2,#3#4,#5#6,#7#8,#9%
+{%
+ \XINT:NE:userefunc_b{#1#3#5#7#9}%
+}%
+\def\XINT:NE:userefunc_b#1#2,#3#4,#5#6,#7#8,#9%
+{%
+ \XINT:NE:userefunc_c{#1#3#5#7#9}%
+}%
+\def\XINT:NE:iftilde #1~#2#3\relax{\unless\if !#21\fi}%
+\def\XINT:NE:ifdollar #1$#2#3\relax{\unless\if !#21\fi}%$
+\def\XINT:NE:ifhash#1{%
+\def\XINT:NE:ifhash##1#1##2##3\relax{\unless\if !##21\fi}%
+}\expandafter\XINT:NE:ifhash\string#%
+\def\XINT:NE:userefunc_c#1#2!%
+{%
+ \if0\XINT:NE:iftilde #1~!\relax\XINT:NE:ifdollar #1$!\relax%$
+ \XINT:NE:ifhash #1##!\relax 0%
+ \expandafter\XINT:NE:userefunc_x
+ \else
+ \expandafter\XINT:NE:userefunc_p
+ \fi
+}%
+\def\XINT:NE:userefunc_x#1#2%
+ {\csname XINT_#1_userefunc_#2\expandafter\endcsname
+ \romannumeral0\xintcsvtolistnonstripped}%
+\def\XINT:NE:userefunc_p #1#2#3%
+ {~xintExpandArgs{XINT_#1_userefunc_#2}{\xintCSVtoListNonStripped{#3}}}%
+% \end{macrocode}
+% \lverb|Back to older stuff.|
+% \begin{macrocode}
+\def\XINT:NE:oneopt#1[#2]#3%
+ {\expandafter\XINT:NE:oneopt_a\romannumeral`&&@#3!{#2}#1}%
+\def\XINT:NE:oneopt_a#1#2!#3#4%
+ {\expandafter\XINT:NE:oneopt_b\romannumeral`&&@#3!#1#4{#1#2}}%
+\def\XINT:NE:oneopt_b#1#2!#3#4%
+ {\expandafter\XINT:NE:oneopt_fork#1#3#4{#1#2}}%
+\def\XINT:NE:oneopt_fork#1#2#3#4{%
+ \if1\if###11\else\if~#11\else\if###21\else\if~#21\else0\fi\fi\fi\fi
+ \xint_dothis {\detokenize{#3}[#4]}\fi
+ \if $#2\xint_dothis {~xintApply::csv{\detokenize{#3}[#4]}}\fi %$
+ \xint_orthat{#3[#4]}%
+}% pas complétement général, mais bon
+\def\XINT:NE:csv #1{\detokenize{#1}}% radicalement fainéant
+\def\XINT:newexpr:one:and:opt #1,#2,#3!#4#5%
+{%
+ \if\relax#3\relax\expandafter\xint_firstoftwo\else
+ \expandafter\xint_secondoftwo\fi
+ {\XINT:NE:one#4}{\XINT:NE:oneopt#5[\XINT:NE:one\xintNum{#2}]}{#1}%
+}%
+\def\XINT:newexpr:tacitzeroifonearg #1,#2,#3!#4#5%
+{%
+ \if\relax#3\relax\expandafter\xint_firstoftwo\else
+ \expandafter\xint_secondoftwo\fi
+ {\XINT:NE:two#4{0}}{\XINT:NE:two#5{\XINT:NE:one\xintNum{#2}}}{#1}%
+}%
+\def\XINT:newiiexpr:tacitzeroifonearg #1,#2,#3!#4%
+{%
+ \if\relax#3\relax\expandafter\xint_firstoftwo\else
+ \expandafter\xint_secondoftwo\fi
+ {\XINT:NE:two#4{0}}{\XINT:NE:two#4{#2}}{#1}%
+}%
+\def\XINT:newexpr:insertdollar~{$noexpand$}%
+\def\XINT:newexpr:two:to:two #1,#2,!#3%
+{%
+ \XINT:NE:two_
+ {\expandafter\XINT:expr:totwo\romannumeral`&&@#3}%
+ {$noexpand$expandafter~XINT:expr:totwo~romannumeral-`0\detokenize{#3}}%
+ {#1}{#2}%
+}%
+\def\XINT:newflexpr:two:to:two #1,#2,!#3%
+{%
+ \XINT:NE:two_
+ {#3}%
+ {\expandafter\XINT:newexpr:insertdollar\detokenize{#3}}%
+ {#1}{#2}%
+}%
+\def\xintiiifNotZeroNE:#1#2,#3,#4,%
+{%
+ \if1\if###11\else\if~#11\else\if$#11\else0%$
+ \fi\fi\fi
+ \xint_dothis{~xintiiifNotZero}\fi
+ \xint_orthat\xintiiifNotZero
+ {#1#2}{#3}{#4}%
+}%
+\def\xintifIntNE:#1#2,#3,#4,%
+{%
+ \if1\if###11\else\if~#11\else\if$#11\else0%$
+ \fi\fi\fi
+ \xint_dothis{~xintifInt}\fi
+ \xint_orthat\xintifInt
+ {#1#2}{#3}{#4}%
+}%
+\def\xintifFloatIntNE:#1#2,#3,#4,%
+{%
+ \if1\if###11\else\if~#11\else\if$#11\else0%$
+ \fi\fi\fi
+ \xint_dothis{~xintifFloatInt}\fi
+ \xint_orthat\xintifFloatInt
+ {#1#2}{#3}{#4}%
+}%
+\def\xintiiifOneNE:#1#2,#3,#4,%
+{%
+ \if1\if###11\else\if~#11\else\if$#11\else0%$
+ \fi\fi\fi
+ \xint_dothis{~xintiiifOne}\fi
+ \xint_orthat\xintiiifOne
+ {#1#2}{#3}{#4}%
+}%
+\def\xintifOneNE:#1#2,#3,#4,%
+{%
+ \if1\if###11\else\if~#11\else\if$#11\else0%$
+ \fi\fi\fi
+ \xint_dothis{~xintifOne}\fi
+ \xint_orthat\xintifOne
+ {#1#2}{#3}{#4}%
+}%
+\def\xintiiifSgnNE:#1#2,#3,#4,#5,%
+{%
+ \if1\if###11\else\if~#11\else\if$#11\else0%$
+ \fi\fi\fi
+ \xint_dothis{~xintiiifSgn}\fi
+ \xint_orthat\xintiiifSgn
+ {#1#2}{#3}{#4}{#5}%
+}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_redefinemacros}}
+% \lverb|Completely refactored at 1.3.|
+% \begin{macrocode}
+\def\XINT_expr_redefinemacros {%
+ \let\XINT:NEhook:one \XINT:NE:one
+ \let\XINT:NEhook:two \XINT:NE:two
+ \let\XINT:NEhook:csv \XINT:NE:csv
+ \let\XINT:NEhook:twosp\XINT:NE:twosp
+ \let\XINT:expr:userfunc \XINT:NE:userfunc
+ \let\XINT:expr:userfunc:none \XINT:NE:userfunc:none
+ \let\XINT:expr:userefunc \XINT:NE:userefunc
+ \let\XINT:expr:userefunc:one \XINT:NE:userefunc:one
+ \let\XINT:expr:userefunc:two \XINT:NE:userefunc:two
+ \let\XINT:expr:macrofunc \XINT:newexpr:macrofunc
+ \let\XINT:expr:one:and:opt \XINT:newexpr:one:and:opt
+ \let\XINT:expr:one:or:two:nums \XINT:newexpr:one:or:two:nums
+ \let\XINT:iiexpr:one:or:two: \XINT:newiiexpr:one:or:two:
+ \let\XINT:expr:tacitzeroifonearg \XINT:newexpr:tacitzeroifonearg
+ \let\XINT:iiexpr:tacitzeroifonearg \XINT:newiiexpr:tacitzeroifonearg
+ \let\XINT:expr:two:to:two \XINT:newexpr:two:to:two
+ \let\XINT:flexpr:two:to:two \XINT:newflexpr:two:to:two
+ \let\xintiiifNotZero: \xintiiifNotZeroNE:
+ \let\xintifInt: \xintifIntNE:
+ \let\xintifFloatInt: \xintifFloatIntNE:
+ \let\xintiiifOne: \xintiiifOneNE:
+ \let\xintifOne: \xintifOneNE:
+ \let\xintiiifSgn: \xintiiifSgnNE:
+ \let\xintSeqNumeric::csv \xintSeq::csv
+ \let\xintiiSeqNumeric::csv \xintiiSeq::csv
+ \let\XINTinFloatSeqNumeric::csv \XINTinFloatSeq::csv
+ \let\xintSeqBNumeric::csv \xintSeqB::csv
+ \let\xintiiSeqBNumeric::csv \xintiiSeqB::csv
+ \let\XINTinFloatSeqBNumeric::csv\XINTinFloatSeqB::csv
+ \def\xintSeq::csv
+ {\XINT:NE:two_\xintSeqNumeric::csv{$noexpand$xintSeq::csv}}%
+ \def\xintiiSeq::csv
+ {\XINT:NE:two_\xintiiSeqNumeric::csv{$noexpand$xintiiSeq::csv}}%
+ \def\XINTinFloatSeq::csv
+ {\XINT:NE:two_\XINTinFloatSeqNumeric::csv{$noexpand$XINTinFloatSeq::csv}}%
+ \def\xintSeqB::csv
+ {\XINT:NE:two_\xintSeqBNumeric::csv{$noexpand$xintSeqB:f:csv}}%
+ \def\xintiiSeqB::csv
+ {\XINT:NE:two_\xintiiSeqBNumeric::csv{$noexpand$xintiiSeqB:f:csv}}%
+ \def\XINTinFloatSeqB::csv
+ {\XINT:NE:two_\XINTinFloatSeqBNumeric::csv{$noexpand$XINTinFloatSeqB:f:csv}}%
+ \def\xintListSel:x:csv {~xintListSel:f:csv }%
+ \def\XINTinRandomFloatSdigits{~XINTinRandomFloatSdigits }%
+ \def\XINTinRandomFloatSixteen{~XINTinRandomFloatSixteen }%
+ \def\xintiiRandRange{~xintiiRandRange }%
+ \def\xintiiRandRangeAtoB{~xintiiRandRangeAtoB }%
+}%
+% \end{macrocode}
+% \subsubsection{\csh{XINT_expr_redefineprints}}
+% \lverb|This is used by \xintNewExpr and prior to 1.3e not by \xintdeffunc,
+% presumably to avoid some supposedly unneeded overhead. Now also used by
+% \xintdeffunc see some comment further below for why.
+% |
+% \begin{macrocode}
+\def\XINT_expr_redefineprints
+{%
+ \def\XINT_flexpr_noopt
+ {%
+ \expandafter
+ \XINT_flexpr_preprint\expandafter-\romannumeral0\xintbarefloateval
+ }%
+ \def\XINT_flexpr_preprint ##1##2%
+ {%
+ \expandafter\XINT_flexpr_wrap
+ \csname .;##1.=\XINT_expr_unlock##2\endcsname
+ }%
+ \def\XINT_expr_unlock_sp ##1.;##2##3.=##4!%
+ {%
+ \if -##2\expandafter\xint_firstoftwo\else\expandafter\xint_secondoftwo\fi
+ \XINTdigits{{##2##3}}{##4}%
+ }%
+ \def\XINT_expr_print ##1{\expandafter
+ \xintSPRaw::csv\expandafter{\romannumeral`&&@\XINT_expr_unlock ##1}}%
+ \def\XINT_iiexpr_print ##1{\expandafter
+ \xintCSV::csv\expandafter{\romannumeral`&&@\XINT_expr_unlock ##1}}%
+ \def\XINT_boolexpr_print ##1{\expandafter
+ \xintIsTrue::csv\expandafter{\romannumeral`&&@\XINT_expr_unlock ##1}}%
+ \def\xintCSV::csv {~xintCSV::csv }%
+ \def\xintSPRaw::csv {~xintSPRaw::csv }%
+ \def\xintPFloat::csv {~xintPFloat::csv }%
+ \def\xintIsTrue::csv {~xintIsTrue::csv }%
+ \def\xintRound::csv {~xintRound::csv }%
+}%
+% \end{macrocode}
+% \subsubsection{\cshnolabel{xintNewExpr}, ..., at last.}
+% \lverb|&
+% 1.2c modifications to accomodate \XINT_expr_deffunc_newexpr etc..
+%
+% 1.2f adds token \XINT_newexpr_clean to be able to have a different
+% \XINT_newfunc_clean.|
+% \begin{macrocode}
+\def\xintNewExpr {\XINT_NewExpr\XINT_expr_redefineprints\xint_firstofone
+ \xinttheexpr\XINT_newexpr_clean}%
+\def\xintNewFloatExpr{\XINT_NewExpr\XINT_expr_redefineprints\xint_firstofone
+ \xintthefloatexpr\XINT_newexpr_clean}%
+\def\xintNewIExpr {\XINT_NewExpr\XINT_expr_redefineprints\xint_firstofone
+ \xinttheiexpr\XINT_newexpr_clean}%
+\def\xintNewIIExpr {\XINT_NewExpr\XINT_expr_redefineprints\xint_firstofone
+ \xinttheiiexpr\XINT_newexpr_clean}%
+\def\xintNewBoolExpr {\XINT_NewExpr\XINT_expr_redefineprints\xint_firstofone
+ \xinttheboolexpr\XINT_newexpr_clean}%
+\def\XINT_newexpr_clean #1>{\noexpand\romannumeral`&&@}%
+% \end{macrocode}
+% \lverb|1.2c for \xintdeffunc, \xintdefiifunc, \xintdeffloatfunc.
+%
+% At 1.3, NewFunc does not use a comma delimited pattern anymore.|
+% \begin{macrocode}
+\def\XINT_NewFunc
+ {\XINT_NewExpr\XINT_expr_redefineprints\xint_gobble_i\xintthebareeval\XINT_newfunc_clean}%
+\def\XINT_NewFloatFunc
+ {\XINT_NewExpr\XINT_expr_redefineprints\xint_gobble_i\xintthebarefloateval\XINT_newfunc_clean}%
+\def\XINT_NewIIFunc
+ {\XINT_NewExpr\XINT_expr_redefineprints\xint_gobble_i\xintthebareiieval\XINT_newfunc_clean}%
+\def\XINT_newfunc_clean #1>{}%
+% \end{macrocode}
+% \lverb|1.2c adds optional logging. For this needed to pass to _NewExpr_a the
+% macro name as parameter.
+%
+% Up to and including 1.2c the definition was global. Starting with 1.2d it is
+% done locally.
+%
+% Modified at 1.3c so that \XINT_NewFunc et al. do not execute the
+% \xintexprSafeCatcodes, as it is now already done earlier by \xintdeffunc:
+% and as already #2 was either \xint_firstofone (for \xintNewExpr et al.) or
+% \xint_gobble_i (for \XINT_NewFunc et al.) we can use that #2. This is only
+% to avoid doing twice the catcodes, as anyhow there is an \endgroup coming
+% later, so external \xintexprRestoreCatcodes would not have been compromised.
+%
+% Modified at 1.3e: \XINT_NewFunc et al. do issue \XINT_expr_redefineprints.
+% I suppose I did not use it formely as I considered it unneeded overhead,
+% but this meant that \xintdeffunc foo(x):=\xintfloatexpr bar(x)\relax; was
+% impossible. And in fact this is convenient for xinttrig.sty to transfer
+% float functions to normal functions.
+% |
+% \begin{macrocode}
+\def\XINT_NewExpr #1#2#3#4#5#6[#7]%
+{%
+ \begingroup
+ \ifcase #7\relax
+ \toks0 {\endgroup\XINT_global\def#5}%
+ \or \toks0 {\endgroup\XINT_global\def#5##1}%
+ \or \toks0 {\endgroup\XINT_global\def#5##1##2}%
+ \or \toks0 {\endgroup\XINT_global\def#5##1##2##3}%
+ \or \toks0 {\endgroup\XINT_global\def#5##1##2##3##4}%
+ \or \toks0 {\endgroup\XINT_global\def#5##1##2##3##4##5}%
+ \or \toks0 {\endgroup\XINT_global\def#5##1##2##3##4##5##6}%
+ \or \toks0 {\endgroup\XINT_global\def#5##1##2##3##4##5##6##7}%
+ \or \toks0 {\endgroup\XINT_global\def#5##1##2##3##4##5##6##7##8}%
+ \or \toks0 {\endgroup\XINT_global\def#5##1##2##3##4##5##6##7##8##9}%
+ \fi
+ #2\xintexprSafeCatcodes
+ \XINT_expr_redefinemacros
+ #1%
+ \XINT_NewExpr_a #2#3#4#5%
+}%
+% \end{macrocode}
+% \lverb|& attention que & est de catcode 14
+%
+% 1.2d's \xintNewExpr makes a local definition. In earlier releases, the
+% definition was global.
+%
+% \the\toks0 inserts the \endgroup, but this will happen
+% after \XINT_tmpa has already been expanded...
+%
+% The $%1 is \xint_firstofone for \xintNewExpr, \xint_gobble_i
+% for \xintdeffunc.
+%
+% The ~ action was modified at 1.3e for ~! constructs (userefunc:f macros).
+% |
+% \begin{macrocode}
+\catcode`~ 13 \catcode`@ 14 \catcode`\% 6 \catcode`# 12 \catcode`$ 11 @ $
+\def\XINT_NewExpr_a %1%2%3%4%5@
+{@
+ \def\XINT_tmpa %%1%%2%%3%%4%%5%%6%%7%%8%%9{%5}@
+ \def~%%1{\if !%%1\noexpand~\else $noexpand$%%1\fi}@
+ \catcode`: 11 \catcode`_ 11
+ \catcode`# 12 \catcode`~ 13 \escapechar 126
+ \endlinechar -1 \everyeof {\noexpand }@
+ \edef\XINT_tmpb
+ {\scantokens\expandafter{\romannumeral`&&@\expandafter
+ %2\XINT_tmpa{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}\relax}@
+ }@
+ \escapechar 92 \catcode`# 6 \catcode`$ 0 @ $
+ \def~%%1{\expandafter\noexpand\csname %%1\endcsname}@
+ \edef\XINT_tmpa %%1%%2%%3%%4%%5%%6%%7%%8%%9@
+ {\scantokens\expandafter{\expandafter%3\meaning\XINT_tmpb}}@
+ \the\toks0\expandafter
+ {\XINT_tmpa{%%1}{%%2}{%%3}{%%4}{%%5}{%%6}{%%7}{%%8}{%%9}}@
+ %1{\ifxintverbose
+ \xintMessage{xintexpr}{Info}@
+ {\string%4\space now with @
+ \ifxintglobaldefs global \fi meaning \meaning%4}@
+ \fi}@
+}@
+\catcode`% 14
+\XINT_setcatcodes % clean up to avoid surprises if something changes
+% \end{macrocode}
+% \subsubsection{\csh{ifxintexprsafecatcodes}, \csh{xintexprSafeCatcodes}, \csh{xintexprRestoreCatcodes}}
+% \changed{1.3c}{2018/06/17}
+% \lverb|Added \ifxintexprsafecatcodes to allow nesting|
+% \begin{macrocode}
+\newif\ifxintexprsafecatcodes
+\let\xintexprRestoreCatcodes\empty
+\def\xintexprSafeCatcodes
+{%
+ \unless\ifxintexprsafecatcodes
+ \edef\xintexprRestoreCatcodes {%
+ \catcode59=\the\catcode59 % ;
+ \catcode34=\the\catcode34 % "
+ \catcode63=\the\catcode63 % ?
+ \catcode124=\the\catcode124 % |
+ \catcode38=\the\catcode38 % &
+ \catcode33=\the\catcode33 % !
+ \catcode93=\the\catcode93 % ]
+ \catcode91=\the\catcode91 % [
+ \catcode94=\the\catcode94 % ^
+ \catcode95=\the\catcode95 % _
+ \catcode47=\the\catcode47 % /
+ \catcode41=\the\catcode41 % )
+ \catcode40=\the\catcode40 % (
+ \catcode42=\the\catcode42 % *
+ \catcode43=\the\catcode43 % +
+ \catcode62=\the\catcode62 % >
+ \catcode60=\the\catcode60 % <
+ \catcode58=\the\catcode58 % :
+ \catcode46=\the\catcode46 % .
+ \catcode45=\the\catcode45 % -
+ \catcode44=\the\catcode44 % ,
+ \catcode61=\the\catcode61 % =
+ \catcode96=\the\catcode96 % `
+ \catcode32=\the\catcode32\relax % space
+ \noexpand\xintexprsafecatcodesfalse
+ }%
+ \fi
+ \xintexprsafecatcodestrue
+ \catcode59=12 % ;
+ \catcode34=12 % "
+ \catcode63=12 % ?
+ \catcode124=12 % |
+ \catcode38=4 % &
+ \catcode33=12 % !
+ \catcode93=12 % ]
+ \catcode91=12 % [
+ \catcode94=7 % ^
+ \catcode95=8 % _
+ \catcode47=12 % /
+ \catcode41=12 % )
+ \catcode40=12 % (
+ \catcode42=12 % *
+ \catcode43=12 % +
+ \catcode62=12 % >
+ \catcode60=12 % <
+ \catcode58=12 % :
+ \catcode46=12 % .
+ \catcode45=12 % -
+ \catcode44=12 % ,
+ \catcode61=12 % =
+ \catcode96=12 % `
+ \catcode32=10 % space
+}%
+\let\XINT_tmpa\undefined \let\XINT_tmpb\undefined \let\XINT_tmpc\undefined
+\ifdefined\RequirePackage\expandafter\xint_firstoftwo\else\expandafter\xint_secondoftwo\fi
+{\RequirePackage{xinttrig}%
+\RequirePackage{xintlog}}%
+{\input xinttrig.sty
+\input xintlog.sty
+}%
+\XINT_restorecatcodes_endinput%
+% \end{macrocode}
+% \StoreCodelineNo {xintexpr}
+% \cleardoublepage\let\xintexprnameUp\undefined
+%\gardesactifs
+%\let</xintexpr>\relax
+%\let<*xinttrig>\gardesinactifs
+%</xintexpr>^^A--------------------------------------------------
+%<*xinttrig>^^A---------------------------------------------------
+%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*-
+% \clearpage\csname xinttrignameUp\endcsname
+% \section{Package \xinttrignameimp implementation}
+% \RaisedLabel{sec:trigimp}
+% \etocarticlestylenomarks
+% \etocsetnexttocdepth {subsubsection}
+%
+% \localtableofcontents
+%
+% The original was done in January 15 and 16, 2019. It provided |asin()| and
+% |acos()| based on a Newton algorithm approach. Then during March 25-31 I
+% revisited the code, adding more inverse trigonometrical functions (with a
+% modified algorithm, quintically convergent), extending the precision range
+% (so that the package reacts to the \csbxint{Digits} value at time of load,
+% or reload), and replaced high level range reduction by some optimized lower
+% level coding.
+%
+% This led me next to improve upon the innards of \csbxint{deffunc} and
+% \csbxint{NewExpr}, and to add to \xintexprnameimp the \csbxint{defefunc}
+% macro (see user documentation).
+%
+% Finally on April 5, 2019 I pushed the idea of the algorithm for the arcsine
+% function to its logical limit obtaining the method finally in use here.
+%
+% Almost all of the code remains written at high level, and in particular it
+% is not easily feasible from this interface to execute computations with
+% guard digits. Expect the last one or two digits to be systematically off.
+%
+% Also, small floating-point inputs are handled quite sub-optimally both for
+% the direct and inverse functions; substantial gains are possible. I added
+% the ilog10() function too late to consider using it here with the high level
+% interface.
+%
+% \subsection{Catcodes, \protect\eTeX{} and reload detection}
+% \begin{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+ \catcode13=5 % ^^M
+ \endlinechar=13 %
+ \catcode123=1 % {
+ \catcode125=2 % }
+ \catcode64=11 % @
+ \catcode35=6 % #
+ \catcode44=12 % ,
+ \catcode45=12 % -
+ \catcode46=12 % .
+ \catcode58=12 % :
+ \catcode94=7 % ^
+ \def\z{\endgroup}%
+ \def\empty{}\def\space{ }\newlinechar10
+ \expandafter\let\expandafter\w\csname ver@xintexpr.sty\endcsname
+ \expandafter
+ \ifx\csname PackageInfo\endcsname\relax
+ \def\y#1#2{\immediate\write-1{Package #1 Info:^^J%
+ \space\space\space\space#2.}}%
+ \else
+ \def\y#1#2{\PackageInfo{#1}{#2}}%
+ \fi
+ \expandafter
+ \ifx\csname numexpr\endcsname\relax
+ \y{xinttrig}{\numexpr not available, aborting input}%
+ \aftergroup\endinput
+ \else
+ \ifx\w\relax % xintexpr.sty not yet loaded.
+ \y{xinttrig}%
+ {Loading should be via \ifx\x\empty\string\usepackage{xintexpr.sty}
+ \else\string\input\space xintexpr.sty \fi
+ rather, aborting}%
+ \aftergroup\endinput
+ \fi
+ \fi
+\z%
+\catcode`_ 11 \XINT_setcatcodes \catcode`? 12
+% \end{macrocode}
+% \subsection{Library identification}
+% \begin{macrocode}
+\ifcsname xintlibver@trig\endcsname
+ \expandafter\xint_firstoftwo
+\else
+ \expandafter\xint_secondoftwo
+\fi
+{\immediate\write-1{Reloading xinttrig library using Digits=\xinttheDigits.}}%
+{\expandafter\gdef\csname xintlibver@trig\endcsname{2019/04/05 1.3e}%
+\XINT_providespackage
+\ProvidesPackage{xinttrig}%
+[2019/04/05 1.3e Trigonometrical functions for xintexpr (JFB)]%
+}%
+% \end{macrocode}
+% \subsection{Ensure used letters are dummy letters}
+% \begin{macrocode}
+\xintFor* #1 in {iDTVtuwxyzX}\do{\xintensuredummy{#1}}%
+% \end{macrocode}
+% \subsection{\csh{xintreloadxinttrig}}
+% \begin{macrocode}
+\def\xintreloadxinttrig
+ {\edef\XINT_restorecatcodes_now{\XINT_restorecatcodes}%
+ \XINT_setcatcodes\catcode`? 12
+ \input xinttrig.sty
+ \XINT_restorecatcodes_now}%
+% \end{macrocode}
+% \subsection{Auxiliary variables (only temporarily needed, but left free to re-use)}
+% \lverb|&
+% These variables don't have really private names but this does not matter
+% because only their actual values will be stored in the functions defined
+% next. Nevertheless they are not unassigned, and are left free to use as is.
+% |
+% \subsubsection{\cshn{twoPi}, \cshn{threePiover2}, \cshn{Pi}, \cshn{Piover2}}
+% \lverb|&
+% We take them with 60 digits
+% and force conversion to \xintDigits setting via "0 + " syntax.
+% |
+% \begin{macrocode}
+\xintdeffloatvar twoPi := 0 +
+ 6.28318530717958647692528676655900576839433879875021164194989;%
+\xintdeffloatvar threePiover2 := 0 +
+ 4.71238898038468985769396507491925432629575409906265873146242;%
+\xintdeffloatvar Pi := 0 +
+ 3.14159265358979323846264338327950288419716939937510582097494;%
+\xintdeffloatvar Piover2 := 0 +
+ 1.57079632679489661923132169163975144209858469968755291048747;%
+% \end{macrocode}
+% \subsubsection{\cshn{oneDegree}, \cshn{oneRadian}}
+% \begin{macrocode}
+\xintdeffloatvar oneDegree := 0 +
+ 0.0174532925199432957692369076848861271344287188854172545609719;% Pi/180
+\xintdeffloatvar oneRadian := 0 +
+ 57.2957795130823208767981548141051703324054724665643215491602;% 180/Pi
+% \end{macrocode}
+% \subsubsection{Inverse factorial coefficients: \cshn{invfact2}, ..., \cshn{invfact44}}
+% \lverb|&
+% Pre-compute 1/n! for n = 2, ..., 44
+%
+% The following example (among many, see below) shows that we must be careful
+% when pre-computing the 1/i!.
+%( Consider 35!=10333147966386144929666651337523200000000.
+%: With \xintDigit:=26; \xintfloateval{35!} obtains 1.0333147966386144929666651e40
+%: which is the correct rounding to 26 digits. But \xintfloateval{1/35!} obtains
+%: 9.6775929586318909920898167e-41 which differs by 3ulps from the correct rounding
+%: of 1/35! to 26 places which is 9.6775929586318909920898164e-41. The problem
+%: isn't in the factorial computations, but in the fact that the rounding of the
+%: inverse of a quantity which is itself a rounding is not necessarily the rounding
+%: of the exact inverse of the original.
+%)
+% Here is a little program to explore this phenomenon systematically:
+%
+%( \xintDigits:=55;$%
+%: \edef\tempNlist{\xintSeq{2}{39}}%
+%: \xintFor*#1in{\tempNlist}\do{$% we precompute some rounding here to
+%: $% speed up things in the next double loop.
+%: \expandafter\edef\csname invfact#1\endcsname {\xintfloatexpr 1/#1!\relax}$%
+%: }$%
+%: \xintFor*#1in{\xintSeq{4}{50}}\do{$%
+%: \xintDigits:=#1;$%
+%: \xintFor*#2in{\tempNlist}\do{$%
+%: (D=#1, N=#2)
+%: $% attention to !== which is parsed as negation operator != followed by = (sigh...)
+%: \xintifboolfloatexpr{(1/#2!)==0+\csname invfact#2\endcsname}$%
+%: {ok}
+%: {mismatch: \xintfloateval{1/#2!} vs (exact)
+%: \xintfloateval{0+\csname invfact#2\endcsname}}$%
+%: \par
+%: }$%
+%: }$%
+%)
+%
+% We can see that for D=16, the problem is there with N=22, 25, 26, 27,
+% 28...and more. If we were to use 1/i! directly in the \xintdeffloatefunc of
+% sin_aux(X) and cos_aux(X) we would have this problem.
+%
+% If we use \xintexpr1/i!\relax encapsulation in the function declaration the
+% rounding will be delayed to actual use of the function... which is bad, so
+% we need it to happen now. We could use (0+\xintexpr1/i!\relax) inside the
+% declaration of the sine and cosine series, which will give the expected
+% result but for readability we use some temporary variables. We could use
+% seq(0+\xintexpr1/i!\relax, i = 2..44) but opt for an rseq. The semi-colon
+% must be braced to hide it from \xintdeffloatvar grabbing of the delimited
+% argument.
+% |
+% \begin{macrocode}
+\xintdeffloatvar invfact\xintListWithSep{, invfact}{\xintSeq{2}{44}}%
+ := seq(0+x, x=\xintexpr rseq(1/2{;}@/i, i=3..44)\relax);% need to hide inner ;
+% \end{macrocode}
+% \subsection{The sine and cosine series}
+% \subsubsection{\cshn{sin_aux()}, \cshn{cos_aux()}}
+% \lverb|&
+% Should I rather use successive divisions by (2n+1)(2n), or rather
+% multiplication by their precomputed inverses, in a modified Horner scheme ?
+% The \ifnum tests are executed at time of definition.
+%
+% Criteria for truncated series using π/4, actually 0.79.
+%
+% Small values of the variable X are very badly handled here because a much
+% shorter truncation of the sine series should be used.
+% |
+% \begin{macrocode}
+\xintdeffloatefunc sin_aux(X) := 1 - X(invfact3 - X(invfact5
+\ifnum\XINTdigits>4
+ - X(invfact7
+\ifnum\XINTdigits>6
+ - X(invfact9
+\ifnum\XINTdigits>8
+ - X(invfact11
+\ifnum\XINTdigits>10
+ - X(invfact13
+\ifnum\XINTdigits>13
+ - X(invfact15
+\ifnum\XINTdigits>15
+ - X(invfact17
+\ifnum\XINTdigits>18
+ - X(invfact19
+\ifnum\XINTdigits>21
+ - X(invfact21
+\ifnum\XINTdigits>24
+ - X(invfact23
+\ifnum\XINTdigits>27
+ - X(invfact25
+\ifnum\XINTdigits>30
+ - X(invfact27
+\ifnum\XINTdigits>33
+ - X(invfact29
+\ifnum\XINTdigits>36
+ - X(invfact31
+\ifnum\XINTdigits>39
+ - X(invfact33
+\ifnum\XINTdigits>43
+ - X(invfact35
+\ifnum\XINTdigits>46
+ - X(invfact37
+\ifnum\XINTdigits>49
+ - X(invfact39
+\ifnum\XINTdigits>53
+ - X(invfact41
+\ifnum\XINTdigits>59
+ - X(invfact43
+ )\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi));%
+% \end{macrocode}
+% \lverb|Criteria on basis of π/4, we actually used 0.79 to choose the
+% transition values and this makes them a bit less favourable at 24, 26,
+% 29...and some more probably. Again this is very bad for small X.|
+% \begin{macrocode}
+\xintdeffloatefunc cos_aux(X) := 1 - X(invfact2 - X(invfact4
+\ifnum\XINTdigits>3
+ - X(invfact6
+\ifnum\XINTdigits>5
+ - X(invfact8
+\ifnum\XINTdigits>7
+ - X(invfact10
+\ifnum\XINTdigits>9
+ - X(invfact12
+\ifnum\XINTdigits>12
+ - X(invfact14
+\ifnum\XINTdigits>14
+ - X(invfact16
+\ifnum\XINTdigits>17
+ - X(invfact18
+\ifnum\XINTdigits>20
+ - X(invfact20
+\ifnum\XINTdigits>23
+ - X(invfact22
+\ifnum\XINTdigits>25
+ - X(invfact24
+\ifnum\XINTdigits>28
+ - X(invfact26
+\ifnum\XINTdigits>32
+ - X(invfact28
+\ifnum\XINTdigits>35
+ - X(invfact30
+\ifnum\XINTdigits>38
+ - X(invfact32
+\ifnum\XINTdigits>41
+ - X(invfact34
+\ifnum\XINTdigits>44
+ - X(invfact36
+\ifnum\XINTdigits>48
+ - X(invfact38
+\ifnum\XINTdigits>51
+ - X(invfact40
+\ifnum\XINTdigits>55
+ - X(invfact42
+\ifnum\XINTdigits>58
+ - X(invfact44
+ )\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi));%
+% \end{macrocode}
+% \subsubsection{Make \cshnnolabel{sin\_aux()} and \cshnnolabel{cos\_aux()}
+% known to \cshnolabel{xintexpr}}
+% \lverb|We need them shortly for the asin() in an \xintexpr variant.
+% We short-circuit the high level interface as it will not be needed to
+% add some \xintFloat wrapper.
+% |
+% \begin{macrocode}
+\expandafter\let\csname XINT_expr_func_sin_aux\expandafter\endcsname
+ \csname XINT_flexpr_func_sin_aux\endcsname
+\expandafter\let\csname XINT_expr_func_cos_aux\expandafter\endcsname
+ \csname XINT_flexpr_func_cos_aux\endcsname
+% \end{macrocode}
+% \subsubsection{\cshn{sin_()}, \cshn{cos_()}}
+% \lverb|&
+% Use this only between -pi/4 and pi/4
+% |
+% \begin{macrocode}
+\xintdeffloatefunc sin_(x) := x * sin_aux(sqr(x));%
+% \end{macrocode}
+% \lverb|&
+% Use this only between -pi/4 and pi/4
+% |
+% \begin{macrocode}
+\xintdeffloatefunc cos_(x) := cos_aux(sqr(x));%
+% \end{macrocode}
+% \subsection{Range reduction for sine and cosine using degrees}
+%
+% Notice that even when handling radians it is much better to convert to
+% degrees and then do range reduction there, because this can be done in the
+% fixed point sense. I lost 1h puzzled about some mismatch of my results with
+% those of Maple (at 16 digits) near -π. Turns out that Maple probably adds π
+% in the floating point sense causing catastrophic loss of digits when one is
+% near -π. On the other hand my sin(x) function will first convert to degrees
+% then add 180 without any loss of floating point precision, even for a result
+% near zero, then convert back to radians and use the sine series.
+%
+% \subsubsection{Core level macro \csh{XINT_mod_ccclx_i}}
+% \lverb|&
+% input: \the\numexpr\XINT_mod_ccclx_i k.N. (delimited by dots)
+%
+% output: (N times 10^k) modulo 360. (with a final dot)
+%
+% Attention N must be non-negative (I could make it accept negative
+% but the fact that numexpr / is not periodical in numerator
+% adds overhead).
+%
+% 360 divides 9000 hence 10^{k} is 280 for k at least 3 and the additive
+% group generated by it modulo 360 is the set of multiples of 40.
+% |
+% \begin{macrocode}
+\def\XINT_mod_ccclx_i #1.% input <k>.<N>. k is a non-negative exponent
+{%
+ \expandafter\XINT_mod_ccclx_e\the\numexpr
+ \expandafter\XINT_mod_ccclx_j\the\numexpr1\ifcase#1 \or0\or00\else000\fi.%
+}%
+\def\XINT_mod_ccclx_j 1#1.#2.% #2=N is a non-negative mantissa
+{%
+ (\XINT_mod_ccclx_ja {++}#2#1\XINT_mod_ccclx_jb 0000000\relax
+}% 1 2345678
+\def\XINT_mod_ccclx_ja #1#2#3#4#5#6#7#8#9%
+{%
+ #9+#8+#7+#6+#5+#4+#3+#2\xint_firstoftwo{+\XINT_mod_ccclx_ja{+#9+#8+#7}}{#1}%
+}%
+\def\XINT_mod_ccclx_jb #1\xint_firstoftwo#2#3{#1+0)*280\XINT_mod_ccclx_jc #1#3}%
+% \end{macrocode}
+% \lverb|&
+% Attention that \XINT_cclcx_e wants non negative input because \numexpr
+% division is not periodical ...
+% |
+% \begin{macrocode}
+\def\XINT_mod_ccclx_jc +#1+#2+#3#4\relax{+80*(#3+#2+#1)+#3#2#1.}%
+\def\XINT_mod_ccclx_e#1.{\expandafter\XINT_mod_ccclx_z\the\numexpr(#1+180)/360-1.#1.}%
+\def\XINT_mod_ccclx_z#1.#2.{#2-360*#1.}%
+% \end{macrocode}
+% \subsubsection{\cshn{sind_()}, \cshn{cosd_()}, and support macros \csh{xintSind}, \csh{xintCosd}}
+% \lverb|&
+%
+% sind_() coded directly at macro level with a macro \xintSind (ATTENTION! it
+% requires a positive argument)
+% which will suitably use \XINT_flexpr_func_sin_ defined from \xintdeffloatefunc
+% |
+% \begin{macrocode}
+\def\XINT_flexpr_func_sind_ #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintSind{\XINT_expr_unlock#3}\endcsname
+}%
+% \end{macrocode}
+% \lverb|&
+% Must be f-expandable for nesting macros from \xintNewExpr
+%
+% ATTENTION ONLY FOR POSITIVE ARGUMENTS
+% |
+% \begin{macrocode}
+\def\xintSind#1{\romannumeral`&&@\expandafter\xintsind
+ \romannumeral0\XINTinfloatS[\XINTdigits]{#1}}%
+\def\xintsind #1[#2#3]%
+{%
+ \xint_UDsignfork
+ #2\XINT_sind
+ -\XINT_sind_int
+ \krof#2#3.#1..%<< attention extra dot
+}%
+\def\XINT_sind #1.#2.% NOT TO BE USED WITH VANISHING (OR NEGATIVE) #2.
+{%
+ \expandafter\XINT_sind_a
+ \romannumeral0\xinttrunc{\XINTdigits}{#2[#1]}%
+}%
+\def\XINT_sind_a{\expandafter\XINT_sind_i\the\numexpr\XINT_mod_ccclx_i0.}%
+\def\XINT_sind_int
+{%
+ \expandafter\XINT_sind_i\the\numexpr\expandafter\XINT_mod_ccclx_i
+}%
+\def\XINT_sind_i #1.% range reduction inside [0, 360[
+{%
+ \ifcase\numexpr#1/90\relax
+ \expandafter\XINT_sind_A
+ \or\expandafter\XINT_sind_B\the\numexpr-90+%
+ \or\expandafter\XINT_sind_C\the\numexpr-180+%
+ \or\expandafter\XINT_sind_D\the\numexpr-270+%
+ \else\expandafter\XINT_sind_E\the\numexpr-360+%
+ \fi#1.%
+}%
+% \end{macrocode}
+% \lverb|&
+% #2 will be empty in the "integer branch". Notice that a single dot "." is
+% valid as input to the xintfrac macros. During developing phase I did many
+% silly mistakes due to wanting to use too low-level interface, e.g. I would
+% use something like #2[-\XINTdigits] with #2 the fractional digits, but there
+% maybe some leading zero and then xintfrac.sty will think the whole thing is
+% zero due to the requirements of my own core format A[N]....
+%
+% The "userefunc" auxiliary macros do not pre-expand their arguments (but the
+% macros which end up used in other ones defined from \csbxintdeffunc do).
+%
+% Multiplication is done exactly but anyway currently float multiplication
+% goes via exact multiplication after rounding arguments ; as here integer
+% part has at most three digits, doing exact multiplication will prove
+% not only more accurate but probably faster.
+% |
+% \begin{macrocode}
+\def\XINT_sind_A#1{%
+\def\XINT_sind_A##1.##2.%
+{%
+ \expandafter\XINT_flexpr_userefunc_sin_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}{#1}}}%
+}%
+}\expandafter
+\XINT_sind_A\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}%
+\def\XINT_sind_B#1{\xint_UDsignfork#1\XINT_sind_B_n-\XINT_sind_B_p\krof #1}%
+\def\XINT_tmpa#1{%
+\def\XINT_sind_B_n-##1.##2.%
+{%
+ \expandafter\XINT_flexpr_userefunc_cos_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}{#1}}}%
+}%
+\def\XINT_sind_B_p##1.##2.%
+{%
+ \expandafter\XINT_flexpr_userefunc_cos_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}{#1}}}%
+}%
+}\expandafter
+\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}%
+\def\XINT_sind_C#1{\xint_UDsignfork#1\XINT_sind_C_n-\XINT_sind_C_p\krof #1}%
+\def\XINT_tmpa#1{%
+\def\XINT_sind_C_n-##1.##2.%
+{%
+ \expandafter\XINT_flexpr_userefunc_sin_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}{#1}}}%
+}%
+\def\XINT_sind_C_p##1.##2.%
+{%
+ \xintiiopp\expandafter\XINT_flexpr_userefunc_sin_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}{#1}}}%
+}%
+}\expandafter
+\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}%
+\def\XINT_sind_D#1{\xint_UDsignfork#1\XINT_sind_D_n-\XINT_sind_D_p\krof #1}%
+\def\XINT_tmpa#1{%
+\def\XINT_sind_D_n-##1.##2.%
+{%
+ \xintiiopp\expandafter\XINT_flexpr_userefunc_cos_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}{#1}}}%
+}%
+\def\XINT_sind_D_p##1.##2.%
+{%
+ \xintiiopp\expandafter\XINT_flexpr_userefunc_cos_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}{#1}}}%
+}%
+}\expandafter
+\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}%
+\def\XINT_sind_E#1{%
+\def\XINT_sind_E-##1.##2.%
+{%
+ \xintiiopp\expandafter\XINT_flexpr_userefunc_sin_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}{#1}}}%
+}%
+}\expandafter
+\XINT_sind_E\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}%
+% \end{macrocode}
+% \lverb|The cosd_ auxiliary function|
+% \begin{macrocode}
+\def\XINT_flexpr_func_cosd_ #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintCosd{\XINT_expr_unlock#3}\endcsname
+}%
+% \end{macrocode}
+% \lverb|&
+% ATTENTION ONLY FOR POSITIVE ARGUMENTS
+% |
+% \begin{macrocode}
+\def\xintCosd#1{\romannumeral`&&@\expandafter\xintcosd
+ \romannumeral0\XINTinfloatS[\XINTdigits]{#1}}%
+\def\xintcosd #1[#2#3]%
+{%
+ \xint_UDsignfork
+ #2\XINT_cosd
+ -\XINT_cosd_int
+ \krof#2#3.#1..%<< attention extra dot
+}%
+\def\XINT_cosd #1.#2.% NOT TO BE USED WITH VANISHING (OR NEGATIVE) #2.
+{%
+ \expandafter\XINT_cosd_a
+ \romannumeral0\xinttrunc{\XINTdigits}{#2[#1]}%
+}%
+\def\XINT_cosd_a{\expandafter\XINT_cosd_i\the\numexpr\XINT_mod_ccclx_i0.}%
+\def\XINT_cosd_int
+{%
+ \expandafter\XINT_cosd_i\the\numexpr\expandafter\XINT_mod_ccclx_i
+}%
+\def\XINT_cosd_i #1.%
+{%
+ \ifcase\numexpr#1/90\relax
+ \expandafter\XINT_cosd_A
+ \or\expandafter\XINT_cosd_B\the\numexpr-90+%
+ \or\expandafter\XINT_cosd_C\the\numexpr-180+%
+ \or\expandafter\XINT_cosd_D\the\numexpr-270+%
+ \else\expandafter\XINT_cosd_E\the\numexpr-360+%
+ \fi#1.%
+}%
+% \end{macrocode}
+% \lverb|#2 will be empty in the "integer" branch, but attention in general
+% branch to handling of negative integer part after the subtraction of 90,
+% 180, 270, or 360, and avoid abusing A[N] notation which yes speeds up
+% xintfrac parsing but has its pitfalls.|
+% \begin{macrocode}
+\def\XINT_cosd_A#1{%
+\def\XINT_cosd_A##1.##2.%
+{%
+ \expandafter\XINT_flexpr_userefunc_cos_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}{#1}}}%
+}%
+}\expandafter
+\XINT_cosd_A\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}%
+\def\XINT_cosd_B#1{\xint_UDsignfork#1\XINT_cosd_B_n-\XINT_cosd_B_p\krof #1}%
+\def\XINT_tmpa#1{%
+\def\XINT_cosd_B_n-##1.##2.%
+{%
+ \expandafter\XINT_flexpr_userefunc_sin_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}{#1}}}%
+}%
+\def\XINT_cosd_B_p##1.##2.%
+{%
+ \xintiiopp\expandafter\XINT_flexpr_userefunc_sin_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}{#1}}}%
+}%
+}\expandafter
+\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}%
+\def\XINT_cosd_C#1{\xint_UDsignfork#1\XINT_cosd_C_n-\XINT_cosd_C_p\krof #1}%
+\def\XINT_tmpa#1{%
+\def\XINT_cosd_C_n-##1.##2.%
+{%
+ \xintiiopp\expandafter\XINT_flexpr_userefunc_cos_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}{#1}}}%
+}%
+\def\XINT_cosd_C_p##1.##2.%
+{%
+ \xintiiopp\expandafter\XINT_flexpr_userefunc_cos_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}{#1}}}%
+}%
+}\expandafter
+\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}%
+\def\XINT_cosd_D#1{\xint_UDsignfork#1\XINT_cosd_D_n-\XINT_cosd_D_p\krof #1}%
+\def\XINT_tmpa#1{%
+\def\XINT_cosd_D_n-##1.##2.%
+{%
+ \xintiiopp\expandafter\XINT_flexpr_userefunc_sin_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}{#1}}}%
+}%
+\def\XINT_cosd_D_p##1.##2.%
+{%
+ \expandafter\XINT_flexpr_userefunc_sin_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}{#1}}}%
+}%
+}\expandafter
+\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}%
+\def\XINT_cosd_E#1{%
+\def\XINT_cosd_E-##1.##2.%
+{%
+ \expandafter\XINT_flexpr_userefunc_cos_\expandafter
+ {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}{#1}}}%
+}%
+}\expandafter
+\XINT_cosd_E\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}%
+% \end{macrocode}
+% \subsection{\cshn{sind()}, \cshn{cosd()}}
+% \begin{macrocode}
+\xintdeffloatefunc sind(x) := ifsgn(x, if(x>=-45, sin_(x*oneDegree), -sind_(-x)),
+ 0,
+ if(x<=45, sin_(x*oneDegree), sind_(x)));%
+\xintdeffloatefunc cosd(x) := ifsgn(x, if(x>=-45, cos_(x*oneDegree), cosd_(-x)),
+ 1,
+ if(x<=45, cos_(x*oneDegree), cosd_(x)));%
+% \end{macrocode}
+% \subsection{\cshn{sin()}, \cshn{cos()}}
+% \lverb|&
+% For some reason I did not define sin() and cos() in January 2019 ??
+% |
+% \begin{macrocode}
+\xintdeffloatefunc sin(x):= if(abs(x)<0.79, sin_(x),%
+ ifsgn(x, -sind_(-x*oneRadian),
+ 0,
+ sind_(x*oneRadian))
+ );%
+\xintdeffloatefunc cos(x):= if(abs(x)<0.79, cos_(x), cosd_(abs(x*oneRadian)));%
+% \end{macrocode}
+% \subsection{\cshn{sinc()}}
+% \lverb|&
+% Should I also consider adding (1-cos(x))/x^2 ?
+% |
+% \begin{macrocode}
+\xintdeffloatefunc sinc(x):=
+ if(abs(x)<0.79, sin_aux(sqr(x)), sind_(abs(x)*oneRadian)/abs(x));%
+% \end{macrocode}
+% \subsection{\cshn{tan()}, \cshn{tand()}, \cshn{cot()}, \cshn{cotd()}}
+% \lverb|The 0 in cot(x) is a dummy place holder, 1/0 would raise an error at
+% time of definition...|
+% \begin{macrocode}
+\xintdeffloatefunc tand(x):= sind(x)/cosd(x);%
+\xintdeffloatefunc cotd(x):= cosd(x)/sind(x);%
+\xintdeffloatefunc tan(x) := ifsgn(x, if(x>-0.79, sin(x)/cos(x), -cotd(90+x*oneRadian)),
+ 0,
+ if(x<0.79, sin(x)/cos(x), cotd(90-x*oneRadian))
+ );%
+\xintdeffloatefunc cot(x) := if(abs(x)<0.79, cos(x)/sin(x),
+ ifsgn(x, -tand(90+x*oneRadian),
+ 0,
+ tand(90-x*oneRadian))
+ );%
+% \end{macrocode}
+%
+% \subsection{\cshn{sec()}, \cshn{secd()}, \cshn{csc()}, \cshn{cscd()}}
+% \begin{macrocode}
+\xintdeffloatefunc sec(x) := inv(cos(x));%
+\xintdeffloatefunc csc(x) := inv(sin(x));%
+\xintdeffloatefunc secd(x):= inv(cosd(x));%
+\xintdeffloatefunc cscd(x):= inv(sind(x));%
+% \end{macrocode}
+% \subsection{Core routine for inverse trigonometry}
+% \lverb|&
+% Compute asin(x)
+%
+% The approach I shall first describe (which is only a first step towards our
+% final approach) converges quintically but requires an initial square root
+% computation. However, when used for atan(x), we then do not have to do any
+% such square root extraction. See code next.
+%
+% The algorithm (for this first approach): we have 0 <= t < 0.72,
+% let t1 = t*(1+t^2/6). We also have
+% u = sqrt(1 - t^2). We seek a = Arcsin t with t = sin(a).
+%
+% Then t1 < Arcsin t and the difference (we don't know it!) δ_1 is < 0.02.
+% We compute D = t*cos(t1)-u*sin(t1). This computation is done "exactly" via
+% the \xintexpr encapsulation. In other terms we use doubled precision.
+% Anyhow, currently (1.3e) the Float macros of xintfrac.sty for multiplication
+% do go via such exact multiplication when the mantissas have the expected
+% sizes. So we can't gain but only lose due to catastrophic subtraction in
+% using float operations here.
+%
+% Thus D is sin(a-t1) = sin(δ_1). And δ_1 = Arcsin D, but D is small!
+% We then use again two terms of the Arcsin series and define
+% t2 = t1 + D * (1 + D^2/6). Let δ_2 = a - t2. Then δ_2 is of the order of
+% the neglected term 3*(δ_1)^5/40.
+%
+% ©copyright J.F. Burnol, March 30, 2019. This surely has a name.
+%
+% The algorithm is quintically convergent! I must have thought about this some
+% many years ago, but I like it a lot and I found it again on March 30, 2019.
+% One can do the same to go from exp to log. Basically the idea is that we can
+% improve the Newton Method for any function f for which knowing target value
+% of f implies one also knows target value of its derivative. In fact I
+% obtained the quintic algorithm by combining the Newton formula with the one
+% from using f(x)/f'(a) and not f(x)/f'(x) in the update to cancel the two
+% quadratic errors.
+%
+% One iteration (t2) gives about 9 digits, two iterations (t3) 49 digits !
+% And if we want hepta-convergence we only need to use one more term
+% of the Arcsin series in the update of the t_n... really this is very nice.
+%
+% And actually (t2) already gives 30 digits of floating point precision for
+% input t<0.1. Let's confirm this:
+%( > Digits := 60:
+%: > t0 := 0.1; t1 := t0*(1+t0^2/6); u0 := sqrt(1-t0^2); D1 :=t0*cos(t1)-u0*sin(t1);
+%: t0 := 0.1
+%:
+%: t1 := 0.100166666666666666666666666666666666666666666666666666666667
+%:
+%: u0 := 0.994987437106619954734479821001206005178126563676806079117605
+%:
+%: -6
+%: D1 := 0.7544948931296072722324333622021201414040837652959011668 10
+%:
+%: > t2 := t1 + D1*(1+D1^2/6);
+%: t2 := 0.100167421161559796345523179452674980956388959919827205633117
+%:
+%: > a := arcsin(0.1);
+%: a := 0.100167421161559796345523179452693318568675972229629541391024
+%: > t2/a;
+%: 0.999999999999999999999999999999816930374423480281306812814173
+%)
+%
+% Each iteration costs a computation of one cos and one sine done at the full
+% final precision. This is stupid because we should compute at an evolving
+% precision, but anyhow this is not our problem anymore as our final algorithm
+% is not a loop but it does exactly one iteration for all inputs. As
+% examplified above it remains true that we could improve its speed for small
+% inputs by using shorter auxiliary series (see below).
+%
+% In January I used a loop via an iter() construct, with some subs() to avoid
+% repeating computations. This can only be done in an \xintNewFunction. Here
+% is how it looked after some optimization for the stopping criteria, after
+% replacing generic Newton algorithm by a specific quintic one for arcsine:
+%
+%( \begingroup
+%: \edef\x{\endgroup
+%: \noexpand\xintNewFunction{asin_l}[2]{%
+%: iter(##1*(1+sqr(##1)/6);%
+%: $% FIXME : réfléchir au critère d'arrêt.
+%: $%
+%: $% Je n'utilise pas abs(D) pour un micro-gain est-ce que le risque en vaut la
+%: $% chandelle ? (avec abs(D) on pourrait utiliser la fonction avec un #1 négatif)
+%: $%
+%: $% Am I sure rounding errors could not cause neverending loop?
+%: $% Such things should be done with increased precision and rounded at end.
+%: subs((D<\ifcase\numexpr2+\XINTdigits-5*(\XINTdigits/5)\relax
+%: 3.68\or2.32\or1.47\or0.923\or0.582\fi
+%: e-\the\numexpr\XINTdigits/5\relax)%
+%: ?{break(@+D*(1+sqr(D)/6))}{@+D*(1+sqr(D)/6)},%
+%: D=\noexpand\xintexpr
+%: subs(##1*cos_aux(X) - ##2*@*sin_aux(X), X=sqr(@))%
+%: \relax
+%: ),%
+%: i=1++)% dummy iteration index, not used but needed by iter()
+%: }}\x
+%)
+%
+% I don't have time to explain the final algorithm below and how the
+% transition values were chosen or why (the series below is enough up to 59
+% digits of precision). It does only one iteration, in all cases. Using it for
+% arcsine requires a preliminary square root extraction, but for arctangent
+% one can arrange things as I did in order to avoid having to compute a square
+% root!
+%
+%
+% ©copyright J.F. Burnol, April 5, 2019. This surely has a name.
+%
+% Certainly I can do similar things to compute logarithms.
+% |
+% \begin{macrocode}
+\xintdeffloatefunc asin_aux(X) := 1
+\ifnum\XINTdigits>3 % actually 4 would achieve 1ulp in place of <0.5ulp
+ + X(1/6
+\ifnum\XINTdigits>9
+ + X(3/40
+\ifnum\XINTdigits>16
+ + X(5/112
+\ifnum\XINTdigits>25
+ + X(35/1152
+\ifnum\XINTdigits>35
+ + X(63/2816
+\ifnum\XINTdigits>46
+ + X(231/13312
+ )\fi)\fi)\fi)\fi)\fi)\fi;%
+\xintdeffloatefunc asin_o(D, T) := T + D*asin_aux(sqr(D));%
+\xintdeffloatefunc asin_n(V, T, t, u) :=% V is square of T
+ asin_o (\xintexpr t*cos_aux(V) - u*T*sin_aux(V)\relax, T);%
+\xintdeffloatefunc asin_m(T, t, u) := asin_n(sqr(T), T, t, u);%
+\xintdeffloatefunc asin_l(t, u) := asin_m(t*asin_aux(sqr(t)), t, u);%
+% \end{macrocode}
+% \subsection{\cshn{asin()}, \cshn{asind()}}
+% \lverb|&
+% Only non-negative arguments t and u for asin_a(t,u), and asind_a(t,u).
+% |
+% \begin{macrocode}
+\xintdeffloatefunc asin_a(t, u) :=
+ if(t<u, asin_l(t, u), Piover2 - asin_l(u, t));%
+\xintdeffloatefunc asind_a(t, u):=
+ if(t<u, asin_l(t, u) * oneRadian, 90 - asin_l(u, t) * oneRadian);%
+\xintdeffloatefunc asin(t) := ifsgn(t, -asin_a(-t, sqrt(1-sqr(t))),
+ 0,
+ asin_a(t, sqrt(1-sqr(t))));%
+\xintdeffloatefunc asind(t) := ifsgn(t, -asind_a(-t, sqrt(1-sqr(t))),
+ 0,
+ asind_a(t, sqrt(1-sqr(t))));%
+% \end{macrocode}
+% \subsection{\cshn{acos()}, \cshn{acosd()}}
+% \begin{macrocode}
+\xintdeffloatefunc acos(t) := Piover2 - asin(t);%
+\xintdeffloatefunc acosd(t):= 90 - asind(t);%
+% \end{macrocode}
+% \subsection{\cshn{atan()}, \cshn{atand()}}
+% \lverb|&
+% This involves no square root!
+%
+% TeX hackers note 1:
+%
+% The subs( , x = ..) mechanism has no utility in a function definition,
+% there is no parallel mechanism at the underlying macros, so in fact
+% the substituted things will remain unevaluated if they involve
+% indeterminates, so this is exactly like not trying to make things
+% more efficient at all.
+%
+% Currently, the only way is thus to employ auxiliary functions like is done
+% next. Contrarily to TeX macros, we must define the functions one after the
+% other in the correct order, so the auxiliaries come first.
+%
+% TeX hackers note 2:
+%
+% The if(,,) and ifsgn(,,,) tests when used numerically compute all ; but when
+% used into a \xintdeffloatefunc, they are converted to macros with basically
+% \firstofthree, \secondofthree, \thirdofthree behaviour so then only the
+% actually executed branch will do computations.
+%
+% For numeric computations the ? and ?? operators are used for this effect,
+% but they can not be used in \xintdeffloatefunc if the test involves unknown
+% variables; as explained above fortunately then if(,,) and ifsgn(,,) work.
+%
+% radians
+% |
+% \begin{macrocode}
+\xintdeffloatefunc atan_b(t, w, z):=%
+ 0.5 * if(w< 0, Pi - asin_a(2z * t, -w*z), asin_a(2z * t, w*z));%
+\xintdeffloatefunc atan_a(t, T) := atan_b(t, 1-T, inv(1+T));%
+\xintdeffloatefunc atan(t):= ifsgn(t,-atan_a(-t, sqr(t)), 0, atan_a(t, sqr(t)));%
+% \end{macrocode}
+% \lverb|&
+% degrees
+% |
+% \begin{macrocode}
+\xintdeffloatefunc atand_b(t, w, z) :=
+ 0.5 * if(w< 0, 180 - asind_a(2z * t, -w*z), asind_a(2z * t, w*z));%
+\xintdeffloatefunc atand_a(t, T) := atand_b(t, 1-T, inv(1+T));%
+\xintdeffloatefunc atand(t):= ifsgn(t,-atand_a(-t, sqr(t)), 0, atand_a(t, sqr(t)));%
+% \end{macrocode}
+% \subsection{\cshn{Arg()}, \cshn{atan2()}, \cshn{Argd()}, \cshn{atan2d()}, \cshn{pArg()}, \cshn{pArgd()}}
+% \lverb|&
+% Arg(x,y) function from -π (excluded) to +π (included)
+% |
+% \begin{macrocode}
+\xintdeffloatefunc Arg(x, y):=
+ if(y>x,
+ if(y>-x, Piover2 - atan(x/y),
+ if(y<0, -Pi + atan(y/x), Pi + atan(y/x))),
+ if(y>-x, atan(y/x), -Piover2 + atan(x/-y))
+ );%
+% \end{macrocode}
+% \lverb|&
+% atan2(y,x) = Arg(x,y) ... (some people have atan2 with arguments reversed
+% but the convention here seems the most often encountered)
+% |
+% \begin{macrocode}
+\xintdeffloatefunc atan2(y,x) := Arg(x, y);%
+% \end{macrocode}
+% \lverb|&
+% Argd(x,y) function from -180 (excluded) to +180 (included)
+% |
+% \begin{macrocode}
+\xintdeffloatefunc Argd(x, y):=
+ if(y>x,
+ if(y>-x, 90 - atand(x/y),
+ if(y<0, -180 + atand(y/x), 180 + atand(y/x))),
+ if(y>-x, atand(y/x), -90 + atand(x/-y))
+ );%
+% \end{macrocode}
+% \lverb|&
+% atan2d(y,x) = Argd(x,y)
+% |
+% \begin{macrocode}
+\xintdeffloatefunc atan2d(y,x) := Argd(x, y);%
+% \end{macrocode}
+% \lverb|&
+% pArg(x,y) function from 0 (included) to 2π (excluded)
+% I hesitated between pArg, Argpos, and Argplus. Opting for pArg in the end.
+% |
+% \begin{macrocode}
+\xintdeffloatefunc pArg(x, y):=
+ if(y>x,
+ if(y>-x, Piover2 - atan(x/y), Pi + atan(y/x)),
+ if(y>-x, if(y<0, twoPi + atan(y/x), atan(y/x)),
+ threePiover2 + atan(x/-y))
+ );%
+% \end{macrocode}
+% \lverb|&
+% pArgd(x,y) function from 0 (included) to 360 (excluded)
+% |
+% \begin{macrocode}
+\xintdeffloatefunc pArgd(x, y):=
+ if(y>x,
+ if(y>-x, 90 - atan(x/y)*oneRadian, 180 + atan(y/x)*oneRadian),
+ if(y>-x, if(y<0, 360 + atan(y/x)*oneRadian, atan(y/x)*oneRadian),
+ 270 + atan(x/-y)*oneRadian)
+ );%
+% \end{macrocode}
+% \subsection{Synonyms: \cshn{tg()}, \cshn{cotg()}}
+% \lverb|These are my childhood notations and I am attached to them. In
+% radians only. We skip some overhead here by using a \let at core level.|
+% \begin{macrocode}
+\expandafter\let\csname XINT_flexpr_func_tg\expandafter\endcsname
+ \csname XINT_flexpr_func_tan\endcsname
+\expandafter\let\csname XINT_flexpr_func_cotg\expandafter\endcsname
+ \csname XINT_flexpr_func_cot\endcsname
+% \end{macrocode}
+% \subsection{Let the functions be known to the \cshnolabel{xintexpr} parser}
+% \lverb|See xint.pdf for some explanations (as well as code comments in
+% xintexpr.sty). In fact it is this context which led to my addition at 1.3e of
+% \xintdefefunc to the \xintexpr syntax. |
+% \begin{macrocode}
+\xintFor #1 in {sin, cos, tan, sec, csc, cot,
+ asin, acos, atan}\do
+{%
+ \xintdefefunc #1(x) := \xintfloatexpr #1(sfloat(x))\relax;%
+ \xintdefefunc #1d(x):= \xintfloatexpr #1d(sfloat(x))\relax;%
+}%
+\xintFor #1 in {Arg, pArg, atan2}\do
+{%
+ \xintdefefunc #1(x, y) := \xintfloatexpr #1(sfloat(x), sfloat(y))\relax;%
+ \xintdefefunc #1d(x, y):= \xintfloatexpr #1d(sfloat(x), sfloat(y))\relax;%
+}%
+\xintdefefunc tg(x) := \xintfloatexpr tg(sfloat(x))\relax;%
+\xintdefefunc cotg(x):= \xintfloatexpr cotg(sfloat(x))\relax;%
+\xintdefefunc sinc(x):= \xintfloatexpr sinc(sfloat(x))\relax;%
+% \end{macrocode}
+% \lverb|Restore used dummy variables to their status prior to the package reloading.
+% On first loading this is not needed naturally, because this is done
+% immediately at end of xintexpr.sty.|
+% \begin{macrocode}
+\xintFor* #1 in {iDTVtuwxyzX}\do{\xintrestorelettervar{#1}}%
+% \end{macrocode}
+% \StoreCodelineNo {xinttrig}
+% \cleardoublepage\let\xinttrignameUp\undefined
+%\gardesactifs
+%\let</xinttrig>\relax
+%\let<*xintlog>\gardesinactifs
+%</xinttrig>^^A--------------------------------------------------
+%<*xintlog>^^A---------------------------------------------------
+%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*-
+% \clearpage\csname xintlognameUp\endcsname
+% \section{Package \xintlognameimp implementation}
+% \RaisedLabel{sec:logimp}
+% \etocarticlestylenomarks
+% \etocsetnexttocdepth {subsubsection}
+%
+% \localtableofcontents
+%
+% \etocsettocstyle{}{}
+%
+% I almost included extended precision implementation for 1.3e but
+% was a bit short on time; besides I hesitated between using poormanlog
+% at starting point or not. For up to 50 digits, it would help reduce
+% considerably the needed series for the logarithm. For more digits
+% I should rather apply my copyrighted method of the arcsine (it must
+% be in literature).
+%
+% \subsection{Catcodes, \protect\eTeX{} and reload detection}
+% \begin{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+ \catcode13=5 % ^^M
+ \endlinechar=13 %
+ \catcode123=1 % {
+ \catcode125=2 % }
+ \catcode64=11 % @
+ \catcode35=6 % #
+ \catcode44=12 % ,
+ \catcode45=12 % -
+ \catcode46=12 % .
+ \catcode58=12 % :
+ \catcode94=7 % ^
+ \def\z{\endgroup}%
+ \def\empty{}\def\space{ }\newlinechar10
+ \expandafter\let\expandafter\w\csname ver@xintexpr.sty\endcsname
+ \expandafter\let\expandafter\x\csname ver@xintlog.sty\endcsname
+ \expandafter
+ \ifx\csname PackageInfo\endcsname\relax
+ \def\y#1#2{\immediate\write-1{Package #1 Info:^^J%
+ \space\space\space\space#2.}}%
+ \else
+ \def\y#1#2{\PackageInfo{#1}{#2}}%
+ \fi
+ \expandafter
+ \ifx\csname numexpr\endcsname\relax
+ \y{xintlog}{\numexpr not available, aborting input}%
+ \aftergroup\endinput
+ \else
+ \ifx\w\relax % xintexpr.sty not yet loaded.
+ \y{xintlog}%
+ {Loading should be via \ifx\x\empty\string\usepackage{xintexpr.sty}
+ \else\string\input\space xintexpr.sty \fi
+ rather, aborting}%
+ \aftergroup\endinput
+ \else
+ \ifx\x\relax % first loading (initiated from xintexpr.sty)
+ \else
+ \ifx\x\empty % LaTeX first loading, \ProvidesPackage not yet seen
+ \else
+ \y{xintlog}{Already loaded, aborting}%
+ \aftergroup\endinput
+ \fi
+ \fi
+ \fi
+ \fi
+\z%
+% \end{macrocode}
+% \lverb|Attention to catcode regime when loading below poormanlog. It (v0.04)
+% uses ^ with its normal catcode but \XINT_setcatcodes would set it to letter.
+%
+% This file can only be loaded from xintexpr.sty and it restores catcodes near
+% its end. To play it safe and be hopefully immune to whatever is done in
+% poormanlog or in xinttrig.sty which is loaded before, we will switch to
+% standard catcode regime here.
+%
+% As I learned the hard way (I never use my user macros), at the worst moment
+% when wrapping up the final things for 1.3e release,
+% \xintexprSafeCatcodes MUST be followed by some \xintexprRestoreCatcodes
+% quickly, else next time it is used (for example by \xintdefvar) the
+% \xintexprRestoreCatcodes will restore an obsolete catcode regime...|
+% \subsection{Library identification}
+% \begin{macrocode}
+\xintexprSafeCatcodes\catcode`_ 11
+\XINT_providespackage
+\ProvidesPackage{xintlog}%
+[2019/04/05 1.3e Logarithms and exponentials for xintexpr (JFB)]%
+% \end{macrocode}
+% \subsection{Loading of \cshn{poormanlog} package}
+% \lverb|Attention to catcode regime when loading poormanlog.|
+% \begin{macrocode}
+\ifdefined\RequirePackage
+ \RequirePackage{poormanlog}%
+\else
+ \input poormanlog.tex
+\fi
+% \end{macrocode}
+% \lverb|\XINT_setcatcodes switches to the standard catcode regime of
+% xint*.sty files. And we need the xintexpr catcode for ! too.
+%
+% See remark above about \xintexprRestoreCatcodes.|
+% \begin{macrocode}
+\xintexprRestoreCatcodes\csname XINT_setcatcodes\endcsname\catcode`\! 11
+% \end{macrocode}
+% \subsection{Support macros for natural logarithm and exponential}
+% \begin{macrocode}
+\def\xintLog#1{\xintMul{\PoorManLogBaseTen{#1}}{23025850923[-10]}}%
+\def\XINTinFloatLog#1{\XINTinFloatMul{\PoorManLogBaseTen{#1}}{23025850923[-10]}}%
+\def\xintExp#1{\PoorManPowerOfTen{\xintMul{#1}{434294481903[-12]}}}%
+\def\XINTinFloatExp#1{\PoorManPowerOfTen{\XINTinFloatMul{#1}{434294481903[-12]}}}%
+% \end{macrocode}
+% \subsection{The \cshn{log()}, \cshn{exp()}, and \cshn{pow()} function}
+% \lverb|The log10() and pow10() are already defined by poormanlog.|
+% \begin{macrocode}
+\def\XINT_expr_func_log #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintLog{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_flexpr_func_log #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\XINTinFloatLog{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_exp #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintExp{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_flexpr_func_exp #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\XINTinFloatExp{\XINT_expr_unlock #3}\endcsname
+}%
+\def\XINT_expr_func_pow #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \expandafter\XINT:NEhook:twosp
+ \romannumeral`&&@\XINT_expr_unlock #3,!\PoorManPower
+ \endcsname
+}%
+\let\XINT_flexpr_func_pow\XINT_expr_func_pow
+% \end{macrocode}
+% \lverb|We don't worry about setting catcodes as this file is theoretically
+% only loadable from xintexpr.sty itself.|
+% \StoreCodelineNo {xintlog}
+% \cleardoublepage\let\xintlognameUp\undefined
+% \MakePercentComment
+%</xintlog>------------------------------------------------------
+%<*dtx>-----------------------------------------------------------
+\iffalse
+% grep -c -e "^{%" xint*sty
+xint.sty:190
+xintbinhex.sty:53
+xintcfrac.sty:183
+xintcore.sty:274
+xintexpr.sty:285
+xintfrac.sty:468
+xintgcd.sty:48
+xintkernel.sty:15
+xintlog.sty:5
+xintseries.sty:48
+xinttools.sty:140
+xinttrig.sty:31
+\fi
+% grep -o "^{%" xint*sty | wc -l
+\def\totala{ 1740}
+\iffalse
+% grep -c -e "^}%" xint*sty
+xint.sty:189
+xintbinhex.sty:52
+xintcfrac.sty:183
+xintcore.sty:271
+xintexpr.sty:312
+xintfrac.sty:470
+xintgcd.sty:50
+xintkernel.sty:16
+xintlog.sty:5
+xintseries.sty:48
+xinttools.sty:139
+xinttrig.sty:32
+\fi
+% grep -o "^}%" xint*sty | wc -l
+\def\totalb{ 1767}
+\cleardoublepage
+\section{Cumulative line count}
+
+\def\mymacro #1{\mymacroaux #1}
+\def\mymacroaux #1#2{\strut \csname #1nameimp\endcsname:& \dtt{ #2.}\tabularnewline }
+\indent
+\begin{tabular}[t]{r@{}r}
+\xintApplyInline\mymacro\storedlinecounts
+\end{tabular}
+\def\mymacroaux #1#2{#2}%
+%
+\parbox[t]{10cm}{Total number of code lines:
+ \dtt{\the\numexpr
+ \xintListWithSep+{\xintApply\mymacro\storedlinecounts}\relax }.
+ \ifdefined\totala
+ (but \dtt{\the\numexpr \totala+\totalb\relax} lines among them
+ start either with \{\% or with \}\%.)\fi
+
+ Each package starts with circa \dtt{50} lines dealing with catcodes,
+ package identification and reloading management, also for Plain
+ \TeX\strut. Version {\xintbndlversion} of {\xintbndldate}.\par
+}
+
+\CheckSum {33274}% 1.3e
+% 31601 pour 1.3d, 31122 pour 1.3c
+% 31069 pour 1.3b, 30482 pour 1.3a, 30621 pour 1.3, 30988 pour 1.2q,
+% 30982 pour 1.2p, 30524 pour 1.2o, 30303 pour 1.2h, 30403 pour 1.2i,
+% 30750 pour 1.2j, 30677 pour 1.2k, 30931 pour 1.2l, 30439 pour 1.2m,
+% 30253 pour 1.2n
+\makeatletter\check@checksum
+\Finale
+%% End of file xint.dtx