summaryrefslogtreecommitdiff
path: root/macros/generic/xint
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
Initial commit
Diffstat (limited to 'macros/generic/xint')
-rw-r--r--macros/generic/xint/CHANGES.html833
-rw-r--r--macros/generic/xint/CHANGES.pdfbin0 -> 104210 bytes
-rw-r--r--macros/generic/xint/Makefile20
-rw-r--r--macros/generic/xint/README205
-rw-r--r--macros/generic/xint/README.html133
-rw-r--r--macros/generic/xint/README.pdfbin0 -> 32957 bytes
-rw-r--r--macros/generic/xint/sourcexint.pdfbin0 -> 919178 bytes
-rw-r--r--macros/generic/xint/xint.dtx40510
-rw-r--r--macros/generic/xint/xint.pdfbin0 -> 987296 bytes
9 files changed, 41701 insertions, 0 deletions
diff --git a/macros/generic/xint/CHANGES.html b/macros/generic/xint/CHANGES.html
new file mode 100644
index 0000000000..5eddbff512
--- /dev/null
+++ b/macros/generic/xint/CHANGES.html
@@ -0,0 +1,833 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
+<head>
+ <meta charset="utf-8" />
+ <meta name="generator" content="pandoc" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
+ <meta name="author" content="xint 1.3e" />
+ <title>CHANGE LOG</title>
+ <style type="text/css">
+ code{white-space: pre-wrap;}
+ span.smallcaps{font-variant: small-caps;}
+ span.underline{text-decoration: underline;}
+ div.column{display: inline-block; vertical-align: top; width: 50%;}
+ </style>
+ <style type="text/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;}
+ </style>
+ <!--[if lt IE 9]>
+ <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
+ <![endif]-->
+</head>
+<body>
+<header>
+<h1 class="title">CHANGE LOG</h1>
+<p class="author">xint 1.3e</p>
+<p class="date">2019/04/05</p>
+</header>
+<nav id="TOC">
+<ul>
+<li><a href="#e-20190405"><code>1.3e (2019/04/05)</code></a><ul>
+<li><a href="#incompatible-changes">Incompatible changes</a></li>
+<li><a href="#improvements-and-new-features">Improvements and new features</a></li>
+<li><a href="#bug-fixes">Bug fixes</a></li>
+</ul></li>
+<li><a href="#d-20190106"><code>1.3d (2019/01/06)</code></a><ul>
+<li><a href="#incompatible-changes-1">Incompatible changes</a></li>
+<li><a href="#improvements-and-new-features-1">Improvements and new features</a></li>
+<li><a href="#bug-fixes-1">Bug fixes</a></li>
+</ul></li>
+<li><a href="#c-20180617"><code>1.3c (2018/06/17)</code></a><ul>
+<li><a href="#improvements-and-new-features-2">Improvements and new features</a></li>
+<li><a href="#bug-fixes-2">Bug fixes</a></li>
+</ul></li>
+<li><a href="#b-20180518"><code>1.3b (2018/05/18)</code></a><ul>
+<li><a href="#improvements-and-new-features-3">Improvements and new features</a></li>
+</ul></li>
+<li><a href="#a-20180307"><code>1.3a (2018/03/07)</code></a><ul>
+<li><a href="#removed">Removed</a></li>
+<li><a href="#improvements-and-new-features-4">Improvements and new features</a></li>
+<li><a href="#bug-fixes-3">Bug fixes</a></li>
+</ul></li>
+<li><a href="#section"><code>1.3 (2018/03/01)</code></a><ul>
+<li><a href="#incompatible-changes-2">Incompatible changes</a></li>
+<li><a href="#improvements-and-new-features-5">Improvements and new features</a></li>
+</ul></li>
+<li><a href="#q-20180206"><code>1.2q (2018/02/06)</code></a><ul>
+<li><a href="#improvements-and-new-features-6">Improvements and new features</a></li>
+<li><a href="#bug-fixes-4">Bug fixes</a></li>
+</ul></li>
+<li><a href="#p-20171205"><code>1.2p (2017/12/05)</code></a><ul>
+<li><a href="#incompatible-changes-3">Incompatible changes</a></li>
+<li><a href="#improvements-and-new-features-7">Improvements and new features</a></li>
+<li><a href="#bug-fixes-5">Bug fixes</a></li>
+</ul></li>
+<li><a href="#o-20170829"><code>1.2o (2017/08/29)</code></a><ul>
+<li><a href="#incompatible-changes-4">Incompatible changes</a></li>
+<li><a href="#deprecated">Deprecated</a></li>
+</ul></li>
+<li><a href="#n-20170806"><code>1.2n (2017/08/06)</code></a><ul>
+<li><a href="#incompatible-changes-5">Incompatible changes</a></li>
+<li><a href="#improvements-and-new-features-8">Improvements and new features</a></li>
+</ul></li>
+<li><a href="#m-20170731"><code>1.2m (2017/07/31)</code></a><ul>
+<li><a href="#incompatible-changes-6">Incompatible changes</a></li>
+<li><a href="#improvements-and-new-features-9">Improvements and new features</a></li>
+<li><a href="#bug-fixes-6">Bug fixes</a></li>
+</ul></li>
+<li><a href="#l-20170726"><code>1.2l (2017/07/26)</code></a><ul>
+<li><a href="#removed-1">Removed</a></li>
+<li><a href="#improvements-and-new-features-10">Improvements and new features</a></li>
+<li><a href="#bug-fixes-7">Bug fixes</a></li>
+</ul></li>
+<li><a href="#k-20170106"><code>1.2k (2017/01/06)</code></a><ul>
+<li><a href="#incompatible-changes-7">Incompatible changes</a></li>
+<li><a href="#improvements-and-new-features-11">Improvements and new features</a></li>
+<li><a href="#bug-fixes-8">Bug fixes</a></li>
+</ul></li>
+<li><a href="#j-20161222"><code>1.2j (2016/12/22)</code></a><ul>
+<li><a href="#improvements-and-new-features-12">Improvements and new features</a></li>
+<li><a href="#bug-fixes-9">Bug fixes</a></li>
+</ul></li>
+<li><a href="#i-20161213"><code>1.2i (2016/12/13)</code></a><ul>
+<li><a href="#incompatible-changes-8">Incompatible changes</a></li>
+<li><a href="#removed-2">Removed</a></li>
+<li><a href="#improvements-and-new-features-13">Improvements and new features</a></li>
+<li><a href="#bug-fixes-10">Bug fixes</a></li>
+</ul></li>
+<li><a href="#h-20161120"><code>1.2h (2016/11/20)</code></a><ul>
+<li><a href="#improvements-and-new-features-14">Improvements and new features</a></li>
+<li><a href="#bug-fixes-11">Bug fixes</a></li>
+</ul></li>
+<li><a href="#g-20160319"><code>1.2g (2016/03/19)</code></a><ul>
+<li><a href="#incompatible-changes-9">Incompatible changes</a></li>
+<li><a href="#improvements-and-new-features-15">Improvements and new features</a></li>
+</ul></li>
+<li><a href="#f-20160312"><code>1.2f (2016/03/12)</code></a><ul>
+<li><a href="#incompatible-changes-10">Incompatible changes</a></li>
+<li><a href="#improvements-and-new-features-16">Improvements and new features</a></li>
+<li><a href="#bug-fixes-12">Bug fixes</a></li>
+</ul></li>
+<li><a href="#e-20151122"><code>1.2e (2015/11/22)</code></a><ul>
+<li><a href="#improvements-and-new-features-17">Improvements and new features</a></li>
+<li><a href="#bug-fixes-13">Bug fixes</a></li>
+</ul></li>
+<li><a href="#d-20151118"><code>1.2d (2015/11/18)</code></a><ul>
+<li><a href="#improvements-and-new-features-18">Improvements and new features</a></li>
+<li><a href="#bug-fixes-14">Bug fixes</a></li>
+</ul></li>
+<li><a href="#c-20151116"><code>1.2c (2015/11/16)</code></a><ul>
+<li><a href="#improvements-and-new-features-19">Improvements and new features</a></li>
+<li><a href="#bug-fixes-15">Bug fixes</a></li>
+</ul></li>
+<li><a href="#b-20151029"><code>1.2b (2015/10/29)</code></a><ul>
+<li><a href="#bug-fixes-16">Bug fixes</a></li>
+</ul></li>
+<li><a href="#a-20151019"><code>1.2a (2015/10/19)</code></a><ul>
+<li><a href="#improvements-and-new-features-20">Improvements and new features</a></li>
+<li><a href="#bug-fixes-17">Bug fixes</a></li>
+</ul></li>
+<li><a href="#section-1"><code>1.2 (2015/10/10)</code></a><ul>
+<li><a href="#removed-3">Removed</a></li>
+<li><a href="#improvements-and-new-features-21">Improvements and new features</a></li>
+</ul></li>
+<li><a href="#c-20150912"><code>1.1c (2015/09/12)</code></a></li>
+<li><a href="#b-20150831"><code>1.1b (2015/08/31)</code></a></li>
+<li><a href="#a-20141107"><code>1.1a (2014/11/07)</code></a></li>
+<li><a href="#section-2"><code>1.1 (2014/10/28)</code></a><ul>
+<li><a href="#incompatible-changes-11">Incompatible changes</a></li>
+<li><a href="#removed-4">Removed</a></li>
+<li><a href="#deprecated-1">Deprecated</a></li>
+<li><a href="#improvements-and-new-features-22">Improvements and new features</a></li>
+<li><a href="#bug-fixes-18">Bug fixes</a></li>
+</ul></li>
+<li><a href="#n-20140401"><code>1.09n (2014/04/01)</code></a></li>
+<li><a href="#m-20140226"><code>1.09m (2014/02/26)</code></a></li>
+<li><a href="#kb-20140213"><code>1.09kb (2014/02/13)</code></a></li>
+<li><a href="#k-20140121"><code>1.09k (2014/01/21)</code></a></li>
+<li><a href="#j-20140109"><code>1.09j (2014/01/09)</code></a></li>
+<li><a href="#i-20131218"><code>1.09i (2013/12/18)</code></a></li>
+<li><a href="#h-20131128"><code>1.09h (2013/11/28)</code></a></li>
+<li><a href="#g-20131122"><code>1.09g (2013/11/22)</code></a></li>
+<li><a href="#f-20131104"><code>1.09f (2013/11/04)</code></a></li>
+<li><a href="#e-20131029"><code>1.09e (2013/10/29)</code></a></li>
+<li><a href="#d-20131022"><code>1.09d (2013/10/22)</code></a></li>
+<li><a href="#c-20131009"><code>1.09c (2013/10/09)</code></a></li>
+<li><a href="#b-20131003"><code>1.09b (2013/10/03)</code></a></li>
+<li><a href="#a-20130924"><code>1.09a (2013/09/24)</code></a></li>
+<li><a href="#b-20130614"><code>1.08b (2013/06/14)</code></a></li>
+<li><a href="#a-20130611"><code>1.08a (2013/06/11)</code></a></li>
+<li><a href="#section-3"><code>1.08 (2013/06/07)</code></a></li>
+<li><a href="#section-4"><code>1.07 (2013/05/25)</code></a></li>
+<li><a href="#b-20130514"><code>1.06b (2013/05/14)</code></a></li>
+<li><a href="#section-5"><code>1.06 (2013/05/07)</code></a></li>
+<li><a href="#section-6"><code>1.05 (2013/05/01)</code></a></li>
+<li><a href="#section-7"><code>1.04 (2013/04/25)</code></a></li>
+<li><a href="#section-8"><code>1.03 (2013/04/14)</code></a></li>
+<li><a href="#section-9"><code>1.0 (2013/03/28)</code></a></li>
+</ul>
+</nav>
+<pre><code>Source: xint.dtx 1.3e 2019/04/05 (doc 2019/04/05)
+Author: Jean-Francois Burnol
+Info: Expandable operations on big integers, decimals, fractions
+License: LPPL 1.3e</code></pre>
+<h2 id="e-20190405"><code>1.3e (2019/04/05)</code></h2>
+<h3 id="incompatible-changes">Incompatible changes</h3>
+<ul>
+<li>When defining functions, sub-expressions can only use the <code>\xint(float)expr...\relax</code> syntax. One can <em>not</em> use there the <code>\xint(float)eval</code> wrappers (anyhow they add overhead and can be replaced with the lower level syntax).</li>
+</ul>
+<h3 id="improvements-and-new-features">Improvements and new features</h3>
+<ul>
+<li>The <strong>xinttrig</strong> library is automatically loaded by <strong>xintexpr</strong>. 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).</li>
+<li>The <strong>xintlog</strong> library is automatically loaded by <strong>xintexpr</strong>. It uses <a href="http://ctan.org/pkg/poormanlog">poormanlog</a> to provide logarithms and exponentials with almost 9 digits of precision. Extended precision is for a future release.</li>
+<li><p><strong>xintexpr</strong>: <code>\xintdefefunc</code>, <code>\xintdeffloatefunc</code>, <code>\xintdefiiefunc</code> define functions which are not protected against expansion in the definition of other functions; refer to <code>xint.pdf</code> for the related explanations.</p>
+Notice that whole area of <code>\xintdef(e)func</code>, <code>\xintNewExpr</code>, <code>\xintNewFunction</code> is complex and to be considered still as work in progress as it has a number of shortcomings.</li>
+<li><strong>xintexpr</strong>: <code>inv()</code>, <code>ilog10()</code>, <code>sfloat()</code>, behaviour of <code>qfloat()</code> slightly modified.</li>
+<li><strong>xintexpr</strong>: <code>\xintensuredummy</code>, <code>\xintrestorelettervar</code>.</li>
+<li><p>The optional argument of <code>\xintfloatexpr</code> or <code>\xintfloateval</code> (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.</p></li>
+</ul>
+<h3 id="bug-fixes">Bug fixes</h3>
+<ul>
+<li>Some bugfixes related to user functions with no variables at all; they were dysfunctional.</li>
+</ul>
+<h2 id="d-20190106"><code>1.3d (2019/01/06)</code></h2>
+<h3 id="incompatible-changes-1">Incompatible changes</h3>
+<ul>
+<li><p><strong>xintexpr</strong>: the <code>gcd()</code> and <code>lcm()</code> functions formerly converted their arguments to integers via <code>\xintNum</code>. They now handle general input with no such modification.</p></li>
+<li><p><strong>xintexpr</strong>: former <code>\xinteval</code>, <code>\xintieval</code>, <code>\xintiieval</code>, and <code>\xintfloateval</code> renamed to <code>\xintexpro</code>, <code>\xintiexpro</code>, <code>\xintiiexpro</code>, and <code>\xintfloatexpro</code>.</p></li>
+</ul>
+<h3 id="improvements-and-new-features-1">Improvements and new features</h3>
+<ul>
+<li><p><strong>xintexpr</strong>: the <code>gcd()</code> and <code>lcm()</code> multi-arguments functions have been refactored to handle general fractions. The dependency on <strong>xintgcd</strong> is removed.</p></li>
+<li><p><strong>xintexpr</strong>: three-way branching <code>\xintifsgnexpr</code>, <code>\xintifsgnfloatexpr</code>, <code>\xintifsgniiexpr</code> conditional macros.</p></li>
+<li><p><strong>xintexpr</strong>: <code>\xintunassignexprfunc</code>, <code>\xintunassigniiexprfunc</code>, <code>\xintunassignfloatexprfunc</code> to “undefine” functions.</p></li>
+<li><p><strong>xintexpr</strong>: <code>\xintunassignvar</code> really makes the (multi-letter) variable unknown (formerly, it only gave it value zero),</p></li>
+<li><p><strong>xintexpr</strong>: functions <code>isone()</code> and <code>isint()</code>.</p></li>
+<li><p><strong>xintexpr</strong>: <code>\xinteval</code>, <code>\xintieval</code>, <code>\xintiieval</code>, and <code>\xintfloateval</code> as synonyms to <code>\xinttheexpr...\relax</code> etc…, but with the (comma-separated) expression as a usual braced macro argument.</p></li>
+</ul>
+<h3 id="bug-fixes-1">Bug fixes</h3>
+<ul>
+<li><strong>xintcore</strong>, <strong>xintexpr</strong> : division in <code>\xintiiexpr</code> was broken for a zero dividend and a one-digit divisor (e.g. <code>0//7</code>) since <code>1.2p</code> due to a bug in <code>\xintiiDivMod</code> for such arguments. The bug was signaled (thanks to Kpym for report) and fixed shortly after <code>1.3c</code> release but I then completely forgot to upload a bugfix release to CTAN at that time, apologies for that.</li>
+</ul>
+<h2 id="c-20180617"><code>1.3c (2018/06/17)</code></h2>
+<h3 id="improvements-and-new-features-2">Improvements and new features</h3>
+<ul>
+<li><p><strong>xintexpr</strong>: with <code>\xintglobaldefstrue</code>, <code>\xintdefvar</code>, <code>\xintdeffunc</code>, <code>\xintNewExpr</code> et al. make definitions with global scope.</p></li>
+<li><p><strong>xintexpr</strong>: <code>qraw()</code> for fast input of (very many) comma separated numbers (in suitable raw format).</p></li>
+<li><p><strong>xintexpr</strong>: the colon in the <code>:=</code> part of the syntax for <code>\xintdefvar</code> and variants is now optional; and if present it may be an active character or have any (reasonable) catcode.</p></li>
+<li><p><strong>xintexpr</strong>: <code>\xintdefvar</code>, <code>\xintdeffunc</code> 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.</p></li>
+<li><p><code>\xintUniformDeviate</code> is better documented and <code>sourcexint.pdf</code> is better hyperlinked and includes indices for the macros defined by each package.</p></li>
+</ul>
+<h3 id="bug-fixes-2">Bug fixes</h3>
+<ul>
+<li><strong>xintfrac</strong>: since <code>1.3</code> release, it loaded <strong>xintgcd</strong> in contradiction to what the documentation says (hence also <strong>xintexpr</strong> loaded <strong>xintgcd</strong> automatically). There is no actual dependency so the loading is removed for now.</li>
+</ul>
+<h2 id="b-20180518"><code>1.3b (2018/05/18)</code></h2>
+<h3 id="improvements-and-new-features-3">Improvements and new features</h3>
+<p>All additions related to randomness are marked as work-in-progress. They require an engine providing the <code>\(pdf)uniformdeviate</code> primitive.</p>
+<ul>
+<li><p><strong>xintkernel</strong>: <code>\xintUniformDeviate</code>.</p></li>
+<li><p><strong>xint</strong>: <code>\xintRandomDigits</code>, <code>\xintXRandomDigits</code>, <code>\xintiiRandRange</code>, <code>\xintiiRandRangeAtoB</code>.</p></li>
+<li><p><strong>xintfrac</strong>: support macros (not public, mainly because internal format for floats is surely not final) for <code>random()</code> and <code>qrand()</code>.</p></li>
+<li><p><strong>xintexpr</strong>: <code>random()</code>, <code>qrand()</code>, and <code>randrange(A[, B])</code>.</p></li>
+<li><p><strong>xintexpr</strong>: when a function <code>foo()</code> is declared via <code>\xintdeffunc</code> (et al.) to be parameter-less, it can be used as <code>foo()</code>; formerly <code>foo(nil)</code> syntax was required.</p></li>
+<li><p>The usual provision of user manual “improvements”.</p></li>
+</ul>
+<h2 id="a-20180307"><code>1.3a (2018/03/07)</code></h2>
+<h3 id="removed">Removed</h3>
+<ul>
+<li><strong>xintcore</strong>, <strong>xint</strong>, <strong>xintfrac</strong>: removal of the internal macros which were used at <code>1.2o</code> to add a deprecation mechanism; all deprecated macros have been removed at <code>1.3</code> so there was no reason to keep the code used for deprecating them.</li>
+</ul>
+<h3 id="improvements-and-new-features-4">Improvements and new features</h3>
+<ul>
+<li><p><strong>xintexpr</strong>: new conditionals <code>ifone()</code> and <code>ifint()</code>.</p></li>
+<li><p><strong>xintfrac</strong>: <code>\xintREZ</code> is faster on inputs having one hundred digits or more.</p></li>
+<li><p>Added to the user manual mention of macros such as <code>\xintDivFloor</code>, <code>\xintMod</code>, <code>\xintModTrunc</code>, which had been left out so far.</p></li>
+</ul>
+<h3 id="bug-fixes-3">Bug fixes</h3>
+<ul>
+<li><strong>xintexpr</strong>: the mechanism for adjunction to the expression parsers of user defined functions was refactored and improved at previous release <code>1.3</code>: in particular recursive definitions became possible. But an oversight made these recursive functions quite inefficient (to remain polite.) This release fixes the problem.</li>
+</ul>
+<h2 id="section"><code>1.3 (2018/03/01)</code></h2>
+<h3 id="incompatible-changes-2">Incompatible changes</h3>
+<ul>
+<li><p><strong>xintcore</strong>, <strong>xint</strong>, <strong>xintfrac</strong>: all macros deprecated at <code>1.2o</code> got removed.</p></li>
+<li><p><strong>xintfrac</strong>: addition and subtraction of <code>a/b</code> and <code>c/d</code> now use the l.c.m. of the denominators. Similarly the macro supporting the modulo operator <code>/:</code> uses a l.c.m. for the denominator of the result.</p></li>
+<li><p><strong>xintexpr</strong>: the addition, subtraction, modulo <code>/:</code>, and the <code>mod()</code> and <code>divmod()</code> functions produce generally smaller denominators (see previous item).</p></li>
+<li><p><strong>xintexpr</strong>: 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 <code>\xintverbosetrue</code>).</p></li>
+</ul>
+<h3 id="improvements-and-new-features-5">Improvements and new features</h3>
+<ul>
+<li><p><strong>xintexpr</strong>: user-defined functions may now be of a recursive nature. This was made possible by a refactoring of the <code>\xintNewExpr</code> mechanism. It became both leaner and more extensive than formerly.</p></li>
+<li><p><strong>xintfrac</strong>: new macros <code>\xintPIrr</code> and <code>\xintDecToString</code>. The latter is a backport of a <code>polexpr 0.4</code> utility, and it is to be considered unstable.</p></li>
+<li><p><strong>xintexpr</strong>: new function <code>preduce()</code> associated with <code>\xintPIrr</code>.</p></li>
+</ul>
+<h2 id="q-20180206"><code>1.2q (2018/02/06)</code></h2>
+<h3 id="improvements-and-new-features-6">Improvements and new features</h3>
+<ul>
+<li><strong>xintexpr</strong>: tacit multiplication extended to cases such as <code>3!4!5!</code> or <code>(1+2)3</code>.</li>
+</ul>
+<h3 id="bug-fixes-4">Bug fixes</h3>
+<ul>
+<li><strong>xintcore</strong>: sadly, refactoring at <code>1.2l</code> of subtraction left an extra character in an inner macro causing breakage in some rare circumstances. This should not have escaped our test suite!</li>
+</ul>
+<h2 id="p-20171205"><code>1.2p (2017/12/05)</code></h2>
+<h3 id="incompatible-changes-3">Incompatible changes</h3>
+<ul>
+<li><p><strong>xintgcd</strong>: <code>\xintBezout{a}{b}</code>’s output consists of <code>{u}{v}{d}</code> with <code>u*a+v*b==d</code>, with <code>d</code> the GCD. Formerly it was <code>{a}{b}{u}{v}{d}</code>, and with <code>u*a-v*b==d</code>.</p></li>
+<li><p><strong>xintgcd</strong>: <code>\xintBezout{0}{0}</code> expands to <code>{0}{0}{0}</code>. Formerly (since <code>1.2l</code>) it raised <code>InvalidOperation</code>.</p></li>
+<li><p><strong>xintcore</strong>: <code>\xintiiMod</code> is now associated with floored division. The former meaning (associated with truncated division) is available as <code>\xintiiModTrunc</code>.</p></li>
+<li><p><strong>xintfrac</strong>: <code>\xintMod</code> is now associated with floored division. The former meaning is available as <code>\xintModTrunc</code>.</p></li>
+<li><p><strong>xintexpr</strong>: the <code>//</code> operator and its associated modulo <code>'mod'</code> (or <code>/:</code>) now correspond to floored division, like the Python language <code>//</code>, <code>%</code>, and <code>divmod(x, y)</code>. Formerly they had been associated to truncated division. This is breaking change for operands of opposite signs.</p></li>
+</ul>
+<h3 id="improvements-and-new-features-7">Improvements and new features</h3>
+<ul>
+<li><p><strong>xinttools</strong>: <code>\xintListWithSep</code>, which had remained unchanged since its introduction at <code>1.04 (2013/04/25)</code>, was rewritten for increased speed.</p></li>
+<li><p><strong>xintexpr</strong>: <code>\xintdefvar</code>’s syntax is extended to allow simultaneous assignments. Examples: <code>\xintdefvar x1, x2, x3 := 1, 3**10, 3**20;</code> or <code>\xintdefiivar A, B := B, A 'mod' B;</code> for already defined variables <code>A</code> and <code>B</code>.</p></li>
+<li><p><strong>xintexpr</strong>: added <code>divmod()</code> to the built-in functions. It is associated with floored division, like the Python language <code>divmod()</code>. Related support macros added to <strong>xintcore</strong>, and <strong>xintfrac</strong>.</p></li>
+</ul>
+<h3 id="bug-fixes-5">Bug fixes</h3>
+<ul>
+<li><p><strong>xintgcd</strong>: <code>\xintBezout{6}{3}</code> (for example) expanded to <code>{6}{3}{-0}{-1}{3}</code>, but the <code>-0</code> should have been <code>0</code>.</p></li>
+<li><p><strong>xintgcd</strong>: it still used macro <code>\xintiAbs</code> although the latter had been deprecated from <strong>xintcore</strong>.</p></li>
+<li><p><strong>xintexpr</strong>: in float expressions the <code>//</code> and <code>/:</code> (aka <code>'mod'</code>) operators did not round their operands to the float precision prior to computing with them, contrarily to other infix arithmetic operators and to the <code>mod(f,g)</code> function; thus, <code>mod(f,g)</code> and <code>f 'mod' g</code> were not completely equivalent.</p></li>
+<li><p>various documentation fixes; in particular, the partial dependency of <strong>xintcfrac</strong> on <strong>xinttools</strong> had not been mentioned.</p></li>
+</ul>
+<h2 id="o-20170829"><code>1.2o (2017/08/29)</code></h2>
+<h3 id="incompatible-changes-4">Incompatible changes</h3>
+<ul>
+<li><strong>xint</strong>: <code>\xintAND</code>, <code>\xintOR</code>, … and similar Boolean logic macros do not apply anymore <code>\xintNum</code> (or <code>\xintRaw</code> if <strong>xintfrac</strong> is loaded), to their arguments (often, from internal usage of <code>\xintSgn</code>), but only f-expand them (using e.g. <code>\xintiiSgn</code>). This is kept un-modified even if loading <strong>xintfrac</strong>.</li>
+</ul>
+<h3 id="deprecated">Deprecated</h3>
+<p>Deprecated macros raise an error but, generally, then expand as in former releases. They will all get removed at some future release.</p>
+<ul>
+<li><p><strong>xintcore</strong>: <code>\xintiOpp</code>, <code>\xintiAbs</code>, <code>\xintiAdd</code>, <code>\xintiSub</code>, <code>\xintiMul</code>, <code>\xintiDivision</code>, <code>\xintiQuo</code>, <code>\xintiRem</code>, <code>\xintiDivRound</code>, <code>\xintiDivTrunc</code>, <code>\xintiMod</code>, <code>\xintiSqr</code>, <code>\xintiPow</code>, and <code>\xintiFac</code> are deprecated. Only the <code>ii</code>-named variants get defined.</p></li>
+<li><p><strong>xintcore</strong>: <code>\xintCmp</code> and <code>\xintSgn</code> are deprecated from <strong>xintcore</strong> (which only defines <code>\xintiiCmp</code> and <code>\xintiiSgn</code>) as they actually belong to <strong>xintfrac</strong>.</p></li>
+<li><p><strong>xintcore</strong>: <code>\xintiiFDg</code>, resp. <code>\xintiiLDg</code>, are renamed <code>\xintFDg</code>, resp. <code>\xintLDg</code>. Former denominations are deprecated.</p></li>
+<li><p><strong>xint</strong>: <code>\xintMON</code>, <code>\xintMMON</code>, <code>\xintiMax</code>, <code>\xintiMin</code>, <code>\xintiMaxof</code>, <code>\xintiMinof</code>, <code>\xintiSquareRoot</code>, <code>\xintiSqrt</code>, <code>\xintiSqrtR</code>, <code>\xintiBinomial</code>, and <code>\xintiPFactorial</code> are deprecated. Only <code>ii</code>-named variants get defined.</p></li>
+<li><p><strong>xint</strong>: <code>\xintEq</code>, <code>\xintGeq</code>, <code>\xintGt</code>, <code>\xintLt</code>, <code>\xintGtorEq</code>, <code>\xintLtorEq</code>, <code>\xintIsZero</code>, <code>\xintIsNotZero</code>, <code>\xintIsOne</code>, <code>\xintOdd</code>, <code>\xintEven</code>, <code>\xintifSgn</code>, <code>\xintifCmp</code>, <code>\xintifEq</code>, <code>\xintifGt</code>, <code>\xintifLt</code>, <code>\xintifZero</code>, <code>\xintifNotZero</code>, <code>\xintifOne</code>, <code>\xintifOdd</code>, are deprecated. These macros belong to <strong>xintfrac</strong>. Package <strong>xint</strong> defines only the <code>ii</code>-named variants.</p></li>
+<li><p><strong>xint</strong>: <code>\xintNeq</code> was renamed to <code>\xintNotEq</code> which however is only provided by <strong>xintfrac</strong>. Package <strong>xint</strong> defines <code>\xintiiNotEq</code>, and <code>\xintNeq</code> is deprecated.</p></li>
+<li><p><strong>xint</strong>: <code>\xintNot</code> was renamed to <code>\xintNOT</code>, former denomination is deprecated. See also item about Boolean logic macros in the <em>Incompatible Changes</em> section.</p></li>
+</ul>
+<h2 id="n-20170806"><code>1.2n (2017/08/06)</code></h2>
+<h3 id="incompatible-changes-5">Incompatible changes</h3>
+<ul>
+<li><strong>xintbinhex</strong> does not load package <strong>xintcore</strong> anymore, but only <strong>xintkernel</strong>.</li>
+</ul>
+<h3 id="improvements-and-new-features-8">Improvements and new features</h3>
+<ul>
+<li><p><strong>xintbinhex</strong> has only <strong>xintkernel</strong> as dependency.</p></li>
+<li><p>Macros of <strong>xintbinhex</strong> have been improved for speed and increased maximal sizes of allowable inputs.</p></li>
+</ul>
+<h2 id="m-20170731"><code>1.2m (2017/07/31)</code></h2>
+<h3 id="incompatible-changes-6">Incompatible changes</h3>
+<ul>
+<li><p><strong>xintbinhex</strong>: the length of the input is now limited. The maximum size depends on the macro and ranges from about <code>4000</code> to about <code>19900</code> digits.</p></li>
+<li><p><strong>xintbinhex</strong>: <code>\xintCHexToBin</code> is now the variant of <code>\xintHexToBin</code> which does not remove leading binary zeroes: <code>N</code> hex-digits give on output exactly <code>4N</code> binary digits.</p></li>
+</ul>
+<h3 id="improvements-and-new-features-9">Improvements and new features</h3>
+<ul>
+<li><strong>xintbinhex</strong>: all macros have been rewritten using techniques from the 1.2 release (they had remained unmodified since <code>1.08</code> of <code>2013/06/07</code>.) The new macros are faster but limited to a few thousand digits. The <code>1.08</code> routines could handle tens of thousands of digits, but not in a reasonable time.</li>
+</ul>
+<h3 id="bug-fixes-6">Bug fixes</h3>
+<ul>
+<li><p>user manual: the <code>Changes</code> section wrongly stated at <code>1.2l</code> that the macros of <strong>xintbinhex</strong> had been made robust against non terminated input such as <code>\number\mathcode`\-</code>. Unfortunately the author fell into the trap of believing his own documentation and he forgot to actually implement the change. Now done.</p></li>
+<li><p>user manual: the PDF bookmarks were messed up.</p></li>
+<li><p><strong>xint</strong>, <strong>xintfrac</strong>: <code>\xintGeq</code>, <code>\xintMax</code>, <code>\xintMin</code>, 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.</p></li>
+</ul>
+<h2 id="l-20170726"><code>1.2l (2017/07/26)</code></h2>
+<h3 id="removed-1">Removed</h3>
+<ul>
+<li><p><code>\xintiiSumExpr</code>, <code>\xintiiPrdExpr</code> (<strong>xint</strong>) and <code>\xintSumExpr</code>, <code>\xintPrdExpr</code> (<strong>xintfrac</strong>). They had not been formally deprecated, but had been left un-documented since <code>1.09d (2013/10/22)</code>.</p></li>
+<li><p>internal macro <code>\xint_gob_til_xint_relax</code> removed.</p></li>
+</ul>
+<h3 id="improvements-and-new-features-10">Improvements and new features</h3>
+<ul>
+<li><p>the underscore character <code>_</code> is accepted by the <strong>xintexpr</strong> parsers as a digit separator (the space character already could be used for improved readability of big numbers). It is not allowed as <em>first</em> character of a number, as it would then be mis-interpreted as the start of a possible variable name.</p></li>
+<li><p>some refactoring in <strong>xintcore</strong> auxiliary routines and in <code>\xintiiSub</code> and <code>\xintiiCmp</code> for some small efficiency gains.</p></li>
+<li><p>code comments in <strong>xintcore</strong> are better formatted, but remain sparse.</p></li>
+<li><p><strong>xintcore</strong>, <strong>xint</strong>, <strong>xintfrac</strong>, … : some macros were not robust against arguments whose expansion looks forward for some termination (e.g. <code>\number\mathcode`\-</code>), and particularly, most were fragile against inputs using non-terminated <code>\numexpr</code> (such as <code>\xintiiAdd{\the\numexpr1}{2}</code> or <code>\xintRaw{\numexpr1}</code>). 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 <strong>xintfrac</strong>) have now been made robust against such inputs. Some macros from <strong>xintcore</strong> primarily destined to internal usage still accept only properly terminated arguments such as <code>\the\mathcode`\-&lt;space&gt;</code> or <code>\the\numexpr1\relax</code>.</p>
+<p>The situation with expressions is unchanged: syntax such as <code>\xintexpr \numexpr1+2\relax</code> is illegal as the ending <code>\relax</code> token will get swallowed by the <code>\numexpr</code>; but it is needed by the <code>xintexpr</code>-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 <code>}</code> for example can not terminate an <code>xintexpr</code>-ession, the parser must find a <code>\relax</code> token at some point). Thus there must be in this example a second <code>\relax</code>.</p></li>
+<li><p>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.</p></li>
+</ul>
+<h3 id="bug-fixes-7">Bug fixes</h3>
+<ul>
+<li><p><strong>xintbinhex</strong>: since <code>1.2 (2015/10/10)</code>, <code>\xintHexToDec</code> was broken due to an undefined macro (it was in <code>xint.sty</code>, but the module by itself is supposedly dependent only upon <code>xintcore.sty</code>).</p></li>
+<li><p><strong>xintgcd</strong>: macro <code>\xintBezout</code> produced partially wrong output if one of its two arguments was zero.</p></li>
+<li><p><strong>xintfrac</strong>: the manual said one could use directly <code>\numexpr</code> compatible expressions in arithmetic macros (without even a <code>\numexpr</code> 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 <code>\the\numexpr</code> prefix and not to worry about the token count… The ending <code>\relax</code> is now un-needed.</p></li>
+</ul>
+<h2 id="k-20170106"><code>1.2k (2017/01/06)</code></h2>
+<h3 id="incompatible-changes-7">Incompatible changes</h3>
+<ul>
+<li><p>macro <code>\xintFloat</code> which rounds its input to a floating point number does <em>not</em> print anymore <code>10.0...0eN</code> 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.</p></li>
+<li><p>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.</p></li>
+</ul>
+<h3 id="improvements-and-new-features-11">Improvements and new features</h3>
+<ul>
+<li><p>the initial rounding to the target precision <code>P</code> which is applied by the floating point macros from <strong>xintfrac</strong> to their arguments achieves the <em>exact (aka correct) rounding</em> even for inputs which are fractions with more than <code>P+2</code> digits in their numerators and denominators (<code>&gt;1</code>.) Hence the computed values depend only on the arguments as rational numbers and not upon their representatives. This is not relevant to <em>expressions</em> (<strong>xintexpr</strong>), because the <code>\xintfloatexpr</code> parser sees there <code>/</code> as an operator and does not (apart from special constructs) get to manipulate fractions as such.</p></li>
+<li><p><code>\xintnewdummy</code> is public interface to a <code>1.2e</code> macro which serves to declare any given catcode 11 character as a dummy variable for expressions (<strong>xintexpr</strong>). This is useful for Unicode engines (the Latin letters being already all pre-declared as dummy variables.)</p></li>
+<li><p>added <code>\xintiSqrtR</code>, there was only <code>\xintiiSqrtR</code> alongside <code>\xintiSqrt</code> and <code>\xintiiSqrt</code> (<strong>xint</strong>).</p></li>
+<li><p>added non public <code>\xintLastItem:f:csv</code> to <strong>xinttools</strong> for faster <code>last()</code> function, and improved <code>\xintNewExpr</code> compatibility. Also <code>\xintFirstItem:f:csv</code>.</p></li>
+</ul>
+<h3 id="bug-fixes-8">Bug fixes</h3>
+<ul>
+<li><p>the <code>1.2f</code> half-integer powers computed within <code>\xintfloatexpr</code> had a silly rounding to the target precision just <em>before</em> the final square-root extraction, thus possibly losing some precision. The <code>1.2k</code> 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 <code>0.52 ulp</code> (for inputs having at most <code>\xinttheDigits</code> digits.)</p></li>
+<li><p>more regressions from <code>1.2i</code> were fixed: <code>\xintLen</code> (<strong>xint</strong>, <strong>xintfrac</strong>) and <code>\xintDouble</code> (<strong>xintcore</strong>) 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.</p></li>
+<li><p><code>\xintiiSquareRoot{0}</code> now produces <code>{1}{1}</code>, which fits better the general documented behaviour of this macro than <code>11</code>.</p></li>
+</ul>
+<h2 id="j-20161222"><code>1.2j (2016/12/22)</code></h2>
+<h3 id="improvements-and-new-features-12">Improvements and new features</h3>
+<ul>
+<li><p><strong>xinttools</strong> and <strong>xintexpr</strong>:</p>
+<ol type="1">
+<li><p>slightly improves the speed of <code>\xintTrim</code>.</p></li>
+<li><p>speed gains for the handlers of comma separated lists implementing Python-like slicing and item extraction. Relevant non (user) documented macros better documented in <code>sourcexint.pdf</code>.</p></li>
+</ol></li>
+<li><p>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 <strong>xintexpr</strong> syntax to a kind of awe-inspiring perfection… except that implementation of some math functions is still lacking.</p></li>
+</ul>
+<h3 id="bug-fixes-9">Bug fixes</h3>
+<ul>
+<li>fix two <code>1.2i</code> regressions caused by undefined macros (<code>\xintNthElt</code> in certain branches and <code>[list][N]</code> item extraction in certain cases.) The test files existed but were not executed prior to release. Automation in progress.</li>
+</ul>
+<h2 id="i-20161213"><code>1.2i (2016/12/13)</code></h2>
+<h3 id="incompatible-changes-8">Incompatible changes</h3>
+<ul>
+<li><code>\xintDecSplit</code> second argument must have no sign (former code replaced it with its absolute value, a sign now may cause an error.)</li>
+</ul>
+<h3 id="removed-2">Removed</h3>
+<ul>
+<li>deprecated macros <code>\xintifTrue</code>, <code>\xintifTrueFalse</code>, <code>\xintQuo</code>, <code>\xintRem</code>, <code>\xintquo</code>, <code>\xintrem</code>.</li>
+</ul>
+<h3 id="improvements-and-new-features-13">Improvements and new features</h3>
+<ul>
+<li><p><strong>xintkernel</strong>: <code>\xintLength</code> is faster. New macros:</p>
+<ul>
+<li><p><code>\xintLastItem</code> to fetch the last item from its argument,</p></li>
+<li><p><code>\romannumeral\xintgobble</code> for gobbling many (up to 531440) upstream braced items or tokens.</p></li>
+<li><p><code>\romannumeral\xintreplicate</code> which is copied over from the expl3 <code>\prg_replicate:nn</code> with some minor changes.</p></li>
+</ul></li>
+<li><p><strong>xinttools</strong>: general token list handling routines <code>\xintKeep</code>, <code>\xintTrim</code> and <code>\xintNthElt</code> are faster; but the novel <code>\xintTrim</code> can only remove up to a maximum of 531440 items.</p>
+<p>Also, <code>\xintFor</code> partially improves on some issues which are reported upon in the documentation.</p></li>
+<li><p>some old macros have been rewritten entirely or partially using techniques which <strong>xint</strong> started using in release <code>1.2</code>:</p>
+<ul>
+<li><p><strong>xintcore</strong>: <code>\xintDouble</code>, <code>\xintHalf</code>, <code>\xintInc</code>, <code>\xintDec</code>, <code>\xintiiLDg</code>, <code>\xintDSR</code> (originally from <strong>xint</strong>), a novel <code>\xintDSRr</code>.</p></li>
+<li><p><strong>xint</strong>: <code>\xintDSH</code>, <code>\xintDSx</code>, <code>\xintDecSplit</code>, <code>\xintiiE</code>.</p></li>
+<li><p><strong>xintfrac</strong>: as a result of the above <code>\xintTrunc</code>, <code>\xintRound</code> and <code>\xintXTrunc</code> 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, <code>\xintXTrunc</code> does not anymore create a dependency of <strong>xintfrac</strong> on <strong>xinttools</strong>.</p></li>
+</ul></li>
+<li><p>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 <code>\xintNewFunction</code> for recursive definitions.</p></li>
+<li><p>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 <strong>xint</strong> is about expansion of macros (plus the use of <code>\numexpr</code>).</p></li>
+</ul>
+<h3 id="bug-fixes-10">Bug fixes</h3>
+<ul>
+<li><code>\xintDecSplitL</code> and <code>\xintDecSplitR</code> from <strong>xint</strong> produced their output in a spurious brace pair (bug introduced in <code>1.2f</code>).</li>
+</ul>
+<h2 id="h-20161120"><code>1.2h (2016/11/20)</code></h2>
+<h3 id="improvements-and-new-features-14">Improvements and new features</h3>
+<ul>
+<li><p>new macro <code>\xintNewFunction</code> in <strong>xintexpr</strong> which allows to extend the parser syntax with functions in situations where <code>\xintdeffunc</code> is not usable (typically, because dummy variables are used over a not yet determined range of values because it depends on the variables).</p></li>
+<li><p>after three years of strict obedience to <code>xint</code> prefix, now <code>\thexintexpr</code>, <code>\thexintiexpr</code>, <code>\thexintfloatexpr</code>, and <code>\thexintiiexpr</code> are provided as synonyms to <code>\xinttheexpr</code>, etc…</p></li>
+</ul>
+<h3 id="bug-fixes-11">Bug fixes</h3>
+<ul>
+<li><p>the <code>(cond)?{foo}{bar}</code> operator from <strong>xintexpr</strong> mis-behaved in certain circumstances (such as an empty <code>foo</code>).</p></li>
+<li><p>the <strong>xintexpr</strong> <code>1.2f</code> <code>binomial</code> function (which uses <code>\xintiiBinomial</code> from <strong>xint.sty</strong> or <code>\xintFloatBinomial</code> from <strong>xintfrac.sty</strong>) deliberately raised an error for <code>binomial(x,y)</code> with <code>y&lt;0</code> or <code>x&lt;y</code>. This was unfortunate, and it now simply evaluates to zero in such cases.</p></li>
+<li><p>similarly the <code>pfactorial</code> function was very strict and <code>pfactorial(x,y)</code> deliberately raised an out-of-range error if not used with non-negative integers with <code>x</code> less than <code>y</code>. It now avoids doing that and allows negative arguments.</p></li>
+<li><p>the <code>add</code> and <code>mul</code> from <strong>xintexpr</strong>, which work with dummy variables since <code>1.1</code>, raised an error since <code>1.2c 2015/11/16</code> when the dummy variable was given an empty range (or list) of values, rather than producing respectively <code>0</code> and <code>1</code> as formerly.</p></li>
+</ul>
+<h2 id="g-20160319"><code>1.2g (2016/03/19)</code></h2>
+<h3 id="incompatible-changes-9">Incompatible changes</h3>
+<ul>
+<li><p>inside expressions, list item selector <code>[L][n]</code> counts starting at zero, not at one. This is more coherent with <code>[L][a:b]</code> which was already exactly like in Python since its introduction. A function len(L) replaces earlier <code>[L][0]</code>.</p></li>
+<li><p>former <code>iter</code> keyword now called <code>iterr</code>. Indeed it matched with <code>rrseq</code>, the new <code>iter</code> (which was somehow missing from <code>1.1</code>) is the one matching <code>rseq</code>. Allows to iterate more easily with a “list” variable.</p></li>
+</ul>
+<h3 id="improvements-and-new-features-15">Improvements and new features</h3>
+<ul>
+<li><p>in <strong>xintexpr.sty</strong>: list selectors <code>[L][n]</code> and <code>[L][a:b]</code> are more efficient: the earlier <code>1.1</code> routines did back and forth conversions from comma separated values to braced tokens, the <code>1.2g</code> routines use macros from <strong>xinttools.sty</strong> handling directly the encountered lists of comma separated values.</p></li>
+<li><p>in <strong>xinttools.sty</strong>: slight improvements in the efficiency of the <code>\xintNthElt</code>, <code>\xintKeep</code>, <code>\xintTrim</code> routines and new routines handling directly comma separated values. The latter are not included in the user manual (they are not <code>\long</code>, 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).</p></li>
+<li><p>a slight speed improvement to <code>\xintFloatSqrt</code> in its quest of correct rounding.</p></li>
+<li><p>float multiplication and division handle more swiftly operands (non-fractional) with few digits, when the float precision is large.</p></li>
+<li><p>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 <code>iter</code> in a float expression.</p></li>
+</ul>
+<h2 id="f-20160312"><code>1.2f (2016/03/12)</code></h2>
+<h3 id="incompatible-changes-10">Incompatible changes</h3>
+<ul>
+<li>no more <code>\xintFac</code> macro but <code>\xintiFac/\xintiiFac/\xintFloatFac</code>.</li>
+</ul>
+<h3 id="improvements-and-new-features-16">Improvements and new features</h3>
+<ul>
+<li><p>functions <code>binomial</code>, <code>pfactorial</code> and <code>factorial</code> in both integer and float versions.</p></li>
+<li><p>macros <code>\xintiiBinomial</code>, <code>\xintiiPFactorial</code> (<strong>xint.sty</strong>) and <code>\xintFloatBinomial</code>, <code>\xintFloatPFactorial</code> (<strong>xintfrac.sty</strong>). Improvements to <code>\xintFloatFac</code>.</p></li>
+<li><p>faster implementation and increased accuracy of float power macros. Half-integer exponents are now accepted inside float expressions.</p></li>
+<li><p>faster implementation of both integral and float square root macros.</p></li>
+<li><p>the float square root achieves <em>correct</em> (aka <em>exact</em>) rounding in arbitrary precision.</p></li>
+<li><p>modified behaviour for the <code>\xintPFloat</code> macro, used by <code>\xintthefloatexpr</code> to prettify its output. It now opts for decimal notation if and only if scientific notation would use an exponent between <code>-5</code> and <code>5</code> inclusive. The zero value is printed <code>0.</code> with a dot.</p></li>
+<li><p>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.</p></li>
+<li><p>the documentation offers a more precise (and accurate) discussion of floating point issues.</p></li>
+<li><p>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.</p></li>
+<li><p>(TeXperts only) the macros defined (internally) from <code>\xintdeffunc</code> et al. constructs do not incorporate an initial <code>\romannumeral</code> anymore.</p></li>
+<li><p>renewed desperate efforts at improving the documentation by random shuffling of sections and well thought additions; cuts were considered and even performed.</p></li>
+</ul>
+<h3 id="bug-fixes-12">Bug fixes</h3>
+<ul>
+<li><p>squaring macro <code>\xintSqr</code> from <strong>xintfrac.sty</strong> was broken due to a misspelled sub-macro name. Dates back to <code>1.1</code> release of <code>2014/10/28</code> <code>:-((</code>.</p></li>
+<li><p><code>1.2c</code>’s fix to the subtraction bug from <code>1.2</code> 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 <code>\xintiiSquareRoot</code>.</p></li>
+<li><p>the comparison operators were not recognized by <code>\xintNewIIExpr</code> and <code>\xintdefiifunc</code> constructs.</p></li>
+</ul>
+<h2 id="e-20151122"><code>1.2e (2015/11/22)</code></h2>
+<h3 id="improvements-and-new-features-17">Improvements and new features</h3>
+<ul>
+<li><p>macro <code>\xintunassignvar</code>.</p></li>
+<li><p>slight modifications of the logged messages in case of <code>\xintverbosetrue</code>.</p></li>
+<li><p>a space in <code>\xintdeffunc f(x)&lt;space&gt;:= expression ;</code> is now accepted.</p></li>
+<li><p>documentation enhancements: the <em>Quick Sort</em> section with its included code samples has been entirely re-written; the <em>Commands of the xintexpr package</em> section has been extended and reviewed entirely.</p></li>
+</ul>
+<h3 id="bug-fixes-13">Bug fixes</h3>
+<ul>
+<li><p>in <strong>xintfrac</strong>: the <code>\xintFloatFac</code> from release <code>1.2</code> parsed its argument only through <code>\numexpr</code> but it should have used <code>\xintNum</code>.</p></li>
+<li><p>in <strong>xintexpr</strong>: release <code>1.2d</code> had broken the recognition of sub-expressions immediately after variable names (with tacit multiplication).</p></li>
+<li><p>in <strong>xintexpr</strong>: contrarily to what <code>1.2d</code> documentation said, tacit multiplication was not yet always done with enhanced precedence. Now yes.</p></li>
+</ul>
+<h2 id="d-20151118"><code>1.2d (2015/11/18)</code></h2>
+<h3 id="improvements-and-new-features-18">Improvements and new features</h3>
+<ul>
+<li><p>the function definitions done by <code>\xintdeffunc</code> et al., as well as the macro declarations by <code>\xintNewExpr</code> et al. now have only local scope.</p></li>
+<li><p>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).</p></li>
+<li><p>some documentation enhancements, particularly in the chapter on xintexpr.sty, and also in the code source comments.</p></li>
+</ul>
+<h3 id="bug-fixes-14">Bug fixes</h3>
+<ul>
+<li>in <strong>xintcore</strong>: release <code>1.2c</code> had inadvertently broken the <code>\xintiiDivRound</code> macro.</li>
+</ul>
+<h2 id="c-20151116"><code>1.2c (2015/11/16)</code></h2>
+<h3 id="improvements-and-new-features-19">Improvements and new features</h3>
+<ul>
+<li><p>macros <code>\xintdeffunc</code>, <code>\xintdefiifunc</code>, <code>\xintdeffloatfunc</code> and boolean <code>\ifxintverbose</code>.</p></li>
+<li><p>on-going code improvements and documentation enhancements, but stopped in order to issue this bugfix release.</p></li>
+</ul>
+<h3 id="bug-fixes-15">Bug fixes</h3>
+<ul>
+<li>in <strong>xintcore</strong>: recent release <code>1.2</code> introduced a bug in the subtraction (happened when 00000001 was found under certain circumstances at certain mod 8 locations).</li>
+</ul>
+<h2 id="b-20151029"><code>1.2b (2015/10/29)</code></h2>
+<h3 id="bug-fixes-16">Bug fixes</h3>
+<ul>
+<li>in <strong>xintcore</strong>: recent release <code>1.2</code> 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).</li>
+</ul>
+<h2 id="a-20151019"><code>1.2a (2015/10/19)</code></h2>
+<h3 id="improvements-and-new-features-20">Improvements and new features</h3>
+<ul>
+<li><p>added <code>\xintKeepUnbraced</code>, <code>\xintTrimUnbraced</code> (<strong>xinttools</strong>) and fixed documentation of <code>\xintKeep</code> and <code>\xintTrim</code> regarding brace stripping.</p></li>
+<li><p>added <code>\xintiiMaxof/\xintiiMinof</code> (<strong>xint</strong>).</p></li>
+<li><p>TeX hackers only: replaced all code uses of <code>\romannumeral-`0</code> by the quicker <code>\romannumeral`&amp;&amp;@</code> (<code>^</code> being used as letter, had to find another character usable with catcode 7).</p></li>
+</ul>
+<h3 id="bug-fixes-17">Bug fixes</h3>
+<ul>
+<li>in <strong>xintexpr</strong>: recent release <code>1.2</code> introduced a bad bug in the parsing of decimal numbers and as a result <code>\xinttheexpr 0.01\relax</code> expanded to <code>0</code> ! (sigh…)</li>
+</ul>
+<h2 id="section-1"><code>1.2 (2015/10/10)</code></h2>
+<h3 id="removed-3">Removed</h3>
+<ul>
+<li>the macros <code>\xintAdd</code>, <code>\xintSub</code>, <code>\xintMul</code>, <code>\xintMax</code>, <code>\xintMin</code>, <code>\xintMaxof</code>, <code>\xintMinof</code> are removed from package <strong>xint</strong>, and only exist in the versions from <strong>xintfrac</strong>. With only <strong>xintcore</strong> or <strong>xint</strong> loaded, one <em>must</em> use <code>\xintiiAdd</code>, <code>\xintiiSub</code>, …, or <code>\xintiAdd</code>, <code>\xintiSub</code>, etc…</li>
+</ul>
+<h3 id="improvements-and-new-features-21">Improvements and new features</h3>
+<ul>
+<li><p>the basic arithmetic implemented in <strong>xintcore</strong> has been entirely rewritten. The mathematics remains the elementary school one, but the <code>TeX</code> 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.</p></li>
+<li><p>the inputs must have less than 19959 digits. But computations with thousands of digits take time.</p></li>
+<li><p>a previously standing limitation of <code>\xintexpr</code>, <code>\xintiiexpr</code>, and of <code>\xintfloatexpr</code> to numbers of less than 5000 digits has been lifted.</p></li>
+<li><p>a <em>qint</em> 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.</p></li>
+<li><p><code>\xintFloatFac</code> macro for computing the factorials of integers as floating point numbers to a given precision. The <code>!</code> postfix operator inside <code>\xintfloatexpr</code> maps to this new macro rather than to the exact factorial as used by <code>\xintexpr</code> and <code>\xintiiexpr</code>.</p></li>
+<li><p>there is more flexibility in the parsing done by the macros from <strong>xintfrac</strong> on fractional input: the decimal parts of both the numerator and the denominator may arise from a separate expansion via <code>\romannumeral-`0</code>. Also the strict <code>A/B[N]</code> format is a bit relaxed: <code>N</code> may be anything understood by <code>\numexpr</code> (it could even be empty but that possibility has been removed by later <code>1.2f</code> release.)</p></li>
+<li><p>on the other hand an isolated dot <code>.</code> 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 <strong>xintfrac</strong>.</p></li>
+<li><p>added <code>\ht</code>, <code>\dp</code>, <code>\wd</code>, <code>\fontcharht</code>, etc… to the tokens recognized by the parsers and expanded by <code>\number</code>.</p></li>
+<li><p>an obscure bug in package <strong>xintkernel</strong> has been fixed, regarding the sanitization of catcodes: under certain circumstances (which could not occur in a normal <code>LaTeX</code> context), unusual catcodes could end up being propagated to the external world.</p></li>
+<li><p>an effort at randomly shuffling around various pieces of the documentation has been done.</p></li>
+</ul>
+<h2 id="c-20150912"><code>1.1c (2015/09/12)</code></h2>
+<ul>
+<li><p>bugfix regarding macro <code>\xintAssign</code> from <strong>xinttools</strong> which did not behave correctly in some circumstances (if there was a space before <code>\to</code>, in particular).</p></li>
+<li><p>very minor code improvements, and correction of some issues regarding the source code formatting in <code>sourcexint.pdf</code>, and minor issues in <code>Makefile.mk</code>.</p></li>
+</ul>
+<h2 id="b-20150831"><code>1.1b (2015/08/31)</code></h2>
+<ul>
+<li><p>bugfix: some macros needed by the integer division routine from <strong>xintcore</strong> had been left in <strong>xint.sty</strong> since release <code>1.1</code>. This for example broke the <code>\xintGCD</code> from <strong>xintgcd</strong> if package <strong>xint</strong> was not loaded.</p></li>
+<li><p>Slight enhancements to the documentation, particularly in the <code>Read this first</code> section.</p></li>
+</ul>
+<h2 id="a-20141107"><code>1.1a (2014/11/07)</code></h2>
+<ul>
+<li><p>fixed a bug which prevented <code>\xintNewExpr</code> from producing correctly working macros from a comma separated replacement text.</p></li>
+<li><p><code>\xintiiSqrtR</code> for rounded integer square root; former <code>\xintiiSqrt</code> already produced truncated integer square root; corresponding function <code>sqrtr</code> added to <code>\xintiiexpr..\relax</code> syntax.</p></li>
+<li><p>use of straight quotes in the documentation for better legibility.</p></li>
+<li><p>added <code>\xintiiIsOne</code>, <code>\xintiiifOne</code>, <code>\xintiiifCmp</code>, <code>\xintiiifEq</code>, <code>\xintiiifGt</code>, <code>\xintiiifLt</code>, <code>\xintiiifOdd</code>, <code>\xintiiCmp</code>, <code>\xintiiEq</code>, <code>\xintiiGt</code>, <code>\xintiiLt</code>, <code>\xintiiLtorEq</code>, <code>\xintiiGtorEq</code>, <code>\xintiiNeq</code>, mainly for efficiency of <code>\xintiiexpr</code>.</p></li>
+<li><p>for the same reason, added <code>\xintiiGCD</code> and <code>\xintiiLCM</code>.</p></li>
+<li><p>added the previously mentioned <code>ii</code> macros, and some others from <code>1.1</code>, to the user manual. But their main usage is internal to <code>\xintiiexpr</code>, to skip unnecessary overheads.</p></li>
+<li><p>various typographical fixes throughout the documentation, and a bit of clean up of the code comments. Improved <code>\Factors</code> example of nested <code>subs</code>, <code>rseq</code>, <code>iter</code> in <code>\xintiiexpr</code>.</p></li>
+</ul>
+<h2 id="section-2"><code>1.1 (2014/10/28)</code></h2>
+<h3 id="incompatible-changes-11">Incompatible changes</h3>
+<ul>
+<li><p>in <code>\xintiiexpr</code>, <code>/</code> does <em>rounded</em> division, rather than the Euclidean division (for positive arguments, this is truncated division). The <code>//</code> operator does truncated division,</p></li>
+<li><p>the <code>:</code> operator for three-way branching is gone, replaced with <code>??</code>,</p></li>
+<li><p><code>1e(3+5)</code> is now illegal. The number parser identifies <code>e</code> and <code>E</code> in the same way it does for the decimal mark, earlier versions treated <code>e</code> as <code>E</code> rather as infix operators of highest precedence,</p></li>
+<li><p>the <code>add</code> and <code>mul</code> have a new syntax, old syntax is with <code>`+`</code> and <code>`*`</code> (left quotes mandatory), <code>sum</code> and <code>prd</code> are gone,</p></li>
+<li><p>no more special treatment for encountered brace pairs <code>{..}</code> by the number scanner, <code>a/b[N]</code> notation can be used without use of braces (the <code>N</code> will end up as is in a <code>\numexpr</code>, it is not parsed by the <code>\xintexpr</code>-ession scanner),</p></li>
+<li><p>in earlier releases, place holders for <code>\xintNewExpr</code> could either be denoted <code>#1</code>, <code>#2</code>, … or also <code>$1</code>, <code>$2</code>, … Only the usual <code>#</code> form is now accepted and the special cases previously treated via the second form are now managed via a <code>protect(...)</code> function.</p></li>
+<li><p><strong>xintfrac</strong>: <code>\xintFloor</code> and <code>\xintCeil</code> add a trailing <code>/1[0]</code> to their (integer) output. New <code>\xintiFloor</code> and <code>\xintiCeil</code> do not.</p></li>
+</ul>
+<h3 id="removed-4">Removed</h3>
+<ul>
+<li><code>\xintnumexpr</code>, <code>\xintthenumexpr</code>, <code>\xintNewNumExpr</code>: use <code>\xintiexpr</code>, <code>\xinttheiexpr</code>, <code>\xintNewIExpr</code>.</li>
+</ul>
+<h3 id="deprecated-1">Deprecated</h3>
+<ul>
+<li><p><code>\xintDivision</code>, <code>\xintQuo</code>, <code>\xintRem</code>: use <code>\xintiDivision</code>, <code>\xintiQuo</code>, <code>\xintiRem</code>.</p></li>
+<li><p><code>\xintMax</code>, <code>\xintMin</code>, <code>\xintAdd</code>, <code>\xintSub</code>, <code>\xintMul</code> (<strong>xint</strong>): their usage without <strong>xintfrac</strong> is deprecated; use <code>\xintiMax</code>, <code>\xintiMin</code>, <code>\xintiAdd</code>, <code>\xintiSub</code>, <code>\xintiMul</code>.</p></li>
+<li><p>the <code>&amp;</code> and <code>|</code> as Boolean operators in <code>xintexpr</code>-essions are deprecated in favour of <code>&amp;&amp;</code> and <code>||</code>. The single letter operators might be assigned some other meaning in some later release (bitwise operations, perhaps). Do not use them.</p></li>
+</ul>
+<h3 id="improvements-and-new-features-22">Improvements and new features</h3>
+<ul>
+<li><p>new package <strong>xintcore</strong> has been split off <strong>xint</strong>. It contains the core arithmetic macros (it is loaded by LaTeX package <strong>bnumexpr</strong>),</p></li>
+<li><p>neither <strong>xint</strong> nor <strong>xintfrac</strong> load <strong>xinttools</strong>. Only <strong>xintexpr</strong> does,</p></li>
+<li><p>whenever some portion of code has been revised, often use has been made of the <code>\xint_dothis</code> and <code>\xint_orthat</code> pair of macros for expandably branching,</p></li>
+<li><p>these tiny helpful macros, and a few others are in package <strong>xintkernel</strong> which contains also the catcode and loading order management code, initially inspired by code found in Heiko Oberdiek’s packages,</p></li>
+<li><p>the source code, which was suppressed from <code>xint.pdf</code> in release <code>1.09n</code>, is now compiled into a separate file <code>sourcexint.pdf</code>,</p></li>
+<li><p>faster handling by <code>\xintAdd</code>, <code>\xintSub</code>, <code>\xintMul</code>, … of the case where one of the arguments is zero,</p></li>
+<li><p>the <code>\xintAdd</code> and <code>\xintSub</code> macros from package <strong>xintfrac</strong> 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,</p></li>
+<li><p>this naturally will be also the case for the <code>+</code> and <code>-</code> operations in <code>\xintexpr</code>,</p></li>
+<li><p><strong>xint</strong> added <code>\xintiiDivRound</code>, <code>\xintiiDivTrunc</code>, <code>\xintiiMod</code> for rounded and truncated division of big integers (next to <code>\xintiiQuo</code> and <code>\xintiiRem</code>),</p></li>
+<li><p>with <strong>xintfrac</strong> loaded, the <code>\xintNum</code> macro does <code>\xintTTrunc</code> (which is truncation to an integer, same as <code>\xintiTrunc {0}</code>),</p></li>
+<li><p>added <code>\xintMod</code> to <strong>xintfrac</strong> for modulo operation with fractional numbers,</p></li>
+<li><p>added <code>\xintiFloor</code> and <code>\xintiCeil</code> to <strong>xintfrac</strong>,</p></li>
+<li><p><code>\xintiexpr</code>, <code>\xinttheiexpr</code> admit an optional argument within brackets <code>[d]</code>, they round the computation result (or results, if comma separated) to <code>d</code> digits after decimal mark, (the whole computation is done exactly, as in <code>xintexpr</code>),</p></li>
+<li><p><code>\xintfloatexpr</code>, <code>\xintthefloatexpr</code> similarly admit an optional argument which serves to keep only <code>d</code> digits of precision, getting rid of cumulated uncertainties in the last digits (the whole computation is done according to the precision set via <code>\xintDigits</code>),</p></li>
+<li><p><code>\xinttheexpr</code> and <code>\xintthefloatexpr</code> <em>pretty-print</em> if possible, the former removing unit denominator or <code>[0]</code> brackets, the latter avoiding scientific notation if decimal notation is practical,</p></li>
+<li><p>the <code>//</code> does truncated division and <code>/:</code> is the associated modulo,</p></li>
+<li><p>multi-character operators <code>&amp;&amp;</code>, <code>||</code>, <code>==</code>, <code>&lt;=</code>, <code>&gt;=</code>, <code>!=</code>, <code>**</code>,</p></li>
+<li><p>multi-letter infix binary words <code>'and'</code>, <code>'or'</code>, <code>'xor'</code>, <code>'mod'</code> (straight quotes mandatory),</p></li>
+<li><p>functions <code>even</code>, <code>odd</code>,</p></li>
+<li><p><code>\xintdefvar A3:=3.1415;</code> 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 <code>@</code> is reserved, and single lowercase and uppercase Latin letters are predefined to work as dummy variables (see next),</p></li>
+<li><p>generation of comma separated lists <code>a..b</code>, <code>a..[d]..b</code>,</p></li>
+<li><p>Python syntax-like list extractors <code>[list][n:]</code>, <code>[list][:n]</code>, <code>[list][a:b]</code> allowing negative indices, but no optional step argument, and <code>[list][n]</code> (<code>n=0</code> for the number of items in the list),</p></li>
+<li><p>functions <code>first</code>, <code>last</code>, <code>reversed</code>,</p></li>
+<li><p>itemwise operations on comma separated lists <code>a*[list]</code>, etc.., possible on both sides <code>a*[list]^b</code>, and obeying the same precedence rules as with numbers,</p></li>
+<li><p><code>add</code> and <code>mul</code> must use a dummy variable: <code>add(x(x+1)(x-1), x=-10..10)</code>,</p></li>
+<li><p>variable substitutions with <code>subs</code>: <code>subs(subs(add(x^2+y^2,x=1..y),y=t),t=20)</code>,</p></li>
+<li><p>sequence generation using <code>seq</code> with a dummy variable: <code>seq(x^3, x=-10..10)</code>,</p></li>
+<li><p>simple recursive lists with <code>rseq</code>, with <code>@</code> given the last value, <code>rseq(1;2@+1,i=1..10)</code>,</p></li>
+<li><p>higher recursion with <code>rrseq</code>, <code>@1</code>, <code>@2</code>, <code>@3</code>, <code>@4</code>, and <code>@@(n)</code> for earlier values, up to <code>n=K</code> where <code>K</code> is the number of terms of the initial stretch <code>rrseq(0,1;@1+@2,i=2..100)</code>,</p></li>
+<li><p>iteration with <code>iter</code> which is like <code>rrseq</code> but outputs only the last <code>K</code> terms, where <code>K</code> was the number of initial terms,</p></li>
+<li><p>inside <code>seq</code>, <code>rseq</code>, <code>rrseq</code>, <code>iter</code>, possibility to use <code>omit</code>, <code>abort</code> and <code>break</code> to control termination,</p></li>
+<li><p><code>n++</code> potentially infinite index generation for <code>seq</code>, <code>rseq</code>, <code>rrseq</code>, and <code>iter</code>, it is advised to use <code>abort</code> or <code>break(..)</code> at some point,</p></li>
+<li><p>the <code>add</code>, <code>mul</code>, <code>seq</code>, … are nestable,</p></li>
+<li><p><code>\xintthecoords</code> converts a comma separated list of an even number of items to the format expected by the <code>TikZ</code> <code>coordinates</code> syntax,</p></li>
+<li><p>completely new version <code>\xintNewExpr</code>, <code>protect</code> function to handle external macros. The dollar sign <code>$</code> for place holders is not accepted anymore, only the standard macro parameter <code>#</code>. Not all constructs are compatible with <code>\xintNewExpr</code>.</p></li>
+</ul>
+<h3 id="bug-fixes-18">Bug fixes</h3>
+<ul>
+<li><p><code>\xintZapFirstSpaces</code> hence also <code>\xintZapSpaces</code> from package <strong>xinttools</strong> were buggy when used with an argument either empty or containing only space tokens.</p></li>
+<li><p><code>\xintiiexpr</code> did not strip leading zeroes, hence <code>\xinttheiiexpr 001+1\relax</code> did not obtain the expected result …</p></li>
+<li><p><code>\xinttheexpr \xintiexpr 1.23\relax\relax</code> should have produced <code>1</code>, but it produced <code>1.23</code></p></li>
+<li><p>the catcode of <code>;</code> was not set at package launching time.</p></li>
+<li><p>the <code>\XINTinFloatPrd:csv</code> macro name had a typo, hence <code>prd</code> was non-functional in <code>\xintfloatexpr</code>.</p></li>
+</ul>
+<h2 id="n-20140401"><code>1.09n (2014/04/01)</code></h2>
+<ul>
+<li><p>the user manual does not include by default the source code anymore: the <code>\NoSourceCode</code> toggle in file <code>xint.tex</code> has to be set to 0 before compilation to get source code inclusion (later release <code>1.1</code> made source code available as <code>sourcexint.pdf</code>).</p></li>
+<li><p>bug fix (<strong>xinttools</strong>) in <code>\XINT_nthelt_finish</code> (this bug was introduced in <code>1.09i</code> of <code>2013/12/18</code> and showed up when the index <code>N</code> was larger than the number of elements of the list).</p></li>
+</ul>
+<h2 id="m-20140226"><code>1.09m (2014/02/26)</code></h2>
+<ul>
+<li><p>new in <strong>xinttools</strong>: <code>\xintKeep</code> keeps the first <code>N</code> or last <code>N</code> elements of a list (sequence of braced items); <code>\xintTrim</code> cuts out either the first <code>N</code> or the last <code>N</code> elements from a list.</p></li>
+<li><p>new in <strong>xintcfrac</strong>: <code>\xintFGtoC</code> finds the initial partial quotients common to two numbers or fractions <code>f</code> and <code>g</code>; <code>\xintGGCFrac</code> is a clone of <code>\xintGCFrac</code> which however does not assume that the coefficients of the generalized continued fraction are numeric quantities. Some other minor changes.</p></li>
+</ul>
+<h2 id="kb-20140213"><code>1.09kb (2014/02/13)</code></h2>
+<ul>
+<li><p>bug fix (<strong>xintexpr</strong>): an aloof modification done by <code>1.09i</code> to <code>\xintNewExpr</code> had resulted in a spurious trailing space present in the outputs of all macros created by <code>\xintNewExpr</code>, making nesting of such macros impossible.</p></li>
+<li><p>bug fix (<strong>xinttools</strong>): <code>\xintBreakFor</code> and <code>\xintBreakForAndDo</code> were buggy when used in the last iteration of an <code>\xintFor</code> loop.</p></li>
+<li><p>bug fix (<strong>xinttools</strong>): <code>\xintSeq</code> from <code>1.09k</code> needed a <code>\chardef</code> which was missing from <code>xinttools.sty</code>, it was in <code>xint.sty</code>.</p></li>
+</ul>
+<h2 id="k-20140121"><code>1.09k (2014/01/21)</code></h2>
+<ul>
+<li><p>inside <code>\xintexpr..\relax</code> (and its variants) tacit multiplication is implied when a number or operand is followed directly with an opening parenthesis,</p></li>
+<li><p>the <code>&quot;</code> for denoting (arbitrarily big) hexadecimal numbers is recognized by <code>\xintexpr</code> and its variants (package <strong>xintbinhex</strong> is required); a fractional hexadecimal part introduced by a dot <code>.</code> is allowed.</p></li>
+<li><p>re-organization of the first sections of the user manual.</p></li>
+<li><p>bug fix (<strong>xinttools</strong>, <strong>xint</strong>, …): forgotten catcode check of <code>&quot;</code> at loading time has been added.</p></li>
+</ul>
+<h2 id="j-20140109"><code>1.09j (2014/01/09)</code></h2>
+<ul>
+<li><p>(<strong>xint</strong>) the core division routines have been re-written for some (limited) efficiency gain, more pronounced for small divisors. As a result the <em>computation of one thousand digits of <span class="math inline"><em>π</em></span></em> is close to three times faster than with earlier releases.</p></li>
+<li><p>some various other small improvements, particularly in the power routines.</p></li>
+<li><p>(<strong>xintfrac</strong>) a macro <code>\xintXTrunc</code> 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 <code>\edef</code>, <code>\write</code>, <code>\message</code>, . It can thus not be nested as argument to another package macro.</p></li>
+<li><p>(<strong>xintexpr</strong>) the tacit multiplication done in <code>\xintexpr..\relax</code> on encountering a count register or variable, or a <code>\numexpr</code>, while scanning a (decimal) number, is extended to the case of a sub <code>\xintexpr</code>-ession.</p></li>
+<li><p><code>\xintexpr</code> can now be used in an <code>\edef</code> with no <code>\xintthe</code> prefix; it will execute completely the computation, and the error message about a missing <code>\xintthe</code> will be inhibited. Previously, in the absence of <code>\xintthe</code>, expansion could only be a full one (with <code>\romannumeral-`0</code>), not a complete one (with <code>\edef</code>). Note that this differs from the behavior of the non-expandable <code>\numexpr</code>: <code>\the</code> or <code>\number</code> (or <code>\romannumeral</code>) are needed not only to print but also to trigger the computation, whereas <code>\xintthe</code> is mandatory only for the printing step.</p></li>
+<li><p>the default behavior of <code>\xintAssign</code> 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.</p></li>
+<li><p>bug fix (<strong>xintfrac</strong>): <code>1.09i</code> did an unexplainable change to <code>\XINT_infloat_zero</code> which broke the floating point routines for vanishing operands =:(((</p></li>
+<li><p>bug fix: the <code>1.09i</code> <code>xint.ins</code> file produced a buggy <code>xint.tex</code> file.</p></li>
+</ul>
+<h2 id="i-20131218"><code>1.09i (2013/12/18)</code></h2>
+<ul>
+<li><p>(<strong>xintexpr</strong>) <code>\xintiiexpr</code> is a variant of <code>\xintexpr</code> which is optimized to deal only with (long) integers, <code>/</code> does a euclidean quotient.</p></li>
+<li><p><em>deprecated</em>: <code>\xintnumexpr</code>, <code>\xintthenumexpr</code>, <code>\xintNewNumExpr</code> are renamed, respectively, <code>\xintiexpr</code>, <code>\xinttheiexpr</code>, <code>\xintNewIExpr</code>. The earlier denominations are kept but are to be removed at some point.</p></li>
+<li><p>it is now possible within <code>\xintexpr...\relax</code> and its variants to use count, dimen, and skip registers or variables without explicit <code>\the/\number</code>: the parser inserts automatically <code>\number</code> and a tacit multiplication is implied when a register or variable immediately follows a number or fraction. Regarding dimensions and <code>\number</code>, see the further discussion in <em>Dimensions</em>.</p></li>
+<li><p>(<strong>xintfrac</strong>) conditional <code>\xintifOne</code>; <code>\xintifTrueFalse</code> renamed to <code>\xintifTrueAelseB</code>; macros <code>\xintTFrac</code> (<code>fractional part</code>, mapped to function <code>frac</code> in <code>\xintexpr</code>-essions), <code>\xintFloatE</code>.</p></li>
+<li><p>(<strong>xinttools</strong>) <code>\xintAssign</code> admits an optional argument to specify the expansion type to be used: <code>[]</code> (none, default), <code>[o]</code> (once), <code>[oo]</code> (twice), <code>[f]</code> (full), <code>[e]</code> (<code>\edef</code>),… to define the macros</p></li>
+<li><p><strong>xinttools</strong> defines <code>\odef</code>, <code>\oodef</code>, <code>\fdef</code> (if the names have already been assigned, it uses <code>\xintoodef</code> etc…). These tools are provided for the case one uses the package macros in a non-expandable context. <code>\oodef</code> expands twice the macro replacement text, and <code>\fdef</code> applies full expansion. They are useful in situations where one does not want a full <code>\edef</code>. <code>\fdef</code> appears to be faster than <code>\oodef</code> in almost all cases (with less than thousand digits in the result), and even faster than <code>\edef</code> for expanding the package macros when the result has a few dozens of digits. <code>\oodef</code> needs that expansion ends up in thousands of digits to become competitive with the other two.</p></li>
+<li><p>some across the board slight efficiency improvement as a result of modifications of various types to <em>fork macros</em> and <em>branching conditionals</em> which are used internally.</p></li>
+<li><p>bug fix (<strong>xint</strong>): <code>\xintAND</code> and <code>\xintOR</code> inserted a space token in some cases and did not expand as promised in two steps <code>:-((</code> (bug dating back to <code>1.09a</code> I think; this bug was without consequences when using <code>&amp;</code> and <code>|</code> in <code>\xintexpr-essions</code>, it affected only the macro form).</p></li>
+<li><p>bug fix (<strong>xintcfrac</strong>): <code>\xintFtoCCv</code> still ended fractions with the <code>[0]</code>’s which were supposed to have been removed since release <code>1.09b</code>.</p></li>
+<li><p><em>deprecated</em>: <code>\xintifTrueFalse</code>, <code>\xintifTrue</code>; use <code>\xintifTrueAelseB</code>.</p></li>
+</ul>
+<h2 id="h-20131128"><code>1.09h (2013/11/28)</code></h2>
+<ul>
+<li><p>parts of the documentation have been re-written or re-organized, particularly the discussion of expansion issues and of input and output formats.</p></li>
+<li><p>the expansion types of macro arguments are documented in the margin of the macro descriptions, with conventions mainly taken over from those in the <code>LaTeX3</code> documentation.</p></li>
+<li><p>a dependency of <strong>xinttools</strong> on <strong>xint</strong> (inside <code>\xintSeq</code>) has been removed.</p></li>
+<li><p>(<strong>xintgcd</strong>) <code>\xintTypesetEuclideAlgorithm</code> and <code>\xintTypesetBezoutAlgorithm</code> have been slightly modified (regarding indentation).</p></li>
+<li><p>(<strong>xint</strong>) macros <code>xintiSum</code> and <code>xintiPrd</code> are renamed to <code>\xintiiSum</code> and <code>\xintiiPrd</code>.</p></li>
+<li><p>(<strong>xinttools</strong>) a count register used in <code>1.09g</code> in the <code>\xintFor</code> loops for parsing purposes has been removed and replaced by use of a <code>\numexpr</code>.</p></li>
+<li><p>the few uses of <code>\loop</code> have been replaced by <code>\xintloop/\xintiloop</code>.</p></li>
+<li><p>all macros of <strong>xinttools</strong> for which it makes sense are now declared <code>\long</code>.</p></li>
+</ul>
+<h2 id="g-20131122"><code>1.09g (2013/11/22)</code></h2>
+<ul>
+<li><p>a package <strong>xinttools</strong> is detached from <strong>xint</strong>, to make tools such as <code>\xintFor</code>, <code>\xintApplyUnbraced</code>, and <code>\xintiloop</code> available without the <strong>xint</strong> overhead.</p></li>
+<li><p>expandable nestable loops <code>\xintloop</code> and <code>\xintiloop</code>.</p></li>
+<li><p>bugfix: <code>\xintFor</code> and <code>\xintFor*</code> do not modify anymore the value of <code>\count 255</code>.</p></li>
+</ul>
+<h2 id="f-20131104"><code>1.09f (2013/11/04)</code></h2>
+<ul>
+<li><p>(<strong>xint</strong>) <code>\xintZapFirstSpaces</code>, <code>\xintZapLastSpaces</code>, <code>\xintZapSpaces</code>, <code>\xintZapSpacesB</code>, for expandably stripping away leading and/or ending spaces.</p></li>
+<li><p><code>\xintCSVtoList</code> by default uses <code>\xintZapSpacesB</code> to strip away spaces around commas (or at the start and end of the comma separated list).</p></li>
+<li><p>also the <code>\xintFor</code> loop will strip out all spaces around commas and at the start and the end of its list argument; and similarly for <code>\xintForpair</code>, <code>\xintForthree</code>, <code>\xintForfour</code>.</p></li>
+<li><p><code>\xintFor</code> <em>et al.</em> accept all macro parameters from <code>#1</code> to <code>#9</code>.</p></li>
+<li><p>for reasons of inner coherence some macros previously with one extra <code>i</code> in their names (e.g. <code>\xintiMON</code>) now have a doubled <code>ii</code> (<code>\xintiiMON</code>) to indicate that they skip the overhead of parsing their inputs via <code>\xintNum</code>. Macros with a <em>single</em> <code>i</code> such as <code>\xintiAdd</code> are those which maintain the non-<strong>xintfrac</strong> output format for big integers, but do parse their inputs via <code>\xintNum</code> (since release <code>1.09a</code>). They too may have doubled-<code>i</code> variants for matters of programming optimization when working only with (big) integers and not fractions or decimal numbers.</p></li>
+</ul>
+<h2 id="e-20131029"><code>1.09e (2013/10/29)</code></h2>
+<ul>
+<li><p>(<strong>xint</strong>) <code>\xintintegers</code>, <code>\xintdimensions</code>, <code>\xintrationals</code> for infinite <code>\xintFor</code> loops, interrupted with <code>\xintBreakFor</code> and <code>\xintBreakForAndDo</code>.</p></li>
+<li><p><code>\xintifForFirst</code>, <code>\xintifForLast</code> for the <code>\xintFor</code> and <code>\xintFor*</code> loops,</p></li>
+<li><p>the <code>\xintFor</code> and <code>xintFor*</code> loops are now <code>\long</code>, the replacement text and the items may contain explicit <code>\par</code>’s.</p></li>
+<li><p>conditionals <code>\xintifCmp</code>, <code>\xintifInt</code>, <code>\xintifOdd</code>.</p></li>
+<li><p>bug fix (<strong>xint</strong>): the <code>\xintFor</code> loop (not <code>\xintFor*</code>) did not correctly detect an empty list.</p></li>
+<li><p>bug fix (<strong>xint</strong>): <code>\xintiSqrt {0}</code> crashed. <code>:-((</code></p></li>
+<li><p>the documentation has been enriched with various additional examples, such as the <em>the quick sort algorithm illustrated</em> or the various ways of <em>computing prime numbers</em>.</p></li>
+<li><p>the documentation explains with more details various expansion related issues, particularly in relation to conditionals.</p></li>
+</ul>
+<h2 id="d-20131022"><code>1.09d (2013/10/22)</code></h2>
+<ul>
+<li><p>bug fix (<strong>xint</strong>): <code>\xintFor*</code> 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 <code>\do</code> in <code>\xintFor* #1 in {{a}{b}{c}&lt;space&gt;} \do {stuff}</code>; spaces at other locations were already harmless). Furthermore this new version <em>f-expands</em> the un-braced list items. After <code>\def\x{{1}{2}}</code> and <code>\def\y{{a}\x {b}{c}\x }</code>, <code>\y</code> will appear to <code>\xintFor*</code> exactly as if it had been defined as <code>\def\y{{a}{1}{2}{b}{c}{1}{2}}</code>.</p></li>
+<li><p>same bug fix for <code>\xintApplyInline</code>.</p></li>
+</ul>
+<h2 id="c-20131009"><code>1.09c (2013/10/09)</code></h2>
+<ul>
+<li><p>(<strong>xintexpr</strong>) added <code>bool</code> and <code>togl</code> to the <code>\xintexpr</code> syntax; also added <code>\xintboolexpr</code> and <code>\xintifboolexpr</code>.</p></li>
+<li><p>added <code>\xintNewNumExpr</code>.</p></li>
+<li><p>the factorial <code>!</code> and branching <code>?</code>, <code>:</code>, operators (in <code>\xintexpr...\relax</code>) have now less precedence than a function name located just before,</p></li>
+<li><p>(<strong>xint</strong>) <code>\xintFor</code> 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 <code>1.09f</code>) and their replacement texts are allowed to close groups as happens with the tabulation in alignments,</p></li>
+<li><p><code>\xintForpair</code>, <code>\xintForthree</code>, <code>\xintForfour</code> are experimental variants of <code>\xintFor</code>,</p></li>
+<li><p><code>\xintApplyInline</code> has been enhanced in order to be usable for generating rows (partially or completely) in an alignment,</p></li>
+<li><p>command <code>\xintSeq</code> to generate (expandably) arithmetic sequences of (short) integers,</p></li>
+<li><p>again various improvements and changes in the documentation.</p></li>
+</ul>
+<h2 id="b-20131003"><code>1.09b (2013/10/03)</code></h2>
+<ul>
+<li><p>various improvements in the documentation,</p></li>
+<li><p>more economical catcode management and re-loading handling,</p></li>
+<li><p>removal of all those <code>[0]</code>’s previously forcefully added at the end of fractions by various macros of <strong>xintcfrac</strong>,</p></li>
+<li><p><code>\xintNthElt</code> with a negative index returns from the tail of the list,</p></li>
+<li><p>macro <code>\xintPRaw</code> to have something like what <code>\xintFrac</code> does in math mode; i.e. a <code>\xintRaw</code> which does not print the denominator if it is one.</p></li>
+</ul>
+<h2 id="a-20130924"><code>1.09a (2013/09/24)</code></h2>
+<ul>
+<li><p>(<strong>xintexpr</strong>) <code>\xintexpr..\relax</code> and <code>\xintfloatexpr..\relax</code> admit functions in their syntax, with comma separated values as arguments, among them <code>reduce, sqr, sqrt, abs, sgn, floor, ceil, quo, rem, round, trunc, float, gcd, lcm, max, min, sum, prd, add, mul, not, all, any, xor</code>.</p></li>
+<li><p>comparison (<code>&lt;</code>, <code>&gt;</code>, <code>=</code>) and logical (<code>|</code>, <code>&amp;</code>) operators.</p></li>
+<li><p>the command <code>\xintthe</code> which converts <code>\xintexpr</code>essions into printable format (like <code>\the</code> with <code>\numexpr</code>) is more efficient, for example one can do <code>\xintthe\x</code> if <code>\x</code> was defined to be an <code>\xintexpr..\relax</code>:</p>
+<pre><code>\def\x{\xintexpr 3^57\relax}
+\def\y{\xintexpr \x^(-2)\relax}
+\def\z{\xintexpr \y-3^-114\relax}
+\xintthe\z</code></pre></li>
+<li><p><code>\xintnumexpr .. \relax</code> (now renamed <code>\xintiexpr</code>) is <code>\xintexpr round( .. ) \relax</code>.</p></li>
+<li><p><code>\xintNewExpr</code> now works with the standard macro parameter character <code>#</code>.</p></li>
+<li><p>both regular <code>\xintexpr</code>-essions and commands defined by <code>\xintNewExpr</code> will work with comma separated lists of expressions,</p></li>
+<li><p>commands <code>\xintFloor</code>, <code>\xintCeil</code>, <code>\xintMaxof</code>, <code>\xintMinof</code> (package <strong>xintfrac</strong>), <code>\xintGCDof</code>, <code>\xintLCM</code>, <code>\xintLCMof</code> (package <strong>xintgcd</strong>), <code>\xintifLt</code>, <code>\xintifGt</code>, <code>\xintifSgn</code>, <code>\xintANDof</code>, …</p></li>
+<li><p>The arithmetic macros from package <strong>xint</strong> now filter their operands via <code>\xintNum</code> which means that they may use directly count registers and <code>\numexpr</code>-essions without having to prefix them by <code>\the</code>. This is thus similar to the situation holding previously already when <strong>xintfrac</strong> was loaded.</p></li>
+<li><p>a bug (<strong>xintfrac</strong>) introduced in <code>1.08b</code> made <code>\xintCmp</code> crash when one of its arguments was zero. <code>:-((</code></p></li>
+</ul>
+<h2 id="b-20130614"><code>1.08b (2013/06/14)</code></h2>
+<ul>
+<li><p>(<strong>xintexpr</strong>) Correction of a problem with spaces inside <code>\xintexpr</code>-essions.</p></li>
+<li><p>(<strong>xintfrac</strong>) Additional improvements to the handling of floating point numbers.</p></li>
+<li><p>section <em>Use of count registers</em> documenting how count registers may be directly used in arguments to the macros of <strong>xintfrac</strong>.</p></li>
+</ul>
+<h2 id="a-20130611"><code>1.08a (2013/06/11)</code></h2>
+<ul>
+<li><p>(<strong>xintfrac</strong>) Improved efficiency of the basic conversion from exact fractions to floating point numbers, with ensuing speed gains especially for the power function macros <code>\xintFloatPow</code> and <code>\xintFloatPower</code>,</p></li>
+<li><p>Better management by <code>\xintCmp</code>, <code>\xintMax</code>, <code>\xintMin</code> and <code>\xintGeq</code> of inputs having big powers of ten in them.</p></li>
+<li><p>Macros for floating point numbers added to the <strong>xintseries</strong> package.</p></li>
+</ul>
+<h2 id="section-3"><code>1.08 (2013/06/07)</code></h2>
+<ul>
+<li><p>(<strong>xint</strong> and <strong>xintfrac</strong>) Macros for extraction of square roots, for floating point numbers (<code>\xintFloatSqrt</code>), and integers (<code>\xintiSqrt</code>).</p></li>
+<li><p>new package <strong>xintbinhex</strong> providing <em>conversion routines</em> to and from binary and hexadecimal bases.</p></li>
+</ul>
+<h2 id="section-4"><code>1.07 (2013/05/25)</code></h2>
+<ul>
+<li><p>The <strong>xintexpr</strong> package is a new core constituent (which loads automatically <strong>xintfrac</strong> and <strong>xint</strong>) and implements the expandable expanding parser</p>
+<pre><code>\xintexpr . . . \relax,</code></pre>
+<p>and its variant</p>
+<pre><code>\xintfloatexpr . . . \relax</code></pre>
+<p>allowing on input formulas using the infix operators <code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>, and <code>^</code>, and arbitrary levels of parenthesizing. Within a float expression the operations are executed according to the current value set by <code>\xintDigits</code>. Within an <code>\xintexpr</code>-ession the binary operators are computed exactly.</p>
+<p>To write the <code>\xintexpr</code> parser I benefited from the commented source of the <code>l3fp</code> parser; the <code>\xintexpr</code> parser has its own features and peculiarities. <em>See its documentation</em>.</p></li>
+<li><p>The floating point precision <code>D</code> is set (this is a local assignment to a <code>\mathchar</code> variable) with <code>\xintDigits := D;</code> and queried with <code>\xinttheDigits</code>. It may be set to anything up to <code>32767</code>.<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a> The macro incarnations of the binary operations admit an optional argument which will replace pointwise <code>D</code>; this argument may exceed the <code>32767</code> bound.</p></li>
+<li><p>The <strong>xintfrac</strong> macros now accept numbers written in scientific notation, the <code>\xintFloat</code> command serves to output its argument with a given number <code>D</code> of significant figures. The value of <code>D</code> is either given as optional argument to <code>\xintFloat</code> or set with <code>\xintDigits := D;</code>. The default value is <code>16</code>.</p></li>
+</ul>
+<h2 id="b-20130514"><code>1.06b (2013/05/14)</code></h2>
+<ul>
+<li>Minor code and documentation improvements. Everywhere in the source code, a more modern underscore has replaced the @ sign.</li>
+</ul>
+<h2 id="section-5"><code>1.06 (2013/05/07)</code></h2>
+<ul>
+<li><p>Some code improvements, particularly for macros of <strong>xint</strong> doing loops.</p></li>
+<li><p>New utilities in <strong>xint</strong> for expandable manipulations of lists:</p>
+<pre><code>\xintNthElt, \xintCSVtoList, \xintRevWithBraces</code></pre></li>
+<li><p>The macros did only a double expansion of their arguments. They now fully expand them (using <code>\romannumeral-`0</code>). Furthermore, in the case of arguments constrained to obey the TeX bounds they will be inserted inside a <code>\numexpr..\relax</code>, hence completely expanded, one may use count registers, even infix arithmetic operations, etc…</p></li>
+</ul>
+<h2 id="section-6"><code>1.05 (2013/05/01)</code></h2>
+<p>Minor changes and additions to <strong>xintfrac</strong> and <strong>xintcfrac</strong>.</p>
+<h2 id="section-7"><code>1.04 (2013/04/25)</code></h2>
+<ul>
+<li><p>New component <strong>xintcfrac</strong> devoted to continued fractions.</p></li>
+<li><p><strong>xint</strong>: faster division.</p></li>
+<li><p><strong>xint</strong>: added expandable macros <code>\xintListWithSep</code> and <code>\xintApply</code> to handle token lists.</p></li>
+<li><p><strong>xintfrac</strong>: added <code>\xintRound</code>.</p></li>
+<li><p><strong>xintseries</strong> has a new implementation of <code>\xintPowerSeries</code> based on a Horner scheme, and new macro <code>\xintRationalSeries</code>. Both to help deal with the <em>denominator buildup</em> plague.</p></li>
+<li><p><code>tex xint.dtx</code> extracts style files (no need for a <code>xint.ins</code>).</p></li>
+<li><p>Bug fix (<strong>xintfrac</strong>): <code>\xintIrr {0}</code> crashed.</p></li>
+</ul>
+<h2 id="section-8"><code>1.03 (2013/04/14)</code></h2>
+<ul>
+<li><p>New modules <strong>xintfrac</strong> (expandable operations on fractions) and <strong>xintseries</strong> (expandable partial sums with xint package).</p></li>
+<li><p>Slightly improved division and faster multiplication (the best ordering of the arguments is chosen automatically).</p></li>
+<li><p>Added illustration of Machin algorithm to the documentation.</p></li>
+</ul>
+<h2 id="section-9"><code>1.0 (2013/03/28)</code></h2>
+<p>Initial announcement:</p>
+<blockquote>
+<p>The <strong>xint</strong> 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.</p>
+</blockquote>
+<blockquote>
+<p>The <strong>xintgcd</strong> package provides implementations of the Euclidean algorithm and of its typesetting.</p>
+</blockquote>
+<blockquote>
+<p>The packages may be used with Plain and with LaTeX.</p>
+</blockquote>
+<section class="footnotes">
+<hr />
+<ol>
+<li id="fn1"><p>but values higher than 100 or 200 will presumably give too slow evaluations.<a href="#fnref1" class="footnote-back">↩</a></p></li>
+</ol>
+</section>
+</body>
+</html>
diff --git a/macros/generic/xint/CHANGES.pdf b/macros/generic/xint/CHANGES.pdf
new file mode 100644
index 0000000000..5ae2956477
--- /dev/null
+++ b/macros/generic/xint/CHANGES.pdf
Binary files differ
diff --git a/macros/generic/xint/Makefile b/macros/generic/xint/Makefile
new file mode 100644
index 0000000000..df8fd9a051
--- /dev/null
+++ b/macros/generic/xint/Makefile
@@ -0,0 +1,20 @@
+# Makefile for compilation of the complete xint
+# documentation, packages, and installation.
+# (C) 2014-2015 Jean-Francois Burnol
+# distributed under LPPL 1.3c or later at your convenience.
+
+# with this file Makefile and xint.dtx in a working
+# repertory run 'make' and then get further instructions.
+
+# Tested with GNU Make 3.81 on Mac OS X Mavericks,
+# with TeXLive 2014 and Pandoc 1.13.1, xint.dtx v1.1
+
+# For some reason I would like Makefile.mk to be always
+# recreated if xint.dtx is newer, *before* being included
+# here via include, but my brief attempt (2015/09/16) did
+# not succeed.
+
+Makefile.mk: xint.dtx ; etex xint.dtx
+
+include Makefile.mk
+
diff --git a/macros/generic/xint/README b/macros/generic/xint/README
new file mode 100644
index 0000000000..9bd0a96470
--- /dev/null
+++ b/macros/generic/xint/README
@@ -0,0 +1,205 @@
+ Source: xint.dtx 1.3e 2019/04/05 (doc 2019/04/05)
+ Author: Jean-Francois Burnol
+ Info: Expandable operations on big integers, decimals, fractions
+ License: LPPL 1.3e
+
+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 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 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 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 (hence also MacTeX) and MikTeX.
+
+There can be a few days of delay between apparition of a new version on
+CTAN 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 and
+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
+
+
+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.
diff --git a/macros/generic/xint/README.html b/macros/generic/xint/README.html
new file mode 100644
index 0000000000..cc66a4ab5d
--- /dev/null
+++ b/macros/generic/xint/README.html
@@ -0,0 +1,133 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
+<head>
+ <meta charset="utf-8" />
+ <meta name="generator" content="pandoc" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
+ <meta name="author" content="xint 1.3e" />
+ <title>README</title>
+ <style type="text/css">
+ code{white-space: pre-wrap;}
+ span.smallcaps{font-variant: small-caps;}
+ span.underline{text-decoration: underline;}
+ div.column{display: inline-block; vertical-align: top; width: 50%;}
+ </style>
+ <style type="text/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;}
+ </style>
+ <!--[if lt IE 9]>
+ <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
+ <![endif]-->
+</head>
+<body>
+<header>
+<h1 class="title">README</h1>
+<p class="author">xint 1.3e</p>
+<p class="date">2019/04/05</p>
+</header>
+<nav id="TOC">
+<ul>
+<li><a href="#aim">Aim</a></li>
+<li><a href="#usage">Usage</a><ul>
+<li><a href="#with-latex">With LaTeX</a></li>
+<li><a href="#with-tex">With TeX</a></li>
+</ul></li>
+<li><a href="#installation">Installation</a><ul>
+<li><a href="#method-a-using-the-package-manager-of-your-tex-distribution">Method A: using the package manager of your TeX distribution</a></li>
+<li><a href="#method-b-manual-installation-using-xint.tds.zip-and-unzip">Method B: manual installation using <code>xint.tds.zip</code> and <code>unzip</code></a></li>
+<li><a href="#method-c-manual-installation-using-makefile-and-xint.dtx">Method C: manual installation using <code>Makefile</code> and <code>xint.dtx</code></a></li>
+<li><a href="#method-d-installation-starting-with-only-xint.dtx">Method D: installation starting with only <code>xint.dtx</code></a></li>
+</ul></li>
+<li><a href="#license">License</a></li>
+</ul>
+</nav>
+<pre><code>Source: xint.dtx 1.3e 2019/04/05 (doc 2019/04/05)
+Author: Jean-Francois Burnol
+Info: Expandable operations on big integers, decimals, fractions
+License: LPPL 1.3e</code></pre>
+<p>This <code>README</code> is also available as <code>README.pdf</code> and <code>README.html</code>.</p>
+<p>Change log is to be found in <code>CHANGES.pdf</code> or <code>CHANGES.html</code>.</p>
+<p>The user manual is <code>xint.pdf</code>, and the commented source code is available as <code>sourcexint.pdf</code>.</p>
+<h1 id="aim">Aim</h1>
+<p>The basic aim is provide <em>expandable</em> computations on integers, fractions, and floating point numbers. For example</p>
+<pre><code>\xinttheexpr reduce(37189719/183618963+11390170/17310720)^17\relax</code></pre>
+<p>will evaluate exactly the fraction; the result has 462 characters (including the fraction slash.) One can also work with dummy variables:</p>
+<pre><code>\xinttheexpr mul(add(x(x+1)(x+2), x=y..y+15), y=171286,98762,9296)\relax</code></pre>
+<p>evaluates to <code>15979066346135829902328007959448563667099190784</code>.</p>
+<p>Float computations are possible at an adjustable precision (default 16).</p>
+<pre><code>\xintDigits:=48;\xintthefloatexpr 123_456_789^1_000.5\relax
+-&gt;3.63692761822782679930738270515740797370813691938e8095</code></pre>
+<p>(as this example shows the underscore character can be used to separate visually digits, one can also use the space character for that purpose).</p>
+<p>Square-root and the four operations achieve correct rounding in the given arbitrary precision.</p>
+<p>Trigonometric functions (direct and inverse) are available with a maximal precision of 60 digits.</p>
+<p>Logarithms and exponentials are available using the <a href="http://www.ctan.org/pkg/poormanlog">poormanlog</a> package which provides only 8 or 9 digits of precision. This will be increased in future.</p>
+<h1 id="usage">Usage</h1>
+<p>It is possible to use the package both with Plain (<code>\input xintexpr.sty</code>) or with LaTeX (<code>\usepackage{xintexpr}</code>).</p>
+<h2 id="with-latex">With LaTeX</h2>
+<pre><code>\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</code></pre>
+<p>The <code>xinttrig</code> and <code>xintlog</code> packages are loaded automatically by <code>xintexpr</code> and will refuse to be loaded directly.</p>
+<p>Further packages: <code>xintbinhex</code>, <code>xintgcd</code>, <code>xintseries</code> and <code>xintcfrac</code>.</p>
+<p>Main dependencies are handled automatically. For example <code>xintexpr</code> automatically loads <code>xinttools</code> and <code>xintfrac</code> (which itself loads <code>xint</code>). Hexadecimal input requires explicit loading of <code>xintbinhex</code>.</p>
+<p>Package <code>xintcore</code> is the subset of <code>xint</code> providing only the five operations on big integers: <code>\xintiiAdd</code>, <code>\xintiiMul</code>, …</p>
+<p>The LaTeX package <a href="http://www.ctan.org/pkg/bnumexpr">bnumexpr</a> 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 <code>xintcore</code> but this can be customized.</p>
+<p>The LaTeX package <a href="http://www.ctan.org/pkg/polexpr">polexpr</a> is based upon <code>xintexpr</code> and allows formal algebra with polynomials, and finding all real roots with arbitrary precision.</p>
+<h2 id="with-tex">With TeX</h2>
+<p>One does for example:</p>
+<pre><code>\input xintexpr.sty</code></pre>
+<p>This will automatically load <code>xintfrac.sty</code>, <code>xinttrig.sty</code>, <code>xintlog.sty</code> and <code>xinttools.sty</code>. The packages may be loaded in any catcode context such that letters, digits, <code>\</code> and <code>%</code> have their standard catcodes.</p>
+<p><code>xintcore.sty</code> and <code>xinttools.sty</code> both import <code>xintkernel.sty</code> which has the catcode handler and package identifier and defines a few utilities such as <code>\oodef/\fdef</code>, <code>\xint_dothis/\xint_orthat</code>, or <code>\xintLength</code>.</p>
+<p>Since <code>1.3b</code>, <code>xintkernel.sty</code> also provides <code>\xintUniformDeviate</code> which is a wrapper of the engine <code>\pdfuniformdeviate</code> or <code>\uniformdeviate</code> done to guarantee more uniformity of the pseudo-random integers.</p>
+<h1 id="installation">Installation</h1>
+<h2 id="method-a-using-the-package-manager-of-your-tex-distribution">Method A: using the package manager of your TeX distribution</h2>
+<p><code>xint</code> is included in <a href="http://tug.org/texlive/">TeXLive</a> (hence also <a href="http://tug.org/mactex/">MacTeX</a>) and <a href="http://www.miktex.org/">MikTeX</a>.</p>
+<p>There can be a few days of delay between apparition of a new version on <a href="http://www.ctan.org/pkg/xint">CTAN</a> and availability via the distribution package manager.</p>
+<h2 id="method-b-manual-installation-using-xint.tds.zip-and-unzip">Method B: manual installation using <code>xint.tds.zip</code> and <code>unzip</code></h2>
+<p>Assumes a GNU/Linux-like system (or Mac OS X).</p>
+<ol type="1">
+<li><p>obtain <code>xint.tds.zip</code> from CTAN: <a href="http://mirror.ctan.org/install/macros/generic/xint.tds.zip" class="uri">http://mirror.ctan.org/install/macros/generic/xint.tds.zip</a></p></li>
+<li><p>cd to the download repertory and issue:</p>
+<pre><code> unzip xint.tds.zip -d &lt;TEXMF&gt;</code></pre>
+<p>where <code>&lt;TEXMF&gt;</code> is a suitable TDS-compliant destination repertory. For example, with TeXLive:</p>
+<ul>
+<li><p>Linux, standard access rights, hence sudo is needed, installation into the “local” tree:</p>
+<pre><code> sudo unzip xint.tds.zip -d /usr/local/texlive/texmf-local
+ sudo texhash /usr/local/texlive/texmf-local</code></pre></li>
+<li><p>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):</p>
+<pre><code> unzip xint.tds.zip -d ~/Library/texmf</code></pre></li>
+</ul></li>
+</ol>
+<h2 id="method-c-manual-installation-using-makefile-and-xint.dtx">Method C: manual installation using <code>Makefile</code> and <code>xint.dtx</code></h2>
+<p>The Makefile automatizes rebuilding from <code>xint.dtx</code> all documentation files as well as <code>xint.tds.zip</code>. It is for GNU/Linux-like (inc. Mac OS X) systems, with a teTeX like installation such as TeXLive. The <a href="http://personal.psu.edu/jcc8/software/latexmk/">Latexmk</a> and <a href="http://johnmacfarlane.net/pandoc/">Pandoc</a> softwares are required to build all the documentation.</p>
+<ol type="1">
+<li><p>obtain <code>xint.dtx</code> and <code>Makefile</code> from <a href="http://mirror.ctan.org/macros/generic/xint" class="uri">http://mirror.ctan.org/macros/generic/xint</a>.</p></li>
+<li><p>put them in an otherwise empty working repertory, run <code>make</code> or equivalently <code>make help</code> for further instructions.</p></li>
+</ol>
+<h2 id="method-d-installation-starting-with-only-xint.dtx">Method D: installation starting with only <code>xint.dtx</code></h2>
+<p>Run <code>etex xint.dtx</code> to extract from <code>xint.dtx</code> all macro files as well as auxiliary files needed for building the documentation. Among them there is <code>Makefile.mk</code>. If you are on a GNU/Linux-type system, rename the file to <code>Makefile</code> and execute <code>make</code> on command line for further help. If you can’t use <code>make</code> read the contents of the <code>Makefile</code> for instructions.</p>
+<p>Finishing the installation in a TDS hierarchy:</p>
+<ul>
+<li><p>move the style files to <code>TDS:tex/generic/xint/</code></p></li>
+<li><p><code>xint.dtx</code> goes to <code>TDS:source/generic/xint/</code></p></li>
+<li><p>The documentation (xint.pdf, README.md,…) goes to <code>TDS:doc/generic/xint/</code></p></li>
+</ul>
+<p>Depending on the destination, it may then be necessary to refresh a filename database.</p>
+<h1 id="license">License</h1>
+<div class="mono">
+<p>Copyright (C) 2013-2019 by Jean-Francois Burnol</p>
+<p>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</p>
+<blockquote>
+<p><a href="http://www.latex-project.org/lppl/lppl-1-3c.txt" class="uri">http://www.latex-project.org/lppl/lppl-1-3c.txt</a></p>
+</blockquote>
+<p>and version 1.3 or later is part of all distributions of LaTeX version 2005/12/01 or later.</p>
+<p>This Work has the LPPL maintenance status <code>author-maintained</code>.</p>
+<p>The Author of this Work is Jean-Francois Burnol.</p>
+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>
+</body>
+</html>
diff --git a/macros/generic/xint/README.pdf b/macros/generic/xint/README.pdf
new file mode 100644
index 0000000000..dd4181d4cc
--- /dev/null
+++ b/macros/generic/xint/README.pdf
Binary files differ
diff --git a/macros/generic/xint/sourcexint.pdf b/macros/generic/xint/sourcexint.pdf
new file mode 100644
index 0000000000..4503773c79
--- /dev/null
+++ b/macros/generic/xint/sourcexint.pdf
Binary files differ
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
diff --git a/macros/generic/xint/xint.pdf b/macros/generic/xint/xint.pdf
new file mode 100644
index 0000000000..991d2ac665
--- /dev/null
+++ b/macros/generic/xint/xint.pdf
Binary files differ