summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
Diffstat (limited to 'Master')
-rw-r--r--Master/texmf-dist/doc/generic/xint/CHANGES.html220
-rw-r--r--Master/texmf-dist/doc/generic/xint/CHANGES.pdfbin101153 -> 104210 bytes
-rw-r--r--Master/texmf-dist/doc/generic/xint/README60
-rw-r--r--Master/texmf-dist/doc/generic/xint/README.html28
-rw-r--r--Master/texmf-dist/doc/generic/xint/README.pdfbin31548 -> 32957 bytes
-rw-r--r--Master/texmf-dist/doc/generic/xint/sourcexint.pdfbin1530668 -> 919178 bytes
-rw-r--r--Master/texmf-dist/doc/generic/xint/xint.pdfbin931961 -> 987296 bytes
-rw-r--r--Master/texmf-dist/source/generic/xint/xint.dtx4324
-rw-r--r--Master/texmf-dist/source/generic/xint/xint.ins92
-rw-r--r--Master/texmf-dist/tex/generic/xint/xint.sty15
-rw-r--r--Master/texmf-dist/tex/generic/xint/xintbinhex.sty4
-rw-r--r--Master/texmf-dist/tex/generic/xint/xintcfrac.sty4
-rw-r--r--Master/texmf-dist/tex/generic/xint/xintcore.sty4
-rw-r--r--Master/texmf-dist/tex/generic/xint/xintexpr.sty766
-rw-r--r--Master/texmf-dist/tex/generic/xint/xintfrac.sty53
-rw-r--r--Master/texmf-dist/tex/generic/xint/xintgcd.sty4
-rw-r--r--Master/texmf-dist/tex/generic/xint/xintkernel.sty7
-rw-r--r--Master/texmf-dist/tex/generic/xint/xintlog.sty118
-rw-r--r--Master/texmf-dist/tex/generic/xint/xintseries.sty4
-rw-r--r--Master/texmf-dist/tex/generic/xint/xinttools.sty4
-rw-r--r--Master/texmf-dist/tex/generic/xint/xinttrig.sty500
21 files changed, 4543 insertions, 1664 deletions
diff --git a/Master/texmf-dist/doc/generic/xint/CHANGES.html b/Master/texmf-dist/doc/generic/xint/CHANGES.html
index 6997ee83981..5eddbff5128 100644
--- a/Master/texmf-dist/doc/generic/xint/CHANGES.html
+++ b/Master/texmf-dist/doc/generic/xint/CHANGES.html
@@ -4,7 +4,7 @@
<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.3d" />
+ <meta name="author" content="xint 1.3e" />
<title>CHANGE LOG</title>
<style type="text/css">
code{white-space: pre-wrap;}
@@ -25,119 +25,124 @@
<body>
<header>
<h1 class="title">CHANGE LOG</h1>
-<p class="author">xint 1.3d</p>
-<p class="date">2019/01/06</p>
+<p class="author">xint 1.3e</p>
+<p class="date">2019/04/05</p>
</header>
<nav id="TOC">
<ul>
-<li><a href="#d-20190106"><code>1.3d (2019/01/06)</code></a><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="#c-20180617"><code>1.3c (2018/06/17)</code></a><ul>
+<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="#b-20180518"><code>1.3b (2018/05/18)</code></a><ul>
+<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="#a-20180307"><code>1.3a (2018/03/07)</code></a><ul>
-<li><a href="#removed">Removed</a></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>
-<li><a href="#bug-fixes-2">Bug fixes</a></li>
</ul></li>
-<li><a href="#section"><code>1.3 (2018/03/01)</code></a><ul>
-<li><a href="#incompatible-changes-1">Incompatible changes</a></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>
-</ul></li>
-<li><a href="#q-20180206"><code>1.2q (2018/02/06)</code></a><ul>
-<li><a href="#improvements-and-new-features-5">Improvements and new features</a></li>
<li><a href="#bug-fixes-3">Bug fixes</a></li>
</ul></li>
-<li><a href="#p-20171205"><code>1.2p (2017/12/05)</code></a><ul>
+<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="#o-20170829"><code>1.2o (2017/08/29)</code></a><ul>
+<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="#deprecated">Deprecated</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="#n-20170806"><code>1.2n (2017/08/06)</code></a><ul>
+<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="#improvements-and-new-features-7">Improvements and new features</a></li>
+<li><a href="#deprecated">Deprecated</a></li>
</ul></li>
-<li><a href="#m-20170731"><code>1.2m (2017/07/31)</code></a><ul>
+<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>
-<li><a href="#bug-fixes-5">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="#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="#k-20170106"><code>1.2k (2017/01/06)</code></a><ul>
-<li><a href="#incompatible-changes-6">Incompatible changes</a></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="#j-20161222"><code>1.2j (2016/12/22)</code></a><ul>
+<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="#i-20161213"><code>1.2i (2016/12/13)</code></a><ul>
-<li><a href="#incompatible-changes-7">Incompatible changes</a></li>
-<li><a href="#removed-2">Removed</a></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="#h-20161120"><code>1.2h (2016/11/20)</code></a><ul>
+<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="#g-20160319"><code>1.2g (2016/03/19)</code></a><ul>
-<li><a href="#incompatible-changes-8">Incompatible changes</a></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="#f-20160312"><code>1.2f (2016/03/12)</code></a><ul>
+<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>
-<li><a href="#bug-fixes-11">Bug fixes</a></li>
</ul></li>
-<li><a href="#e-20151122"><code>1.2e (2015/11/22)</code></a><ul>
+<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="#d-20151118"><code>1.2d (2015/11/18)</code></a><ul>
+<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="#c-20151116"><code>1.2c (2015/11/16)</code></a><ul>
+<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="#b-20151029"><code>1.2b (2015/10/29)</code></a><ul>
+<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="#a-20151019"><code>1.2a (2015/10/19)</code></a><ul>
-<li><a href="#improvements-and-new-features-19">Improvements and new features</a></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-20">Improvements and new features</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-10">Incompatible changes</a></li>
+<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-21">Improvements and new features</a></li>
-<li><a href="#bug-fixes-17">Bug fixes</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>
@@ -165,31 +170,50 @@
<li><a href="#section-9"><code>1.0 (2013/03/28)</code></a></li>
</ul>
</nav>
-<pre><code>Source: xint.dtx 1.3d 2019/01/06 (doc 2019/01/06)
+<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.3d</code></pre>
-<h2 id="d-20190106"><code>1.3d (2019/01/06)</code></h2>
+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">Improvements and new features</h3>
+<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>\xintthexpr...\relax</code> etc…, but with the (comma-separated) expression as a usual braced macro argument.</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">Bug fixes</h3>
+<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-1">Improvements and new features</h3>
+<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>
@@ -197,12 +221,12 @@ License: LPPL 1.3d</code></pre>
<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-1">Bug fixes</h3>
+<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-2">Improvements and new features</h3>
+<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>
@@ -217,41 +241,41 @@ License: LPPL 1.3d</code></pre>
<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-3">Improvements and new features</h3>
+<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-2">Bug fixes</h3>
+<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-1">Incompatible changes</h3>
+<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-4">Improvements and new features</h3>
+<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-5">Improvements and new features</h3>
+<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-3">Bug fixes</h3>
+<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-2">Incompatible changes</h3>
+<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>
@@ -259,13 +283,13 @@ License: LPPL 1.3d</code></pre>
<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-6">Improvements and new features</h3>
+<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-4">Bug fixes</h3>
+<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>
@@ -273,7 +297,7 @@ License: LPPL 1.3d</code></pre>
<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-3">Incompatible changes</h3>
+<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>
@@ -289,26 +313,26 @@ License: LPPL 1.3d</code></pre>
<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-4">Incompatible changes</h3>
+<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-7">Improvements and new features</h3>
+<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-5">Incompatible changes</h3>
+<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-8">Improvements and new features</h3>
+<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-5">Bug fixes</h3>
+<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>
@@ -320,7 +344,7 @@ License: LPPL 1.3d</code></pre>
<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-9">Improvements and new features</h3>
+<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>
@@ -329,33 +353,33 @@ License: LPPL 1.3d</code></pre>
<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-6">Bug fixes</h3>
+<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-6">Incompatible changes</h3>
+<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-10">Improvements and new features</h3>
+<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-7">Bug fixes</h3>
+<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-11">Improvements and new features</h3>
+<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">
@@ -364,12 +388,12 @@ License: LPPL 1.3d</code></pre>
</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-8">Bug fixes</h3>
+<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-7">Incompatible changes</h3>
+<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>
@@ -377,7 +401,7 @@ License: LPPL 1.3d</code></pre>
<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-12">Improvements and new features</h3>
+<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>
@@ -396,17 +420,17 @@ License: LPPL 1.3d</code></pre>
<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-9">Bug fixes</h3>
+<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-13">Improvements and new features</h3>
+<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-10">Bug fixes</h3>
+<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>
@@ -414,12 +438,12 @@ License: LPPL 1.3d</code></pre>
<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-8">Incompatible changes</h3>
+<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-14">Improvements and new features</h3>
+<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>
@@ -428,11 +452,11 @@ License: LPPL 1.3d</code></pre>
<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-9">Incompatible changes</h3>
+<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-15">Improvements and new features</h3>
+<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>
@@ -446,60 +470,60 @@ License: LPPL 1.3d</code></pre>
<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-11">Bug fixes</h3>
+<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-16">Improvements and new features</h3>
+<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-12">Bug fixes</h3>
+<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-17">Improvements and new features</h3>
+<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-13">Bug fixes</h3>
+<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-18">Improvements and new features</h3>
+<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-14">Bug fixes</h3>
+<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-15">Bug fixes</h3>
+<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-19">Improvements and new features</h3>
+<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-16">Bug fixes</h3>
+<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>
@@ -508,7 +532,7 @@ License: LPPL 1.3d</code></pre>
<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-20">Improvements and new features</h3>
+<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>
@@ -542,7 +566,7 @@ License: LPPL 1.3d</code></pre>
<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-10">Incompatible changes</h3>
+<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>
@@ -562,7 +586,7 @@ License: LPPL 1.3d</code></pre>
<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-21">Improvements and new features</h3>
+<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>
@@ -600,7 +624,7 @@ License: LPPL 1.3d</code></pre>
<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-17">Bug fixes</h3>
+<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>
diff --git a/Master/texmf-dist/doc/generic/xint/CHANGES.pdf b/Master/texmf-dist/doc/generic/xint/CHANGES.pdf
index 1bc50a5f9a1..5ae29564773 100644
--- a/Master/texmf-dist/doc/generic/xint/CHANGES.pdf
+++ b/Master/texmf-dist/doc/generic/xint/CHANGES.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/generic/xint/README b/Master/texmf-dist/doc/generic/xint/README
index 4ee35b71c98..9bd0a964705 100644
--- a/Master/texmf-dist/doc/generic/xint/README
+++ b/Master/texmf-dist/doc/generic/xint/README
@@ -1,7 +1,7 @@
- Source: xint.dtx 1.3d 2019/01/06 (doc 2019/01/06)
+ 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.3d
+ License: LPPL 1.3e
This README is also available as README.pdf and README.html.
@@ -35,19 +35,23 @@ Float computations are possible at an adjustable precision (default 16).
(as this example shows the underscore character can be used to separate
visually digits, one can also use the space character for that purpose).
-Currently, only integer and half-integer exponents are allowed for the
-power operation in expressions and only the square-root operation is
-implemented besides the four arithmetic operations. Square-root and the
-four operations achieve correct rounding in the given arbitrary
-precision.
+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 with Plain (using for example
-\input xintexpr.sty) or with LaTeX (\usepackage{xintexpr}).
+It is possible to use the package both with Plain (\input xintexpr.sty)
+or with LaTeX (\usepackage{xintexpr}).
With LaTeX
@@ -57,12 +61,14 @@ With LaTeX
\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).
-But the gcd()/lcm() functions require extra loading of xintgcd and
-hexadecimal input requires xintbinhex.
+Hexadecimal input requires explicit loading of xintbinhex.
Package xintcore is the subset of xint providing only the five
operations on big integers: \xintiiAdd, \xintiiMul, …
@@ -73,6 +79,10 @@ 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
@@ -80,8 +90,9 @@ One does for example:
\input xintexpr.sty
-The packages may be loaded in any catcode context such that letters,
-digits, \ and % have their standard catcodes.
+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
@@ -89,8 +100,7 @@ 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. This is used by
-xintexpr.sty for implementing random() and randrange() functions.
+guarantee more uniformity of the pseudo-random integers.
@@ -151,14 +161,8 @@ 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 not,
-you will need to examine the contents of this file to see the commands
-needed to produce the documentation with latexmk (extraction will have
-created a configuration file .latexmkrc) and pandoc. If not using
-latexmk, you will need to execute suitable makeindex -s xint-gind.ist
-calls to produce the indices of macros for inclusion into
-sourcexint.pdf. It is also possible to get xint.pdf to include the
-source code. For this, see the instructions in xint.tex.
+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:
@@ -194,8 +198,8 @@ 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,
-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, Makefile.mk, xint-gind.ist,
-and .latexmkrc.
+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/Master/texmf-dist/doc/generic/xint/README.html b/Master/texmf-dist/doc/generic/xint/README.html
index 92968a9a8b3..cc66a4ab5da 100644
--- a/Master/texmf-dist/doc/generic/xint/README.html
+++ b/Master/texmf-dist/doc/generic/xint/README.html
@@ -4,7 +4,7 @@
<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.3d" />
+ <meta name="author" content="xint 1.3e" />
<title>README</title>
<style type="text/css">
code{white-space: pre-wrap;}
@@ -25,8 +25,8 @@
<body>
<header>
<h1 class="title">README</h1>
-<p class="author">xint 1.3d</p>
-<p class="date">2019/01/06</p>
+<p class="author">xint 1.3e</p>
+<p class="date">2019/04/05</p>
</header>
<nav id="TOC">
<ul>
@@ -44,10 +44,10 @@
<li><a href="#license">License</a></li>
</ul>
</nav>
-<pre><code>Source: xint.dtx 1.3d 2019/01/06 (doc 2019/01/06)
+<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.3d</code></pre>
+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>
@@ -61,24 +61,28 @@ License: LPPL 1.3d</code></pre>
<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>Currently, only integer and half-integer exponents are allowed for the power operation in expressions and only the square-root operation is implemented besides the four arithmetic operations. Square-root and the four operations achieve correct rounding in the given arbitrary precision.</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 with Plain (using for example <code>\input xintexpr.sty</code>) or with LaTeX (<code>\usepackage{xintexpr}</code>).</p>
+<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>). But the <code>gcd()/lcm()</code> functions require extra loading of <code>xintgcd</code> and hexadecimal input requires <code>xintbinhex</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>The packages may be loaded in any catcode context such that letters, digits, <code>\</code> and <code>%</code> have their standard catcodes.</p>
+<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. This is used by <code>xintexpr.sty</code> for implementing <code>random()</code> and <code>randrange()</code> functions.</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>
@@ -105,7 +109,7 @@ License: LPPL 1.3d</code></pre>
<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 not, you will need to examine the contents of this file to see the commands needed to produce the documentation with <code>latexmk</code> (extraction will have created a configuration file <code>.latexmkrc</code>) and <code>pandoc</code>. If not using <code>latexmk</code>, you will need to execute suitable <code>makeindex -s xint-gind.ist</code> calls to produce the indices of macros for inclusion into <code>sourcexint.pdf</code>. It is also possible to get <code>xint.pdf</code> to include the source code. For this, see the instructions in <code>xint.tex</code>.</p>
+<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>
@@ -123,7 +127,7 @@ License: LPPL 1.3d</code></pre>
<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, 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, Makefile.mk, xint-gind.ist, and .latexmkrc.
+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/Master/texmf-dist/doc/generic/xint/README.pdf b/Master/texmf-dist/doc/generic/xint/README.pdf
index d453f2144e9..dd4181d4cc8 100644
--- a/Master/texmf-dist/doc/generic/xint/README.pdf
+++ b/Master/texmf-dist/doc/generic/xint/README.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/generic/xint/sourcexint.pdf b/Master/texmf-dist/doc/generic/xint/sourcexint.pdf
index 5c18907d36a..4503773c791 100644
--- a/Master/texmf-dist/doc/generic/xint/sourcexint.pdf
+++ b/Master/texmf-dist/doc/generic/xint/sourcexint.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/generic/xint/xint.pdf b/Master/texmf-dist/doc/generic/xint/xint.pdf
index 17524693b45..991d2ac6658 100644
--- a/Master/texmf-dist/doc/generic/xint/xint.pdf
+++ b/Master/texmf-dist/doc/generic/xint/xint.pdf
Binary files differ
diff --git a/Master/texmf-dist/source/generic/xint/xint.dtx b/Master/texmf-dist/source/generic/xint/xint.dtx
index 7640d897593..f5312323f1c 100644
--- a/Master/texmf-dist/source/generic/xint/xint.dtx
+++ b/Master/texmf-dist/source/generic/xint/xint.dtx
@@ -3,27 +3,27 @@
% Extract all files via "etex xint.dtx" and do "make help"
% or follow instructions from extracted README.md.
%<*dtx>
-\def\xintdtxtimestamp {Time-stamp: <06-01-2019 at 18:00:05 CET>}
+\def\xintdtxtimestamp {Time-stamp: <06-04-2019 at 18:55:58 CEST>}
%</dtx>
%<*drv>
%% ---------------------------------------------------------------
-\def\xintdocdate {2019/01/06}
-\def\xintbndldate{2019/01/06}
-\def\xintbndlversion {1.3d}
+\def\xintdocdate {2019/04/05}
+\def\xintbndldate{2019/04/05}
+\def\xintbndlversion {1.3e}
%</drv>
%<readme>% README
%<changes>% CHANGE LOG
-%<readme|changes>% xint 1.3d
-%<readme|changes>% 2019/01/06
+%<readme|changes>% xint 1.3e
+%<readme|changes>% 2019/04/05
%<readme|changes>
-%<readme|changes> Source: xint.dtx 1.3d 2019/01/06 (doc 2019/01/06)
+%<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.3d
+%<readme|changes> License: LPPL 1.3e
%<readme|changes>
-%<*!readme&!changes&!dohtmlsh&!dopdfsh&!makefile&!latexmkrc&!gind>
+%<*!readme&!changes&!dohtmlsh&!dopdfsh&!makefile>
%% ---------------------------------------------------------------
-%% The xint bundle 1.3d 2019/01/06
+%% 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
@@ -35,8 +35,10 @@
%<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&!latexmkrc&!gind>
+%</!readme&!changes&!dohtmlsh&!dopdfsh&!makefile>
%<*dtx>
\bgroup\catcode2 0 \catcode`\\ 12 ^^Biffalse
%</dtx>
@@ -71,18 +73,21 @@ Float computations are possible at an adjustable precision (default 16).
(as this example shows the underscore character can be used to separate
visually digits, one can also use the space character for that purpose).
-Currently, only integer and half-integer exponents are allowed for the
-power operation in expressions and only the square-root operation is
-implemented besides the four arithmetic operations. Square-root and the
-four operations achieve correct rounding in the given arbitrary
-precision.
+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 with Plain (using for example
-`\input xintexpr.sty`) or with LaTeX (`\usepackage{xintexpr}`).
+It is possible to use the package both with Plain
+(`\input xintexpr.sty`) or with LaTeX (`\usepackage{xintexpr}`).
## With LaTeX
@@ -91,12 +96,14 @@ It is possible to use the package with Plain (using for example
\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`). But the `gcd()/lcm()` functions require extra loading of
-`xintgcd` and hexadecimal input requires `xintbinhex`.
+`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`, ...
@@ -107,14 +114,20 @@ 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
-The packages may be loaded in any catcode context such that letters,
-digits, `\` and `%` have their standard catcodes.
+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
@@ -123,9 +136,7 @@ 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. This is
-used by `xintexpr.sty` for implementing `random()` and `randrange()`
-functions.
+done to guarantee more uniformity of the pseudo-random integers.
Installation
============
@@ -185,13 +196,8 @@ 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 not, you will need to examine the contents of this file to see
-the commands needed to produce the documentation with `latexmk`
-(extraction will have created a configuration file `.latexmkrc`) and
-`pandoc`. If not using `latexmk`, you will need to execute suitable
-`makeindex -s xint-gind.ist` calls to produce the indices of macros for
-inclusion into `sourcexint.pdf`. It is also possible to get `xint.pdf`
-to include the source code. For this, see the instructions in `xint.tex`.
+help. If you can't use `make` read the contents of the `Makefile` for
+instructions.
Finishing the installation in a TDS hierarchy:
@@ -225,14 +231,58 @@ 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, xintbinhex.sty, xintgcd.sty, xintseries.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,
-Makefile.mk, xint-gind.ist, and .latexmkrc.</div>
+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)`
----
@@ -264,7 +314,7 @@ Makefile.mk, xint-gind.ist, and .latexmkrc.</div>
- **xintexpr**: functions `isone()` and `isint()`.
- **xintexpr**: `\xinteval`, `\xintieval`, `\xintiieval`, and
- `\xintfloateval` as synonyms to `\xintthexpr...\relax` etc..., but
+ `\xintfloateval` as synonyms to `\xinttheexpr...\relax` etc..., but
with the (comma-separated) expression as a usual braced macro
argument.
@@ -1878,7 +1928,9 @@ Initial announcement:
# then run "make help"
# Starting with xint 1.3c, uses Latexmk for easier compilation of
-# sourcexint.pdf as it includes indices.
+# 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.
@@ -1998,18 +2050,18 @@ 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
+ 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 .latexmkrc xint-gind.ist
+ doHTMLs.sh doPDFs.sh pandoctpl.latex
doc_pdf = README.pdf CHANGES.pdf
doc_html = README.html CHANGES.html
filesfortex = $(packages)
-filesforsource = xint.dtx xint.ins Makefile
+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\
@@ -2101,8 +2153,6 @@ uninstalllocal:
clean:
rm -fr auto/ TEMP*/
rm -f $(auxiliaryfiles)\
- sourcexint*.ilg sourcexint*.idx sourcexint*.ind\
- xint*.ilg xint*.idx xint*.ind\
sourcexint.fls sourcexint.fdb_latexmk\
xint.fls xint.fdb_latexmk
@@ -2111,28 +2161,6 @@ cleanall: clean
README README.tex CHANGES.tex\
xint.pdf sourcexint.pdf xint.tds.zip xint.zip Makefile.mk
%</makefile>$-----------------------------------------------------
-%<*latexmkrc>------------------------------------------------------
-$makeindex = 'makeindex -s xint-gind.ist %O -o %D %S';
-%</latexmkrc>$-----------------------------------------------------
-%<*gind>------------------------------------------------------
-%%
-%% Based upon `gind.ist' from LaTeX2e's base package `doc'
-actual '='
-quote '&'
-level '>'
-preamble
-"\n \\begin{theindex} \n \\catcode`_\\active \\let_\\textunderscore \\makeatletter\\scan@allowedfalse\n"
-postamble
-"\n\n \\end{theindex}\n"
-item_x1 "\\efill \n \\subitem "
-item_x2 "\\efill \n \\subsubitem "
-delim_0 "\\pfill "
-delim_1 "\\pfill "
-delim_2 "\\pfill "
-heading_prefix "{\\bfseries\\hfil "
-heading_suffix "\\hfil}\\nopagebreak\n"
-headings_flag 1
-%</gind>$-----------------------------------------------------
%<*pandoctpl>-----------------------------------------------------
\newcommand{\tightlist}{%
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
@@ -2287,9 +2315,6 @@ dvipdfmx CHANGES.dvi
%% (quoting may differ, depending on the shell)
%% dvipdfmx sourcexint.dvi
%%
-%% Notice that this will need files .latexmkrc and xint-gind.ist
-%% which are produced from "tex xint.dtx" (or "tex xint.ins").
-%%
%% It is naturally possible to replace latexmk by suitable latex
%% and makeindex calls, but details are left out here.
%%
@@ -2298,8 +2323,7 @@ dvipdfmx CHANGES.dvi
%% - replace 1 by 0 in \chardef line below,
%% - make clean
%% - make xint.pdf
-%% This will use latexmk. Details on how to do it without make
-%% and latexmk are left out here.
+%% 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)]%
@@ -2329,10 +2353,8 @@ dvipdfmx CHANGES.dvi
\file{doPDFs.sh}{\from{xint.dtx}{dopdfsh}}
\ifx\numexpr\undefined\else\catcode9 11
\file{Makefile.mk}{\from{xint.dtx}{makefile}}\fi
-\file{.latexmkrc}{\from{xint.dtx}{latexmkrc}}
\usepreamble\defaultpreamble
\usepostamble\defaultpostamble
-\file{xint-gind.ist}{\from{xint.dtx}{gind}}
\file{pandoctpl.latex}{\from{xint.dtx}{pandoctpl}}
\file{xint.tex}{\from{xint.dtx}{drv}}
\file{xintkernel.sty}{\from{xint.dtx}{xintkernel}}
@@ -2344,7 +2366,9 @@ dvipdfmx CHANGES.dvi
\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{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{********************************************************************}
@@ -2361,6 +2385,8 @@ dvipdfmx CHANGES.dvi
\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}
@@ -2418,6 +2444,8 @@ dvipdfmx CHANGES.dvi
\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}%
@@ -2442,12 +2470,10 @@ dvipdfmx CHANGES.dvi
% 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{.latexmkrc}{\from{xint.dtx}{latexmkrc}}
\file{doHTMLs.sh}{\from{xint.dtx}{dohtmlsh}}
\file{doPDFs.sh}{\from{xint.dtx}{dopdfsh}}
\usepreamble\defaultpreamble
\usepostamble\defaultpostamble
- \file{xint-gind.ist}{\from{xint.dtx}{gind}}
\file{pandoctpl.latex}{\from{xint.dtx}{pandoctpl}}
\file{xint.ins}{\from{xint.dtx}{ins}}
\file{xint.tex}{\from{xint.dtx}{drv}}
@@ -2460,7 +2486,9 @@ dvipdfmx CHANGES.dvi
\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{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.
@@ -2515,26 +2543,6 @@ dvipdfmx CHANGES.dvi
\ifnum\NoSourceCode=1
\OnlyDescription
-\else
-\makeatletter
-% As there is currently no index for user manual, we can define
-% already here some doc.sty macros for indexing of source code. See
-% further customization where source starts.
- \EnableCrossrefs
- \def\StartPackageIndex#1%
- {\immediate\openout\package@indexfile=\jobname#1.idx\relax
- \typeout{Writing index file \jobname#1.idx}}
- \def\StopPackageIndex%
- {\immediate\closeout\package@indexfile}
- \def\index{\@bsphack \begingroup \@sanitize \@wrindex }%
- % attention that hyperref redefines \@wrindex
- % so we delay our definition to right before source code
- \newwrite \@indexfile % will be opened at start of source code
- \newwrite \package@indexfile
- \let\makeindex\@empty
- \PageIndex
- \CodelineNumbered
-\makeatother
\fi
@@ -2552,6 +2560,7 @@ dvipdfmx CHANGES.dvi
\usepackage[utf8]{inputenc}
\DeclareUnicodeCharacter{03B4}{\ensuremath{\delta}}%δ
\DeclareUnicodeCharacter{03BE}{\ensuremath{\xi}}%ξ
+ \DeclareUnicodeCharacter{03C0}{\ensuremath{\pi}}%π
\fi
\usepackage{multicol}
@@ -2567,6 +2576,7 @@ dvipdfmx CHANGES.dvi
\usepackage{xintseries}
\usepackage{xintcfrac}
\usepackage{amsmath}% for \cfrac usage
+\DeclareMathOperator{\sinc}{sinc}
\usepackage{pifont}% for \ding{73} (hollow star)
\fi
@@ -2815,7 +2825,9 @@ pdfpagemode=UseOutlines}
\unless\ifinmanualmaintoc\leaders\etoctoclineleaders\fi
\hfill\nobreak
\strut\makebox[\MARGEPAGENO][r]{\small\etocpage}\endgraf }
- {\end{multicols}\endgroup\addvspace{\smallskipamount}}%
+ {\end{multicols}\endgroup
+ %\addvspace{\smallskipamount}
+ }%
\etocsetstyle{subsubsection}
{\begingroup\normalfont\small
@@ -3093,7 +3105,8 @@ pdfpagemode=UseOutlines}
\relax \ifmmode\else\leavevmode\null\fi
\bgroup
\let\do\@makeother \dospecials
- \@ifstar{\@sverb}% \verb* is used in the index, leave it using ambient font
+ \@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
@@ -3389,6 +3402,8 @@ pdfpagemode=UseOutlines}
\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...
% ==============================
@@ -3398,7 +3413,8 @@ pdfpagemode=UseOutlines}
{(xintkernel,kernel),
(xinttools,tools),
(xintcore,core),(xint,xint),(xintbinhex,binhex),(xintgcd,gcd),%
- (xintfrac,frac),(xintseries,series),(xintcfrac,cfrac),(xintexpr,expr)}
+ (xintfrac,frac),(xintseries,series),(xintcfrac,cfrac),(xintexpr,expr),%
+ (xinttrig, trig), (xintlog, log)}
\do
{%
\expandafter\def\csname #1name\endcsname
@@ -3413,28 +3429,8 @@ pdfpagemode=UseOutlines}
{\relax{\color{blue}\MakeNameUp{#1}}}}%
{#1}%
\xspace }%
- \expandafter\def\csname #1nameind\endcsname
- {\texorpdfstring
- {\hyperref[sec:#2ind]%
- {\relax{\color[named]{ForestGreen}\MakeNameUp{#1}}}}%
- {#1}%
- \xspace }%
}%
- \def\indexcumulatif
- {\texorpdfstring
- {\hyperref[sec:indexcumulatif]%
- {\relax{\color[named]{ForestGreen}\MakeNameUp{all}}}}%
- {all}%
- \xspace }%
-
- \def\DOCxintindices
- {\texorpdfstring
- {\hyperref[sec:indices]%
- {\relax{\color[named]{ForestGreen}indices}}}%
- {indices}%
- \xspace }%
-
\def\DOCxintfrontpage
{\texorpdfstring
{\hyperref[frontpage]{\relax{\color{joli}TOC}}}%
@@ -3509,13 +3505,13 @@ pdfpagemode=UseOutlines}
\xintcorename,
\xintname,
\xintfracname,
- \xintexprname,
+ \xintexprname, \xinttrigname, \xintlogname,
\xintbinhexname,
\xintgcdname,
\xintseriesname,
\xintcfracname,
\xinttoolsname}}
-\markboth{\xintRunningHeader}{\xintRunningHeader}
+\markboth{\makebox[0pt]{\xintRunningHeader}}{\makebox[0pt]{\xintRunningHeader}}
% Skips safely.
\ifnum\dosourcexint=1
@@ -3682,6 +3678,9 @@ pdfpagemode=UseOutlines}
\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
@@ -3693,6 +3692,10 @@ pdfpagemode=UseOutlines}
\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);
@@ -3710,20 +3713,23 @@ pdfpagemode=UseOutlines}
\begin{addmargin}{2cm}
\normalfont\footnotesize Dependency graph for the
- \xintname bundle components: modules at the bottom \textbf{automatically}
- import modules at the
- top when connected by a continuous line. No module will be loaded twice,
- this is managed internally under Plain as well as \LaTeX. Dashed lines
+ \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 necessary to use
- the suitable |\usepackage| (\LaTeX) or |\input| (Plain \TeX.)\par
+ 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.
- Note: at |1.2n| \xintbinhexname has no dependency on \xintcorename
- anymore, it only loads \xintkernelname.
+ \href{http://ctan.org/pkg/polexpr}{polexpr} is a
+ separate (\LaTeX{} only) package by the author which requires \xintexprname.
- The \href{http://ctan.org/pkg/bnumexpr}{bnumexpr} package is a
- separate package (\LaTeX{} only) by the author which uses (by default)
- \xintcorename as its mathematical engine.\par
+ \xinttrigname and \xintlogname are loaded automatically by \xintexprname; they
+ will refuse to be loaded directly (but see \csbxint{reloadxinttrig}).
+\par
\end{addmargin}
\vfill
@@ -3736,6 +3742,26 @@ pdfpagemode=UseOutlines}
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}
+
@@ -3782,6 +3808,13 @@ This section provides recommended reading on first discovering the package.
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}
@@ -3796,7 +3829,7 @@ Further modules:
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.\NewWith{1.3d}
+ 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
@@ -3834,32 +3867,42 @@ for other formats, you can do computations such as the following.
\begin{description}
\item[with floats:]\leavevmode\par
\begin{everbatim*}
-\thexintfloatexpr 3.25^100/3.2^100, 2^1000000, sqrt(1000!), 10^-3.5\relax\par
+\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*}
-And |1.3d| adds the input syntax with braces:\NewWith{1.3d}
+ The \csbxint{floateval} macro using braces was introduced at |1.3d|.
+ Formerly, one did:
\begin{everbatim}
-\xintfloateval{3.25^100/3.2^100, 2^1000000, sqrt(1000!), 10^-3.5}
+\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*}
-\thexintexpr reduce(add((-1)^(i-1)/i**2, i=1..25))\relax
-% or \xinteval{reduce(add((-1)^(i-1)/i**2, i=1..25))}
+$\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}
-\thexintiiexpr 3^159+2^234\relax % or equivalently:
-\end{everbatim}
\begin{everbatim*}
-\xintiieval{3^159+2^234}
+\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 by a prior assignment to |\xintDigits|:
+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}.}
@@ -3867,38 +3910,6 @@ We can even try daring things:\footnote{The \cs{printnumber} is not part of
{\xintDigits:=500;\printnumber{\xintfloateval{sqrt(2)}}}
\end{everbatim*}
-\medskip
-
-This is release \expandafter|\xintbndlversion|.
-\begin{enumerate}
-\item |exp|, |cos|, |sin|, etc... are \emph{yet to be implemented},
-\item |NaN|, |+Infty|, |-Infty|, etc... are \emph{yet to be implemented},
-\item powers work currently only with integral and
- half-integral exponents (but the latter only for float
- expressions),
-\item \xintname can handle numbers with thousands of digits, but execution
- times limit the practical range to a few hundreds (if many such computations
- are needed),
-\item computations in |\thexintexpr| and |\thexintiiexpr| are exact (except if
- using |sqrt|, naturally),
-\item fractions are not systematically reduced to smallest terms, use
- |reduce| function,
-\item for producing fixed point numbers with |d| digits after decimal mark,
- use (note the extra `|i|' in the parser name!) |\thexintiexpr [d]
- ...\relax|. This is actually essentially synonymous with |\thexintexpr
- round(..,d)\relax| (for |d=0|, |\thexintiexpr [0]| is the same as
- |\thexintiexpr| without optional argument, and is like |\thexintexpr
- round(..)\relax|). If truncation rather than rounding is needed use thus
- |\thexintexpr trunc(..,d)\relax| (and |\thexintexpr trunc(..)\relax| for
- truncation to integers),
-\item all three parsers allow some constructs with dummy variables as seen
- above; it is possible to define new functions or to declare variables for
- use in upcoming computations,
-\item |\thexintiiexpr| is slightly faster than |\thexintexpr|, but usually one
- can use the latter with no significant time penalty also for integer-only
- computations.
-\end{enumerate}
-
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
@@ -3958,53 +3969,73 @@ computations associated in expressions with the various symbols like |+, *, ^,
\end{framed}
\begin{framed}
- Currently, the sole available non-algebraic function is the square root
- extraction \func{sqrt}. It is allowed in |\xintexpr..\relax| but naturally
- can't return an \emph{exact} value, hence computes as if it was in
- |\xintfloatexpr..\relax|. The power operator |^| (equivalently |**|) works
- with integral exponents only in \csbxint{iiexpr} (non-negative) and
- \csbxint{expr} (negative exponents allowed, of course) and also with
- half-integral exponents in \csbxint{floatexpr} (it proceeds via an integral
- power followed by a square-root extraction).
+ 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}[nosep]
+\begin{itemize}
\item the comma (to separate distinct computations or arguments to a
function),
\item parentheses,
-\item infix operators |+|, |-|, |*|, |/|, |^| (or |**|),
-\item |//| does floored division and |/:| is associated modulo,
-\item branching operators |(x)?{x non zero}{x zero}|, |(x)??{x<0}{x=0}{x>0}|,
-\item boolean operators |!|, |&&| or |'and'|, \verb+||+ or |'or'|,
+\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 post-fix operator |!|,
-\item |"| for hexadecimal input (uppercase only; package \xintbinhexname
- must be loaded additionally to \xintexprname),
+\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 functions \xintFor #1 in {num, preduce, reduce, abs, sgn, frac, floor, ceil, sqr, sqrt,
- sqrtr, float, round, trunc, mod, quo, rem,
- max, min, |`+`|, |`*`|, not, all, any, xor, if, ifint, ifone, ifsgn, even,
- odd, isint, isone, first,
- last, reversed, bool, togl, gcd, lcm, factorial, binomial, pfactorial}\do {\func{#1}, }
-\item functions \func{random}, \func{qrand}, \func{randrange} for random
- floats or integers (requires that \TeX\ engine provides
- \csa{pdfuniformdeviate} or \csa{uniformdeviate} primitive),
-\item functions with dummy variables \xintFor #1 in {add, mul, seq, subs,
- rseq, iter, rrseq, iterr}\do {\func{#1}\xintifForLast{.}{, }}
+\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 the built-in syntax elements.
+for a complete description.
The normal mode of operation of the parsers is to unveil the parsed material
-token by token. This means that all elements 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.
-This general behaviour has exceptions, in particular constructs with dummy
-variables need 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.
+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*}
@@ -4035,8 +4066,7 @@ the assignment to |\xintDigits| is limited by the braces):
(<- notice the size of the power of ten: this surely largely exceeds your pocket
calculator abilities).
-It is also possible to do some computer algebra like
-evaluations (only numerically though):
+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
@@ -4090,6 +4120,8 @@ 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
@@ -4402,81 +4434,61 @@ For more information see
The formatted source code is available in file |sourcexint.pdf|:
\centeredline{|texdoc sourcexint|}
-\noindent|1.3d|:
+\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 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
+\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}
-\pagebreak[3]
-\noindent|1.3c|:\par
-\begin{itemize}[nosep]
-\item adds \csbxint{globaldefstrue} to give global scope to definitions done
- by \csbxint{defvar}, \csbxint{deffunc}, \csbxint{NewExpr}, et al.,
-\item \func{qraw},
-\item the colon in the |:=| part of the syntax for
- \csbxint{defvar} and variants is now optional; and if present it may be
- an active character or have any (reasonable) catcode.
-\item \csbxint{defvar}, \csbxint{deffunc} 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.
-\item \csbxint{UniformDeviate} is better documented and |sourcexint.pdf| is
- better hyperlinked and includes indices for the macros defined by each
- package.
-\item since |1.3| release, \xintfracname (hence \xintexprname) loaded
- \xintgcdname in contradiction to what documentation says. Removed for now.
-\end{itemize}
-
-\noindent|1.3b|:
-\begin{itemize}[nosep]
-\item adds \csbxint{UniformDeviate}, \func{random}, \func{qrand},
- \func{randrange},
-\item and their support macros \csbxint{RandomDigits}, \csbxint{iiRandRange},
- \csbxint{iiRandRangeAtoB}, also \csbxint{XRandomDigits}.
-\end{itemize}
-
-\noindent|1.3a|:
-\begin{itemize}[nosep]
-\item makes more efficient |1.3|'s \hyperref[sssec:recursive]{recursive definitions} via \csbxint{deffunc},
-\item adds \func{ifone} and \func{ifint} conditionals,
-\item faster \csbxint{REZ},
-\item documents \csbxint{DivFloor} and other macros which,
-although long existing, had somehow not made it into the user manual yet.
-\end{itemize}
-
-\noindent|1.3|:
-\begin{itemize}[nosep]
-\item makes possible \hyperref[sssec:recursive]{recursive definitions} via \csbxint{deffunc};
-\item adds \csbxint{PIrr} and function \func{preduce},
-\item adds \csbxint{DecToString},
-\item introduces some significant breaking changes:
- \begin{itemize}[nosep]
- \item Addition (\csbxint{Add}) and subtraction (\csbxint{Sub}) of
- fractions use the least common multiple of the denominators.
- \item This modified also addition, subtraction as executed in |xintexpr|.
- Similarly the modulo operator |/:| and the \func{mod} and \func{divmod} functions
- were changed to use a l.c.m. for the denominator of the
- result.
- \item The macros deprecated at |1.2o| were removed. See
- \autoref{ssec:coredeprecated}, \autoref{ssec:xintdeprecated}, and
- \autoref{ssec:xintdeprecatedNum} for details.
- \end{itemize}
-\end{itemize}
-
-
\section{The syntax of \xintexprname expressions}
\label{sec:xintexprsyntax}
@@ -4506,8 +4518,8 @@ separated list of results.
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 |sqrt| function is available and works
- according to the |\xintDigits| precision or according to its second optional
+ done \emph{exactly.} The \func{sqrt} function is available and obeys
+ either the |\xintDigits| precision or its second optional
argument.
\end{itemize}
@@ -4652,6 +4664,12 @@ at each level.
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
@@ -4798,13 +4816,21 @@ corresponding definitions.
\begin{table}[htbp]
\capstart
\centering
-\xintAssignArray\xintCSVtoList{!, ?, |`*`|, |`+`|, abs, add, all, any, binomial, bool, ceil,
-divmod, even, factorial, first, float, floor, frac, gcd, if, ifint, ifone, ifsgn,
-isint, isone,
-iter, iterr, last, lcm, len, max, min, mod, mul, not, num, odd, pfactorial,
-preduce, qfloat,
-qfrac, qint, qrand, qraw, quo, random, randrange, reduce, rem, reversed, round, rrseq, rseq, seq, sgn, sqr,
-sqrt, sqrtr, subs, togl, trunc, xor}
+\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
@@ -4974,16 +5000,26 @@ Recall that this is NOT done automatically, for example when adding fractions.
\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.
- \funcdesc{sqrt} in |\xintiiexpr|, truncated square root; in |\xintexpr| or
+\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.
- \funcdesc{sqrtr} in |\xintiiexpr| only, rounded square root.
- \funcdesc{factorial} factorial function (like the
+ 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 discussion later.
+ |\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.
@@ -5013,8 +5049,15 @@ $\xintthefloatexpr 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: they require the closing parenthesis of their argument to
- be immediately visible, it can not arise from expansion.
+ 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
@@ -5066,6 +5109,10 @@ $\xintthefloatexpr subs(((x-1)/x, x/x, (x+1)/x), x=2**30)\relax
|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}
@@ -5179,6 +5226,39 @@ $\xintthefloatexpr subs(((x-1)/x, x/x, (x+1)/x), x=2**30)\relax
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}
@@ -5189,6 +5269,10 @@ $\xintthefloatexpr subs(((x-1)/x, x/x, (x+1)/x), x=2**30)\relax
\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.
@@ -5199,6 +5283,9 @@ $\xintthefloatexpr subs(((x-1)/x, x/x, (x+1)/x), x=2**30)\relax
\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
@@ -5676,6 +5763,14 @@ First Fibonacci number at least |2^31| and its index
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}
@@ -5877,8 +5972,7 @@ Look at the
% completely inefficient in comparison, and was quite easier to come up with
% than |\Factorize|.
-\subsection{User defined variables: \csh{xintdefvar}, \csh{xintdefiivar},
- \csh{xintdeffloatvar}}
+\subsection{User defined variables}
\label{ssec:uservariables}
\label{xintdefvar}
\label{xintdefiivar}
@@ -6052,9 +6146,24 @@ For example with Xe\TeX\ or Lua\LaTeX\ the following works:
Under \csbxint{globaldefstrue} regime the effect of \csa{xintnewdummy} is
global.
-\subsection{User defined functions: \cshnolabel{xintdeffunc},
- \cshnolabel{xintdefiifunc}, \cshnolabel{xintdeffloatfunc},
- \cshnolabel{xintNewFunction}}
+\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
@@ -6070,48 +6179,97 @@ Since release |1.2c| it is possible to declare functions:
\end{everbatim*}(notice the numerous tacit multiplications in this expression;
and that |x/2y| is interpreted as |x/(2y)|.)
-\begin{framed}
- 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}).
-
- 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.
-
- A function can have at most nine variables.
-%
-
- \csbxint{deffunc} makes the function known only to the \csbxint{expr}
- parser. See \csbxint{defiifunc} and \csbxint{deffloatfunc} for the two other
- parsers.\IMPORTANT
-\end{framed}
-% \footnotetext{with the current syntax, the |;| as used for |iterr|, |rseq|,
-% |rrseq| must be hidden as |{;}| to not be confused with the |;| ending the
-% declaration.}
-It is perfectly 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:
+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}
-\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);
+\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}
-The mechanism for functions is identical with the one underlying the
-\csbxint{NewExpr} macro (and has the same
-\hyperref[sssec:limitations]{limitations}). See \csbxint{exprSafeCatcodes} for
-catcode matters.
-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
+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;
@@ -6136,21 +6294,23 @@ only to the extent that their values are numerical. For example
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.}
-\begin{everbatim*}
-\xintdeffunc f(x):=`+`([1..x]^2);\xinttheexpr seq(f(x), x=1..20)\relax
-\end{everbatim*}
+% 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*}
+% 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:
@@ -6160,6 +6320,14 @@ iterated over do not depend upon the function parameters:
\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}
@@ -6178,7 +6346,119 @@ For usage in the \csbxint{iiexpr} parser, it is required to use
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}.
+\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}}
@@ -6228,7 +6508,18 @@ 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:
@@ -6249,32 +6540,72 @@ and we can check that they work:
\xinttheexpr f(10)\relax; \xinttheexpr g(10)\relax
\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.
+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 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
+\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*}
-Cleaning up:
+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*}
-\xintunassignexprfunc{g}%
+\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*}
-\subsubsection{\csh{ifxintglobaldefs} conditional}
-\label{xintglobaldefstrue}
-\label{xintglobaldefsfalse}
-\label{ifxintglobaldefs}
+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*}
-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.
+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}
@@ -6307,77 +6638,6 @@ precision for the evaluation.
}
\end{everbatim*}
-\subsubsection{Using the same name for both a variable and a function}
-\label{sssec:overload}
-
-It is licit to overload a variable name (all Latin letters are predefined as
-dummy variables) with a function name and vice versa. The parsers will decide
-from the context if the function or variable interpretation must be used
-(dropping various cases of tacit multiplication as normally applied).
-\begin{everbatim*}
-\xintdefiifunc f(x):=x^3;
-\xinttheiiexpr add(f(f),f=100..120)\relax\newline
-\xintdeffunc f(x,y):=x^2+y^2;
-\xinttheexpr mul(f(f(f,f),f(f,f)),f=1..10)\relax
-\xintunassigniiexprfunc{f}\xintunassignexprfunc{f}%
-\end{everbatim*}
-
-\subsubsection{Recursive definitions}
-\label{sssec:recursive}
-
-Since |1.3|, it is possible to make recursive definitions.\NewWith{1.3} 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.
-
\subsubsection{\csh{xintNewFunction}}
\label{xintNewFunction}
@@ -6909,12 +7169,12 @@ bound. It does not provide an expression parser.%
\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. Currently
-(\expandafter|\xintbndlversion|), the only non-elementary operation
-implemented for floating point numbers is the square-root extraction; no
-signed infinities, signed zeroes, |NaN|'s, error traps\dots, have been
-implemented, only the notion of `scientific notation with a given number of
-significant figures'.%
+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
@@ -7047,14 +7307,16 @@ is intended to clean up the result from dubious last digits.
}
-Currently, the only non-elementary operation is the square root. Since release
+Since release
|1.2f|, square root extraction achieves correct rounding in arbitrary
precision.
-The elementary transcendantal functions are not yet implemented. The power
+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
@@ -9435,7 +9697,8 @@ its salt compared to \csbxint{Length}.
\csa{xintUniformDeviate}|{x}|\etype{\numx} is a wrapper of engine
|\pdfuniformdeviate| (or |\uniformdeviate|).%
%
-\footnote{Currently this primitive is not provided by Xe\TeX\ engine.}
+\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}%
@@ -9595,9 +9858,10 @@ 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 a 100 times a random integer to the tenth power:
+let's raise 100 times a random integer to the tenth power:
%
-\footnote{This is done on a |2.4GHz| processor.}
+\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
@@ -12206,7 +12470,7 @@ operators and functions. This section now adds some complementary information.
|!|, |&|, \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 the expressions.
+ |?|, |;| 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
@@ -12386,6 +12650,13 @@ 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}
@@ -12447,8 +12718,9 @@ The material between |\xintexpr| and |\relax| should contain only expandable
material.
The once expanded |\xintexpr| is |\romannumeral0\xintexpro|.\CHANGED{1.3d}
-\centeredline{ATTENTION! Formerly the |\xintexpro| macro was named
- |\xinteval|. But this |\xinteval| is now something else.} And there
+\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}.
@@ -12674,10 +12946,14 @@ The target precision for the computation is from the
current setting of |\xintDigits|. Comma separated lists of expressions are
allowed.
-An optional (positive) parameter within brackets is allowed: the final float
-will have that many digits of precision. This is provided to get rid of
-possibly irrelevant last digits, thus makes sense only if this parameter is
-less than the |\xinttheDigits| precision.
+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.
@@ -12735,8 +13011,8 @@ like this:
\begin{everbatim}
\def\xinteval#1{\romannumeral-`0\xinttheexpr#1\relax}
\end{everbatim}
-so it expands in two steps exactly like \csbxint{theexpr} (its
-exact definition differs from the above to achieve a slight optimization).
+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*}
@@ -12758,6 +13034,12 @@ argument must be located inside the braces:
\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
@@ -13203,29 +13485,46 @@ All the preceeding applies identically for \csbxint{deffunc}, \csbxint{defiifunc
\csa{xintNewIIExpr}, ..., replacing the |#1|, |#2|, ... in the discussion by
the letters used as function arguments.
-There is a final syntax restriction which however applies only to
-\csa{xintNewExpr} et al., and not to \csa{xintdeffunc}, \csa{xintdefiifunc},
-\csa{xintdeffloatfunc} : it is possible to use sub-expressions only if they use
-\csa{xintexpr}, those with \csa{xinttheexpr} are illegal.
+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 already
+works, but
\begin{everbatim}
\xintNewExpr \FD [1] {#1+\xinttheexpr 1\relax}
\end{everbatim}
-doesn't. On the other hand
-\begin{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*}
+\end{everbatim}
and even
-\begin{everbatim*}
+\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*}
-have no issue. Anyway, one should never use |\xinttheexpr| for sub-expressions
-but only |\xintexpr|, so this restriction on the \csa{xintNewExpr} syntax
-isn't really one.
+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}
@@ -13376,6 +13675,330 @@ 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}|}
@@ -16920,9 +17543,8 @@ be treated as first item) number.
\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| (twice) then
- |makeindex -s xint-gind.ist| on all |.idx| files, then again |latex| twice
- and finally |dvipdfmx|.
+ the last step to execute manually |latex| on |xint.tex| (thrice)
+ then |dvipdfmx|.
\end{framed}
\fi
@@ -16962,40 +17584,6 @@ be treated as first item) number.
\unexpanded\expandafter{\storedlinecounts}%
{{#1}{\the\c@CodelineNo}}}\c@CodelineNo\z@ }
-% Customizing doc.sty's indexing
-% ==============================
-
-% cf xintkernel.sty's \XINT_setcatcodes : this is default across xint
-% codebase
-\def\xintMakePrivateLetters{%
- \catcode`_ 11 \catcode`: 11 \catcode`^ 11
- \catcode`@ 11 \catcode`? 11 }
-% additionally, the ! is generally of catcode letter in xintexpr.sty
-\odef\xintexprMakePrivateLetters{\xintMakePrivateLetters \catcode`! 11 }
-
-\let\MakePrivateLetters\xintMakePrivateLetters
-
-\edef\quotechar{\string&}
-
-\def\index@prologue{}
-
-\def\PrintPackageIndex#1{\@input@{\jobname#1.ind}}
-\def\PrintMainIndex{\@input@{\jobname.ind}}
-
-\immediate\openout\@indexfile=\jobname.idx
-\typeout{Writing index file \jobname.idx}
-
-% because it got redefined by hyperref
-{\catcode`| 12
-\gdef\@wrindex #1%
- {%
- \protected@write\package@indexfile{}{\string\indexentry{#1|hyperpage}{\thepage}}%
- \protected@write\@indexfile{}{\string\indexentry{#1|hyperpage}{\thepage}}%
- \endgroup
- \@esphack
- }%
-}
-
% \macrocode
% ==========
% 2014/11/04 did some hack with active characters à la upquote for
@@ -17139,8 +17727,10 @@ be treated as first item) number.
\xintgcdnameimp,
\xintfracnameimp,
\xintseriesnameimp,
- \xintcfracnameimp, \xintexprnameimp, \DOCxintindices}}
-\markboth{\xintImpRunningHeader}{\xintImpRunningHeader}
+ \xintcfracnameimp,
+ \xintexprnameimp,
+ \xinttrignameimp, \xintlognameimp}}
+\markboth{\makebox[0pt]{\xintImpRunningHeader}}{\makebox[0pt]{\xintImpRunningHeader}}
\makeatother
@@ -17148,175 +17738,59 @@ be treated as first item) number.
This is \expandafter|\xintbndlversion| of \expandafter|\xintbndldate|.
-\begin{itemize}
-\item Release |1.3d| of |2019/01/06|:
- \begin{itemize}[nosep]
-\item \csbn{gcd()} and \csbn{lcm()} in \csbxint{expr}|...\relax| now handle
- general arguments, without converting them to integers,
-\item it is not needed anymore to load package \xintgcdnameimp to benefit from
- \csbn{gcd()} and \csbn{lcm()} in the parsers,
-\item \csbxint{unassignvar} slightly refactored,
-\item \csbxint{ifsgnexpr}, \csbxint{ifsgnfloatexpr}, \csbxint{ifsgniiexpr},
-\item \csbxint{unassignexprfunc} and variants for the other parsers,
-\item \csbn{isone()} and \csbn{isint()},
-\item \csbxint{eval}, \csbxint{ieval}, \csbxint{iieval}, and
- \csbxint{floateval} (attention that these macros previously existed with
- different meanings, now available under new names \csbxint{expro},
- \csbxint{iexpro}, \csbxint{iiexpro}, and \csbxint{floatexpro}),
-\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}
-\item Release |1.3c| of |2018/06/17|:
- \begin{itemize}[nosep]
- \item \csbxint{globaldefstrue} to give global scope to definitions done by
- \csbxint{defvar}, \csbxint{deffunc}, \csbxint{NewExpr}, et al.
- \item \csbn{qraw()} to allow bypassing the normal mode of functioning
- and reduce memory footprint from parsing (very many) comma separated
- numerical items.
- \item the colon in the |:=| part of the syntax for
- \csbxint{defvar} and variants is now optional; and if present it may be
- an active character or have any (reasonable) catcode.
- \item \csbxint{defvar}, \csbxint{deffunc} 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.
- \item \csbxint{exprSafeCatcodes} sets a toggle to allow some nested usage.
- \item \csbxint{UniformDeviate} is better documented and |sourcexint.pdf| is
- better hyperlinked and includes indices for the macros defined by each
- package.
- \item since |1.3| release, \xintfracnameimp (hence \xintexprnameimp) loaded
- \xintgcdnameimp in contradiction to what documentation says. Removed for now.
- \end{itemize}
-\item Release |1.3b| of |2018/05/18|:
- \begin{itemize}[nosep]
- \item \csbxint{UniformDeviate}, \csbn{random()}, \csbn{qrand()},
- \csbn{randrange()},
- \item and their support macros \csbXINT{inRandomFloatSdigits},
- \csbXINT{inRandomFloatSixteen}, \csbxint{RandomDigits},
- \csbxint{iiRandRange}, \csbxint{iiRandRangeAtoB}, also
- \csbxint{XRandomDigits},
- \item functions defined via \csbxint{deffunc} (et al.) to be without
- argument can be used as |foo()|: |foo(nil)| syntax not anymore required.
- \end{itemize}
-\item Release |1.3a| of |2018/03/07|:
- \begin{itemize}[nosep]
- \item removes from \xintcorenameimp, \xintnameimp and \xintfracnameimp the
- whole deprecation mechanism, as there are no more currently any
- deprecated macro,
- \item adds \csbn{ifone()} and \csbn{ifint()} conditionals to the expression parsers,
- \item has a completely redone \csbXINT{_factortens}, in the style of |1.2|
- release (but about 100 digits at least are needed for noticeable speed
- gain),
- \item and last but not least fixes via addition of \csbxint{ExpandArgs} the
- meaning of user defined functions, which in case of recursivity (as made
- possible at |1.3|) were badly inefficient for lack of expansion of their
- arguments.
- \end{itemize}
-\item Release |1.3| of |2018/03/01|:
- \begin{itemize}[nosep]
- \item removed all macros previously deprecated at |1.2o|,
- \item modified addition, subtraction and modulo operations to use a least
- common multiple for the denominator of the result,
- \item added \csbxint{PIrr}, \csbxint{DecToString} and \csbn{preduce()},
- \item and last but not least refactored extensively the
- \csbxint{NewExpr}/\csbxint{deffunc} mechanism. It got both leaner and stronger
- and makes possible recursive function definitions.
- \end{itemize}
-
-\item Release |1.2q| of |2018/02/06| was a bugfix release with these changes:
- \begin{itemize}[nosep]
- \item fix to an |1.2l| \xintcorenameimp subtraction bug causing a breakage
- under some rare circumstances |:-(|. It was caused by a refactoring
- left-over (extra |!| in |XINT_sub_l_Ida| replacement text), and should
- have been detected by the test suite, but manual testing from early days
- was not yet entirely included in our automated procedure.
- \item new feature: tacit multiplication in front of digits, for example
- |10!20!30!| or |(10+10)10|.
- \end{itemize}
-
-\item Release |1.2p| of |2017/12/05|
- had some breaking changes:
- \begin{itemize}[nosep]
- \item new output for the \csbxint{Bezout} macro (\xintgcdnameimp),
- \item the \xintexprnameimp operators |/:| (aka |'mod'|) and |//|, and the
- supporting macros from \xintcorenameimp and \xintfracnameimp, are now
- associated with the \emph{floored} division. Formerly it was the
- \emph{truncated} division. This is breaking change for operands of
- opposite signs.
- \end{itemize}
- Improvements and new features:
- \begin{itemize}[nosep]
- \item \xinttoolsnameimp macro \csbxint{ListWithSep} is faster (first update
- since |1.04-2013/04/25|...).
- \item \csbn{divmod()} function added to the \xintexprnameimp parsers,
- \item \csbxint{defvar}, \csbxint{deffloatvar}, \csbxint{defiivar} extended to allow
- multiple simultaneous assignments.
- \end{itemize}
+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.
-\item Release |1.2o| of |2017/08/29| deprecated those macros from
- \xintcorenameimp and \xintnameimp which filtered their arguments via
- \csbxint{Num}. Currently these macros execute as formerly but raise an error
- message. This deprecation is overruled for most if \xintfracnameimp is
- loaded as it provides their proper definitions. Some however (like
- |\xintiAdd|) remain deprecated even if loading \xintfracnameimp. All these
- deprecated macros are destined to be removed at some future release.
-
- A few macros got renamed (e.g. |\xintNot| became \csbxint{NOT}.) Former names
- emit a deprecation error and will get removed at some future release.
-
-\item Release |1.2n| of |2017/08/06| removed the \xintbinhexnameimp
- dependencies upon \xintcorenameimp; the package now depends upon, and
- loads, only \xintkernelnameimp. The allowed maximal size for the inputs of
- the base conversion macros got increased. The speed got slightly improved.
-
-\item Release |1.2m| of |2017/07/31| rewrote entirely the \xintbinhexnameimp
- module in the style of the techniques from |1.2| \xintcorenameimp. The new
- macros expand faster but their inputs are now limited to a few thousand
- characters (the earlier routines, which dated back to |1.08| could handle
- (slowly) tens of thousands of digits.)
-
-\item Release |1.2l| of |2017/07/26| refactored the subtraction and also
- \csbxint{iiCmp} got a rewrite. It should certainly use |\pdfstrcmp| for
- dramatic speed-up but I do not want to have to worry about multi-engine
- usage.
-
- Some utility routines in \xintcorenameimp manipulating blocks of eight
- digits and still in |O(N^2)| style got rewritten analogously to the
- |1.2i| version of macros such as \csbxint{Inc}. Also \csbxint{iNum} was
- revisited.
-
- The arithmetic macros of \xintcorenameimp and all macros of
- \xintfracnameimp using \csbXINT{_infrac} were made compatible with arguments
- using non-delimited |\the\numexpr| or |\the\mathcode| etc... But
- \csbxint{iiAbs} and \csbxint{iiOpp} were not modified (to avoid some overhead)
- as well as routines such as \csbxint{Inc} which are primarily for internal
- usage.
-
-\item Release |1.2i| of |2016/12/13| rewrote some legacy macros like
- \csbxint{DSR} or \csbxint{DecSplit} in the style of the techniques of |1.2|. But
- this means also that they got limited to about \dtt{22480} digits for
- the former and \dtt{19970} digits for the latter (this is with the input
- stack size at \dtt{5000} and the maximal expansion depth at \dtt{10000}.)
- This is not really an issue from the point of view of calling macros (such
- as \csbxint{Trunc}, \csbxint{Round}), because they usually had since |1.2| their
- own limitation at about \dtt{19950} digits from other code parts (such as
- division.) The macro \csbxint{XTrunc} (which is not f-expandable however) can
- produce tens of thousands of digits and it escapes these limitations. Old
- macros such as \csbxint{Length} are not limited either (incidentally it got a
- lifting in |1.2i|.) The macros from \xinttoolsnameimp (\csbxint{Keep},
- \csbxint{Trim}, \csbxint{NthElt}) also are not limited (but slower.)
-
-\item Release |1.2| of |2015/10/10| entirely rewrote the core
- arithmetic routines located in \xintcorenameimp. The parser of
- \xintexprnameimp got faster and the limitation at |5000| digits per
- number was removed.
-
-\item Extensive changes in release |1.1| of |2014/10/28| were located in
- \xintexprnameimp. Also with that release, packages \xintkernelnameimp and
- \xintcorenameimp were extracted from \xinttoolsnameimp and \xintnameimp,
- and \csbxint{Add} was modified to not multiply denominators blindly.
+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
@@ -17342,8 +17816,6 @@ math shift catcode.
%<*xintkernel>^^A-------------------------------------------------
%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*-
% \clearpage\csname xintkernelnameUp\endcsname
-% \StartPackageIndex{kernel}
-% \let\MakePrivateLetters\xintMakePrivateLetters
% \section {Package \xintkernelnameimp implementation}
% \RaisedLabel{sec:kernelimp}
%
@@ -17523,7 +17995,7 @@ math shift catcode.
\fi
\XINT_providespackage
\ProvidesPackage {xintkernel}%
- [2019/01/06 1.3d Paraphernalia for the xint packages (JFB)]%
+ [2019/04/05 1.3e Paraphernalia for the xint packages (JFB)]%
% \end{macrocode}
% \subsection{Constants}
% \begin{macrocode}
@@ -18085,10 +18557,15 @@ math shift catcode.
%
% \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}
@@ -18113,21 +18590,12 @@ math shift catcode.
}%
\begingroup\lccode`$ 32 \catcode`/ 11 \catcode`! 11 \catcode32 11 % $
% \end{macrocode}
-% \odef\MakePrivateLetters{\xintMakePrivateLetters
-% \catcode`/ 11 \catcode`! 11 \catcode32 11\relax}
-% \SpecialIndex{\ ! /}\let\MakePrivateLetters\xintMakePrivateLetters
-%^^A using \SpecialMainIndex does not not work, and trying without
-%^^A \SpecialIndex and letting doc parsing next line does not work either
-% \SpecialEscapechar{\+}^^A avoid doc.sty indexing erroneously \<space>
% \begin{macrocode}
\lowercase{\endgroup\XINT_expandableerror$\ ! /\let\ ! /\xint_undefined}% $
-% \end{macrocode}
-%^^A the special escapechar is used only for one macrocode environment
-% \begin{macrocode}
\XINT_restorecatcodes_endinput%
% \end{macrocode}
% \StoreCodelineNo {xintkernel}
-% \cleardoublepage\StopPackageIndex\let\xintkernelnameUp\undefined
+% \cleardoublepage\let\xintkernelnameUp\undefined
%\gardesactifs
%\let</xintkernel>\relax
%\let<*xinttools>\gardesinactifs
@@ -18135,8 +18603,6 @@ math shift catcode.
%<*xinttools>^^A--------------------------------------------------
%^^A -*- coding: utf-8; mode: doctex; -*-
% \clearpage\csname xinttoolsnameUp\endcsname
-% \StartPackageIndex{tools}
-% \let\MakePrivateLetters\xintMakePrivateLetters
% \section{Package \xinttoolsnameimp implementation}
% \RaisedLabel{sec:toolsimp}
%
@@ -18203,7 +18669,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xinttools}%
- [2019/01/06 1.3d Expandable and non-expandable utilities (JFB)]%
+ [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.|
@@ -18388,7 +18854,11 @@ math shift catcode.
% [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.|
+% 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
@@ -20086,7 +20556,7 @@ math shift catcode.
\XINT_restorecatcodes_endinput%
% \end{macrocode}
% \StoreCodelineNo {xinttools}
-% \cleardoublepage\StopPackageIndex\let\xinttoolsnameUp\undefined
+% \cleardoublepage\let\xinttoolsnameUp\undefined
%\gardesactifs
%\let</xinttools>\relax
%\let<*xintcore>\gardesinactifs
@@ -20094,8 +20564,6 @@ math shift catcode.
%<*xintcore>^^A---------------------------------------------------
%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*-
% \clearpage\csname xintcorenameUp\endcsname
-% \StartPackageIndex{core}
-% \let\MakePrivateLetters\xintMakePrivateLetters
% \section{Package \xintcorenameimp implementation}
% \RaisedLabel{sec:coreimp}
%
@@ -20170,7 +20638,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintcore}%
- [2019/01/06 1.3d Expandable arithmetic on big integers (JFB)]%
+ [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
@@ -20246,9 +20714,6 @@ math shift catcode.
\csname XINT_InvalidOperation_istrapped\endcsname
\csname XINT_Overflow_istrapped\endcsname
\csname XINT_Underflow_istrapped\endcsname
-% \end{macrocode}
-% \odef\MakePrivateLetters{\xintMakePrivateLetters \catcode`- 11 }
-% \begin{macrocode}
\catcode`- 11
\def\XINT_ConversionSyntax-signal {{InvalidOperation}}%
\let\XINT_DivisionImpossible-signal\XINT_ConversionSyntax-signal
@@ -20298,7 +20763,6 @@ math shift catcode.
\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)
-% \odef\MakePrivateLetters{\xintMakePrivateLetters \catcode`. 11 }
% \begin{macrocode}
\catcode`. 11
\let\XINT_Clamped.handler\xint_firstofone % WIP
@@ -20315,7 +20779,6 @@ math shift catcode.
\def\XINT_Underflow.handler#1{_NaN}% WIP
\catcode`. 12
% \end{macrocode}
-% \let\MakePrivateLetters\xintMakePrivateLetters
% \subsection{Counts for holding needed constants}
% \begin{macrocode}
\ifdefined\m@ne\let\xint_c_mone\m@ne
@@ -23422,7 +23885,7 @@ math shift catcode.
\XINT_restorecatcodes_endinput%
% \end{macrocode}
% \StoreCodelineNo {xintcore}
-% \cleardoublepage\StopPackageIndex\let\xintcorenameUp\undefined
+% \cleardoublepage\let\xintcorenameUp\undefined
%\gardesactifs
%\let</xintcore>\relax
%\let<*xint>\gardesinactifs
@@ -23430,8 +23893,6 @@ math shift catcode.
%<*xint>^^A-------------------------------------------------------
%^^A -*- coding: utf-8; mode: doctex -*-
% \clearpage\csname xintnameUp\endcsname
-% \StartPackageIndex{xint}
-% \let\MakePrivateLetters\xintMakePrivateLetters
% \section{Package \xintnameimp implementation}
% \RaisedLabel{sec:xintimp}
%
@@ -23494,7 +23955,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xint}%
- [2019/01/06 1.3d Expandable operations on big integers (JFB)]%
+ [2019/04/05 1.3e Expandable operations on big integers (JFB)]%
% \end{macrocode}
% \subsection{More token management}
% \begin{macrocode}
@@ -23545,6 +24006,23 @@ math shift catcode.
\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.
@@ -25818,7 +26296,7 @@ math shift catcode.
\XINT_restorecatcodes_endinput%
% \end{macrocode}
% \StoreCodelineNo {xint}
-% \cleardoublepage\StopPackageIndex\let\xintnameUp\undefined
+% \cleardoublepage\let\xintnameUp\undefined
%\gardesactifs
%\let</xint>\relax
%\let<*xintbinhex>\gardesinactifs
@@ -25826,8 +26304,6 @@ math shift catcode.
%<*xintbinhex>^^A-------------------------------------------------
%^^A -*- coding: utf-8; mode: doctex; -*-
% \clearpage\csname xintbinhexnameUp\endcsname
-% \StartPackageIndex{binhex}
-% \let\MakePrivateLetters\xintMakePrivateLetters
% \section{Package \xintbinhexnameimp implementation}
% \RaisedLabel{sec:binheximp}
%
@@ -25903,7 +26379,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintbinhex}%
- [2019/01/06 1.3d Expandable binary and hexadecimal conversions (JFB)]%
+ [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.|
@@ -26471,7 +26947,7 @@ math shift catcode.
\XINT_restorecatcodes_endinput%
% \end{macrocode}
% \StoreCodelineNo {xintbinhex}
-% \cleardoublepage\StopPackageIndex\let\xintbinhexnameUp\undefined
+% \cleardoublepage\let\xintbinhexnameUp\undefined
%\gardesactifs
%\let</xintbinhex>\relax
%\let<*xintgcd>\gardesinactifs
@@ -26479,8 +26955,6 @@ math shift catcode.
%<*xintgcd>^^A----------------------------------------------------
%^^A -*- coding: utf-8; mode: doctex; -*-
% \clearpage\csname xintgcdnameUp\endcsname
-% \StartPackageIndex{gcd}
-% \let\MakePrivateLetters\xintMakePrivateLetters
% \section{Package \xintgcdnameimp implementation}
% \RaisedLabel{sec:gcdimp}
%
@@ -26557,7 +27031,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintgcd}%
- [2019/01/06 1.3d Euclide algorithm with xint package (JFB)]%
+ [2019/04/05 1.3e Euclide algorithm with xint package (JFB)]%
% \end{macrocode}
% \subsection{\csh{xintGCD}, \csh{xintiiGCD}}
% \lverb|&
@@ -26572,7 +27046,7 @@ math shift catcode.
\def\xintgcd #1#2{\xintiigcd {\xintNum{#1}}{\xintNum{#2}}}%
\def\xintiiGCD {\romannumeral0\xintiigcd }%
% \end{macrocode}
-% This abuses the way \csbxint{iiabs} expands.
+% \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%
@@ -27195,7 +27669,7 @@ math shift catcode.
\XINT_restorecatcodes_endinput%
% \end{macrocode}
% \StoreCodelineNo {xintgcd}
-% \cleardoublepage\StopPackageIndex\let\xintgcdnameUp\undefined
+% \cleardoublepage\let\xintgcdnameUp\undefined
%\gardesactifs
%\let</xintgcd>\relax
%\let<*xintfrac>\gardesinactifs
@@ -27203,8 +27677,6 @@ math shift catcode.
%<*xintfrac>^^A---------------------------------------------------
%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*-
% \clearpage\csname xintfracnameUp\endcsname
-% \StartPackageIndex{frac}
-% \let\MakePrivateLetters\xintMakePrivateLetters
% \section{Package \xintfracnameimp implementation}
% \RaisedLabel{sec:fracimp}
%
@@ -27269,7 +27741,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintfrac}%
- [2019/01/06 1.3d Expandable operations on fractions (JFB)]%
+ [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
@@ -27762,6 +28234,47 @@ math shift catcode.
}%
\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}
@@ -29828,7 +30341,7 @@ math shift catcode.
}%
\def\XINT_float_pos_done #1.#2;{ #2e#1}%
% \end{macrocode}
-% \subsection{\csh{XINTinFloat}, \csh{XINTinFloatS}}
+% \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.
@@ -29848,7 +30361,7 @@ math shift catcode.
% 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
@@ -29856,11 +30369,18 @@ math shift catcode.
%
% 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. |
+% \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}
@@ -29885,6 +30405,21 @@ math shift catcode.
{\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}
@@ -30477,6 +31012,13 @@ math shift catcode.
% \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.
%
@@ -31011,11 +31553,12 @@ math shift catcode.
}%
% \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 \XINTinfloat #1\xint:}%
+\def\XINTinfloatfac #1{\XINT_flfac_chkopt \XINTinfloatS #1\xint:}%
\def\XINT_flfac_chkopt #1#2%
{%
\ifx [#2\expandafter\XINT_flfac_opt
@@ -31917,7 +32460,7 @@ math shift catcode.
\XINT_restorecatcodes_endinput%
% \end{macrocode}
% \StoreCodelineNo {xintfrac}
-% \cleardoublepage\StopPackageIndex\let\xintfracnameUp\undefined
+% \cleardoublepage\let\xintfracnameUp\undefined
%\gardesactifs
%\let</xintfrac>\relax
%\let<*xintseries>\gardesinactifs
@@ -31925,8 +32468,6 @@ math shift catcode.
%<*xintseries>^^A-------------------------------------------------
%^^A -*- coding: utf-8; mode: doctex; -*-
% \clearpage\csname xintseriesnameUp\endcsname
-% \StartPackageIndex{series}
-% \let\MakePrivateLetters\xintMakePrivateLetters
% \section{Package \xintseriesnameimp implementation}
% \RaisedLabel{sec:seriesimp}
%
@@ -31991,7 +32532,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintseries}%
- [2019/01/06 1.3d Expandable partial sums with xint package (JFB)]%
+ [2019/04/05 1.3e Expandable partial sums with xint package (JFB)]%
% \end{macrocode}
% \subsection{\csh{xintSeries}}
% \begin{macrocode}
@@ -32411,7 +32952,7 @@ math shift catcode.
\XINT_restorecatcodes_endinput%
% \end{macrocode}
% \StoreCodelineNo {xintseries}
-% \cleardoublepage\StopPackageIndex\let\xintseriesnameUp\undefined
+% \cleardoublepage\let\xintseriesnameUp\undefined
%\gardesactifs
%\let</xintseries>\relax
%\let<*xintcfrac>\gardesinactifs
@@ -32419,8 +32960,6 @@ math shift catcode.
%<*xintcfrac>^^A--------------------------------------------------
%^^A -*- coding: utf-8; mode: doctex; -*-
% \clearpage\csname xintcfracnameUp\endcsname
-% \StartPackageIndex{cfrac}
-% \let\MakePrivateLetters\xintMakePrivateLetters
% \section{Package \xintcfracnameimp implementation}
% \RaisedLabel{sec:cfracimp}
%
@@ -32494,7 +33033,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintcfrac}%
- [2019/01/06 1.3d Expandable continued fractions with xint package (JFB)]%
+ [2019/04/05 1.3e Expandable continued fractions with xint package (JFB)]%
% \end{macrocode}
% \subsection{\csh{xintCFrac}}
% \begin{macrocode}
@@ -33601,7 +34140,7 @@ math shift catcode.
\XINT_restorecatcodes_endinput%
% \end{macrocode}
% \StoreCodelineNo {xintcfrac}
-% \cleardoublepage\StopPackageIndex\let\xintcfracnameUp\undefined
+% \cleardoublepage\let\xintcfracnameUp\undefined
%\gardesactifs
%\let</xintcfrac>\relax
%\let<*xintexpr>\gardesinactifs
@@ -33609,8 +34148,6 @@ math shift catcode.
%<*xintexpr>^^A---------------------------------------------------
%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*-
% \clearpage\csname xintexprnameUp\endcsname
-% \StartPackageIndex{expr}
-% \let\MakePrivateLetters\xintexprMakePrivateLetters
% \section{Package \xintexprnameimp implementation}
% \RaisedLabel{sec:exprimp}
% \etocarticlestylenomarks
@@ -33745,86 +34282,104 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintexpr}%
- [2019/01/06 1.3d Expandable expression parser (JFB)]%
+ [2019/04/05 1.3e Expandable expression parser (JFB)]%
\catcode`! 11
\let\XINT_Cmp \xintiiCmp
% \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.
+% \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.
%
-% 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.
+% ATTENTION! 1.3d renamed \xinteval to \xintexpro etc...
%
-% 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...).|
+% Some renaming of macros at 1.3e here.|
% \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
+\def\xintiexpro #1%
{%
- \if#2>%
- \xintHexToDec{#1}%
- \else
- \xintiiMul{\xintiiPow{625}{\xintLength{#3}}}{\xintHexToDec{#1#3}}%
- [\the\numexpr-4*\xintLength{#3}]%
- \fi
+ \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
}%
-\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{\csh{XINT_expr_wrap}, \csh{XINT_iiexpr_wrap}}
+% \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_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_protectii}, \csh{XINT_expr_usethe}}
+% \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_boolexpr_print}}
-% \lverb|See also the \XINT_flexpr_print which is special, below.|
+% \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_boolexpr_print #1{\xintIsTrue::csv {\XINT_expr_unlock #1}}%
-% \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 }%
+\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}%
@@ -33835,6 +34390,16 @@ math shift catcode.
\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}
@@ -33847,46 +34412,9 @@ math shift catcode.
\def\xintiieval #1%
{\romannumeral`&&@\expandafter\XINT_iiexpr_print\romannumeral0\xintbareiieval#1\relax}%
% \end{macrocode}
-% \subsection{\csh{xintthe}, \csh{xintthe_o}}
+% \subsection{\csh{xintthe}}
% \begin{macrocode}
\def\xintthe #1{\romannumeral`&&@\expandafter\xint_gobble_iii\romannumeral`&&@#1}%
-\def\xintthe_o #1{\expandafter\xint_gobble_iii\romannumeral`&&@#1}%
-% \end{macrocode}
-% \subsection{\csh{thexintexpr}, \csh{thexintiexpr}, \csh{thexintfloatexpr},
-% \csh{thexintiiexpr}}
-% \lverb|New with 1.2h. I have been three years long very strict in terms of
-% prefixing macros, but well.|
-% \begin{macrocode}
-\let\thexintexpr \xinttheexpr
-\let\thexintiexpr \xinttheiexpr
-\let\thexintfloatexpr\xintthefloatexpr
-\let\thexintiiexpr \xinttheiiexpr
-% \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{\csh{xintbareeval}, \csh{xintbarefloateval}, \csh{xintbareiieval}}
% \begin{macrocode}
@@ -33903,74 +34431,23 @@ math shift catcode.
\def\xintthebarefloateval {\expandafter\XINT_expr_unlock\romannumeral0\xintbarefloateval}%
\def\xintthebareiieval {\expandafter\XINT_expr_unlock\romannumeral0\xintbareiieval}%
% \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{XINT_iexpr_wrap}}
-% \lverb|Optional argument since 1.1.|
+% \subsection{\csh{xintboolexpr}, \csh{XINT_boolexpr_print}, \csh{xinttheboolexpr},
+% \csh{thexintboolexpr}}
% \lverb|ATTENTION! 1.3d renamed \xinteval to \xintexpro etc...|
% \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_wrap \expandafter 0\romannumeral0\xintbareeval }%
-\def\XINT_iexpr_withopt [#1]%
-{%
- \expandafter\XINT_iexpr_wrap\expandafter
- {\the\numexpr \xint_zapspaces #1 \xint_gobble_i\expandafter}%
- \romannumeral0\xintbareeval
-}%
-\def\XINT_iexpr_wrap #1#2%
-{%
- \expandafter\XINT_expr_wrap
- \csname .=\xintRound::csv {#1}{\XINT_expr_unlock #2}\endcsname
-}%
-% \end{macrocode}
-% \subsection{\csh{xintfloatexpro}, \csh{XINT_flexpr_wrap}, \csh{XINT_flexpr_print}}
-% \lverb|Optional argument since 1.1|
-% \lverb|ATTENTION! 1.3d renamed \xinteval to \xintexpro etc...|
-% \begin{macrocode}
-\def\xintfloatexpro #1%
-{%
- \ifx [#1\expandafter\XINT_flexpr_withopt_a\else\expandafter\XINT_flexpr_noopt
- \fi #1%
-}%
-\def\XINT_flexpr_noopt
-{%
- \expandafter\XINT_flexpr_withopt_b\expandafter\xinttheDigits
- \romannumeral0\xintbarefloateval
-}%
-\def\XINT_flexpr_withopt_a [#1]%
-{%
- \expandafter\XINT_flexpr_withopt_b\expandafter
- {\the\numexpr\xint_zapspaces #1 \xint_gobble_i\expandafter}%
- \romannumeral0\xintbarefloateval
-}%
-\def\XINT_flexpr_withopt_b #1#2%
+\def\xintboolexpr
{%
- \expandafter\XINT_flexpr_wrap\csname .;#1.=% ; and not : as before b'cause NewExpr
- \XINTinFloat::csv {#1}{\XINT_expr_unlock #2}\endcsname
+ \romannumeral0\expandafter\expandafter\expandafter
+ \XINT_boolexpr_done\expandafter\xint_gobble_iv\romannumeral0\xintexpro
}%
-\def\XINT_flexpr_wrap { !\XINT_expr_usethe\XINT_protectii\XINT_flexpr_print }%
-\def\XINT_flexpr_print #1%
+\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
{%
- \expandafter\xintPFloat::csv
- \romannumeral`&&@\expandafter\XINT_expr_unlock_sp\string #1!%
+ \romannumeral`&&@\expandafter\expandafter\expandafter
+ \XINT_boolexpr_print\expandafter\xint_gobble_iv\romannumeral0\xintexpro
}%
-\def\XINT_expr_unlock_sp #1.;#2.=#3!{{#2}{#3}}%
-% \end{macrocode}
-% \subsection{\csh{xintboolexpr}, \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\xinttheboolexpr {\romannumeral`&&@\expandafter\expandafter\expandafter
- \XINT_boolexpr_print\expandafter\xint_gobble_iv\romannumeral0\xintexpro }%
\let\thexintboolexpr\xinttheboolexpr
-\def\XINT_boolexpr_done { !\XINT_expr_usethe\XINT_protectii\XINT_boolexpr_print }%
% \end{macrocode}
% \subsection{\csh{xintifboolexpr}, \csh{xintifboolfloatexpr}, \csh{xintifbooliiexpr}}
% \lverb|Do not work with comma separated expressions.|
@@ -33987,13 +34464,88 @@ math shift catcode.
\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:two\empty
\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)}
@@ -34043,42 +34595,61 @@ math shift catcode.
\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::_b\expandafter
- {\the\numexpr#1\expandafter}\expandafter{\expandafter}\romannumeral`&&@#2,^,}%
-\def\XINT_round::_b #1#2#3,{\expandafter\XINT_round::_c \romannumeral`&&@#3,{#1}{#2}}%
+\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}}%
+\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::_b\expandafter
- {\the\numexpr #1\expandafter}\expandafter{\expandafter}\romannumeral`&&@#2,^,}%
-\def\XINT_infloat::_b #1#2#3,{\XINT_infloat::_c #3,{#1}{#2}}%
+\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}}%
+\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::_b\expandafter
- {\the\numexpr #1\expandafter}\expandafter{\expandafter}\romannumeral`&&@#2,^,}%
-\def\XINT_pfloat::_b #1#2#3,{\expandafter\XINT_pfloat::_c \romannumeral`&&@#3,{#1}{#2}}%
+\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}}%
+\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
@@ -34174,7 +34745,6 @@ math shift catcode.
% `+`(...), but `+(...) is also valid. The opening parenthesis must be there,
% it is not allowed to come from expansion.@
%
-% \odef\MakePrivateLetters{\xintexprMakePrivateLetters \catcode`` 11 }
% \begin{macrocode}
\catcode96 11 % `
\def\XINT_expr_scan_nbr_or_func #1% this #1 has necessarily here catcode 12
@@ -34188,9 +34758,6 @@ math shift catcode.
\def\XINT_expr_gotnil{\expandafter\XINT_expr_getop\csname.= \endcsname}%
\def\XINT_expr_onliteral_` #1#2#3({\xint_c_xviii `{#2}}%
\catcode96 12 % `
-% \end{macrocode}
-% \let\MakePrivateLetters\xintexprMakePrivateLetters
-% \begin{macrocode}
\def\XINT_expr_startint #1%
{%
\if #10\expandafter\XINT_expr_gobz_a\else\XINT_expr_scanint_a\fi #1%
@@ -34574,9 +35141,6 @@ math shift catcode.
{%
\expandafter\XINT_expr_getop_a\expandafter #1\romannumeral`&&@#2%
}%
-% \end{macrocode}
-% \odef\MakePrivateLetters{\xintexprMakePrivateLetters \catcode`* 11 }
-% \begin{macrocode}
\catcode`* 11
\def\XINT_expr_getop_a #1#2%
{%
@@ -34593,9 +35157,6 @@ math shift catcode.
{\expandafter\XINT_expr_getop_b \string#2#1}%
}%
\catcode`* 12
-% \end{macrocode}
-% \let\MakePrivateLetters\xintexprMakePrivateLetters
-% \begin{macrocode}
\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
@@ -34650,7 +35211,6 @@ math shift catcode.
% and abort in iterations over dummy variables. This has been removed by
% 1.2c, see the subsection where omit and abort are discussed.|
%
-% \odef\MakePrivateLetters{\xintexprMakePrivateLetters \catcode`) 11 }
% \begin{macrocode}
\catcode`) 11
\def\XINT_tmpa #1#2#3#4%
@@ -34697,7 +35257,6 @@ math shift catcode.
}%
\def\XINT_expr_missing_) {\xintError:inserted \xint_c_ \XINT_expr_done }%
% \end{macrocode}
-% \let\MakePrivateLetters\xintexprMakePrivateLetters
% \lverb|We should be using until_( notation to stay synchronous with until_+,
% until_* etc..., but I found that until_) was more telling.|
% \begin{macrocode}
@@ -34757,10 +35316,6 @@ math shift catcode.
% 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.)|
-%^^A mais ne sert à rien je pense à cause des \csname
-%^^A\def\MakePrivateLetters{\catcode`_ 11 \catcode`: 11 \catcode`^ 11
-%^^A \catcode`@ 11 \catcode`! 11
-%^^A \catcode`. 11 \catcode`= 11 \catcode`+ 11 }
% \begin{macrocode}
\catcode`. 11 \catcode`= 11 \catcode`+ 11
\xintFor #1 in {expr,flexpr,iiexpr} \do {%
@@ -35166,9 +35721,6 @@ math shift catcode.
\csname XINT_#1_op_-vi\expandafter\endcsname
\csname XINT_expr_precedence_:\endcsname {#1}%
}%
-% \end{macrocode}
-% \odef\MakePrivateLetters{\xintexprMakePrivateLetters \catcode`[ 11 \catcode`] 11 }
-% \begin{macrocode}
\catcode`[ 11 \catcode`] 11
\let\XINT_expr_precedence_:] \xint_c_iii
\def\XINT_expr_op_:] #1%
@@ -35190,7 +35742,6 @@ math shift catcode.
\let\XINT_iiexpr_op_][: \XINT_expr_op_][:
\catcode`[ 12 \catcode`] 12
% \end{macrocode}
-% \let\MakePrivateLetters\xintexprMakePrivateLetters
% \subsubsection{\csh{xintListSel:x:csv}}
% \lverb|1.2j. Because there is \xintKeep:x:csv which is faster than
% \xintKeep:f:csv.|
@@ -35684,7 +36235,6 @@ math shift catcode.
% \numexpr will not handle catcode 11 digits, but adding a \detokenize will
% suddenly make illicit for N to rely on macro expansion.|
%
-% \odef\MakePrivateLetters{\xintexprMakePrivateLetters \catcode`[ 11 }
% \begin{macrocode}
\catcode`[ 11
\let\XINT_expr_precedence_[ \xint_c_vii
@@ -35699,8 +36249,6 @@ math shift catcode.
{\xint_zapspaces #2 \xint_gobble_i}\endcsname}%
\catcode`[ 12
% \end{macrocode}
-% \let\MakePrivateLetters\xintexprMakePrivateLetters
-%
% \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
@@ -35769,6 +36317,8 @@ math shift catcode.
% 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
@@ -35781,7 +36331,7 @@ math shift catcode.
\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 .=\XINTinFloatdigits{#1}\endcsname }%
+ {\expandafter\XINT_expr_getop\csname .=\XINTinFloatSdigits{#1}\endcsname }%
\def\XINT_expr_onliteral_qraw #1)%
{\expandafter\XINT_expr_getop\csname .=#1\endcsname }%
% \end{macrocode}
@@ -35850,7 +36400,6 @@ math shift catcode.
% \end{itemize}
% \lverb|
% |
-% \odef\MakePrivateLetters{\xintexprMakePrivateLetters \catcode`* 11 }
% \begin{macrocode}
\catcode`* 11
\def\XINT_expr_defvar_one #1#2%
@@ -35867,13 +36416,10 @@ math shift catcode.
\fi
}%
\catcode`* 12
-% \end{macrocode}
-% \let\MakePrivateLetters\xintexprMakePrivateLetters
-% \begin{macrocode}
\catcode`~ 13
\catcode`: 12
\def\XINT_expr_defvar_getname #1:#2~{\endgroup
- \def\XINT_expr_tmpa{#1}\edef\XINT_expr_tmpc{\xintCSVLength{#1}}}%
+ \def\XINT_defvar_tmpa{#1}\edef\XINT_defvar_tmpc{\xintCSVLength{#1}}}%
\def\XINT_expr_defvar #1#2#3;%
{%
\xintexprRestoreCatcodes
@@ -35883,39 +36429,39 @@ math shift catcode.
% colon (even if in math mode with a math active colon..).|
% \begin{macrocode}
\begingroup\lccode`~`: \lowercase{\let~}\empty
- \edef\XINT_expr_tmpa{#2}%
- \edef\XINT_expr_tmpa{\xint_zapspaces_o\XINT_expr_tmpa}%
+ \edef\XINT_defvar_tmpa{#2}%
+ \edef\XINT_defvar_tmpa{\xint_zapspaces_o\XINT_defvar_tmpa}%
\expandafter\XINT_expr_defvar_getname
- \detokenize\expandafter{\XINT_expr_tmpa}:~%
- \ifcase\XINT_expr_tmpc
+ \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_expr_tmpb{\romannumeral0#1#3\relax}%
- \XINT_expr_defvar_one\XINT_expr_tmpa\XINT_expr_tmpb
+ \edef\XINT_defvar_tmpb{\romannumeral0#1#3\relax}%
+ \XINT_expr_defvar_one\XINT_defvar_tmpa\XINT_defvar_tmpb
\else
- \edef\XINT_expr_tmpb
+ \edef\XINT_defvar_tmpb
{\expandafter\XINT_expr_unlock\romannumeral0#1#3\relax}%
- \edef\XINT_expr_tmpd{\xintCSVLength{\XINT_expr_tmpb}}%
- \ifnum\XINT_expr_tmpc=\XINT_expr_tmpd\space
- \xintAssignArray\xintCSVtoList\XINT_expr_tmpa\to\XINT_expr_tmpvar
+ \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_expr_tmpb}%
- \to\XINT_expr_tmpval
- \def\XINT_expr_tmpd{1}%
+ \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_expr_tmpvar\XINT_expr_tmpd\expandafter\endcsname
- \csname XINT_expr_tmpval\XINT_expr_tmpd\endcsname
- \ifnum\XINT_expr_tmpd<\XINT_expr_tmpc\space
- \edef\XINT_expr_tmpd{\the\numexpr\XINT_expr_tmpd+1}%
+ \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_expr_tmpvar
- \xintRelaxArray\XINT_expr_tmpval
+ \xintRelaxArray\XINT_defvar_tmpvar
+ \xintRelaxArray\XINT_defvar_tmpval
\else
\xintMessage {xintexpr}{Warning}
- {Aborting: mismatch between number of variables (\XINT_expr_tmpc)
- and number of values (\XINT_expr_tmpd).}%
+ {Aborting: mismatch between number of variables (\XINT_defvar_tmpc)
+ and number of values (\XINT_defvar_tmpd).}%
\fi
\fi
}%
@@ -35946,24 +36492,24 @@ math shift catcode.
% \csbXINT{_expr_op_`}.
% \begin{macrocode}
\def\xintunassignvar #1{%
- \edef\XINT_expr_tmpa{#1}%
- \edef\XINT_expr_tmpa {\xint_zapspaces_o\XINT_expr_tmpa}%
- \ifcsname XINT_expr_var_\XINT_expr_tmpa\endcsname
- \ifnum\expandafter\xintLength\expandafter{\XINT_expr_tmpa}=\@ne
- \expandafter\xintnewdummy\XINT_expr_tmpa
+ \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_expr_tmpa\endcsname\xint_undefined
+ \let\csname XINT_expr_var_\XINT_unvar_tmpa\endcsname\xint_undefined
\XINT_global\expandafter
- \let\csname XINT_expr_onliteral_\XINT_expr_tmpa\endcsname\xint_undefined
+ \let\csname XINT_expr_onliteral_\XINT_unvar_tmpa\endcsname\xint_undefined
\ifxintverbose\xintMessage {xintexpr}{Info}
- {Variable \XINT_expr_tmpa\space has been
+ {Variable \XINT_unvar_tmpa\space has been
\ifxintglobaldefs globally \fi ``unassigned''.}%
\fi
\fi
\else
\xintMessage {xintexpr}{Warning}
- {Error: there was no such variable \XINT_expr_tmpa\space to unassign.}%
+ {Error: there was no such variable \XINT_unvar_tmpa\space to unassign.}%
\fi
}%
% \end{macrocode}
@@ -35995,7 +36541,7 @@ math shift catcode.
% minus sign, etc...). But the code manages simultaneously expr, flexpr
% and iiexpr.|
%
-% \subsubsection{All letters usable as dummy variables}
+% \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
@@ -36025,13 +36571,29 @@ math shift catcode.
% already locked value \.=<number>.
%
% The tacit multiplication in case of the ``nil'' variable doesn't make much
-% sense but we do it anyhow.|
+% 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?
+% |
%
-% \odef\MakePrivateLetters{\xintexprMakePrivateLetters \catcode`* 11 }
% \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}%
@@ -36053,7 +36615,35 @@ math shift catcode.
{\XINT_expr_precedence_*** *\expandafter\noexpand\csname .= \endcsname (}%
\catcode`* 12
% \end{macrocode}
-% \let\MakePrivateLetters\xintexprMakePrivateLetters
+% \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.
@@ -36115,7 +36705,6 @@ math shift catcode.
%
% For the record, the ~ has catcode 3 in this code.|
%
-% \odef\MakePrivateLetters{\xintexprMakePrivateLetters \catcode`* 11 }
% \begin{macrocode}
\catcode`? 3 \catcode`* 11
\def\XINT_expr_var_@ #1~#2{#2#1~#2}%
@@ -36132,9 +36721,6 @@ math shift catcode.
\expandafter\def\csname XINT_expr_onliteral_@4\endcsname #1~#2#3#4#5%
{\XINT_expr_precedence_*** *#5(#1~#2#3#4#5}%
\catcode`* 12
-% \end{macrocode}
-% \let\MakePrivateLetters\xintexprMakePrivateLetters
-% \begin{macrocode}
\def\XINT_expr_func_@@ #1#2#3#4~#5?%
{%
\expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand
@@ -36812,7 +37398,10 @@ math shift catcode.
% \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.|
+% 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}%
@@ -36966,28 +37555,38 @@ math shift catcode.
\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}}
-% \lverb|for \xintNewExpr matters, mainly.|
+% \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|
+% \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\XINTinFloatdigits\romannumeral`&&@#1,^,{0[0]}}%
+ \expandafter\XINTinFloatSdigits\romannumeral`&&@#1,^,{0[0]}}%
\def\XINTinFloatMinof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintmin
- \expandafter\XINTinFloatdigits\romannumeral`&&@#1,^,{0[0]}}%
+ \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.|
+% \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\XINTinFloatdigits\romannumeral`&&@#1,^,{0[0]}}%
+ \expandafter\XINTinFloatSdigits\romannumeral`&&@#1,^,{0[0]}}%
\def\XINTinFloatPrd:csv #1{\expandafter\XINT_oncsv:_a\expandafter\XINTinfloatmul
- \expandafter\XINTinFloatdigits\romannumeral`&&@#1,^,{1[0]}}%
+ \expandafter\XINTinFloatSdigits\romannumeral`&&@#1,^,{1[0]}}%
% \end{macrocode}
% \subsection{Auxiliary wrappers for function macros}
% \begin{macrocode}
@@ -37012,23 +37611,15 @@ math shift catcode.
\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}%
+ \expandafter\XINT:expr:totwo\romannumeral`&&@#3{#1}{#2}%
}%
-\def\XINT:expr:two:to:one #1,#2,!#3%
-{%
- #3{#1}{#2}%
-}%
-\def\XINT:flexpr:two:to:one #1,#2,!#3%
-{%
- #3{#1}{#2}%
-}%
-\let\XINT:flexpr:two:to:two\XINT:flexpr:two:to:one
+\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}
-% {round}{trunc}{mod}{quo}{rem}{divmod}{gcd}{lcm}{max}{min}
+% {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}
@@ -37240,6 +37831,16 @@ math shift catcode.
\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.=%
@@ -37270,6 +37871,10 @@ math shift catcode.
\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.=%
@@ -37278,7 +37883,34 @@ math shift catcode.
\endcsname
}%
\let\XINT_flexpr_func_float\XINT_expr_func_float
-% \XINT_iiexpr_func_float not defined
+\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.=%
@@ -37286,10 +37918,13 @@ math shift catcode.
\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:flexpr:two:to:two
+ \expandafter\XINT:NEhook:twosp
\romannumeral`&&@\XINT_expr_unlock #3,!\XINTinFloatDivMod
\endcsname
}%
@@ -37303,63 +37938,63 @@ math shift catcode.
\def\XINT_expr_func_mod #1#2#3%
{%
\expandafter #1\expandafter #2\csname.=%
- \expandafter\XINT:expr:two:to:one
+ \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:flexpr:two:to:one
+ \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:expr:two:to:one
+ \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:expr:two:to:one
+ \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:flexpr:two:to:one
+ \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:expr:two:to:one
+ \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:expr:two:to:one
+ \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:flexpr:two:to:one
+ \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:expr:two:to:one
+ \expandafter\XINT:NEhook:twosp
\romannumeral`&&@\XINT_expr_unlock #3,!\xintiiPFactorial
\endcsname
}%
@@ -37395,7 +38030,7 @@ math shift catcode.
\def\XINT_expr_func_quo #1#2#3%
{%
\expandafter #1\expandafter #2\csname.=%
- \expandafter\XINT:expr:two:to:one
+ \expandafter\XINT:NEhook:twosp
\romannumeral`&&@\XINT_expr_unlock #3,!\xintiQuo
\endcsname
}%
@@ -37403,14 +38038,14 @@ math shift catcode.
\def\XINT_iiexpr_func_quo #1#2#3%
{%
\expandafter #1\expandafter #2\csname.=%
- \expandafter\XINT:expr:two:to:one
+ \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:expr:two:to:one
+ \expandafter\XINT:NEhook:twosp
\romannumeral`&&@\XINT_expr_unlock #3,!\xintiRem
\endcsname
}%
@@ -37418,7 +38053,7 @@ math shift catcode.
\def\XINT_iiexpr_func_rem #1#2#3%
{%
\expandafter #1\expandafter #2\csname.=%
- \expandafter\XINT:expr:two:to:one
+ \expandafter\XINT:NEhook:twosp
\romannumeral`&&@\XINT_expr_unlock #3,!\xintiiRem
\endcsname
}%
@@ -37729,7 +38364,7 @@ math shift catcode.
\XINT_seqb:f:csv_nc\XINT_seqb:f:csv_nb\XINT_flseqb:f:csv_na {#1}{#2}%
}%
% \end{macrocode}
-% \subsection{User defined functions: \csh{xintdeffunc}, \csh{xintdefiifunc},
+% \subsection{\csh{xintdeffunc}, \csh{xintdefiifunc},
% \csh{xintdeffloatfunc}}
%
% \changed{1.2c}{2015/11/12}
@@ -37748,25 +38383,36 @@ math shift catcode.
\def\XINT_tmpa #1#2#3#4%
{%
\def #1##1(##2)##3=##4;{%
- \edef\XINT_expr_tmpa {##1}%
- \edef\XINT_expr_tmpa {\xint_zapspaces_o \XINT_expr_tmpa}%
- \def\XINT_expr_tmpb {0}%
- \def\XINT_expr_tmpc {(##4)}%
- \xintFor ####1 in {##2} \do
- {\edef\XINT_expr_tmpb {\the\numexpr\XINT_expr_tmpb+\xint_c_i}%
- \edef\XINT_expr_tmpc {subs(\unexpanded\expandafter{\XINT_expr_tmpc},%
- ####1=################\XINT_expr_tmpb)}%
+ \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)}%
}%
- \expandafter\XINT_expr_defuserfunc
- \csname XINT_#2_func_\XINT_expr_tmpa\expandafter\endcsname
- \expandafter{\XINT_expr_tmpa}{#2}%
- \expandafter#3\csname XINT_#2_userfunc_\XINT_expr_tmpa\endcsname
- [\XINT_expr_tmpb]{\XINT_expr_tmpc}%
+ \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_expr_tmpa\space for \string\xint #4 parser
- associated to \string\XINT_#2_userfunc_\XINT_expr_tmpa\space
+ {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_expr_tmpa\endcsname}%
+ \csname XINT_#2_userfunc_\XINT_deffunc_tmpa\endcsname}%
\fi
\xintexprRestoreCatcodes
}%
@@ -37781,16 +38427,192 @@ math shift catcode.
{%
\XINT_global
\def #1##1##2##3{\expandafter ##1\expandafter ##2%
- \csname .=\XINT:expr:userfunc{#3}{#2}{\XINT_expr_unlock ##3}\endcsname
+ \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}}%
-\catcode`~ 12
-\def\XINT:newexpr:userfunc #1#2#3%
- {~xintExpandArgs{XINT_#1_userfunc_#2}{\xintCSVtoListNonStripped{#3}}}%
-\catcode`~ 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
@@ -37798,14 +38620,16 @@ math shift catcode.
% 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_expr_tmpa{##1}%
- \edef\XINT_expr_tmpa {\xint_zapspaces_o\XINT_expr_tmpa}%
+ \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_func_\XINT_expr_tmpa\endcsname\xint_undefined
+ \let\csname XINT_#1_userfunc_\XINT_unfunc_tmpa\endcsname\xint_undefined
\XINT_global\expandafter
- \let\csname XINT_#1_userfunc_\XINT_expr_tmpa\endcsname\xint_undefined
+ \let\csname XINT_#1_userefunc_\XINT_unfunc_tmpa\endcsname\xint_undefined
\ifxintverbose\xintMessage {xintexpr}{Info}
- {Function \XINT_expr_tmpa\space for \string\xint #1 parser now
+ {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}%
@@ -37822,9 +38646,9 @@ math shift catcode.
\def\XINT_expr_wrapit #1{\expandafter\XINT_expr_wrap\csname.=#1\endcsname}%
\def\xintNewFunction #1#2[#3]#4%
{%
- \edef\XINT_expr_tmpa {#1}%
- \edef\XINT_expr_tmpa {\xint_zapspaces_o \XINT_expr_tmpa}%
- \def\XINT_expr_tmpb ##1##2##3##4##5##6##7##8##9{#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{}%
@@ -37841,26 +38665,26 @@ math shift catcode.
\expandafter
\endgroup\expandafter
\XINT_global\expandafter
- \def\csname XINT_expr_macrofunc_\XINT_expr_tmpa\expandafter\endcsname
- \the\toks0\expandafter{\XINT_expr_tmpb
+ \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_expr_tmpa\expandafter\endcsname
- \expandafter{\XINT_expr_tmpa}{eval}\xintbareeval
+ \csname XINT_expr_func_\XINT_newfunc_tmpa\expandafter\endcsname
+ \expandafter{\XINT_newfunc_tmpa}{eval}\xintbareeval
\expandafter\XINT_expr_newfunction
- \csname XINT_iiexpr_func_\XINT_expr_tmpa\expandafter\endcsname
- \expandafter{\XINT_expr_tmpa}{iieval}\xintbareiieval
+ \csname XINT_iiexpr_func_\XINT_newfunc_tmpa\expandafter\endcsname
+ \expandafter{\XINT_newfunc_tmpa}{iieval}\xintbareiieval
\expandafter\XINT_expr_newfunction
- \csname XINT_flexpr_func_\XINT_expr_tmpa\expandafter\endcsname
- \expandafter{\XINT_expr_tmpa}{floateval}\xintbarefloateval
+ \csname XINT_flexpr_func_\XINT_newfunc_tmpa\expandafter\endcsname
+ \expandafter{\XINT_newfunc_tmpa}{floateval}\xintbarefloateval
\ifxintverbose
\xintMessage {xintexpr}{Info}
- {Function \XINT_expr_tmpa\space for the expression parsers is
- associated to \string\XINT_expr_macrofunc_\XINT_expr_tmpa\space
+ {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_expr_tmpa\endcsname}%
+ \csname XINT_expr_macrofunc_\XINT_newfunc_tmpa\endcsname}%
\fi
}%
\def\XINT_expr_newfunction #1#2#3#4%
@@ -37979,6 +38803,15 @@ math shift catcode.
% 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}}%
@@ -38003,10 +38836,12 @@ math shift catcode.
\def\XINT_applyon:::_end #1,#2#3#4{\xint_secondoftwo #4}%
% \end{macrocode}
% \subsubsection{Mysterious stuff}
-% \lverb|~ and $$ of catcode 12 in what follows.|
+% \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}}%
@@ -38033,13 +38868,118 @@ math shift catcode.
\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{%
+\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%
@@ -38086,11 +39026,6 @@ math shift catcode.
{\expandafter\XINT:newexpr:insertdollar\detokenize{#3}}%
{#1}{#2}%
}%
-\def\XINT:newexpr:two:to:one #1,#2,!#3%
-{%
- \XINT:NE:two#3{#1}{#2}%
-}%
-\let\XINT:newflexpr:two:to:one\XINT:newexpr:two:to:one
\def\xintiiifNotZeroNE:#1#2,#3,#4,%
{%
\if1\if###11\else\if~#11\else\if$#11\else0%$
@@ -38144,20 +39079,23 @@ math shift catcode.
% \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: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:expr:two:to:one \XINT:newexpr:two:to:one
- \let\XINT:flexpr:two:to:one \XINT:newflexpr:two:to:one
- \let\XINT:expr:two:to:one \XINT:newexpr:two:to:one
- \let\XINT:flexpr:two:to:two \XINT:newflexpr:two:to:two
- \let\XINT:flexpr:two:to:one \XINT:newflexpr:two:to:one
+ \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:
@@ -38183,8 +39121,6 @@ math shift catcode.
\def\XINTinFloatSeqB::csv
{\XINT:NE:two_\XINTinFloatSeqBNumeric::csv{$noexpand$XINTinFloatSeqB:f:csv}}%
\def\xintListSel:x:csv {~xintListSel:f:csv }%
- \let\XINT:expr:userfunc \XINT:newexpr:userfunc
- \let\XINT:expr:macrofunc\XINT:newexpr:macrofunc
\def\XINTinRandomFloatSdigits{~XINTinRandomFloatSdigits }%
\def\XINTinRandomFloatSixteen{~XINTinRandomFloatSixteen }%
\def\xintiiRandRange{~xintiiRandRange }%
@@ -38192,26 +39128,34 @@ math shift catcode.
}%
% \end{macrocode}
% \subsubsection{\csh{XINT_expr_redefineprints}}
-% \lverb|This is used by \xintNewExpr but not by \xintdeffunc.|
+% \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_withopt_b\expandafter-\romannumeral0\xintbarefloateval }%
- \def\XINT_flexpr_withopt_b ##1##2%
- {\expandafter\XINT_flexpr_wrap\csname .;##1.=\XINT_expr_unlock ##2\endcsname }%
+ {%
+ \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}}%
+ {%
+ \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 }%
@@ -38243,11 +39187,11 @@ math shift catcode.
% At 1.3, NewFunc does not use a comma delimited pattern anymore.|
% \begin{macrocode}
\def\XINT_NewFunc
- {\XINT_NewExpr{}\xint_gobble_i\xintthebareeval\XINT_newfunc_clean}%
+ {\XINT_NewExpr\XINT_expr_redefineprints\xint_gobble_i\xintthebareeval\XINT_newfunc_clean}%
\def\XINT_NewFloatFunc
- {\XINT_NewExpr{}\xint_gobble_i\xintthebarefloateval\XINT_newfunc_clean}%
+ {\XINT_NewExpr\XINT_expr_redefineprints\xint_gobble_i\xintthebarefloateval\XINT_newfunc_clean}%
\def\XINT_NewIIFunc
- {\XINT_NewExpr{}\xint_gobble_i\xintthebareiieval\XINT_newfunc_clean}%
+ {\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
@@ -38263,6 +39207,11 @@ math shift catcode.
% 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]%
@@ -38296,13 +39245,15 @@ math shift catcode.
%
% 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~{$noexpand$}@
+ \def~%%1{\if !%%1\noexpand~\else $noexpand$%%1\fi}@
\catcode`: 11 \catcode`_ 11
\catcode`# 12 \catcode`~ 13 \escapechar 126
\endlinechar -1 \everyeof {\noexpand }@
@@ -38311,6 +39262,7 @@ math shift catcode.
%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
@@ -38322,6 +39274,7 @@ math shift catcode.
\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}
@@ -38386,121 +39339,1144 @@ math shift catcode.
\catcode96=12 % `
\catcode32=10 % space
}%
-\let\XINT_tmpa\relax \let\XINT_tmpb\relax \let\XINT_tmpc\relax
+\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\StopPackageIndex\let\xintexprnameUp\undefined
+% \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
-%</xintexpr>------------------------------------------------------
+%</xintlog>------------------------------------------------------
%<*dtx>-----------------------------------------------------------
\iffalse
% grep -c -e "^{%" xint*sty
-xint.sty:189
+xint.sty:190
xintbinhex.sty:53
xintcfrac.sty:183
xintcore.sty:274
-xintexpr.sty:256
-xintfrac.sty:462
+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{ 1668}
+\def\totala{ 1740}
\iffalse
% grep -c -e "^}%" xint*sty
-xint.sty:188
+xint.sty:189
xintbinhex.sty:52
xintcfrac.sty:183
xintcore.sty:271
-xintexpr.sty:281
-xintfrac.sty:463
+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{ 1691}
+\def\totalb{ 1767}
\cleardoublepage
-\makeatletter
-\setlength{\columnsep}{20pt}
-\setlength{\columnseprule}{0.4pt}
-\def\IndexParms{%
- \parindent \z@
- \columnsep 15pt % no effect whatsoever
- \parskip 0pt plus 1pt
- \rightskip 0pt % 15pt
- \mathsurround \z@
- \parfillskip=0pt % -15pt
- \small
- \def\@idxitem{\par\hangindent 30pt}%
- \def\subitem{\@idxitem\hspace*{15pt}}%
- \def\subsubitem{\@idxitem\hspace*{25pt}}%
- \def\indexspace{\par\vspace{10pt plus 2pt minus 3pt}}%
- }
-\makeatother
-\def\zzz{\DOCxintfrontpage,
- \xintkernelnameind,
- \xinttoolsnameind,
- \xintcorenameind,
- \xintnameind,
- \xintbinhexnameind,
- \xintgcdnameind,
- \xintfracnameind,
- \xintseriesnameind,
- \xintcfracnameind, \xintexprnameind, \indexcumulatif}
-\csname xintkernelnameUp\endcsname
-\markboth{\zzz}{\zzz}
-\section{Per package indices of control sequences}
-\RaisedLabel{sec:indices}
-
-\DeleteShortVerb{\|}
-
-\xintForpair #1#2 in
-{(xintkernel,kernel),
- (xinttools,tools),
- (xintcore,core),(xint,xint),(xintbinhex,binhex),(xintgcd,gcd),%
- (xintfrac,frac),(xintseries,series),(xintcfrac,cfrac), (xintexpr,expr)}
-\do
-{\csname #1nameUp\endcsname
-\subsection{Index of \csname #1nameimp\endcsname}
-\xintifForFirst{\RaisedLabel[8]}{\RaisedLabel}{sec:#2ind}
-
-\xintifForLast{%
-Particularly for this package, there are quite a few macros which are defined
-via constructs such as \verb|\expandafter\def\csname ...\endcsname|, and their
-indexing needs some extra mark-up which is yet to be added to the commented
-source code.}{}\par
-
-\PrintPackageIndex{#2}
-\cleardoublepage
-\expandafter\let\csname #1nameUp\endcsname\undefined
-}
-
-\csname allnameUp\endcsname
-\section{Cumulative index}
-\RaisedLabel{sec:indexcumulatif}
-
-
-Currently there are some macros which did not make it to the indices because
-they are defined via constructs such as \verb|\expandafter\def\csname
-...\endcsname|, thus their indexing needs some extra mark-up which is yet to
-be added. This is particularly true for some definitions done by
-\xintexprnameimp.
-
-The first indicated page number is the one where the macro is first
-encountered, hence this is most likely also the page where it gets defined (if
-it is not one of those which are only used as delimiters).
-
-\PrintMainIndex
-
-\cleardoublepage
-\let\allnameUp\undefined
-
-\markboth{\xintImpRunningHeader}{\xintImpRunningHeader}
\section{Cumulative line count}
\def\mymacro #1{\mymacroaux #1}
@@ -38523,8 +40499,8 @@ it is not one of those which are only used as delimiters).
\TeX\strut. Version {\xintbndlversion} of {\xintbndldate}.\par
}
-\CheckSum {31601}% 1.3d
-% 31122 pour 1.3c
+\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,
diff --git a/Master/texmf-dist/source/generic/xint/xint.ins b/Master/texmf-dist/source/generic/xint/xint.ins
deleted file mode 100644
index b48bc725697..00000000000
--- a/Master/texmf-dist/source/generic/xint/xint.ins
+++ /dev/null
@@ -1,92 +0,0 @@
-%%
-%% This is file `xint.ins',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% xint.dtx (with options: `ins')
-%%
-%% IMPORTANT NOTICE:
-%%
-%% For the copyright see the source file.
-%%
-%% Any modified versions of this file must be renamed
-%% with new filenames distinct from xint.ins.
-%%
-%% For distribution of the original source see the terms
-%% for copying and modification in the file xint.dtx.
-%%
-%% This generated file may be distributed as long as the
-%% original source files, as listed above, are part of the
-%% same distribution. (The sources need not necessarily be
-%% in the same archive or directory.)
-%% ---------------------------------------------------------------
-%% The xint bundle 1.3d 2019/01/06
-%% Copyright (C) 2013-2019 by Jean-Francois Burnol
-%% ---------------------------------------------------------------
-%%
-%% `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
-\file{.latexmkrc}{\from{xint.dtx}{latexmkrc}}
-\usepreamble\defaultpreamble
-\usepostamble\defaultpostamble
-\file{xint-gind.ist}{\from{xint.dtx}{gind}}
-\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}}}
-\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{* 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
-\endinput
-%%
-%% End of file `xint.ins'.
diff --git a/Master/texmf-dist/tex/generic/xint/xint.sty b/Master/texmf-dist/tex/generic/xint/xint.sty
index f8413488235..4137ad675a7 100644
--- a/Master/texmf-dist/tex/generic/xint/xint.sty
+++ b/Master/texmf-dist/tex/generic/xint/xint.sty
@@ -21,7 +21,7 @@
%% same distribution. (The sources need not necessarily be
%% in the same archive or directory.)
%% ---------------------------------------------------------------
-%% The xint bundle 1.3d 2019/01/06
+%% The xint bundle 1.3e 2019/04/05
%% Copyright (C) 2013-2019 by Jean-Francois Burnol
%% xint: Expandable operations on big integers
%% ---------------------------------------------------------------
@@ -70,7 +70,7 @@
\XINTsetupcatcodes% defined in xintkernel.sty (loaded by xintcore.sty)
\XINT_providespackage
\ProvidesPackage{xint}%
- [2019/01/06 1.3d Expandable operations on big integers (JFB)]%
+ [2019/04/05 1.3e Expandable operations on big integers (JFB)]%
\long\def\xint_firstofthree #1#2#3{#1}%
\long\def\xint_secondofthree #1#2#3{#2}%
\long\def\xint_thirdofthree #1#2#3{#3}%
@@ -98,6 +98,17 @@
{%
\expandafter\XINT_length_loop\xint_UDsignfork#1{}-#1\krof
}%
+\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}%
\def\xintReverseDigits {\romannumeral0\xintreversedigits }%
\def\xintreversedigits #1%
{%
diff --git a/Master/texmf-dist/tex/generic/xint/xintbinhex.sty b/Master/texmf-dist/tex/generic/xint/xintbinhex.sty
index a1799fbc3da..07e52be6dfc 100644
--- a/Master/texmf-dist/tex/generic/xint/xintbinhex.sty
+++ b/Master/texmf-dist/tex/generic/xint/xintbinhex.sty
@@ -21,7 +21,7 @@
%% same distribution. (The sources need not necessarily be
%% in the same archive or directory.)
%% ---------------------------------------------------------------
-%% The xint bundle 1.3d 2019/01/06
+%% The xint bundle 1.3e 2019/04/05
%% Copyright (C) 2013-2019 by Jean-Francois Burnol
%% xintbinhex: Expandable binary and hexadecimal conversions
%% ---------------------------------------------------------------
@@ -70,7 +70,7 @@
\XINTsetupcatcodes% defined in xintkernel.sty
\XINT_providespackage
\ProvidesPackage{xintbinhex}%
- [2019/01/06 1.3d Expandable binary and hexadecimal conversions (JFB)]%
+ [2019/04/05 1.3e Expandable binary and hexadecimal conversions (JFB)]%
\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
diff --git a/Master/texmf-dist/tex/generic/xint/xintcfrac.sty b/Master/texmf-dist/tex/generic/xint/xintcfrac.sty
index 530d6e3db7e..c62037bbc24 100644
--- a/Master/texmf-dist/tex/generic/xint/xintcfrac.sty
+++ b/Master/texmf-dist/tex/generic/xint/xintcfrac.sty
@@ -21,7 +21,7 @@
%% same distribution. (The sources need not necessarily be
%% in the same archive or directory.)
%% ---------------------------------------------------------------
-%% The xint bundle 1.3d 2019/01/06
+%% The xint bundle 1.3e 2019/04/05
%% Copyright (C) 2013-2019 by Jean-Francois Burnol
%% xintcfrac: Expandable continued fractions with xint package
%% ---------------------------------------------------------------
@@ -70,7 +70,7 @@
\XINTsetupcatcodes% defined in xintkernel.sty
\XINT_providespackage
\ProvidesPackage{xintcfrac}%
- [2019/01/06 1.3d Expandable continued fractions with xint package (JFB)]%
+ [2019/04/05 1.3e Expandable continued fractions with xint package (JFB)]%
\def\xintCFrac {\romannumeral0\xintcfrac }%
\def\xintcfrac #1%
{%
diff --git a/Master/texmf-dist/tex/generic/xint/xintcore.sty b/Master/texmf-dist/tex/generic/xint/xintcore.sty
index b93057a82bd..b0f8ff5d0f2 100644
--- a/Master/texmf-dist/tex/generic/xint/xintcore.sty
+++ b/Master/texmf-dist/tex/generic/xint/xintcore.sty
@@ -21,7 +21,7 @@
%% same distribution. (The sources need not necessarily be
%% in the same archive or directory.)
%% ---------------------------------------------------------------
-%% The xint bundle 1.3d 2019/01/06
+%% The xint bundle 1.3e 2019/04/05
%% Copyright (C) 2013-2019 by Jean-Francois Burnol
%% xintcore: Expandable arithmetic on big integers
%% ---------------------------------------------------------------
@@ -70,7 +70,7 @@
\XINTsetupcatcodes% defined in xintkernel.sty
\XINT_providespackage
\ProvidesPackage{xintcore}%
- [2019/01/06 1.3d Expandable arithmetic on big integers (JFB)]%
+ [2019/04/05 1.3e Expandable arithmetic on big integers (JFB)]%
\csname XINT_Clamped_istrapped\endcsname
\csname XINT_ConversionSyntax_istrapped\endcsname
\csname XINT_DivisionByZero_istrapped\endcsname
diff --git a/Master/texmf-dist/tex/generic/xint/xintexpr.sty b/Master/texmf-dist/tex/generic/xint/xintexpr.sty
index 13bbb335437..8ed1191fb8a 100644
--- a/Master/texmf-dist/tex/generic/xint/xintexpr.sty
+++ b/Master/texmf-dist/tex/generic/xint/xintexpr.sty
@@ -21,7 +21,7 @@
%% same distribution. (The sources need not necessarily be
%% in the same archive or directory.)
%% ---------------------------------------------------------------
-%% The xint bundle 1.3d 2019/01/06
+%% The xint bundle 1.3e 2019/04/05
%% Copyright (C) 2013-2019 by Jean-Francois Burnol
%% xintexpr: Expandable expression parser
%% ---------------------------------------------------------------
@@ -81,142 +81,154 @@
\XINTsetupcatcodes%
\XINT_providespackage
\ProvidesPackage{xintexpr}%
- [2019/01/06 1.3d Expandable expression parser (JFB)]%
+ [2019/04/05 1.3e Expandable expression parser (JFB)]%
\catcode`! 11
\let\XINT_Cmp \xintiiCmp
-\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
-\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_protectii #1{\noexpand\XINT_protectii\noexpand #1\noexpand }%
-\protected\def\XINT_expr_usethe\XINT_protectii {\xintError:missing_xintthe!}%
-\def\XINT_expr_print #1{\xintSPRaw::csv {\XINT_expr_unlock #1}}%
-\def\XINT_iiexpr_print #1{\xintCSV::csv {\XINT_expr_unlock #1}}%
-\def\XINT_boolexpr_print #1{\xintIsTrue::csv {\XINT_expr_unlock #1}}%
\def\xintexpr {\romannumeral0\xintexpro }%
\def\xintiexpr {\romannumeral0\xintiexpro }%
\def\xintfloatexpr {\romannumeral0\xintfloatexpro }%
\def\xintiiexpr {\romannumeral0\xintiiexpro }%
-\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}%
-\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}%
-\def\xintthe #1{\romannumeral`&&@\expandafter\xint_gobble_iii\romannumeral`&&@#1}%
-\def\xintthe_o #1{\expandafter\xint_gobble_iii\romannumeral`&&@#1}%
-\let\thexintexpr \xinttheexpr
-\let\thexintiexpr \xinttheiexpr
-\let\thexintfloatexpr\xintthefloatexpr
-\let\thexintiiexpr \xinttheiiexpr
-\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^{}%
-\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 }%
-\def\xintthebareeval {\expandafter\XINT_expr_unlock\romannumeral0\xintbareeval}%
-\def\xintthebarefloateval {\expandafter\XINT_expr_unlock\romannumeral0\xintbarefloateval}%
-\def\xintthebareiieval {\expandafter\XINT_expr_unlock\romannumeral0\xintbareiieval}%
\def\xintexpro {\expandafter\XINT_expr_wrap\romannumeral0\xintbareeval }%
\def\xintiiexpro {\expandafter\XINT_iiexpr_wrap\romannumeral0\xintbareiieval }%
\def\xintiexpro #1%
- {\ifx [#1\expandafter\XINT_iexpr_withopt\else\expandafter\XINT_iexpr_noopt \fi #1}%
+{%
+ \ifx [#1\expandafter\XINT_iexpr_withopt\else\expandafter\XINT_iexpr_noopt
+ \fi #1%
+}%
\def\XINT_iexpr_noopt
- {\expandafter\XINT_iexpr_wrap \expandafter 0\romannumeral0\xintbareeval }%
+{%
+ \expandafter\XINT_iexpr_preprint\expandafter 0%
+ \romannumeral0\xintbareeval
+}%
\def\XINT_iexpr_withopt [#1]%
{%
- \expandafter\XINT_iexpr_wrap\expandafter
+ \expandafter\XINT_iexpr_preprint\expandafter
{\the\numexpr \xint_zapspaces #1 \xint_gobble_i\expandafter}%
\romannumeral0\xintbareeval
}%
-\def\XINT_iexpr_wrap #1#2%
+\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_a\else\expandafter\XINT_flexpr_noopt
+ \ifx [#1\expandafter\XINT_flexpr_withopt\else\expandafter\XINT_flexpr_noopt
\fi #1%
}%
\def\XINT_flexpr_noopt
{%
- \expandafter\XINT_flexpr_withopt_b\expandafter\xinttheDigits
- \romannumeral0\xintbarefloateval
+ \expandafter\XINT_flexpr_preprint\expandafter\xinttheDigits
+ \romannumeral0\xintbarefloateval
}%
-\def\XINT_flexpr_withopt_a [#1]%
+\def\XINT_flexpr_withopt [#1]%
{%
- \expandafter\XINT_flexpr_withopt_b\expandafter
+ \expandafter\XINT_flexpr_preprint\expandafter
{\the\numexpr\xint_zapspaces #1 \xint_gobble_i\expandafter}%
\romannumeral0\xintbarefloateval
}%
-\def\XINT_flexpr_withopt_b #1#2%
+\def\XINT_flexpr_preprint #1#2%
{%
- \expandafter\XINT_flexpr_wrap\csname .;#1.=% ; and not : as before b'cause NewExpr
- \XINTinFloat::csv {#1}{\XINT_expr_unlock #2}\endcsname
+ \expandafter\XINT_flexpr_wrap
+ \csname .;#1.=\XINTinFloat::csv {#1}{\XINT_expr_unlock #2}\endcsname
}%
-\def\XINT_flexpr_wrap { !\XINT_expr_usethe\XINT_protectii\XINT_flexpr_print }%
+\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}%
+\def\XINT_protectii #1{\noexpand\XINT_protectii\noexpand #1\noexpand }%
+\protected\def\XINT_expr_usethe\XINT_protectii {\xintError:missing_xintthe!}%
+\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}}%
-\def\xintboolexpr {\romannumeral0\expandafter\expandafter\expandafter
- \XINT_boolexpr_done \expandafter\xint_gobble_iv\romannumeral0\xintexpro }%
-\def\xinttheboolexpr {\romannumeral`&&@\expandafter\expandafter\expandafter
- \XINT_boolexpr_print\expandafter\xint_gobble_iv\romannumeral0\xintexpro }%
+\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}%
+\let\thexintexpr \xinttheexpr
+\let\thexintiexpr \xinttheiexpr
+\let\thexintfloatexpr\xintthefloatexpr
+\let\thexintiiexpr \xinttheiiexpr
+\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}%
+\def\xintthe #1{\romannumeral`&&@\expandafter\xint_gobble_iii\romannumeral`&&@#1}%
+\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 }%
+\def\xintthebareeval {\expandafter\XINT_expr_unlock\romannumeral0\xintbareeval}%
+\def\xintthebarefloateval {\expandafter\XINT_expr_unlock\romannumeral0\xintbarefloateval}%
+\def\xintthebareiieval {\expandafter\XINT_expr_unlock\romannumeral0\xintbareiieval}%
+\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
-\def\XINT_boolexpr_done { !\XINT_expr_usethe\XINT_protectii\XINT_boolexpr_print }%
\def\xintifboolexpr #1{\romannumeral0\xintiiifnotzero {\xinttheexpr #1\relax}}%
\def\xintifboolfloatexpr #1{\romannumeral0\xintiiifnotzero {\xintthefloatexpr #1\relax}}%
\def\xintifbooliiexpr #1{\romannumeral0\xintiiifnotzero {\xinttheiiexpr #1\relax}}%
\def\xintifsgnexpr #1{\romannumeral0\xintiiifsgn {\xinttheexpr #1\relax}}%
\def\xintifsgnfloatexpr #1{\romannumeral0\xintiiifsgn {\xintthefloatexpr #1\relax}}%
\def\xintifsgniiexpr #1{\romannumeral0\xintiiifsgn {\xinttheiiexpr #1\relax}}%
-\let\XINT:NEhook:two\empty
+\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^{}%
+\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
\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}}%
\def\XINT_::_end #1,#2{\xint_gobble_i #2}%
\def\xintCSV::csv #1{\expandafter\XINT_csv::_a\romannumeral`&&@#1,^,}%
\def\XINT_csv::_a {\XINT_csv::_b {}}%
@@ -245,34 +257,39 @@
\def\XINT_istrue::_d #1,{\expandafter\XINT_istrue::_e\romannumeral0\xintisnotzero {#1},}%
\def\XINT_istrue::_e #1,#2{\XINT_istrue::_b {#2, #1}}%
\def\XINT_:::_end #1,#2#3{\xint_gobble_i #3}%
-\def\xintRound::csv #1#2{\romannumeral0\expandafter\XINT_round::_b\expandafter
- {\the\numexpr#1\expandafter}\expandafter{\expandafter}\romannumeral`&&@#2,^,}%
-\def\XINT_round::_b #1#2#3,{\expandafter\XINT_round::_c \romannumeral`&&@#3,{#1}{#2}}%
+\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}}%
-\def\XINTinFloat::csv #1#2{\romannumeral0\expandafter\XINT_infloat::_b\expandafter
- {\the\numexpr #1\expandafter}\expandafter{\expandafter}\romannumeral`&&@#2,^,}%
-\def\XINT_infloat::_b #1#2#3,{\XINT_infloat::_c #3,{#1}{#2}}%
+\def\XINT_round::_e #1,#2#3{\XINT_round::_b #2.{#3, #1}}%
+\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}}%
-\def\xintPFloat::csv #1#2{\romannumeral0\expandafter\XINT_pfloat::_b\expandafter
- {\the\numexpr #1\expandafter}\expandafter{\expandafter}\romannumeral`&&@#2,^,}%
-\def\XINT_pfloat::_b #1#2#3,{\expandafter\XINT_pfloat::_c \romannumeral`&&@#3,{#1}{#2}}%
+\def\XINT_infloat::_e #1,#2#3{\XINT_infloat::_b #2.{#3, #1}}%
+\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}}%
+\def\XINT_pfloat::_e #1,#2#3{\XINT_pfloat::_b #2.{#3, #1}}%
\def\XINT_expr_getnext #1%
{%
\expandafter\XINT_expr_getnext_a\romannumeral`&&@#1%
@@ -1446,7 +1463,7 @@
\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 .=\XINTinFloatdigits{#1}\endcsname }%
+ {\expandafter\XINT_expr_getop\csname .=\XINTinFloatSdigits{#1}\endcsname }%
\def\XINT_expr_onliteral_qraw #1)%
{\expandafter\XINT_expr_getop\csname .=#1\endcsname }%
\def\XINT_expr_onliteral_random #1)%
@@ -1486,44 +1503,44 @@
\catcode`~ 13
\catcode`: 12
\def\XINT_expr_defvar_getname #1:#2~{\endgroup
- \def\XINT_expr_tmpa{#1}\edef\XINT_expr_tmpc{\xintCSVLength{#1}}}%
+ \def\XINT_defvar_tmpa{#1}\edef\XINT_defvar_tmpc{\xintCSVLength{#1}}}%
\def\XINT_expr_defvar #1#2#3;%
{%
\xintexprRestoreCatcodes
\begingroup\lccode`~`: \lowercase{\let~}\empty
- \edef\XINT_expr_tmpa{#2}%
- \edef\XINT_expr_tmpa{\xint_zapspaces_o\XINT_expr_tmpa}%
+ \edef\XINT_defvar_tmpa{#2}%
+ \edef\XINT_defvar_tmpa{\xint_zapspaces_o\XINT_defvar_tmpa}%
\expandafter\XINT_expr_defvar_getname
- \detokenize\expandafter{\XINT_expr_tmpa}:~%
- \ifcase\XINT_expr_tmpc
+ \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_expr_tmpb{\romannumeral0#1#3\relax}%
- \XINT_expr_defvar_one\XINT_expr_tmpa\XINT_expr_tmpb
+ \edef\XINT_defvar_tmpb{\romannumeral0#1#3\relax}%
+ \XINT_expr_defvar_one\XINT_defvar_tmpa\XINT_defvar_tmpb
\else
- \edef\XINT_expr_tmpb
+ \edef\XINT_defvar_tmpb
{\expandafter\XINT_expr_unlock\romannumeral0#1#3\relax}%
- \edef\XINT_expr_tmpd{\xintCSVLength{\XINT_expr_tmpb}}%
- \ifnum\XINT_expr_tmpc=\XINT_expr_tmpd\space
- \xintAssignArray\xintCSVtoList\XINT_expr_tmpa\to\XINT_expr_tmpvar
+ \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_expr_tmpb}%
- \to\XINT_expr_tmpval
- \def\XINT_expr_tmpd{1}%
+ \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_expr_tmpvar\XINT_expr_tmpd\expandafter\endcsname
- \csname XINT_expr_tmpval\XINT_expr_tmpd\endcsname
- \ifnum\XINT_expr_tmpd<\XINT_expr_tmpc\space
- \edef\XINT_expr_tmpd{\the\numexpr\XINT_expr_tmpd+1}%
+ \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_expr_tmpvar
- \xintRelaxArray\XINT_expr_tmpval
+ \xintRelaxArray\XINT_defvar_tmpvar
+ \xintRelaxArray\XINT_defvar_tmpval
\else
\xintMessage {xintexpr}{Warning}
- {Aborting: mismatch between number of variables (\XINT_expr_tmpc)
- and number of values (\XINT_expr_tmpd).}%
+ {Aborting: mismatch between number of variables (\XINT_defvar_tmpc)
+ and number of values (\XINT_defvar_tmpd).}%
\fi
\fi
}%
@@ -1536,29 +1553,39 @@
\def\xintdefiivar_a #1={\XINT_expr_defvar\xintbareiieval {#1}}%
\def\xintdeffloatvar_a #1={\XINT_expr_defvar\xintbarefloateval {#1}}%
\def\xintunassignvar #1{%
- \edef\XINT_expr_tmpa{#1}%
- \edef\XINT_expr_tmpa {\xint_zapspaces_o\XINT_expr_tmpa}%
- \ifcsname XINT_expr_var_\XINT_expr_tmpa\endcsname
- \ifnum\expandafter\xintLength\expandafter{\XINT_expr_tmpa}=\@ne
- \expandafter\xintnewdummy\XINT_expr_tmpa
+ \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_expr_tmpa\endcsname\xint_undefined
+ \let\csname XINT_expr_var_\XINT_unvar_tmpa\endcsname\xint_undefined
\XINT_global\expandafter
- \let\csname XINT_expr_onliteral_\XINT_expr_tmpa\endcsname\xint_undefined
+ \let\csname XINT_expr_onliteral_\XINT_unvar_tmpa\endcsname\xint_undefined
\ifxintverbose\xintMessage {xintexpr}{Info}
- {Variable \XINT_expr_tmpa\space has been
+ {Variable \XINT_unvar_tmpa\space has been
\ifxintglobaldefs globally \fi ``unassigned''.}%
\fi
\fi
\else
\xintMessage {xintexpr}{Warning}
- {Error: there was no such variable \XINT_expr_tmpa\space to unassign.}%
+ {Error: there was no such variable \XINT_unvar_tmpa\space to unassign.}%
\fi
}%
\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}%
@@ -1579,6 +1606,30 @@
\edef\XINT_expr_onliteral_nil
{\XINT_expr_precedence_*** *\expandafter\noexpand\csname .= \endcsname (}%
\catcode`* 12
+\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
+}%
\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}%
@@ -2114,16 +2165,18 @@
\def\xintiiLCMof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintiilcm
\expandafter\xint_firstofone\romannumeral`&&@#1,^,0}%
\def\XINTinFloatdigits {\XINTinFloat [\XINTdigits]}%
+\def\XINTinFloatSdigits {\XINTinFloatS [\XINTdigits]}%
\def\XINTinFloatSqrtdigits {\XINTinFloatSqrt[\XINTdigits]}%
\def\XINTinFloatFacdigits {\XINTinFloatFac [\XINTdigits]}%
+\def\XINTFloatiLogTendigits{\XINTFloatiLogTen[\XINTdigits]}%
\def\XINTinFloatMaxof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintmax
- \expandafter\XINTinFloatdigits\romannumeral`&&@#1,^,{0[0]}}%
+ \expandafter\XINTinFloatSdigits\romannumeral`&&@#1,^,{0[0]}}%
\def\XINTinFloatMinof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintmin
- \expandafter\XINTinFloatdigits\romannumeral`&&@#1,^,{0[0]}}%
+ \expandafter\XINTinFloatSdigits\romannumeral`&&@#1,^,{0[0]}}%
\def\XINTinFloatSum:csv #1{\expandafter\XINT_oncsv:_a\expandafter\XINTinfloatadd
- \expandafter\XINTinFloatdigits\romannumeral`&&@#1,^,{0[0]}}%
+ \expandafter\XINTinFloatSdigits\romannumeral`&&@#1,^,{0[0]}}%
\def\XINTinFloatPrd:csv #1{\expandafter\XINT_oncsv:_a\expandafter\XINTinfloatmul
- \expandafter\XINTinFloatdigits\romannumeral`&&@#1,^,{1[0]}}%
+ \expandafter\XINTinFloatSdigits\romannumeral`&&@#1,^,{1[0]}}%
\def\XINT:expr:one:and:opt #1,#2,#3!#4#5%
{%
\if\relax#3\relax\expandafter\xint_firstoftwo\else
@@ -2145,18 +2198,10 @@
\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}%
+ \expandafter\XINT:expr:totwo\romannumeral`&&@#3{#1}{#2}%
}%
-\def\XINT:expr:two:to:one #1,#2,!#3%
-{%
- #3{#1}{#2}%
-}%
-\def\XINT:flexpr:two:to:one #1,#2,!#3%
-{%
- #3{#1}{#2}%
-}%
-\let\XINT:flexpr:two:to:two\XINT:flexpr:two:to:one
+\let\XINT:flexpr:two:to:two\XINT:expr:two:to:two
+\let\XINT:iiexpr:two:to:two\XINT:expr:two:to:two
\def\XINT_expr_func_num #1#2#3%
{%
\expandafter #1\expandafter #2\csname.=%
@@ -2352,6 +2397,16 @@
\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.=%
@@ -2390,6 +2445,33 @@
\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
+\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.=%
@@ -2400,7 +2482,7 @@
\def\XINT_flexpr_func_divmod #1#2#3%
{%
\expandafter #1\expandafter #2\csname.=%
- \expandafter\XINT:flexpr:two:to:two
+ \expandafter\XINT:NEhook:twosp
\romannumeral`&&@\XINT_expr_unlock #3,!\XINTinFloatDivMod
\endcsname
}%
@@ -2414,63 +2496,63 @@
\def\XINT_expr_func_mod #1#2#3%
{%
\expandafter #1\expandafter #2\csname.=%
- \expandafter\XINT:expr:two:to:one
+ \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:flexpr:two:to:one
+ \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:expr:two:to:one
+ \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:expr:two:to:one
+ \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:flexpr:two:to:one
+ \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:expr:two:to:one
+ \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:expr:two:to:one
+ \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:flexpr:two:to:one
+ \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:expr:two:to:one
+ \expandafter\XINT:NEhook:twosp
\romannumeral`&&@\XINT_expr_unlock #3,!\xintiiPFactorial
\endcsname
}%
@@ -2506,7 +2588,7 @@
\def\XINT_expr_func_quo #1#2#3%
{%
\expandafter #1\expandafter #2\csname.=%
- \expandafter\XINT:expr:two:to:one
+ \expandafter\XINT:NEhook:twosp
\romannumeral`&&@\XINT_expr_unlock #3,!\xintiQuo
\endcsname
}%
@@ -2514,14 +2596,14 @@
\def\XINT_iiexpr_func_quo #1#2#3%
{%
\expandafter #1\expandafter #2\csname.=%
- \expandafter\XINT:expr:two:to:one
+ \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:expr:two:to:one
+ \expandafter\XINT:NEhook:twosp
\romannumeral`&&@\XINT_expr_unlock #3,!\xintiRem
\endcsname
}%
@@ -2529,7 +2611,7 @@
\def\XINT_iiexpr_func_rem #1#2#3%
{%
\expandafter #1\expandafter #2\csname.=%
- \expandafter\XINT:expr:two:to:one
+ \expandafter\XINT:NEhook:twosp
\romannumeral`&&@\XINT_expr_unlock #3,!\xintiiRem
\endcsname
}%
@@ -2806,25 +2888,32 @@
\def\XINT_tmpa #1#2#3#4%
{%
\def #1##1(##2)##3=##4;{%
- \edef\XINT_expr_tmpa {##1}%
- \edef\XINT_expr_tmpa {\xint_zapspaces_o \XINT_expr_tmpa}%
- \def\XINT_expr_tmpb {0}%
- \def\XINT_expr_tmpc {(##4)}%
- \xintFor ####1 in {##2} \do
- {\edef\XINT_expr_tmpb {\the\numexpr\XINT_expr_tmpb+\xint_c_i}%
- \edef\XINT_expr_tmpc {subs(\unexpanded\expandafter{\XINT_expr_tmpc},%
- ####1=################\XINT_expr_tmpb)}%
+ \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)}%
}%
- \expandafter\XINT_expr_defuserfunc
- \csname XINT_#2_func_\XINT_expr_tmpa\expandafter\endcsname
- \expandafter{\XINT_expr_tmpa}{#2}%
- \expandafter#3\csname XINT_#2_userfunc_\XINT_expr_tmpa\endcsname
- [\XINT_expr_tmpb]{\XINT_expr_tmpc}%
+ \fi
+ \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_expr_tmpa\space for \string\xint #4 parser
- associated to \string\XINT_#2_userfunc_\XINT_expr_tmpa\space
+ {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_expr_tmpa\endcsname}%
+ \csname XINT_#2_userfunc_\XINT_deffunc_tmpa\endcsname}%
\fi
\xintexprRestoreCatcodes
}%
@@ -2839,34 +2928,157 @@
{%
\XINT_global
\def #1##1##2##3{\expandafter ##1\expandafter ##2%
- \csname .=\XINT:expr:userfunc{#3}{#2}{\XINT_expr_unlock ##3}\endcsname
+ \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}}%
-\catcode`~ 12
-\def\XINT:newexpr:userfunc #1#2#3%
- {~xintExpandArgs{XINT_#1_userfunc_#2}{\xintCSVtoListNonStripped{#3}}}%
-\catcode`~ 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}%
+\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
+ \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}}%
+ \ifcase\XINT_defefunc_tmpb\space
+ \expandafter\XINT_expr_defuserefunc_none\csname
+ \or
+ \expandafter\XINT_expr_defuserefunc_one\csname
+ \or
+ \expandafter\XINT_expr_defuserefunc_two\csname
+ \else
+ \expandafter\XINT_expr_defuserefunc_many\csname
+ \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}%
+}%
+\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}%
+}%
+\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}}%
+\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}%
+}%
\def\XINT_tmpa #1{\expandafter\def\csname xintunassign#1func\endcsname ##1{%
- \edef\XINT_expr_tmpa{##1}%
- \edef\XINT_expr_tmpa {\xint_zapspaces_o\XINT_expr_tmpa}%
+ \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_func_\XINT_expr_tmpa\endcsname\xint_undefined
+ \let\csname XINT_#1_userfunc_\XINT_unfunc_tmpa\endcsname\xint_undefined
\XINT_global\expandafter
- \let\csname XINT_#1_userfunc_\XINT_expr_tmpa\endcsname\xint_undefined
+ \let\csname XINT_#1_userefunc_\XINT_unfunc_tmpa\endcsname\xint_undefined
\ifxintverbose\xintMessage {xintexpr}{Info}
- {Function \XINT_expr_tmpa\space for \string\xint #1 parser now
+ {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}%
\def\XINT_expr_wrapit #1{\expandafter\XINT_expr_wrap\csname.=#1\endcsname}%
\def\xintNewFunction #1#2[#3]#4%
{%
- \edef\XINT_expr_tmpa {#1}%
- \edef\XINT_expr_tmpa {\xint_zapspaces_o \XINT_expr_tmpa}%
- \def\XINT_expr_tmpb ##1##2##3##4##5##6##7##8##9{#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{}%
@@ -2883,26 +3095,26 @@
\expandafter
\endgroup\expandafter
\XINT_global\expandafter
- \def\csname XINT_expr_macrofunc_\XINT_expr_tmpa\expandafter\endcsname
- \the\toks0\expandafter{\XINT_expr_tmpb
+ \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_expr_tmpa\expandafter\endcsname
- \expandafter{\XINT_expr_tmpa}{eval}\xintbareeval
+ \csname XINT_expr_func_\XINT_newfunc_tmpa\expandafter\endcsname
+ \expandafter{\XINT_newfunc_tmpa}{eval}\xintbareeval
\expandafter\XINT_expr_newfunction
- \csname XINT_iiexpr_func_\XINT_expr_tmpa\expandafter\endcsname
- \expandafter{\XINT_expr_tmpa}{iieval}\xintbareiieval
+ \csname XINT_iiexpr_func_\XINT_newfunc_tmpa\expandafter\endcsname
+ \expandafter{\XINT_newfunc_tmpa}{iieval}\xintbareiieval
\expandafter\XINT_expr_newfunction
- \csname XINT_flexpr_func_\XINT_expr_tmpa\expandafter\endcsname
- \expandafter{\XINT_expr_tmpa}{floateval}\xintbarefloateval
+ \csname XINT_flexpr_func_\XINT_newfunc_tmpa\expandafter\endcsname
+ \expandafter{\XINT_newfunc_tmpa}{floateval}\xintbarefloateval
\ifxintverbose
\xintMessage {xintexpr}{Info}
- {Function \XINT_expr_tmpa\space for the expression parsers is
- associated to \string\XINT_expr_macrofunc_\XINT_expr_tmpa\space
+ {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_expr_tmpa\endcsname}%
+ \csname XINT_expr_macrofunc_\XINT_newfunc_tmpa\endcsname}%
\fi
}%
\def\XINT_expr_newfunction #1#2#3#4%
@@ -2953,6 +3165,7 @@
\def\XINT_applyon:::_end #1,#2#3#4{\xint_secondoftwo #4}%
\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}}%
@@ -2979,13 +3192,75 @@
\if #2~\xint_dothis{#4}\fi
\xint_orthat{#3}%
}%
+\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{%
+\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}%
}%
+\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}}%
+\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
+ \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}}%
+\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}}}%
\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%
@@ -3032,11 +3307,6 @@
{\expandafter\XINT:newexpr:insertdollar\detokenize{#3}}%
{#1}{#2}%
}%
-\def\XINT:newexpr:two:to:one #1,#2,!#3%
-{%
- \XINT:NE:two#3{#1}{#2}%
-}%
-\let\XINT:newflexpr:two:to:one\XINT:newexpr:two:to:one
\def\xintiiifNotZeroNE:#1#2,#3,#4,%
{%
\if1\if###11\else\if~#11\else\if$#11\else0%$
@@ -3086,20 +3356,23 @@
{#1#2}{#3}{#4}{#5}%
}%
\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: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:expr:two:to:one \XINT:newexpr:two:to:one
- \let\XINT:flexpr:two:to:one \XINT:newflexpr:two:to:one
- \let\XINT:expr:two:to:one \XINT:newexpr:two:to:one
- \let\XINT:flexpr:two:to:two \XINT:newflexpr:two:to:two
- \let\XINT:flexpr:two:to:one \XINT:newflexpr:two:to:one
+ \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:
@@ -3125,8 +3398,6 @@
\def\XINTinFloatSeqB::csv
{\XINT:NE:two_\XINTinFloatSeqBNumeric::csv{$noexpand$XINTinFloatSeqB:f:csv}}%
\def\xintListSel:x:csv {~xintListSel:f:csv }%
- \let\XINT:expr:userfunc \XINT:newexpr:userfunc
- \let\XINT:expr:macrofunc\XINT:newexpr:macrofunc
\def\XINTinRandomFloatSdigits{~XINTinRandomFloatSdigits }%
\def\XINTinRandomFloatSixteen{~XINTinRandomFloatSixteen }%
\def\xintiiRandRange{~xintiiRandRange }%
@@ -3135,21 +3406,26 @@
\def\XINT_expr_redefineprints
{%
\def\XINT_flexpr_noopt
- {\expandafter\XINT_flexpr_withopt_b\expandafter-\romannumeral0\xintbarefloateval }%
- \def\XINT_flexpr_withopt_b ##1##2%
- {\expandafter\XINT_flexpr_wrap\csname .;##1.=\XINT_expr_unlock ##2\endcsname }%
+ {%
+ \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}}%
+ {%
+ \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 }%
@@ -3168,11 +3444,11 @@
\xinttheboolexpr\XINT_newexpr_clean}%
\def\XINT_newexpr_clean #1>{\noexpand\romannumeral`&&@}%
\def\XINT_NewFunc
- {\XINT_NewExpr{}\xint_gobble_i\xintthebareeval\XINT_newfunc_clean}%
+ {\XINT_NewExpr\XINT_expr_redefineprints\xint_gobble_i\xintthebareeval\XINT_newfunc_clean}%
\def\XINT_NewFloatFunc
- {\XINT_NewExpr{}\xint_gobble_i\xintthebarefloateval\XINT_newfunc_clean}%
+ {\XINT_NewExpr\XINT_expr_redefineprints\xint_gobble_i\xintthebarefloateval\XINT_newfunc_clean}%
\def\XINT_NewIIFunc
- {\XINT_NewExpr{}\xint_gobble_i\xintthebareiieval\XINT_newfunc_clean}%
+ {\XINT_NewExpr\XINT_expr_redefineprints\xint_gobble_i\xintthebareiieval\XINT_newfunc_clean}%
\def\XINT_newfunc_clean #1>{}%
\def\XINT_NewExpr #1#2#3#4#5#6[#7]%
{%
@@ -3198,7 +3474,7 @@
\def\XINT_NewExpr_a %1%2%3%4%5@
{@
\def\XINT_tmpa %%1%%2%%3%%4%%5%%6%%7%%8%%9{%5}@
- \def~{$noexpand$}@
+ \def~%%1{\if !%%1\noexpand~\else $noexpand$%%1\fi}@
\catcode`: 11 \catcode`_ 11
\catcode`# 12 \catcode`~ 13 \escapechar 126
\endlinechar -1 \everyeof {\noexpand }@
@@ -3207,6 +3483,7 @@
%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
@@ -3218,6 +3495,7 @@
\fi}@
}@
\catcode`% 14
+\XINT_setcatcodes % clean up to avoid surprises if something changes
\newif\ifxintexprsafecatcodes
\let\xintexprRestoreCatcodes\empty
\def\xintexprSafeCatcodes
@@ -3277,7 +3555,13 @@
\catcode96=12 % `
\catcode32=10 % space
}%
-\let\XINT_tmpa\relax \let\XINT_tmpb\relax \let\XINT_tmpc\relax
+\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%
\endinput
%%
diff --git a/Master/texmf-dist/tex/generic/xint/xintfrac.sty b/Master/texmf-dist/tex/generic/xint/xintfrac.sty
index 09b2c87192d..11d4185c722 100644
--- a/Master/texmf-dist/tex/generic/xint/xintfrac.sty
+++ b/Master/texmf-dist/tex/generic/xint/xintfrac.sty
@@ -21,7 +21,7 @@
%% same distribution. (The sources need not necessarily be
%% in the same archive or directory.)
%% ---------------------------------------------------------------
-%% The xint bundle 1.3d 2019/01/06
+%% The xint bundle 1.3e 2019/04/05
%% Copyright (C) 2013-2019 by Jean-Francois Burnol
%% xintfrac: Expandable operations on fractions
%% ---------------------------------------------------------------
@@ -70,7 +70,7 @@
\XINTsetupcatcodes% defined in xintkernel.sty
\XINT_providespackage
\ProvidesPackage{xintfrac}%
- [2019/01/06 1.3d Expandable operations on fractions (JFB)]%
+ [2019/04/05 1.3e Expandable operations on fractions (JFB)]%
\def\XINT_cntSgnFork #1%
{%
\ifcase #1\expandafter\xint_secondofthree
@@ -397,6 +397,41 @@
\expandafter\XINT_raw\romannumeral0\XINT_infrac
}%
\def\XINT_raw #1#2#3{ #2/#3[#1]}%
+\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
+}%
\def\xintPRaw {\romannumeral0\xintpraw }%
\def\xintpraw
{%
@@ -1902,6 +1937,17 @@
\def\XINT_infloatS_clean #1%
{\if #1!\xint_dothis\XINT_infloatS_clean_a\fi\xint_orthat{ }#1}%
\def\XINT_infloatS_clean_a !#1.{ }%
+\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}%
\def\XINT_infloat [#1]#2%
{%
\expandafter\XINT_infloat_a\the\numexpr #1\expandafter.%
@@ -2255,6 +2301,7 @@
\expandafter\XINT_FL_mul_b\romannumeral0\XINTinfloatS[#3]{#4}#1[#2]%
}%
\def\XINT_FL_mul_b #1[#2]#3[#4]{\xintiiMul{#3}{#1}/1[#4+#2]}%
+\def\XINTinFloatInv#1{\XINTinFloatS[\XINTdigits]{\xintInv{#1}}}%
\def\xintFloatDiv {\romannumeral0\xintfloatdiv }%
\def\xintfloatdiv #1{\XINT_fldiv_chkopt \xintfloat #1\xint:}%
\def\XINTinFloatDiv {\romannumeral0\XINTinfloatdiv }%
@@ -2609,7 +2656,7 @@
\def\xintFloatFac {\romannumeral0\xintfloatfac}%
\def\xintfloatfac #1{\XINT_flfac_chkopt \xintfloat #1\xint:}%
\def\XINTinFloatFac {\romannumeral0\XINTinfloatfac }%
-\def\XINTinfloatfac #1{\XINT_flfac_chkopt \XINTinfloat #1\xint:}%
+\def\XINTinfloatfac #1{\XINT_flfac_chkopt \XINTinfloatS #1\xint:}%
\def\XINT_flfac_chkopt #1#2%
{%
\ifx [#2\expandafter\XINT_flfac_opt
diff --git a/Master/texmf-dist/tex/generic/xint/xintgcd.sty b/Master/texmf-dist/tex/generic/xint/xintgcd.sty
index 60a38048466..ecd3d3f8532 100644
--- a/Master/texmf-dist/tex/generic/xint/xintgcd.sty
+++ b/Master/texmf-dist/tex/generic/xint/xintgcd.sty
@@ -21,7 +21,7 @@
%% same distribution. (The sources need not necessarily be
%% in the same archive or directory.)
%% ---------------------------------------------------------------
-%% The xint bundle 1.3d 2019/01/06
+%% The xint bundle 1.3e 2019/04/05
%% Copyright (C) 2013-2019 by Jean-Francois Burnol
%% xintgcd: Euclidean algorithm with xint package
%% ---------------------------------------------------------------
@@ -70,7 +70,7 @@
\XINTsetupcatcodes% defined in xintkernel.sty
\XINT_providespackage
\ProvidesPackage{xintgcd}%
- [2019/01/06 1.3d Euclide algorithm with xint package (JFB)]%
+ [2019/04/05 1.3e Euclide algorithm with xint package (JFB)]%
\def\xintGCD {\romannumeral0\xintgcd }%
\def\xintgcd #1#2{\xintiigcd {\xintNum{#1}}{\xintNum{#2}}}%
\def\xintiiGCD {\romannumeral0\xintiigcd }%
diff --git a/Master/texmf-dist/tex/generic/xint/xintkernel.sty b/Master/texmf-dist/tex/generic/xint/xintkernel.sty
index 63719d70a97..2b03201a5f5 100644
--- a/Master/texmf-dist/tex/generic/xint/xintkernel.sty
+++ b/Master/texmf-dist/tex/generic/xint/xintkernel.sty
@@ -21,7 +21,7 @@
%% same distribution. (The sources need not necessarily be
%% in the same archive or directory.)
%% ---------------------------------------------------------------
-%% The xint bundle 1.3d 2019/01/06
+%% The xint bundle 1.3e 2019/04/05
%% Copyright (C) 2013-2019 by Jean-Francois Burnol
%% xintkernel: Paraphernalia for the xint packages
%% ---------------------------------------------------------------
@@ -156,7 +156,7 @@
\fi
\XINT_providespackage
\ProvidesPackage {xintkernel}%
- [2019/01/06 1.3d Paraphernalia for the xint packages (JFB)]%
+ [2019/04/05 1.3e Paraphernalia for the xint packages (JFB)]%
\chardef\xint_c_ 0
\chardef\xint_c_i 1
\chardef\xint_c_ii 2
@@ -564,8 +564,11 @@
}%
}%
\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
\newif\ifxintglobaldefs
diff --git a/Master/texmf-dist/tex/generic/xint/xintlog.sty b/Master/texmf-dist/tex/generic/xint/xintlog.sty
new file mode 100644
index 00000000000..0ba983d2530
--- /dev/null
+++ b/Master/texmf-dist/tex/generic/xint/xintlog.sty
@@ -0,0 +1,118 @@
+%%
+%% This is file `xintlog.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% xint.dtx (with options: `xintlog')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from xintlog.sty.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file xint.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+%% ---------------------------------------------------------------
+%% The xint bundle 1.3e 2019/04/05
+%% Copyright (C) 2013-2019 by Jean-Francois Burnol
+%% xintlog: Logarithms and exponentials for xintexpr
+%% ---------------------------------------------------------------
+\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%
+\xintexprSafeCatcodes\catcode`_ 11
+\XINT_providespackage
+\ProvidesPackage{xintlog}%
+[2019/04/05 1.3e Logarithms and exponentials for xintexpr (JFB)]%
+\ifdefined\RequirePackage
+ \RequirePackage{poormanlog}%
+\else
+ \input poormanlog.tex
+\fi
+\xintexprRestoreCatcodes\csname XINT_setcatcodes\endcsname\catcode`\! 11
+\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]}}}%
+\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
+\endinput
+%%
+%% End of file `xintlog.sty'.
diff --git a/Master/texmf-dist/tex/generic/xint/xintseries.sty b/Master/texmf-dist/tex/generic/xint/xintseries.sty
index 7958c90d75d..38ea5b473c4 100644
--- a/Master/texmf-dist/tex/generic/xint/xintseries.sty
+++ b/Master/texmf-dist/tex/generic/xint/xintseries.sty
@@ -21,7 +21,7 @@
%% same distribution. (The sources need not necessarily be
%% in the same archive or directory.)
%% ---------------------------------------------------------------
-%% The xint bundle 1.3d 2019/01/06
+%% The xint bundle 1.3e 2019/04/05
%% Copyright (C) 2013-2019 by Jean-Francois Burnol
%% xintseries: Expandable partial sums with xint package
%% ---------------------------------------------------------------
@@ -70,7 +70,7 @@
\XINTsetupcatcodes% defined in xintkernel.sty
\XINT_providespackage
\ProvidesPackage{xintseries}%
- [2019/01/06 1.3d Expandable partial sums with xint package (JFB)]%
+ [2019/04/05 1.3e Expandable partial sums with xint package (JFB)]%
\def\xintSeries {\romannumeral0\xintseries }%
\def\xintseries #1#2%
{%
diff --git a/Master/texmf-dist/tex/generic/xint/xinttools.sty b/Master/texmf-dist/tex/generic/xint/xinttools.sty
index f6d378e7c24..c38614a2a1e 100644
--- a/Master/texmf-dist/tex/generic/xint/xinttools.sty
+++ b/Master/texmf-dist/tex/generic/xint/xinttools.sty
@@ -21,7 +21,7 @@
%% same distribution. (The sources need not necessarily be
%% in the same archive or directory.)
%% ---------------------------------------------------------------
-%% The xint bundle 1.3d 2019/01/06
+%% The xint bundle 1.3e 2019/04/05
%% Copyright (C) 2013-2019 by Jean-Francois Burnol
%% xinttools: Expandable and non-expandable utilities
%% ---------------------------------------------------------------
@@ -70,7 +70,7 @@
\XINTsetupcatcodes% defined in xintkernel.sty
\XINT_providespackage
\ProvidesPackage{xinttools}%
- [2019/01/06 1.3d Expandable and non-expandable utilities (JFB)]%
+ [2019/04/05 1.3e Expandable and non-expandable utilities (JFB)]%
\newtoks\XINT_toks
\xint_firstofone{\let\XINT_sptoken= } %<- space here!
\def\xintgodef {\global\xintodef }%
diff --git a/Master/texmf-dist/tex/generic/xint/xinttrig.sty b/Master/texmf-dist/tex/generic/xint/xinttrig.sty
new file mode 100644
index 00000000000..b2e41c7b21f
--- /dev/null
+++ b/Master/texmf-dist/tex/generic/xint/xinttrig.sty
@@ -0,0 +1,500 @@
+%%
+%% This is file `xinttrig.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% xint.dtx (with options: `xinttrig')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from xinttrig.sty.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file xint.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+%% ---------------------------------------------------------------
+%% The xint bundle 1.3e 2019/04/05
+%% Copyright (C) 2013-2019 by Jean-Francois Burnol
+%% xinttrig: Trigonometry for the xintexpr package
+%% ---------------------------------------------------------------
+\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
+\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)]%
+}%
+\xintFor* #1 in {iDTVtuwxyzX}\do{\xintensuredummy{#1}}%
+\def\xintreloadxinttrig
+ {\edef\XINT_restorecatcodes_now{\XINT_restorecatcodes}%
+ \XINT_setcatcodes\catcode`? 12
+ \input xinttrig.sty
+ \XINT_restorecatcodes_now}%
+\xintdeffloatvar twoPi := 0 +
+ 6.28318530717958647692528676655900576839433879875021164194989;%
+\xintdeffloatvar threePiover2 := 0 +
+ 4.71238898038468985769396507491925432629575409906265873146242;%
+\xintdeffloatvar Pi := 0 +
+ 3.14159265358979323846264338327950288419716939937510582097494;%
+\xintdeffloatvar Piover2 := 0 +
+ 1.57079632679489661923132169163975144209858469968755291048747;%
+\xintdeffloatvar oneDegree := 0 +
+ 0.0174532925199432957692369076848861271344287188854172545609719;% Pi/180
+\xintdeffloatvar oneRadian := 0 +
+ 57.2957795130823208767981548141051703324054724665643215491602;% 180/Pi
+\xintdeffloatvar invfact\xintListWithSep{, invfact}{\xintSeq{2}{44}}%
+ := seq(0+x, x=\xintexpr rseq(1/2{;}@/i, i=3..44)\relax);% need to hide inner ;
+\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));%
+\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));%
+\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
+\xintdeffloatefunc sin_(x) := x * sin_aux(sqr(x));%
+\xintdeffloatefunc cos_(x) := cos_aux(sqr(x));%
+\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}%
+\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.}%
+\def\XINT_flexpr_func_sind_ #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintSind{\XINT_expr_unlock#3}\endcsname
+}%
+\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.%
+}%
+\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}%
+\def\XINT_flexpr_func_cosd_ #1#2#3%
+{%
+ \expandafter #1\expandafter #2\csname.=%
+ \XINT:NEhook:one\xintCosd{\XINT_expr_unlock#3}\endcsname
+}%
+\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.%
+}%
+\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}%
+\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)));%
+\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)));%
+\xintdeffloatefunc sinc(x):=
+ if(abs(x)<0.79, sin_aux(sqr(x)), sind_(abs(x)*oneRadian)/abs(x));%
+\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))
+ );%
+\xintdeffloatefunc sec(x) := inv(cos(x));%
+\xintdeffloatefunc csc(x) := inv(sin(x));%
+\xintdeffloatefunc secd(x):= inv(cosd(x));%
+\xintdeffloatefunc cscd(x):= inv(sind(x));%
+\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);%
+\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))));%
+\xintdeffloatefunc acos(t) := Piover2 - asin(t);%
+\xintdeffloatefunc acosd(t):= 90 - asind(t);%
+\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)));%
+\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)));%
+\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))
+ );%
+\xintdeffloatefunc atan2(y,x) := Arg(x, y);%
+\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))
+ );%
+\xintdeffloatefunc atan2d(y,x) := Argd(x, y);%
+\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))
+ );%
+\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)
+ );%
+\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
+\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;%
+\xintFor* #1 in {iDTVtuwxyzX}\do{\xintrestorelettervar{#1}}%
+\endinput
+%%
+%% End of file `xinttrig.sty'.