diff options
17 files changed, 2088 insertions, 991 deletions
diff --git a/Master/texmf-dist/doc/generic/xint/CHANGES.html b/Master/texmf-dist/doc/generic/xint/CHANGES.html index 8a4255f97bc..ea5747f29b5 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.4a" /> + <meta name="author" content="xint 1.4b" /> <title>CHANGE LOG</title> <style type="text/css"> code{white-space: pre-wrap;} @@ -25,39 +25,44 @@ <body> <header> <h1 class="title">CHANGE LOG</h1> -<p class="author">xint 1.4a</p> -<p class="date">2020/02/19</p> +<p class="author">xint 1.4b</p> +<p class="date">2020/02/25</p> </header> <nav id="TOC"> <ul> -<li><a href="#a-20200219"><code>1.4a (2020/02/19)</code></a><ul> -<li><a href="#breaking-changes">Breaking changes</a></li> +<li><a href="#b-20200225"><code>1.4b (2020/02/25)</code></a><ul> +<li><a href="#future">Future</a></li> <li><a href="#new-features">New features</a></li> <li><a href="#bug-fixes">Bug fixes</a></li> </ul></li> +<li><a href="#a-20200219"><code>1.4a (2020/02/19)</code></a><ul> +<li><a href="#breaking-changes">Breaking changes</a></li> +<li><a href="#new-features-1">New features</a></li> +<li><a href="#bug-fixes-1">Bug fixes</a></li> +</ul></li> <li><a href="#section"><code>1.4 (2020/01/31)</code></a><ul> <li><a href="#breaking-changes-1">Breaking changes</a></li> <li><a href="#improvements-and-new-features">Improvements and new features</a></li> -<li><a href="#bug-fixes-1">Bug fixes</a></li> +<li><a href="#bug-fixes-2">Bug fixes</a></li> <li><a href="#todo">TODO</a></li> </ul></li> <li><a href="#f-20190910"><code>1.3f (2019/09/10)</code></a><ul> <li><a href="#improvements-and-new-features-1">Improvements and new features</a></li> -<li><a href="#bug-fixes-2">Bug fixes</a></li> +<li><a href="#bug-fixes-3">Bug fixes</a></li> </ul></li> <li><a href="#e-20190405"><code>1.3e (2019/04/05)</code></a><ul> <li><a href="#breaking-changes-2">Breaking changes</a></li> <li><a href="#improvements-and-new-features-2">Improvements and new features</a></li> -<li><a href="#bug-fixes-3">Bug fixes</a></li> +<li><a href="#bug-fixes-4">Bug fixes</a></li> </ul></li> <li><a href="#d-20190106"><code>1.3d (2019/01/06)</code></a><ul> <li><a href="#breaking-changes-3">Breaking changes</a></li> <li><a href="#improvements-and-new-features-3">Improvements and new features</a></li> -<li><a href="#bug-fixes-4">Bug fixes</a></li> +<li><a href="#bug-fixes-5">Bug fixes</a></li> </ul></li> <li><a href="#c-20180617"><code>1.3c (2018/06/17)</code></a><ul> <li><a href="#improvements-and-new-features-4">Improvements and new features</a></li> -<li><a href="#bug-fixes-5">Bug fixes</a></li> +<li><a href="#bug-fixes-6">Bug fixes</a></li> </ul></li> <li><a href="#b-20180518"><code>1.3b (2018/05/18)</code></a><ul> <li><a href="#improvements-and-new-features-5">Improvements and new features</a></li> @@ -65,7 +70,7 @@ <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-6">Improvements and new features</a></li> -<li><a href="#bug-fixes-6">Bug fixes</a></li> +<li><a href="#bug-fixes-7">Bug fixes</a></li> </ul></li> <li><a href="#section-1"><code>1.3 (2018/03/01)</code></a><ul> <li><a href="#breaking-changes-4">Breaking changes</a></li> @@ -73,12 +78,12 @@ </ul></li> <li><a href="#q-20180206"><code>1.2q (2018/02/06)</code></a><ul> <li><a href="#improvements-and-new-features-8">Improvements and new features</a></li> -<li><a href="#bug-fixes-7">Bug fixes</a></li> +<li><a href="#bug-fixes-8">Bug fixes</a></li> </ul></li> <li><a href="#p-20171205"><code>1.2p (2017/12/05)</code></a><ul> <li><a href="#breaking-changes-5">Breaking changes</a></li> <li><a href="#improvements-and-new-features-9">Improvements and new features</a></li> -<li><a href="#bug-fixes-8">Bug fixes</a></li> +<li><a href="#bug-fixes-9">Bug fixes</a></li> </ul></li> <li><a href="#o-20170829"><code>1.2o (2017/08/29)</code></a><ul> <li><a href="#breaking-changes-6">Breaking changes</a></li> @@ -91,31 +96,31 @@ <li><a href="#m-20170731"><code>1.2m (2017/07/31)</code></a><ul> <li><a href="#breaking-changes-8">Breaking changes</a></li> <li><a href="#improvements-and-new-features-11">Improvements and new features</a></li> -<li><a href="#bug-fixes-9">Bug fixes</a></li> +<li><a href="#bug-fixes-10">Bug fixes</a></li> </ul></li> <li><a href="#l-20170726"><code>1.2l (2017/07/26)</code></a><ul> <li><a href="#removed-1">Removed</a></li> <li><a href="#improvements-and-new-features-12">Improvements and new features</a></li> -<li><a href="#bug-fixes-10">Bug fixes</a></li> +<li><a href="#bug-fixes-11">Bug fixes</a></li> </ul></li> <li><a href="#k-20170106"><code>1.2k (2017/01/06)</code></a><ul> <li><a href="#breaking-changes-9">Breaking changes</a></li> <li><a href="#improvements-and-new-features-13">Improvements and new features</a></li> -<li><a href="#bug-fixes-11">Bug fixes</a></li> +<li><a href="#bug-fixes-12">Bug fixes</a></li> </ul></li> <li><a href="#j-20161222"><code>1.2j (2016/12/22)</code></a><ul> <li><a href="#improvements-and-new-features-14">Improvements and new features</a></li> -<li><a href="#bug-fixes-12">Bug fixes</a></li> +<li><a href="#bug-fixes-13">Bug fixes</a></li> </ul></li> <li><a href="#i-20161213"><code>1.2i (2016/12/13)</code></a><ul> <li><a href="#breaking-changes-10">Breaking changes</a></li> <li><a href="#removed-2">Removed</a></li> <li><a href="#improvements-and-new-features-15">Improvements and new features</a></li> -<li><a href="#bug-fixes-13">Bug fixes</a></li> +<li><a href="#bug-fixes-14">Bug fixes</a></li> </ul></li> <li><a href="#h-20161120"><code>1.2h (2016/11/20)</code></a><ul> <li><a href="#improvements-and-new-features-16">Improvements and new features</a></li> -<li><a href="#bug-fixes-14">Bug fixes</a></li> +<li><a href="#bug-fixes-15">Bug fixes</a></li> </ul></li> <li><a href="#g-20160319"><code>1.2g (2016/03/19)</code></a><ul> <li><a href="#breaking-changes-11">Breaking changes</a></li> @@ -124,26 +129,26 @@ <li><a href="#f-20160312"><code>1.2f (2016/03/12)</code></a><ul> <li><a href="#breaking-changes-12">Breaking changes</a></li> <li><a href="#improvements-and-new-features-18">Improvements and new features</a></li> -<li><a href="#bug-fixes-15">Bug fixes</a></li> +<li><a href="#bug-fixes-16">Bug fixes</a></li> </ul></li> <li><a href="#e-20151122"><code>1.2e (2015/11/22)</code></a><ul> <li><a href="#improvements-and-new-features-19">Improvements and new features</a></li> -<li><a href="#bug-fixes-16">Bug fixes</a></li> +<li><a href="#bug-fixes-17">Bug fixes</a></li> </ul></li> <li><a href="#d-20151118"><code>1.2d (2015/11/18)</code></a><ul> <li><a href="#improvements-and-new-features-20">Improvements and new features</a></li> -<li><a href="#bug-fixes-17">Bug fixes</a></li> +<li><a href="#bug-fixes-18">Bug fixes</a></li> </ul></li> <li><a href="#c-20151116"><code>1.2c (2015/11/16)</code></a><ul> <li><a href="#improvements-and-new-features-21">Improvements and new features</a></li> -<li><a href="#bug-fixes-18">Bug fixes</a></li> +<li><a href="#bug-fixes-19">Bug fixes</a></li> </ul></li> <li><a href="#b-20151029"><code>1.2b (2015/10/29)</code></a><ul> -<li><a href="#bug-fixes-19">Bug fixes</a></li> +<li><a href="#bug-fixes-20">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-22">Improvements and new features</a></li> -<li><a href="#bug-fixes-20">Bug fixes</a></li> +<li><a href="#bug-fixes-21">Bug fixes</a></li> </ul></li> <li><a href="#section-2"><code>1.2 (2015/10/10)</code></a><ul> <li><a href="#removed-3">Removed</a></li> @@ -157,7 +162,7 @@ <li><a href="#removed-4">Removed</a></li> <li><a href="#deprecated-1">Deprecated</a></li> <li><a href="#improvements-and-new-features-24">Improvements and new features</a></li> -<li><a href="#bug-fixes-21">Bug fixes</a></li> +<li><a href="#bug-fixes-22">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> @@ -185,37 +190,57 @@ <li><a href="#section-10"><code>1.0 (2013/03/28)</code></a></li> </ul> </nav> -<pre><code>Source: xint.dtx 1.4a 2020/02/19 (doc 2020/02/19) +<pre><code>Source: xint.dtx 1.4b 2020/02/25 (doc 2020/02/25) Author: Jean-Francois Burnol Info: Expandable operations on big integers, decimals, fractions License: LPPL 1.3c</code></pre> +<h2 id="b-20200225"><code>1.4b (2020/02/25)</code></h2> +<p>All changes regard the <strong>xintexpr</strong> module.</p> +<h3 id="future">Future</h3> +<ul> +<li><p><code>&</code>, <code>|</code>, (as Boolean operators) and <code>=</code> (as equality test) have long been deprecated in favour of <code>&&</code>, <code>||</code> and <code>==</code>. They will be removed at next major release.</p></li> +<li><p>At next major release the power operators <code>**</code> and <code>^</code> will turn from left to right associative. I.e. <code>2**2**3</code> will give <code>256</code>, not <code>64</code>. This is to match with Python and l3fp.</p></li> +<li><p><code>\thexintexpr</code> et al. (introduced at <code>1.2h</code> but not documented anymore for some time) will be removed at next major release. The original <code>\xinttheexpr</code> et al. have always been so much better names. Besides, since <code>1.4</code>, <code>\xintexpr</code> can be used directly in typesetting flow.</p></li> +</ul> +<h3 id="new-features">New features</h3> +<ul> +<li><p>Function <code>zip()</code> is modeled on Python’s function of the same name.</p></li> +<li><p>Function <code>flat()</code> removes all nesting to produce a “one-dimensional” list having the exact same leaves (some possibly empty) as the original (in the same order).</p></li> +<li><p>Chaining of comparison operators (e.g. <code>x<y<z</code>) as in Python (but all comparisons are done even if one is found false) and l3fp.</p></li> +<li><p>Strangely, it was possible since <code>1.4</code>’s <code>\xintFracToSciE</code> to configure the separator between mantissas and exponents in the output of <code>\xinteval</code> but this did not modify the output of <code>\xintfloateval</code>. This is now fixed via the added <code>\xintPFloatE</code>.</p></li> +</ul> +<h3 id="bug-fixes">Bug fixes</h3> +<ul> +<li><code>\xintieval{[D]...}</code> with a negative <code>D</code> (a feature added at <code>1.4a</code>) used erroneously a catcode 12 <code>e</code> in output. And its customization via <code>\xintFracToSciE</code> remained without effect.</li> +</ul> <h2 id="a-20200219"><code>1.4a (2020/02/19)</code></h2> <h3 id="breaking-changes">Breaking changes</h3> <ul> <li><strong>xintexpr</strong>: the macros implementing customization of <code>\xintthealign</code> have modified meanings and names.</li> </ul> -<h3 id="new-features">New features</h3> +<h3 id="new-features-1">New features</h3> <ul> <li><p><strong>xintexpr</strong>: <code>\xintthespaceseparated</code> (serves to provide suitable input to PS-Tricks <code>\listplot</code>).</p></li> -<li><p><strong>xintexpr</strong>: the optional argument <code>[D]</code> to <code>\xintieval/\xintiexpr</code> can be negative, with the same meaning as the non-negative case, i.e. <em>quantization</em> to an integer multiple of <code>10^(-D)</code>.</p> +<li><p><strong>xintexpr</strong>: the optional argument <code>[D]</code> to <code>\xintieval/\xintiexpr</code> can be negative, with the same meaning as the non-negative case, i.e. rounding to an integer multiple of <code>10^(-D)</code>.</p> <p>The same applies to the functions <code>trunc()</code> and <code>round()</code>. And to the <code>\xintTrunc</code>, <code>\xintRound</code>, <code>\xintiTrunc</code>, and <code>\xintiRound</code> macros of <strong>xintfrac</strong>.</p></li> </ul> -<h3 id="bug-fixes">Bug fixes</h3> +<h3 id="bug-fixes-1">Bug fixes</h3> <ul> <li><p><strong>xintexpr</strong>: usage of <code>round()</code> and <code>trunc()</code> within <code>\xintdeffunc</code> got broken at <code>1.4</code>.</p></li> <li><p><strong>xintexpr</strong>: <code>add()</code> and <code>mul()</code> were supposedly accepting the <code>omit</code>, <code>abort</code> and <code>break()</code> keywords since <code>1.4</code> but this was broken.</p></li> </ul> <h2 id="section"><code>1.4 (2020/01/31)</code></h2> <h3 id="breaking-changes-1">Breaking changes</h3> -<p>Please note that this list is currently incomplete. If not otherly specified all items regard the <strong>xintexpr</strong> module.</p> +<p>Please note that this list may still be incomplete. If not otherly specified all items regard the <strong>xintexpr</strong> module.</p> <ul> <li><p>The <code>\expanded</code> primitive (TeXLive 2019) is <strong>required</strong>. This does not affect the macro layer <strong>xintcore</strong>, <strong>xint</strong>, <strong>xintfrac</strong>, <strong>xinttools</strong> (yet).</p></li> +<li><p>Formerly square brackets <code>[...]</code> were, on their own, not different from parentheses (and thus disappeared from the output), but they are now a genuine constructor of nested lists. For example <code>\xinteval{1, [2, [3, 4]], 5}</code> produces <code>1, [2, [3, 4]], 5</code> (recall this is free bloatware).</p></li> +<li><p>The output of <code>\xinteval</code> has changed (besides containing brackets). It does not use anymore the so-called <em>raw</em> <strong>xintfrac</strong> format, i.e. things such as <code>A/B[N]</code> (which can still be used in input but are discouraged in <strong>xintexpr</strong> context), but scientific notation <code>AeN/B</code>. As formerly, the denominator is printed only if <code>B>1</code> and the scientific part is dropped if the exponent vanishes. In this way the output of <code>\xinteval</code> can be pasted to alternative software.</p></li> +<li><p>The output format of <code>\xinthe\xintboolexpr</code> also has changed. It uses <code>True</code> and <code>False</code> (which are accepted on input), and this can easily be configured otherwise (also <code>true</code> and <code>false</code> are accepted on input).</p></li> <li><p>The “broadcasting” (as it turned out, à la <code>NumPy</code>) of scalar operations on one-dimensional “lists”, e.g <code>3*[1,3,5,7]+10</code> acting itemwise is <strong>dropped</strong>. It is hoped to implement such operations again in stronger form in future releases. Pre-existing alternative syntax is available, also to produce the bracketed (cf. next item) <code>[13,19,25,31]</code> which will be the output in future.</p></li> -<li><p>Formerly square brackets <code>[...]</code> were, on their own, not different from parentheses, but they are now a genuine constructor of nested lists. For example <code>\xinteval{1, [2, [3, 4]], 5}</code> produces <code>1, [2, [3, 4]], 5</code> (recall this is free bloatware).</p></li> <li><p>The <code>divmod()</code> function now produces on output such a bracketed pair, but simultaneous assignment such as <code>\xintdefvar xq, xr = divmod(a,b);</code> will work transparently.</p></li> <li><p>The syntax for using conditionals in function declarations has changed. Now, one <em>must</em> use the <code>?</code> and <code>??</code> short-circuit boolean branching operators whereas in the past it was explained that the syntax had to use the <code>if()</code> and <code>ifsgn()</code> functions.</p></li> -<li><p>The output of <code>\xinteval</code> has changed (besides containing brackets). It does not use anymore the so-called <em>raw</em> <strong>xintfrac</strong> format, i.e. things such as <code>A/B[N]</code> (which can still be used in input but are discouraged in <strong>xintexpr</strong> context), but scientific notation <code>AeN/B</code>. As formerly, the denominator is printed only if <code>B>1</code> and the scientific part is dropped if the exponent vanishes. In this way the output of <code>\xinteval</code> can be pasted to alternative software.</p> -<p>The output format of <code>\xinthe\xintboolexpr</code> has changed. It uses <code>True</code> and <code>False</code> (which are accepted on input), and this can easily be configured otherwise (also <code>true</code> and <code>false</code> are accepted on input).</p></li> +<li><p>Macros <code>\xintGCD</code>, <code>\xintLCM</code>, <code>\xintGCDof</code> and <code>\xintLCMof</code> formerly provided by <strong>xintgcd</strong> got moved to <strong>xintfrac</strong> (which is not loaded by <strong>xintgcd</strong>). Moreover, they were extended to handle general fractions on input but this also means that their output is now obiding by the raw <strong>xintfrac</strong> format. The integer only <code>\xintiiGCD</code>, <code>\xintiiLCM</code> also got moved out of <strong>xintgcd</strong>, but to <strong>xint</strong> which is now loaded automatically by <strong>xintgcd</strong>. The few remaining macros of <strong>xintgcd</strong> at least do not need other imports as <strong>xintgcd</strong> now loads also automatically <strong>xinttools</strong> which is a dependency for two of them.</p></li> </ul> <h3 id="improvements-and-new-features">Improvements and new features</h3> <p>Please note that this list is currently incomplete. For more information look at the user manual and the documented source code <code>sourcexint.pdf</code>.</p> @@ -251,7 +276,7 @@ License: LPPL 1.3c</code></pre> <li><p>Function declarations are able to parse a much wider part of the syntax, but some severe limitations remain. Refer to the user manual for related information.</p></li> <li><p>We have made an effort on some error messages, and when working interactively in a shell it may even be sometimes possible to insert for example a correct variable or function name in place of the not recognized one. But don’t expect miracles when trying to intervene in the midst of a purely expandable expansion…</p></li> </ul> -<h3 id="bug-fixes-1">Bug fixes</h3> +<h3 id="bug-fixes-2">Bug fixes</h3> <p>Bugs? Those identified in <code>1.3f</code> were almost features. As per <code>1.4</code> the code base of <strong>xintexpr</strong> received multiple successive core refactorings and added numerous new features, and our test suite although significantly enlarged is not yet extensive enough. Please report bugs by mail.</p> <h3 id="todo">TODO</h3> <ul> @@ -267,7 +292,7 @@ License: LPPL 1.3c</code></pre> <li><p><strong>xintexpr</strong>: add starred variants <code>\xintDigits*</code> and <code>\xintSetDigits*</code> which execute <code>\xintreloadxinttrig</code>.</p> <p>Revert 1.3e ban on usage of <code>\xinteval</code> et al. inside expressions by <code>\xintdeffunc</code>. And make them usable also inside macro definitions via <code>\xintNewExpr</code>.</p></li> </ul> -<h3 id="bug-fixes-2">Bug fixes</h3> +<h3 id="bug-fixes-3">Bug fixes</h3> <ul> <li><p><strong>xintexpr</strong>: fix bug preventing usage of <code>\xintdefefunc</code> to define a function without variables.</p> <p>Fix some issue with <code>\xintfloatexpr[D]..\relax</code> if used inside an expression parsed by <code>\xintdeffunc</code> et al.</p></li> @@ -287,7 +312,7 @@ License: LPPL 1.3c</code></pre> <li><p><strong>xintexpr</strong>: <code>\xintensuredummy</code>, <code>\xintrestorelettervar</code>.</p></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-3">Bug fixes</h3> +<h3 id="bug-fixes-4">Bug fixes</h3> <ul> <li>Some bugfixes related to user functions with no variables at all; they were dysfunctional.</li> </ul> @@ -306,7 +331,7 @@ License: LPPL 1.3c</code></pre> <li><p><strong>xintexpr</strong>: functions <code>isone()</code> and <code>isint()</code>.</p></li> <li><p><strong>xintexpr</strong>: <code>\xinteval</code>, <code>\xintieval</code>, <code>\xintiieval</code>, and <code>\xintfloateval</code> as synonyms to <code>\xinttheexpr...\relax</code> etc…, but with the (comma-separated) expression as a usual braced macro argument.</p></li> </ul> -<h3 id="bug-fixes-4">Bug fixes</h3> +<h3 id="bug-fixes-5">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> @@ -319,7 +344,7 @@ License: LPPL 1.3c</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-5">Bug fixes</h3> +<h3 id="bug-fixes-6">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> @@ -345,7 +370,7 @@ License: LPPL 1.3c</code></pre> <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-6">Bug fixes</h3> +<h3 id="bug-fixes-7">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> @@ -368,7 +393,7 @@ License: LPPL 1.3c</code></pre> <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-7">Bug fixes</h3> +<h3 id="bug-fixes-8">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> @@ -387,7 +412,7 @@ License: LPPL 1.3c</code></pre> <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-8">Bug fixes</h3> +<h3 id="bug-fixes-9">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> @@ -430,7 +455,7 @@ License: LPPL 1.3c</code></pre> <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-9">Bug fixes</h3> +<h3 id="bug-fixes-10">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> @@ -451,7 +476,7 @@ License: LPPL 1.3c</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-10">Bug fixes</h3> +<h3 id="bug-fixes-11">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> @@ -470,7 +495,7 @@ License: LPPL 1.3c</code></pre> <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-11">Bug fixes</h3> +<h3 id="bug-fixes-12">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> @@ -486,7 +511,7 @@ License: LPPL 1.3c</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-12">Bug fixes</h3> +<h3 id="bug-fixes-13">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> @@ -518,7 +543,7 @@ License: LPPL 1.3c</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-13">Bug fixes</h3> +<h3 id="bug-fixes-14">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> @@ -528,7 +553,7 @@ License: LPPL 1.3c</code></pre> <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-14">Bug fixes</h3> +<h3 id="bug-fixes-15">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<0</code> or <code>x<y</code>. This was unfortunate, and it now simply evaluates to zero in such cases.</p></li> @@ -568,7 +593,7 @@ License: LPPL 1.3c</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-15">Bug fixes</h3> +<h3 id="bug-fixes-16">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> @@ -582,7 +607,7 @@ License: LPPL 1.3c</code></pre> <li><p>a space in <code>\xintdeffunc f(x)<space>:= 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-16">Bug fixes</h3> +<h3 id="bug-fixes-17">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> @@ -595,7 +620,7 @@ License: LPPL 1.3c</code></pre> <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-17">Bug fixes</h3> +<h3 id="bug-fixes-18">Bug fixes</h3> <ul> <li>in <strong>xintcore</strong>: release <code>1.2c</code> had inadvertently broken the <code>\xintiiDivRound</code> macro.</li> </ul> @@ -605,12 +630,12 @@ License: LPPL 1.3c</code></pre> <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-18">Bug fixes</h3> +<h3 id="bug-fixes-19">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-19">Bug fixes</h3> +<h3 id="bug-fixes-20">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> @@ -621,7 +646,7 @@ License: LPPL 1.3c</code></pre> <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`&&@</code> (<code>^</code> being used as letter, had to find another character usable with catcode 7).</p></li> </ul> -<h3 id="bug-fixes-20">Bug fixes</h3> +<h3 id="bug-fixes-21">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> @@ -722,7 +747,7 @@ License: LPPL 1.3c</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-21">Bug fixes</h3> +<h3 id="bug-fixes-22">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/README.md b/Master/texmf-dist/doc/generic/xint/README.md index 317827fbea1..9146c736669 100644 --- a/Master/texmf-dist/doc/generic/xint/README.md +++ b/Master/texmf-dist/doc/generic/xint/README.md @@ -1,8 +1,8 @@ % README -% xint 1.4a -% 2020/02/19 +% xint 1.4b +% 2020/02/25 - Source: xint.dtx 1.4a 2020/02/19 (doc 2020/02/19) + Source: xint.dtx 1.4b 2020/02/25 (doc 2020/02/25) Author: Jean-Francois Burnol Info: Expandable operations on big integers, decimals, fractions License: LPPL 1.3c @@ -10,27 +10,44 @@ Aim and usage ============= -The basic aim is provide *expandable* computations on integers, -fractions, and floating point numbers. For example, with fractions: +It is possible to use the package both with Plain (`\input xintexpr.sty`) +or with the LaTeX macro format (`\usepackage{xintexpr}`). + +The basic aim is provide *expandable* computations on (arbitrily big) +integers, fractions, and floating point numbers (at a user chosen +precision). The four operations and the square-root extraction achieve +so-called *correct rounding* for the given arbitrary precision. + +The syntax knows dummy variables, as in this example: + + \xinteval{reduce(add(x/(x+7), x = 1000..1010))} + +which expands to: - \xinteval{reduce(37189719/183618963+11390170/17310720)^17} + 108959959329292321880648657/9974444716475301992902544 -The result has `462` characters (forward slash included.) -One can also work with dummy variables: +Trigonometrical functions are available: - \xinteval{mul(add(x(x+1)(x+2), x=y..y+15), y=171286,98762,9296)} + \xintDigits*:=48\relax -and do computations with floating point numbers at an adjustable -precision (default `16`). + \xintfloateval{[-2] sind(37)} - \xintDigits:=48;\xintfloateval{123_456_789^10_000.5} - expands to 1.56866129625858270633170234772583710433908855336e80919 +expands to: -Release `1.4` adds support for nested structures: + 0.6018150231520482799179770004414898414256377098 + +The [-2] means to round the result to 2 digits less than float precision: +currently trigonometrical functions are mostly implemented at high level +via the user interface for declaring functions and variables and have no +way to use guard digits, hence the last two digits are often not +accurate. + +Release `1.4` adds support for nested structures. For example: \xintthealign\xintexpr ndseq(1/(i+j), i=1..5; j=1..5)\relax -will print on the page +will print on the page (this is customizable, e.g. to use a pmatrix +environnement rather): [[ 1/2, 1/3, 1/4, 1/5, 1/6 ], [ 1/3, 1/4, 1/5, 1/6, 1/7 ], @@ -38,15 +55,9 @@ will print on the page [ 1/5, 1/6, 1/7, 1/8, 1/9 ], [ 1/6, 1/7, 1/8, 1/9, 1/10 ]] -The four operations and the square-root extraction achieve so-called -*correct rounding* in the given arbitrary precision. - -Trigonometric functions (direct and inverse) are available up to a -maximal precision of about `58` digits. Logarithms and exponentials are -currently evaluated only with `8` or `9` digits precision. - -It is possible to use the package both with Plain (`\input xintexpr.sty`) -or with the LaTeX macro format (`\usepackage{xintexpr}`). +It is possible to declare "universal functions" (à la NumPy) which will +act itemwise on all leaves of such "arrays". More features are planned +such as providing an interface to algebra of matrices in this framework. Installation ============ @@ -87,8 +98,8 @@ Documentation Requirements ============ -Attention, since release `1.4` `xintexpr` requires the `\expanded` -primitive (it is provided by all major TeX engines since TeXLive 2019). +Since release `1.4`, `xintexpr` requires the `\expanded` primitive. This +is a functionality of all major TeX engines since TeXLive 2019. License ======= diff --git a/Master/texmf-dist/doc/generic/xint/sourcexint.pdf b/Master/texmf-dist/doc/generic/xint/sourcexint.pdf Binary files differindex 77f901f6402..b45bfc7ca82 100644 --- a/Master/texmf-dist/doc/generic/xint/sourcexint.pdf +++ b/Master/texmf-dist/doc/generic/xint/sourcexint.pdf diff --git a/Master/texmf-dist/doc/generic/xint/xint.pdf b/Master/texmf-dist/doc/generic/xint/xint.pdf Binary files differindex be2a945ee08..bbfcbe7f35d 100644 --- a/Master/texmf-dist/doc/generic/xint/xint.pdf +++ b/Master/texmf-dist/doc/generic/xint/xint.pdf diff --git a/Master/texmf-dist/source/generic/xint/xint.dtx b/Master/texmf-dist/source/generic/xint/xint.dtx index 49fbd503512..dabb98f21c2 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: <19-02-2020 at 09:09:07 CET>} +\def\xintdtxtimestamp {Time-stamp: <25-02-2020 at 23:06:44 CET>} %</dtx> %<*drv> %% --------------------------------------------------------------- -\def\xintdocdate {2020/02/19} -\def\xintbndldate{2020/02/19} -\def\xintbndlversion {1.4a} +\def\xintdocdate {2020/02/25} +\def\xintbndldate{2020/02/25} +\def\xintbndlversion {1.4b} %</drv> %<readme>% README %<changes>% CHANGE LOG -%<readme|changes>% xint 1.4a -%<readme|changes>% 2020/02/19 +%<readme|changes>% xint 1.4b +%<readme|changes>% 2020/02/25 %<readme|changes> -%<readme|changes> Source: xint.dtx 1.4a 2020/02/19 (doc 2020/02/19) +%<readme|changes> Source: xint.dtx 1.4b 2020/02/25 (doc 2020/02/25) %<readme|changes> Author: Jean-Francois Burnol %<readme|changes> Info: Expandable operations on big integers, decimals, fractions %<readme|changes> License: LPPL 1.3c %<readme|changes> %<*!readme&!changes&!dohtmlsh&!makefile> %% --------------------------------------------------------------- -%% The xint bundle 1.4a 2020/02/19 +%% The xint bundle 1.4b 2020/02/25 %% Copyright (C) 2013-2020 by Jean-Francois Burnol %<xintkernel>%% xintkernel: Paraphernalia for the xint packages %<xinttools>%% xinttools: Expandable and non-expandable utilities @@ -46,27 +46,44 @@ Aim and usage ============= -The basic aim is provide *expandable* computations on integers, -fractions, and floating point numbers. For example, with fractions: +It is possible to use the package both with Plain (`\input xintexpr.sty`) +or with the LaTeX macro format (`\usepackage{xintexpr}`). + +The basic aim is provide *expandable* computations on (arbitrily big) +integers, fractions, and floating point numbers (at a user chosen +precision). The four operations and the square-root extraction achieve +so-called *correct rounding* for the given arbitrary precision. + +The syntax knows dummy variables, as in this example: + + \xinteval{reduce(add(x/(x+7), x = 1000..1010))} + +which expands to: + + 108959959329292321880648657/9974444716475301992902544 + +Trigonometrical functions are available: - \xinteval{reduce(37189719/183618963+11390170/17310720)^17} + \xintDigits*:=48\relax -The result has `462` characters (forward slash included.) -One can also work with dummy variables: + \xintfloateval{[-2] sind(37)} - \xinteval{mul(add(x(x+1)(x+2), x=y..y+15), y=171286,98762,9296)} +expands to: -and do computations with floating point numbers at an adjustable -precision (default `16`). + 0.6018150231520482799179770004414898414256377098 - \xintDigits:=48;\xintfloateval{123_456_789^10_000.5} - expands to 1.56866129625858270633170234772583710433908855336e80919 +The [-2] means to round the result to 2 digits less than float precision: +currently trigonometrical functions are mostly implemented at high level +via the user interface for declaring functions and variables and have no +way to use guard digits, hence the last two digits are often not +accurate. -Release `1.4` adds support for nested structures: +Release `1.4` adds support for nested structures. For example: \xintthealign\xintexpr ndseq(1/(i+j), i=1..5; j=1..5)\relax -will print on the page +will print on the page (this is customizable, e.g. to use a pmatrix +environnement rather): [[ 1/2, 1/3, 1/4, 1/5, 1/6 ], [ 1/3, 1/4, 1/5, 1/6, 1/7 ], @@ -74,15 +91,9 @@ will print on the page [ 1/5, 1/6, 1/7, 1/8, 1/9 ], [ 1/6, 1/7, 1/8, 1/9, 1/10 ]] -The four operations and the square-root extraction achieve so-called -*correct rounding* in the given arbitrary precision. - -Trigonometric functions (direct and inverse) are available up to a -maximal precision of about `58` digits. Logarithms and exponentials are -currently evaluated only with `8` or `9` digits precision. - -It is possible to use the package both with Plain (`\input xintexpr.sty`) -or with the LaTeX macro format (`\usepackage{xintexpr}`). +It is possible to declare "universal functions" (à la NumPy) which will +act itemwise on all leaves of such "arrays". More features are planned +such as providing an interface to algebra of matrices in this framework. Installation ============ @@ -123,8 +134,8 @@ Documentation Requirements ============ -Attention, since release `1.4` `xintexpr` requires the `\expanded` -primitive (it is provided by all major TeX engines since TeXLive 2019). +Since release `1.4`, `xintexpr` requires the `\expanded` primitive. This +is a functionality of all major TeX engines since TeXLive 2019. License ======= @@ -153,6 +164,49 @@ See `xint.pdf` for contact information. %</readme>-------------------------------------------------------- %<*changes>------------------------------------------------------- +`1.4b (2020/02/25)` +---- + +All changes regard the **xintexpr** module. + +### Future + + - `&`, `|`, (as Boolean operators) and `=` (as equality test) have long + been deprecated in favour of `&&`, `||` and `==`. They will be + removed at next major release. + + - At next major release the power operators `**` and `^` will turn from + left to right associative. I.e. `2**2**3` will give `256`, not `64`. + This is to match with Python and l3fp. + + - `\thexintexpr` et al. (introduced at `1.2h` but not documented + anymore for some time) will be removed at next major release. The + original `\xinttheexpr` et al. have always been so much better names. + Besides, since `1.4`, `\xintexpr` can be used directly in typesetting + flow. + +### New features + + - Function `zip()` is modeled on Python's function of the same name. + + - Function `flat()` removes all nesting to produce a "one-dimensional" + list having the exact same leaves (some possibly empty) as the + original (in the same order). + + - Chaining of comparison operators (e.g. `x<y<z`) as in Python (but all + comparisons are done even if one is found false) and l3fp. + + - Strangely, it was possible since `1.4`'s `\xintFracToSciE` to + configure the separator between mantissas and exponents in the output + of `\xinteval` but this did not modify the output of + `\xintfloateval`. This is now fixed via the added `\xintPFloatE`. + +### Bug fixes + + - `\xintieval{[D]...}` with a negative `D` (a feature added at `1.4a`) + used erroneously a catcode 12 `e` in output. And its customization + via `\xintFracToSciE` remained without effect. + `1.4a (2020/02/19)` ---- @@ -168,7 +222,7 @@ See `xint.pdf` for contact information. - **xintexpr**: the optional argument `[D]` to `\xintieval/\xintiexpr` can be negative, with the same meaning as the non-negative case, i.e. - *quantization* to an integer multiple of `10^(-D)`. + rounding to an integer multiple of `10^(-D)`. The same applies to the functions `trunc()` and `round()`. And to the `\xintTrunc`, `\xintRound`, `\xintiTrunc`, and `\xintiRound` macros @@ -189,13 +243,32 @@ See `xint.pdf` for contact information. ### Breaking changes -Please note that this list is currently incomplete. If not otherly +Please note that this list may still be incomplete. If not otherly specified all items regard the **xintexpr** module. - The `\expanded` primitive (TeXLive 2019) is **required**. This does not affect the macro layer **xintcore**, **xint**, **xintfrac**, **xinttools** (yet). + - Formerly square brackets `[...]` were, on their own, not different + from parentheses (and thus disappeared from the output), but they are + now a genuine constructor of nested lists. For example `\xinteval{1, + [2, [3, 4]], 5}` produces `1, [2, [3, 4]], 5` (recall this is free + bloatware). + + - The output of `\xinteval` has changed (besides containing brackets). + It does not use anymore the so-called *raw* **xintfrac** format, + i.e. things such as `A/B[N]` (which can still be used in input but + are discouraged in **xintexpr** context), but scientific notation + `AeN/B`. As formerly, the denominator is printed only if `B>1` and + the scientific part is dropped if the exponent vanishes. In this way + the output of `\xinteval` can be pasted to alternative software. + + - The output format of `\xinthe\xintboolexpr` also has changed. It uses + `True` and `False` (which are accepted on input), and this can + easily be configured otherwise (also `true` and `false` are accepted + on input). + - The "broadcasting" (as it turned out, à la `NumPy`) of scalar operations on one-dimensional "lists", e.g `3*[1,3,5,7]+10` acting itemwise is **dropped**. It is hoped to implement such operations @@ -203,11 +276,6 @@ specified all items regard the **xintexpr** module. syntax is available, also to produce the bracketed (cf. next item) `[13,19,25,31]` which will be the output in future. - - Formerly square brackets `[...]` were, on their own, not different - from parentheses, but they are now a genuine constructor of nested - lists. For example `\xinteval{1, [2, [3, 4]], 5}` produces `1, - [2, [3, 4]], 5` (recall this is free bloatware). - - The `divmod()` function now produces on output such a bracketed pair, but simultaneous assignment such as `\xintdefvar xq, xr = divmod(a,b);` will work transparently. @@ -217,19 +285,17 @@ specified all items regard the **xintexpr** module. branching operators whereas in the past it was explained that the syntax had to use the `if()` and `ifsgn()` functions. - - The output of `\xinteval` has changed (besides containing brackets). - It does not use anymore the so-called *raw* **xintfrac** format, - i.e. things such as `A/B[N]` (which can still be used in input but - are discouraged in **xintexpr** context), but scientific notation - `AeN/B`. As formerly, the denominator is printed only if `B>1` and - the scientific part is dropped if the exponent vanishes. In this way - the output of `\xinteval` can be pasted to alternative software. - - The output format of `\xinthe\xintboolexpr` has changed. It uses - `True` and `False` (which are accepted on input), and this can - easily be configured otherwise (also `true` and `false` are accepted - on input). - + - Macros `\xintGCD`, `\xintLCM`, `\xintGCDof` and `\xintLCMof` formerly + provided by **xintgcd** got moved to **xintfrac** (which is not + loaded by **xintgcd**). Moreover, they were extended to handle + general fractions on input but this also means that their output is + now obiding by the raw **xintfrac** format. The integer only + `\xintiiGCD`, `\xintiiLCM` also got moved out of **xintgcd**, but to + **xint** which is now loaded automatically by **xintgcd**. The few + remaining macros of **xintgcd** at least do not need other imports as + **xintgcd** now loads also automatically **xinttools** which is a + dependency for two of them. + ### Improvements and new features Please note that this list is currently incomplete. For more @@ -2914,7 +2980,7 @@ pdfpagemode=UseNone,% \itshape \xintListWithSep{\,}{#1}\ $\star$\quad }}}% \vskip\dp\strutbox }\strut\@esphack} -\def\retype #1{\@bsphack +\def\xtype #1{\@bsphack \vadjust{\vskip-\dp\strutbox \hbox{\smash{\hbox to 0pt {\hss\color[named]{PineGreen}% \itshape \xintListWithSep{\,}{#1}\ \ding{73}\quad }}}% @@ -2970,6 +3036,14 @@ pdfpagemode=UseNone,% \vtop{\noindent Unstable! #1}\ }}}% \vskip\dp\strutbox }\strut\@esphack} +\def\unstable#1{\@bsphack + \vadjust{\vskip-\dp\strutbox + \hbox{\smash{\hbox to 0pt {\hss\color[named]{Red}% + \normalfont\small\bfseries + \hsize 1.5cm\rightskip.5cm minus.5cm + \vtop{\noindent unstable? #1}\ }}}% + \vskip\dp\strutbox }\strut\@esphack} + \def\DEPRECATED #1{\@bsphack \vadjust{\vskip-\dp\strutbox \hbox{\smash{\hbox to 0pt {\hss\color[named]{PineGreen}% @@ -3205,8 +3279,11 @@ pdfpagemode=UseNone,% \def\everbatimindent {\z@} % voir plus loin atbegindocument -\def\endeverbatim {\if@newlist \leavevmode\fi\endtrivlist } -\expandafter\let\csname endeverbatim*\endcsname \endeverbatim +\def\endeverbatim {\if@newlist \leavevmode\fi\endtrivlist } + +\@namedef{endeverbatim*}{\endeverbatim\aftergroup\everbatimundoparskip} +%\def\everbatimundoparskip{\ifdim\parskip>\z@\vskip-\parskip\fi} +\def\everbatimundoparskip{\vbox{}\kern-\baselineskip\kern-\parskip} \def\s@everbatim {% % \ineverbtrue @@ -3221,7 +3298,9 @@ pdfpagemode=UseNone,% \let\do\do@noligs \verbatim@nolig@list \makestarlowast \everbatimhook - \trivlist\item\relax + \trivlist + \@topsepadd \z@skip + \item\relax \leftskip \@totalleftmargin \rightskip \z@skip \parindent \z@ @@ -3863,16 +3942,54 @@ quality of the document). Reports welcome.% \footnote{Thanks to Jürgen Gilg for keeping the author motivated and helping proof-read the documentation.} -\subsection{The \texttt{1.4a} release of \texttt{2020/02/19}} +\subsection{Features added since the \texttt{1.4} release} -It is mainly a bugfix release. Check |CHANGES.html| file (|texdoc --list -xint|). +For bugfixes and possibly more details check |CHANGES.html|: +\centeredline{|texdoc --list xint|} +\begin{itemize} + \item The function \func{zip}. + + \item The function \func{flat}. + + \item Chaining of \hyperlink{\detokenize{prec-10}}{comparison operators} à la + Python (no short-circuit, though) and |l3fp|. + + \item \csbxint{PFloatE} to specify like \csbxint{FracToSciE} does for + \csbxint{eval} since |1.4| the separator to use between mantissa and + exponent in the output of \csbxint{floateval} output. + + \item \csbxint{thespaceseparated} (serves to provide suitable input + to PS-Tricks |\listplot|). + + \item The optional argument |[D]| to \csbxint{iexpr} (or \csbxint{ieval}) + can be negative, with the same meaning as the non-negative case, i.e. + rounding to an integer multiple of |1e-D| (as formerly, for |D| positive + the output uses fixed point notation with decimal digits and with |D=0| the + output is an integer with no decimal separator; with |D<0| scientific + notation is used% +% +\footnote{This was introduced at |1.4a| but due to a bug the |e| was by error of + catcode 12, and \csbxint{FracToSciE} had no effect on it. Fixed at \texttt{1.4b}}% +% + ). + + \item The same applies to the functions \func{trunc} and \func{round}. And + matching updates to \csbxint{Trunc}, \csbxint{Round}, \csbxint{iTrunc}, + and \csbxint{iRound}. + + \item Support by \func{add} and \func{mul} for \keyword{omit}, \keyword{abort} + and \func{break}.% +% +\footnote{Feature supposedly added at |1.4| but broken there.} + +\end{itemize} \subsection{The \texttt{1.4} release of \texttt{2020/01/31}} -|1.4| was a major release with new features and breaking changes. See -|CHANGES.html| file (|texdoc --list xint|) which may contain information -not yet included in the PDF documentation. +|1.4| brought some new features (involving significant evolution of the +\xintexprname.sty source code) and a few (but important) breaking changes. +See |CHANGES.html| which contains information which may not yet have been +included into this PDF documentation. The main new feature was (initial) support for nested structures. For a quick idea of already available related abilities check for example \func{ndseq} or @@ -3880,15 +3997,38 @@ idea of already available related abilities check for example \func{ndseq} or author a few decades to finish absorbing Python/NumPy. \begin{framed} - The main breaking change is that \xintexprname |1.4| requires the - |\expanded| primitive. It is available with all major \TeX{} engines - since \TeX Live 2019. - - The macro packages \xintcorename, \xintname, - \xintfracname, \xinttoolsname et al. do not (yet) require |\expanded|. - - It is probable also |\pdfstrcmp| (|\strcmp|) will be required at some point - but it has been provided by major \TeX{} engines for a long time already. + The main breaking changes were: + \begin{itemize} + \item \xintexprname |1.4| requires the |\expanded| primitive, which is + provided by all major \TeX{} engines since \TeX Live 2019. The macro + packages \xintname, \xintfracname, \xinttoolsname et al. do not (yet) + require |\expanded|. + + It is probable also |\pdfstrcmp| (|\strcmp|) will be required at some point + but it has been provided by major \TeX{} engines for a long time already. + + \item \csbxint{eval} (and \csbxint{expr}) output does not use anymore the + \xintfracname ``raw'' format |A/B[N]|, rather it uses scientific notation + |AeN/B|, dropping the exponent and/or denominator if they are + respectively \dtt{0} and/or \dtt{1}. This means that output can now be + copied pasted directly to competing software on the market, such as Python + or Maple. The output format of \csbxint{floatexpr} (which uses macro + \csbxint{PFloat}) was left un-modified although the prettifying done by it + is not necessarily the best choice when displaying a nested structure via + \csbxint{thealign} (perhaps next major release will reconsider that + choice); and the way the zero value is output by \csbxint{floateval}, + currently \dtt{\xintfloateval{0}} is yet to be chosen definitely. The + used (\emph{expandable}) macro for output can be specified by user. + + \item Syntax such as |x*[a, b, c]| or |[a, b, c]+x| for itemwise operation + on «lists» has been (provisorily) dropped. Indeed, the brackets |[...]| + are now genuine constructors of nestable structures, and implementing the + feature (analogous to NumPy's concepts) will require overloading all + scalar infix operators. Alternative already exist in the syntax for + example |seq(x*y, y = a,b,c)|. Actually in future |x*[a, b, c]| will be + as |[x*a, x*b, x*c]| i.e.\@ will keep the brackets, which prior to |1.4| + on their own were no different from parentheses. + \end{itemize} \end{framed} \subsection{License and installation instructions} @@ -3901,9 +4041,18 @@ author a few decades to finish absorbing Python/NumPy. is probably no need for a custom install: just use the package manager to update if necessary \xintname to the latest version available. -On \TeX\ distributions with a |"texdoc"| or similar utility, +Else, \href{https://ctan.org/pkg/xint}{CTAN} access provides |xint.tds.zip| +which has all source code and documentation in a TDS-compliant archive, only +waiting to be |unzip -d <DIR>| into some suitable hierarchical structure. + +Else, |etex xint.dtx| extracts all source code. A |Makefile| is also provided +with targets such as |xint.pdf| or |sourcexint.pdf|. Even if your system does +not allow executing |make|, the rules it contains can be imitated manually +(if possible using |Latexmk|). + +Back to \TeX\ distributions with a |"texdoc"| or similar utility, \centeredline{|texdoc --list xint|} -will offer to display one of those files: +gives the choice to display one of: \begin{itemize}[nosep] \item |xint.pdf| (this file), \item |sourcexint.pdf| (source code), @@ -3939,7 +4088,7 @@ The rendering here uses extra decoration. \localtableofcontents -\subsection{Oples and nut-ples: terminology for a new \xintname generation} +\subsection{Oples and nut-ples: terminology for the \text{1.4} \xintname generation} \emph{Skip this on first reading, else you will never start using the package.} \fbox{SKIP THIS!} (understood?) @@ -3972,7 +4121,7 @@ Notes: \item We denote the empty set \dtt{$\emptyset$} by \emph{nil}. There is actually a built-in variable with this name. At |1.4|, |\xintexpr\relax| is -legal\NewWith{1.4} and also generates the \emph{nil}. +legal and also generates the \emph{nil}. \item Concatenation is represented in the syntax by the @@ -4189,21 +4338,24 @@ want to write the underlying software! \subsection{The three parsers} \xintexprname provides three numerical expression parsers and two subsidiary -ones. They are designed to be compatible with expansion only context; in -particular they can be nested arbitrarily one within the other, modifying on -the fly the context for computations (for such things, please use the core -syntax \csbxint{expr}|...\relax| as commented upon later on). - -The user can define variables and functions. Definition of functions is either -per parser (\csbxint{deffunc}, \csbxint{deffloatfunc}, ...), but there are -some restrictions, or generic (\csbxint{NewFunction}) but the latter is only -syntactic sugar for function-like disguise of a \TeX{} macro having not done -any pre-parsing. +ones. They are designed to be compatible with expansion only context. All +computations ultimately rely on (and reduce to) usage of the |\numexpr| +primitive from \eTeX{}% +% +\footnote{It can handle only integers, and they must be at most +$2^{31}-1={}$\dtt{\the\numexpr"7FFFFFFF\relax}. Thus some work has to be done +to handle arbitrarily big integers or arbitrary float precision.}. +% +These \eTeX{} extensions date +back to 1999 and are by default incorporated into the |pdftex| +etc... executables from major modern \TeX{} installations for more than +fifteen years now. \begin{itemize} \item \csbxint{eval}\marg{expression} handles integers, decimal numbers, numbers in scientific notation and fractions. The algebraic computations are - done \emph{exactly.} + done \emph{exactly}, and in particular \oper{/} simply constructs + fractions. Use \oper{//} for floored division. \begin{everbatim*} \xinteval{add(x/(x+1), x = 1000..1014)}\par \end{everbatim*} @@ -4214,20 +4366,54 @@ irreducible, but this is not always the case: smallest terms the output: |A/B| multiplied by |C/D| returns |AC/BD|, and |A/B| added to |C/D| uses |lcm(B, D)| as denominator. \end{snugframed} +Arbitrarily long numbers are allowed in the input. The space character +(contrarily to the situation inside |\numexpr|) and also the underscore +character (as allowed in Python too) can serve to separate groups of digits +for better readability. But the package currently provides no macros to let +the output be formatted with such separators. + +Formatting of numeric output is apart from some minimal facilities such as +\csbxint{Frac}, \csbxint{DecToString}, \csbxint{PRaw}, \csbxint{FracToSci} or \csbxint{PFloat} left +to user macros or third-party packages% +% +\footnote{For example I hesitated whether to let \csbxint{FracToSciE} be + actually a macro with one mandatory argument as this would give a hook to + customize formatting the scientific exponent. But then, why not also wrap + the mantissa or the denominator in hook macros? and should the |/| or the + decimal separator also be customizable? It was reasonable to provide a way + to use |E| in place of |e| for the scientific part, as |E| is accepted input + in \csbxint{eval} or \csbxint{floateval}. + % It is already possible for the no-argument macro \csbxint{FracToSciE} to + % probe the sign of the exponent and for example insert a |+| if desired, + % although there is no way (the exponent having no known delimiter) for it to + % act globally on the exponent. + It looked however better to leave additional + formatting to external utilities.}. +\begin{everbatim*} +\xinteval{123_456_789_012^5} +\end{everbatim*} \item \csbxint{iieval}\marg{expression} does exact computations \emph{on (big) - integers only.} The forward slash \dtt{/} does the \emph{rounded} integer - division to match behaviour of |\numexpr|. + integers only.} It is (of course) slightly faster than \csbxint{eval} for + equivalent operations. The forward slash \oper{/} does the \emph{rounded} + integer division to match behaviour of |\numexpr|. The \oper{//} operator + does floored division as in \csbxint{eval}. The \oper{/:} is the associated + modulo operator (we could easily let the catcode 12 |%| + character be an alias, but using such an unusual percent character would be + a bit cumbersome in a \TeX{} workflow, if only for matters of + syntax highlighting in \TeX-aware text editors). \begin{everbatim*} \xintiieval{add((i/:7)?{omit}{i^5}, i=1000..1020)}% only add fifth powers of multiples of 7 \end{everbatim*} \item \csbxint{floateval}\marg{expression} does floating point computations with a given precision \dtt{P}, as specified via a prior assignment - |\xintDigits:=P\relax |. + |\xintDigits:=P\relax |. The \oper{/} will compute the correct rounding of + the exact fraction. Again \oper{//} is floored division and \oper{/:} its + associated modulo (see also \func{divmod}). \begin{everbatim*} \begingroup -\xintDigits:=64; +\xintDigits:=64\relax \xintfloateval{sqrt(3)} \endgroup \end{everbatim*} @@ -4246,8 +4432,17 @@ irreducible, but this is not always the case: implementation of trigonometrical functions (\xinttrigname) is provisory and does not use guard digits, using |[-2]| will trim the last two, probably wrong, digits. + + On output, \csbxint{floateval} uses \csbxint{PFloat} for each number. This + can be modified (cf.\@ \csbxint{floatexprPrintOne}). \end{itemize} +The user can define variables and functions. Definition of functions is either +per parser (\csbxint{deffunc}, \csbxint{deffloatfunc}, ...), but there are +some restrictions, or generic (\csbxint{NewFunction}) but the latter is only +syntactic sugar for function-like disguise of a \TeX{} macro having not done +any pre-parsing. + Two derived parsers: \begin{itemize} \item \csbxint{ieval}\marg{expression} does all computations like \csbxint{eval} @@ -4257,14 +4452,19 @@ Two derived parsers: \item if |D>0|: the nearest fixed point number with |D| digits after the decimal mark, \item if |D=0|: the nearest integer, - \item if |D<0|: the nearest multiple of |10^(-D)| (i.e. \emph{quantization}, - this case is new with |1.4a|).\NewWith{1.4a} + \item if |D<0|: the\NewWith{1.4a} nearest multiple of |10^(-D)| (this case + is new with |1.4a| and uses scientific notation). \end{itemize} ATTENTION: the optional argument |[D]| is to be located \emph{within} the braces at the start of the expression. \item \csbxint{theboolexpr}\meta{expression}|\relax| does all computations like \csbxint{eval} - but converts the (itemwise) results to |True| or |False|. This - is configurable. There is no |\xintbooleval|. + then converts all (non-empty) leaves% +% +\footnote{Currently, empty leaves are output using \csbxint{exprEmptyItem}, + i.e.\@ default to \dtt{\xintexprEmptyItem}. This may change.} +% +to |True| or |False| + (cf.\@ \csbxint{boolexprPrintOne}). There is no |\xintbooleval|. \end{itemize} These macros are wrappers for a more core syntax: @@ -4275,20 +4475,24 @@ These macros are wrappers for a more core syntax: \item \csbxint{iexpr}\meta{expression}|\relax|, \item \csbxint{boolexpr}\meta{expression}|\relax|. \end{itemize} -This core syntax can be used directly in typesetting flow.\NewWith{1.4} But in an |\edef| -they expand to some braced nested data prefixed with some |\protected| -«typesetter» macros. When using \csbxint{eval} (in contrast to -\csbxint{expr}), the protection of the «typesetter» is removed and the expansion -gives explicit digits and other characters such as those of scientific -notation or brackets. +This core syntax can be used directly in typesetting flow.\NewWith{1.4} In an +|\edef| they expand to some braced nested data (all computations having been +done) prefixed with some |\protected| «typesetter» macros. When using +\csbxint{eval} (in contrast to \csbxint{expr}), the protection of the +«typesetter» is removed and its action gives (expandably, in two steps) +explicit digits and other characters such as those of scientific notation or +brackets. It is possible to use the core syntax\NewWith{1.4} -\csbxint{expr}\marg{expression}|\relax| also in so-called moving arguments, -because when written out to a file they use only standard catcodes and the -output will get retokenized and will expand as expected. +\csbxint{expr}\meta{expression}|\relax| also in so-called moving arguments, +because when written out to a file the final expansion result uses only +standard catcodes and thus will get retokenized and the typesetter macro +(which being |\protected| is there intact in external file) will expand +as expected. -One needs \csbxint{eval} et al. only if one really wants the final characters -of the typeset result. +One needs \csbxint{eval} et al. only if one really wants the final digits (and +other characters), for example in a context where \TeX{} expects a number or a +dimension. As alternative to \csbxint{eval}\marg{expression}, an equivalent is \csbxint{the}\csbxint{expr}\meta{expression}|\relax|. Similarly \csbxint{the} @@ -4345,14 +4549,23 @@ this will break the parser. The fix is to use in the macro definition thinking there is an optional argument and it will then disappear during expansion. - -\subsection{\csh{xintthealign} and output related customizations} +\begin{footnotesize} + If comparing to other languages able to handle floating point numbers or big + integers, such as Python, one should take into account that what the \xintname + packages manipulate are streams of ascii bytes, one per digit. At no time + (due to expandability) is it possible to store intermediate results in an + arithmetic CPU register; each elementary operation via |\the\numexpr| will + output digit tokens (hence as many bytes), not things such as handles to + memory locations where some numbers are stored as memory words. The process + can never put aside things but can only possibly permute them with upcoming + tokens, to use them later, or, via combinations of |\expanded| and + |\unexpanded| or some other more antiquated means grab some tokens and shift + the expansion to some distant locations to later come back. The process is a + never-ending one-dimensional one...\par +\end{footnotesize} + +\subsection{\csh{xintthealign} and its customization} \label{xintthealign} -\label{xintexprEmptyItem} -\label{xintexprPrintOne} -\label{xintiiexprPrintOne} -\label{xintfloatexprPrintOne} -\label{xintboolexprPrintOne} With \csbxint{thealign} one can get nested data use a \TeX{} alignment in the output. Attention, this must be followed by \csbxint{expr} et al., never by @@ -4364,7 +4577,13 @@ Here is an example : It is possible to customize the behaviour of |\xintthealign|.\CHANGED{1.4a} The helper macros, apart from |\xintexpralignbegin| and |\xintexpralignend| -will be subjected to a complete (|\expanded|) expansion (once). The package +will be subjected to a complete (|\expanded|) expansion (once).% +% +\footnote{\csa{xintexpralignend} is expanded once, after the body has been + submitted to exhaustive expansion, and prior to the expansion of + \csa{xintexpralignbegin}.} +% +The package uses here |\protected| with no strong reason, as the replacement tokens are not expanding anyhow, but the idea is that this allows to define a macro in an |\edef| and later change the meaning of the auxiliary macros depending on what @@ -4399,7 +4618,15 @@ Use for example this for outputting to a file or a terminal: \def\xintexpralignrightbracket{]}% \end{everbatim} -And here is an example using a |pmatrix| environment. +\medskip + +And here is an example using a |pmatrix| environment. But it will not break +across pages, contrarily to the display produced by the default +\csbxint{thealign} configuration which uses \TeX{}'s |\halign|. + +%\kern10\baselineskip +%\hbox{Big empty space here} +%\kern-11\baselineskip \begin{everbatim*} \[ \def\xintexpralignbegin {\begin{pmatrix}}% @@ -4414,19 +4641,23 @@ l.c.m.=\xintthealign\xintiiexpr ndmap(lcm, 1..12; 1..10)\relax \] \end{everbatim*} +\subsection{Customization of typesetting of individual items} +\label{xintexprEmptyItem} +\label{xintexprPrintOne} +\label{xintiiexprPrintOne} +\label{xintfloatexprPrintOne} +\label{xintboolexprPrintOne} + The way individual items are formatted (whether or not using -|\xintthealign|) is also customizable: +\csa{xintthealign}) is also customizable:\kern-2pt +% the \kern is to fix some extra white line from first line being a bit overfull \begin{everbatim} \def\xintexprEmptyItem{[]} -% The used macro (here \xintFracToSci) must understand the xintfrac.sty raw format \let\xintexprPrintOne\xintFracToSci \def\xintFracToSciE{e} -% In the integer-only parser, internal format coincides simply with the digit tokens -% Attention this may change in future \def\xintiiexprPrintOne #1{#1} -% The used macro (here \xintPFloat) must understand the xintfrac.sty raw format \def\xintfloatexprPrintOne#1#2{\xintPFloat[#1]{#2}} -% Same here +\def\xintPFloatE{e} \def\xintboolexprPrintOne#1{\xintiiifNotZero{#1}{True}{False}} \end{everbatim} Attention! The above macros convert from \xintexprname internal numeric data @@ -4435,6 +4666,27 @@ if the internal data format changes, which may happen at each release. Of course the default for |\xintexprPrintOne| etc... will be adjusted accordingly, but user custom definitions may break. +Currently, this means that the macros used in place of \csbxint{FracToSci} and +\csbxint{PFloat} must understand both the raw \xintfracname format |A/B[N]| +and the decimal format |A.ddddd..dd|.% +% +\footnote{Furthermore \csbxint{ieval}|{[D]...}| with a \emph{negative} |D| + (feature added at |1.4a|) relies on the \csbxint{exprPrintOne} ability to + react to a catcode 12 |e| (it is always used with detokenized + input). \csbxint{FracToSci} has this ability and uses catcode 11 |e| in + output (or rather whatever \csbxint{FracToSciE} expands to).} +% +The typesetter for +\csa{xintiiexpr} simply prints ``as is'', but this may change in future. + +The used macros must be compatible with expansion-only context, but do not +have to be \fexpan dable. + +Note: when not using \csbxint{thealign}, output of nested structures uses left +and right brackets, and commas and spaces in a non-customizable way, except +via \csa{xintexprEmptyItem}. Use the \csa{xintthealign} interface for full +customizability. + \subsection{Built-in operators and their precedences} @@ -4459,7 +4711,7 @@ user custom definitions may break. \hyperref[ssec:builtinfunctions]{built-in} or \hyperref[ssec:userfunctions]{user-defined} functions, \item \hyperref[ssec:uservariables]{variables}, - \item the \oper{\empty*} unpacking operator, + \item the \oper{\empty\lowast} unpacking operator, \item and intrinsic constituents of numbers: decimal mark \oper{\strut.}, \oper{e} and \oper{E} of scientific notation, hexadecimal prefix \oper{"}. @@ -4469,22 +4721,24 @@ user custom definitions may break. \hline \prec{20}& postfix \oper{!} and branching \oper{?}, \oper{??} operators\strut\\\hline % - \prec{-}& minus sign as unary operator\strut\\\hline + \prec{-}& minus sign as unary operator inherits the precedence of + the infix operator it follows, if that precedence is higher than the one of + binary \oper{+} and \oper{-}, else it inherits the latter\strut\\\hline % - \prec{18}& \oper{\string^} and \oper{**} are a priori synonymous (but see + \prec{18}& \oper{\string^} and \oper{\lowast\lowast} are a priori synonymous (but see \xintlogname)\strut\\\hline % \prec{16}& \hyperref[ssec:tacit multiplication]{Tacit multiplication} has an elevated precedence\strut\\\hline % - \prec{14}& \oper{*}, \oper{/}, \oper{//} (floored division), + \prec{14}& \oper{\lowast}, \oper{/}, \oper{//} (floored division), and \oper{/:} (associated modulo, alias \oper{'mod'})\strut\\\hline % \prec{12}& \oper{+}, \oper{-}\strut\\\hline % \prec{10}& \oper{<}, \oper{>}, \oper{==}, \oper{<=}, \oper{>=}, - \oper{!=}\strut\\\hline + \oper{!=} (they can be chained)\strut\\\hline % \prec{8}& Boolean conjunction \oper{\Ampersand\Ampersand} and its alias \oper{'and'}\strut\\\hline @@ -4523,7 +4777,7 @@ when using variables. \end{tabular} \caption{Precedence levels} \label{tab:precedences} -\etoctoccontentsline {table}{\textbf{(table)} \protect\emph{Precedence levels of operators}} +\etoctoccontentsline {table}{\protect\emph{Table of precedence levels of operators}} \restorehtdpstrutbox \end{table} @@ -4531,6 +4785,7 @@ The entries of \autoref{tab:precedences} are hyperlinked to the more detailed discussion at each level. \begin{description} +%[parsep=0pt, listparindent=\leftmarginiii] % [parsep=0pt,align=left,itemindent=0pt, % leftmargin=\leftmarginii, labelwidth=\leftmarginii, labelsep=0pt, % labelindent=0pt, listparindent=\leftmarginiii] @@ -4541,12 +4796,12 @@ discussion at each level. \item[{\hyperref[ssec:builtinfunctions]{functions} and \hyperref[ssec:uservariables]{variables}}] Functions (even the logic functions - \func{!} and \func{?} whose names consists of a single non-letter character) + \func{!} and \func{?} whose names consist of a single non-letter character) must be used with parentheses. These parentheses may arise from expansion after the function name is parsed (there are exceptions which are documented at the relevant locations.) - \operdesc{\empty*} Python-like «unpacking» prefix operator. Sometimes one + \operdesc{\empty\lowast} Python-like «unpacking» prefix operator. Sometimes one needs to use it as function |*()| (but I can't find an example right now) but most of the time parentheses are unneeded. @@ -4624,18 +4879,25 @@ discussion at each level. % % \end{description} -\precdesc{-} As prefix unary operator it inherits the precedence of - the infix operator it follows. +\precdesc{-} As unary operator, the minus sign inherits the precedence of + the infix operator it follows (plus signs as unary operators are simply ignored). \begin{everbatim*} \xintexpr -3-4*-5^-7, (-3)-(4*(-(5^(-7))))\relax\newline -\xintexpr -3^-4*-5-7, (-((3^(-4))*(-5)))-7\relax\par -\end{everbatim*} - |2^-10| is perfectly accepted input, no need for parentheses. +\xintexpr -3^-4*-5-7, (-((3^(-4))*(-5)))-7\relax\newline +|2^-10| gives \xintexpr 2^-10\relax\space +\end{everbatim*}and is thus perfectly legal, no need for parentheses. + + Note (|1.4b|): the above is what this documentation has always said, but it + has also always been only partially true. I.e.\@ it applies only when |-| + follows an infix binary operator having at least the precedence level of |+| + and |-|. When the unary |-| follows an infix operator (or operator word) of + less precedence, its precedence will be set to the one for the infix + operators |+| and |-|. «Seul |sourcexint.pdf| fait foi». \precdesc{18} \begin{description} \operdesc{\string^} -\operdesc{**} Both compute powers in left associative way. +\operdesc{\lowast\lowast} Both compute powers in left associative way. \begin{everbatim*} \xintiiexpr 2^2^3\relax \end{everbatim*} @@ -4651,7 +4913,7 @@ discussion at each level. \precdesc{14} \begin{description} -\operdesc{*} multiplication +\operdesc{\lowast} multiplication \operdesc{/} division: exact in \csbxint{eval}, correctly rounded in \csbxint{floateval} (numerator and denominator are rounded before the division is done), and rounded to an integer (like |\numexpr| does: @@ -4671,7 +4933,10 @@ discussion at each level. \xintexpr 100000/:13/13\relax \end{everbatim*} -\operdesc{'mod'} is same as \oper{/:} +\operdesc{'mod'} is same as \oper{/:}. + +Note: The enclosing (right) ticks are +mandatory part of all such infix operator «words». \end{description} @@ -4687,7 +4952,7 @@ case of equal precedence, it is \end{everbatim*} \end{description} -\precdesc{10} Comparison operators are currently all at the same level of +\precdesc{10} Comparison operators are (as in Python) all at the same level of precedence, use parentheses for disambiguation. \begin{description} \operdesc{<} |a<b| evaluates to \dtt{1} if the strict inequality holds to \dtt{0} @@ -4711,6 +4976,18 @@ precedence, use parentheses for disambiguation. if not. \end{description} + Comparisons\NewWith{1.4b} can be chained arbitrarily, e.g., |x < y <= z != + t| is equivalent to |x < y 'and' y <= z 'and' z != t| (and also to |all(x<y, + y<=z, z!=t)|), except that if |y| and |z| involve computations, they + are evaluated only once. Currently there is no short-circuit here, i.e.\@ + even if some intermediate comparison turns out false (in fact |0|), all the + remaining conditionals will still be evaluated. + +\begin{everbatim*} +\xintifboolexpr{1<=2!=3<4>1}{true}{\error}, \xintifboolexpr{1<=2>=3<4>1}{\error}{false} +\end{everbatim*} + + \precdesc{8} \begin{description} \operdesc{\Ampersand\Ampersand} logical conjunction. Evaluates to \dtt{1} if @@ -4792,10 +5069,7 @@ precedence, use parentheses for disambiguation. \operdesc{;} The semi-colon as involved as part of the syntax of \func{iter}, \func{rseq}, \func{ndseq}, \func{ndmap} has the same - precedence as a closing parenthesis. It also serves as syntax terminator for - \csbxint{defvar} and \csbxint{deffunc}. Inner semi-colons do not need to be - braced to avoid being mistaken for the terminator (but they may be which - speeds up by micro-second the parsing). + precedence as a closing parenthesis. \end{description} \item[|\relax|] This is the expression terminator for \csbxint{expr} et al. @@ -4804,6 +5078,11 @@ precedence, use parentheses for disambiguation. argument. \end{description} +The |;| also serves as syntax terminator for \csbxint{defvar} and +\csbxint{deffunc}. It can in this rôle not arise from expansion as the +expression body up to it is fetched by a delimited macro. But this is done in +a way which does not require any specific hiding for inner semi-colons as +involved in the syntax of \func{iter}, etc... \subsection{Built-in functions}\label{ssec:builtinfunctions} @@ -4819,13 +5098,13 @@ corresponding definitions. \begin{table}[htbp] \capstart \centering -\xintAssignArray\xintCSVtoList{!, ?, |`*`|, |`+`|, +\xintAssignArray\xintCSVtoList{!, ?, \textasciigrave\lowast\textasciigrave, \textasciigrave+\textasciigrave, 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, float\string_, floor, frac, gcd, +factorial, first, flat, float, float\string_, floor, frac, gcd, if, ifint, ifone, ifsgn, ilog10, isint, isone, iter, iterr, inv, last, lcm, len, log, log10, max, min, mod, mul, ndmap, ndseq, ndfillraw, @@ -4836,7 +5115,7 @@ random, randrange, rbit, reduce, rem, reversed, round, rrseq, rseq, sec, secd, seq, sgn, sin, sinc, sind, sqr, sqrt, sqrtr, subs, subsm, subsn, tan, tand, tg, togl, trunc, unpack, -xor} +xor, zip} \to\Functions \cnta\Functions{0} \cntb\xinttheexpr ceil(\cnta/7)\relax\space @@ -4857,7 +5136,7 @@ xor} \\\hline}% \end{tabular}} \caption{Functions (click on names)}\label{tab:functions} -\etoctoccontentsline {table}{\textbf{(table)} \protect\emph{Functions in expressions}} +\etoctoccontentsline {table}{\protect\emph{Table of functions in expressions}} \etocsetnexttocdepth{subsubsection} \localtableofcontents \end{table} @@ -4866,13 +5145,13 @@ xor} Miscellaneous notes: \begin{itemize}[nosep] \item since release |1.3d| \func{gcd} and \func{lcm} are extended to apply - to fractions too, and they do NOT require the loading of \xintgcdname, + to fractions too, and do NOT require the loading of \xintgcdname, \item The randomness related functions \func{random}, \func{qrand} and \func{randrange} require that the \TeX\ engine provides the \csa{uniformdeviate} or \csa{pdfuniformdeviate} primitive. This is - currently the case for |pdftex|, |(u)ptex|, |luatex|, and will be for - |xetex| starting with \TeX Live 2019.\IMPORTANT + currently the case for |pdftex|, |(u)ptex|, |luatex|, and also for + |xetex| since \TeX Live 2019.\IMPORTANT \item \func{togl} is provided for the case |etoolbox| package is loaded, @@ -4884,16 +5163,9 @@ Miscellaneous notes: \item Also \hyperlink{ssec:dummies}{functions with dummy variables} use delimited macros for some tasks. See the relevant explanations there. - \item A more prominent distinction should be made between built-in \emph{regular} and - \emph{pseudo} functions. But this documentation needs to be revamped at - a later time. - - \item Functions may be called with \emph{oples} as arguments as long as + \item Functions may be called with \emph{oples} as arguments as long as the total length is the number of arguments the function expects. - - \item Some descriptions may be obsolete to various degree due to changes - at 1.4. -\end{itemize} + \end{itemize} \subsubsection{Functions with no argument} @@ -5020,7 +5292,7 @@ Recall that this is NOT done automatically, for example when adding fractions. 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 + post-fix \oper{!} operator.) When used in |\xintexpr| or |\xintfloatexpr| there is an optional second argument. See \func{factorial}. \funcdesc{?} is the truth value, $1$ if non zero, $0$ if zero. Must use parentheses. \funcdesc{!} is logical not, $0$ if non zero, $1$ if zero. Must use parentheses. @@ -5130,8 +5402,22 @@ $\xintthefloatexpr subs(((x-1)/x, x/x, (x+1)/x), x=2**30)\relax \funcdesc{unpack} is alternative for |*| unpacking operator.\NewWith{1.4} \begin{everbatim*} -\xinteval{unpack(nuple(1,2,3))} +\xinteval{unpack([1,2,3])} +\end{everbatim*} + + \funcdesc[ople]{flat} removes\NewWith{1.4b} all nesting to produce a + (non-bracketed) ople having the same leaves (some possibly empty) but + located at depth 1. +\begin{everbatim*} +\xinteval{flat([[[[1,[],3],[4,[[[5,6,[]],[8,9],[[],11]],12],[13,14]]], [[],16]]], [])} \end{everbatim*} + + I almost\unstable{} delayed indefinitely release because I was hesitating + on the name: perhaps better with |flattened()|, but long names add + (negligible, but still) overhead compared to short names. For this reason, + consider that name may change. + + \end{description} \subsubsection{Functions with an alphanumeric argument} @@ -5248,8 +5534,8 @@ $\xintthefloatexpr subs(((x-1)/x, x/x, (x+1)/x), x=2**30)\relax \csbxint{floateval}, not \csbxint{eval}, the first argument (here |2^30/3^5|) would already have been computed as floating point number with numerator and denominator rounded separately first to the prevailing - precision. To avoid that, use |\xintexpr2^9/3^5\relax| wrapper. - Then the rounding or truncation will be applied to the exact fraction. + precision. To avoid that, use |\xintexpr...\relax| wrapper. + Then the rounding or truncation will be applied to an exact fraction. \funcdesc[{x[, n]}]{sfloat} It is the same as \func{float}, but in case of a short (non-fractional) input it gets stored internally @@ -5355,7 +5641,7 @@ $\xintthefloatexpr subs(((x-1)/x, x/x, (x+1)/x), x=2**30)\relax Prior to |1.2p| it computed |f - g*trunc(f/g)|. - The |/:| and |'mod'| infix operators are both mapped to the same underlying + The \oper{/:} and \oper{'mod'} infix operators are both mapped to the same underlying macro as this |mod(f, g)| function. At |1.3| this macro produces smaller denominators when handling fractions than formerly. \begin{everbatim*} @@ -5497,7 +5783,7 @@ explicit |\xinteval| wrapping. checks if |cond| is true or false and takes the corresponding branch. Any non zero number or fraction is logical true. The zero value is logical false. Both ``branches'' are evaluated (they are - not really branches but just numbers). See also the |?| operator. + not really branches but just numbers). See also the \oper{?} operator. \funcdesc[x,yes,no]{ifint} (twofold-way conditional)\mbox{} @@ -5514,20 +5800,23 @@ explicit |\xinteval| wrapping. \funcdesc[cond,<0,=0,>0]{ifsgn} (threefold-way conditional)\mbox{} checks the sign of |cond| and - proceeds correspondingly. All three are evaluated. See also the |??| + proceeds correspondingly. All three are evaluated. See also the \oper{??} operator. \end{description} \subsubsection{Functions with an arbitrary number of arguments} -At |1.4| functions |all()|, |any()|, |xor()|, |`+`|, |`*`|, |max()|, |min()|, -|gcd()|, |lcm()|, |first()|, |last()|, |reversed()| and |len()| admit: +At |1.4| \func{all}, \func{any}, \func{xor}, +\func{\textasciigrave+\textasciigrave}, +\func{\textasciigrave\lowast\textasciigrave}, +\func{max}, \func{min}, \func{gcd}, \func{lcm}, \func{first}, \func{last}, +\func{reversed} and \func{len} admit: \begin{itemize} \item at least two arguments, and then operate as expected in backward compatible way, \item or only one argument,\IMPORTANT{} which then \emph{must} be a |nut-ple|, i.e. a - variable or explicit bracketed list. In the case of |reversed()| the output + variable or explicit bracketed list. In the case of \func{reversed} the output is a |nut-ple| if the input was one. \end{itemize} Notice that this is breaking change as the functions do not work anymore with @@ -5563,12 +5852,12 @@ the resulting logical assertion, \xinteval{xor(1,1,1), xor([1,0,1]), xor([1,1,1])} \end{everbatim*} -\funcdesc[x, y, ...]{|`+`|} adds (left ticks mandatory): +\funcdesc[x, y, ...]{\textasciigrave+\textasciigrave} adds (left ticks mandatory): \begin{everbatim*} \xinttheexpr `+`(1,3,19), `+`(1**2,3**2,sqr(19)), `+`([1**2,3**2,sqr(19)])\relax \end{everbatim*} -\funcdesc[x, y, ...]{|`*`|} multiplies (left ticks mandatory): +\funcdesc[x, y, ...]{\textasciigrave\lowast\textasciigrave} multiplies (left ticks mandatory): \begin{everbatim*} \xinttheexpr `*`(1,3,19), `*`(1^2,3^2,19^2), `*`([1^2,3^2,19^2])\relax \end{everbatim*} @@ -5635,6 +5924,33 @@ the case here. \begin{everbatim*} \xinttheiiexpr len(1..50, [101..150], 1001..1050), len([1..10])\relax \end{everbatim*} + + \funcdesc[\lowast nutples]{zip} behaves\NewWith{1.4b} similarly to + the Python function of the same name: i.e. it produces \emph{an ople of nut-ples, + where the i-th nut-ple contains the i-th element from each of the argument + nut-ples. The ople ends when the shortest input nut-ple is exhausted. + With a single nut-ple argument, it returns an ople of 1-nutples. + With no arguments, it returns the empty ople.} + + As there is no exact match in \xintexprname of the concept of «iterator» object,% +% +\footnote{% +Speaking of iterators, I have some ideas about this: as \csbxint{expr} does not +have the global expression in its hands it is difficult to organize globally +expandably the idea of iterator, but locally via syntax like the one for +\func{seq} this is feasible. When one thinks about it, \func{seq} is closely related +to the iterator idea.} +% + there is a significant difference here that (for example) the |zip(x,x,x)| + Python idiom to cluster the iterator |x| into successive chunks of length 3 + does not apply. Consider for this reason even the name of the function as + work-in-progress, susceptible to change.\unstable{} +\begin{everbatim*} +\xintiieval{zip([1..9], [0, 1, 2], [11..29], [111..139])} +\end{everbatim*} + + See also \csbxint{thespaceseparated} for some possible usage in combination with \func{flat}. + \end{description} \subsubsection{Functions requiring dummy variables} @@ -5646,47 +5962,51 @@ The pseudo-functions \xintFor #1 in {subs, seq, subsm, subsn, iter, add, mul, \begin{itemize} \item for all of them, whenever a |<varname>=| chunk must be parsed into a (non-assigned) variable name, then the equal sign must be visible, -\item and if the syntax is with «|,<varname>=|» the initial comma also must be +\item and if the syntax is with |,<varname>=| the initial comma also must be visible (spaces do not matter), \item for all of them but \func{ndmap} and \func{ndfillraw} the final closing parenthesis must be visible. \end{itemize} -Although delimited macros involving commas are used to locate «|,<varname=|» -this is done in a way which will ignore commas located inside correctly -balanced parentheses. And the semi-colons involved in the syntax can -always arise from expansion alone. For \func{rseq}, \func{iter}, \func{rrseq} -and \func{iterr} the |,<varname>=| part may also be created from the expansion -which will generate the initial comma separated values delimited by a -semi-colon. +Although delimited macros involving commas are used to locate |,<varname=| +this is done in a way silently ignoring commas located inside correctly +balanced parentheses. Thus, as the examples will show, nesting works as +expected. + +The semi-colons involved in the syntax may arise from expansion alone. For +\func{rseq}, \func{iter}, \func{rrseq} and \func{iterr} the |,<varname>=| part +may also be created from the expansion which will generate the initial comma +separated values delimited by a semi-colon. Prior to |1.4|, semi-colons needed to be braced or otherwise hidden when -located in an expression parsed by \csbxint{defvar} or \csbxint{deffunc},\NewWith{1.4} to -not be confused with the expression terminator. This is not needed anymore. +located in an expression parsed by \csbxint{defvar} or +\csbxint{deffunc}, to not be confused with the expression +terminator. +This is not needed anymore.\NewWith{1.4} \func{seq}, \func{rseq}, \func{iter}, \func{rrseq}, \func{iterr} and also \func{add}, \func{mul}, but not \func{subs} admit the -\keyword{omit}, \keyword{abort}, and \keyword{break}|()| keywords. This is a -new feature for \func{add} and \func{mul}. +\keyword{omit}, \keyword{abort}, and \func{break} keywords. This is a +new feature at |1.4| for \func{add} and \func{mul}. In the case of a potentially infinite list generated by the |<integer>++| syntax, use of -\keyword{abort} or of \keyword{break}|()| is mandatory, naturally. +\keyword{abort} or of \func{break} is mandatory, naturally. All lowercase and uppercase Latin letters are pre-configured for usage as dummy variables. In Unicode engines one can use \csbxint{newdummy} to turn any letter into a usable dummy variable. -Since |1.4|,\NewWith{1.4} \csbxint{newdummy} works (in all engines) to turn a multi-letter -word into a dummy variable. +And since |1.4|,\NewWith{1.4} \csbxint{newdummy} works (in all engines) to +turn a multi-letter word into a dummy variable. In the descriptions, +|varname| stands for such a dummy variable, either single-letter or word. \begin{description} % [parsep=0pt,align=left, % leftmargin=0pt, itemindent=0pt, % labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt, % listparindent=\leftmarginiii] - -\funcdesc[expr, letter=values]{subs} for variable substitution +\funcdesc[expr, varname=values]{subs} for variable substitution. \begin{everbatim*} \xinttheexpr subs(subs(seq(x*z,x=1..10),z=y^2),y=10)\relax\newline \end{everbatim*}% @@ -5704,55 +6024,58 @@ One should rather define auxiliary functions to compute intermediate results. Or one can use \func{seq}. See the documentation of \csbxint{deffunc}. -\funcdesc[expr, letter=values]{add} addition +\funcdesc[expr, varname=values]{add} addition \begin{everbatim*} \xintiiexpr add(x^3,x=1..20), add(x(x+1), x=1,3,19)\relax\newline +\xintiiexpr add(x^3, x = 1..[2]..20)\relax\newline % add only odd cubes \xintiiexpr add((odd(x))?{x^3}{omit}, x = 1..20)\relax\par % add only odd cubes \end{everbatim*} -\noindent At |1.4|,\NewWith {1.4a} the keywords \keyword{omit}, \keyword{abort} and -\keyword{break}|()| are allowed. But this was broken and got fixed at |1.4a|. -The |@| special variable holds the so-far accumulated value. Initially its -value is zero. +At |1.4| (fixed at |1.4a|),\NewWith {1.4a} the keywords \keyword{omit} (as in +example above), \keyword{abort} and \func{break} are allowed. +The meaning of \func{break} is specific: its argument serves as last +operand for the addition, not as ultimate value. \begin{everbatim*} -\xintiiexpr add(1 + @, i=1..10)\relax % iterates x <- 2x+1 +\xintiiexpr add((x>10)?{break(1000)}{x}, x = 1..15)\relax \end{everbatim*} -The meaning of \keyword{break}|()| is specific: its argument serves as last -operand for the addition, not as ultimate value. +The |@| special variable holds the so-far accumulated value. Initially its +value is zero. \begin{everbatim*} -\xintiiexpr add((x>10)?{break(1000)}{x}, x = 1..15)\relax +\xintiiexpr add(1 + @, i=1..10)\relax % iterates x <- 2x+1 \end{everbatim*} -See |`+`| for syntax without a dummy variable. +See \func{\textasciigrave+\textasciigrave} for syntax simply adding items of a +list without usage of a dummy variable. -\funcdesc[expr, letter=values]{mul} multiplication +\funcdesc[expr, varname=values]{mul} multiplication \begin{everbatim*} -\xintiiexpr mul(x^2, x=1,3,19), mul(2n+1,n=1..10)\relax +\xintiiexpr mul(x^2, x = 1, 3, 19, 37..50)\relax \end{everbatim*} -\noindent At |1.4|,\NewWith {1.4a} the keywords \keyword{omit}, \keyword{abort} and -\keyword{break}|()| are allowed. But this was broken and got fixed at |1.4a|. The |@| special variable holds the so-far accumulated value. Initially its value is one. -The meaning of \keyword{break}|()| is specific: its argument serves as last -operand for the multiplication, not as ultimate value. +At |1.4| (fixed at |1.4a|),\NewWith {1.4a} the keywords \keyword{omit}, +\keyword{abort} and \func{break} are allowed. The meaning of \func{break} is +specific: its argument serves as last operand for the multiplication, not as +ultimate value. \begin{everbatim*} \xintiieval{mul((i==100)?{break(i^4)}{i}, i = 98, 99, 100)} \end{everbatim*} -See |`*`| for syntax without a dummy variable. +See \func{\textasciigrave\lowast\textasciigrave} for syntax without a dummy variable. -\funcdesc[expr, letter=values]{seq} comma separated values generated according to a formula +\funcdesc[expr, varname=values]{seq} comma separated values generated according to a formula \begin{everbatim*} -\xinttheiiexpr seq(x(x+1)(x+2)(x+3),x=1..10), `*`(seq(3x+2,x=1..10))\relax +\xintiiexpr seq(x(x+1)(x+2)(x+3),x=1..10), `*`(seq(3x+2,x=1..10))\relax \end{everbatim*} \begin{everbatim*} -\xinttheiiexpr seq(seq(i^2+j^2, i=0..j), j=0..10)\relax +\smallskip +\leavevmode\vbox{\xintthealign\xintiiexpr [seq([seq(i^2+j^2, i=0..j)], j=0..10)]\relax} \end{everbatim*} -\funcdesc[initial value; expr, letter=values]{rseq} recursive sequence, |@| for the previous value. +\funcdesc[initial value; expr, varname=values]{rseq} recursive sequence, |@| for the previous value. \begin{everbatim*} \printnumber {\xintthefloatexpr subs(rseq (1; @/2+y/2@, i=1..10),y=1000)\relax }\newline \end{everbatim*}% @@ -5765,22 +6088,25 @@ iteration to the whole list. Use parentheses at each iteration to maintain this ``nuple''. For example: \begin{everbatim*} \printnumber{\xintthefloatexpr rseq(1,10^6; - (sqrt([@][0]*[@][1]),([@][0]+[@][1])/2), i=1..7)\relax } + (sqrt(@[0]*@[1]),(@[0]+@[1])/2), i=1..7)\relax } \end{everbatim*} -\funcdesc[initial value; expr, letter=values]{iter} is exactly like |rseq|, except that it only prints - the last iteration. Strangely it was lacking from |1.1| release, or rather - what was available from |1.1| to |1.2f| is what is called now \func{iterr} - (described below). +Prior to |1.4| the above example had to be written with |[@]|. This is still +possible (|@| stands for an ople with two items, bracketing then extracting is +like extracting directly), but it is leaner to drop the extra «packing». + +\funcdesc[initial value; expr, varname=values]{iter} is exactly like |rseq|, except that it only prints + the last iteration. + \hypertarget{BrentSalamin}{} - The new |iter()| is convenient to handle compactly higher order iterations. + |iter()| is convenient to handle compactly higher order iterations. We can illustrate its use with an expandable (!) implementation of the Brent-Salamin algorithm for the computation of $\pi$: \begin{everbatim*} \xintDigits:= 87\relax % Below 83 is 87-3-1 (3 guard digits, target 84=1+83 digits) and 43 is 84/2+1. -\xintdeffloatefunc BS(a, b, t, p):= 0.5*(a+b), sqrt(a*b), t-p*sqr(a-b), \xintiiexpr 2p\relax; +\xintdeffloatfunc BS(a, b, t, p):= 0.5*(a+b), sqrt(a*b), t-p*sqr(a-b), \xintiiexpr 2p\relax; \xinteval {trunc(% I feel truncation is better than rounding to display decimals of π \xintfloatexpr @@ -5806,7 +6132,7 @@ this ``nuple''. For example: Prior to |1.4| the above example had to use notation such as |[@][0]|; this would still work but |@[0]| is leaner. -\funcdesc[initial values; expr, letter=values]{rrseq} recursive sequence with multiple initial terms. Say, there are +\funcdesc[initial values; expr, varname=values]{rrseq} recursive sequence with multiple initial terms. Say, there are |K| of them. Then |@1|, ..., |@4| and then |@@(n)| up to |n=K| refer to the last |K| values. Notice the difference with |rseq()| for which |@| refers to a list of items in case the initial value is a list and not a single item.% @@ -5838,45 +6164,58 @@ this ``nuple''. For example: I implemented an |Rseq| which at all times keeps the memory of \emph{all} previous items, but decided to drop it as the package was becoming big. -\funcdesc[initial values; expr, letter=values]{iterr} same as |rrseq| but does not print any value until the last |K|. +\funcdesc[initial values; expr, varname=values]{iterr} same as |rrseq| but does not print any value until the last |K|. \begin{everbatim*} \xinttheiiexpr iterr(0,1; @1+@2, i=2..5, 6..10)\relax % the iterated over list is allowed to have disjoint defining parts. \end{everbatim*} -\funcdesc[expr, var1=value1; var2=value2; ....; varN=valueN]{subsm} -Simultaneous substitutions. The assigned values must not involve the +\funcdesc[expr, var1=value1; var2=value2; ....; varN=valueN{[;]}]{subsm} +Simultaneous\NewWith{1.4} +substitutions. The assigned values must not involve the variables. An optional final -semi-colon is allowed.\NewWith{1.4} +semi-colon is allowed. \begin{everbatim*} \xintiieval{subsm(x+2y+3z+4t, x=1; y=10; z=100; t=1000;)} \end{everbatim*} -\funcdesc[expr, var1=value1; var2=value2; ....; varN=valueN]{subsn} -Simultaneous substitutions. The assigned values may involve all variables +\funcdesc[expr, var1=value1; var2=value2; ....; varN=valueN{[;]}]{subsn} +Simultaneous\NewWith{1.4} +substitutions. The assigned values may involve all variables located further to its right. An optional final semi-colon is allowed. -\NewWith{1.4} \begin{everbatim*} \xintiieval{subsn(x+y+z+t, x=20y; y=20z; z=20t; t=1)} \end{everbatim*} -\funcdesc[function, values1; values2; ....; valuesN]{ndmap} Construction of an -|ndlist| with |N| dimensions from function values. The function must be an -|N|-variable function. Its value may be scalar... or not. An optional final -semi-colon is allowed. \NewWith{1.4} +\funcdesc[function, values1; values2; ....; valuesN{[;]}]{ndmap} +% +Construction\NewWith{1.4} of a nested list (a priori having |N| dimensions) from function +values. The function must be an |N|-variable function (or a function accepting +arbitrarily many arguments), but it is not constrained to produce only scalar +values. Only in the latter case is the output really an |N|-dimensional +«|ndlist|» type object. An optional final semi-colon in the input before the +closing parenthesis is +allowed. \begin{everbatim*} \xintdeffunc foo(a,b,c,d) = a+b+c+d; +\begin{multicols}{2} \xintthealign\xintexpr ndmap(foo, 1000,2000,3000; 100,200,300; 10,20,30; 1,2,3)\relax +\end{multicols} \end{everbatim*} -\funcdesc[function, var1=values1; var2=values2; ....; varN = valuesN]{ndseq} -Construction of an |ndlist| with |N| dimensions from simultaneous substitutions in an expression -in |N| variables. Its value may be scalar... or not. An optional final -semi-colon is allowed. -\NewWith{1.4} +\funcdesc[expr, var1=values1; var2=values2; ....; varN = valuesN{[;]}]{ndseq} +% +Constructs\NewWith{1.4} a nested list (a priori having |N| dimensions) from +substitutions in an expression involving |N| (dummy) variables. The +expression is not constrained to produce only scalar values. Only in the +latter case is the output really an |N|-dimensional «|ndlist|» type object. +An optional final semi-colon in the input before the closing parenthesis is +allowed. \begin{everbatim*} +\begin{multicols}{2} \xintthealign\xintexpr ndseq(a+b+c+d, a=1000,2000,3000; b=100,200,300; c=10,20,30; d=1,2,3;)\relax +\end{multicols}% in case of page break, this makes amusing zigzag rendering \end{everbatim*} \end{description} @@ -5892,10 +6231,10 @@ The following keywords are recognized: \keyworddesc{omit} it is a pseudo-variable which says to omit this value and go to next one. - \keyworddesc{break} it is a function |break(stuff)| which says to abort and have |stuff| as last value. + \funcdesc[stuff]{break} says to abort and insert |stuff| as last value. \keyworddesc{<integer>++} serves to generate a potentially infinite list. In - conjunction with an \keyword{abort} or \keyword{break}|()| this is often + conjunction with an \keyword{abort} or \func{break} this is often more efficient than iterating over a pre-established list of values. \begin{everbatim*} \xinttheiiexpr iter(1;(@>10^40)?{break(@)}{2@},i=1++)\relax @@ -5920,18 +6259,6 @@ if one also wants the previous Fibonacci number one only has to use |break(@2, \end{description} -All operations executed by the parsers are based on underlying macros from -packages \xintfracname and \xintname which are loaded automatically by -\xintexprname. With \xintbinhexname loaded the -parsers can handle hexadecimal notation on (even fractional) input. - -All macros doing computations ultimately rely on (and reduce to) the -|\numexpr| primitive from \eTeX{}. These \eTeX{} extensions date back to 1999 -and are by default incorporated into the |pdftex| etc... executables from -major modern \TeX{} installations since more than ten years now. - - - \subsection{Generators of arithmetic progressions} \label{ssec:arithseq} @@ -5987,7 +6314,7 @@ major modern \TeX{} installations since more than ten years now. \dtt{6} digits mantissas (in this example). \end{itemize} -\subsection{Python slicing and indexing of one-dimensional sequences} +\subsection{Python slicing and indexing of one-di\-men\-sional sequences} \label{ssec:lists} There are some breaking changes in the syntax at |1.4|,\CHANGED{1.4} because previously @@ -6188,129 +6515,144 @@ which is not at all the presumably hoped for: \label{xintdeffloatvar} Since release |1.1| it is possible to make an assignment to a variable name -and let it be known to the parsers of \xintexprname. -\begin{everbatim*} -% definitions -\xintdefvar Pi:=3.141592653589793238462643;% -\xintdefvar x_1 := 10;\xintdefvar x_2 := 20;\xintdefvar y@3 := 30;% -\xintdefiivar List := seq(x(x+1)/2, x=0..10);% -% usage -$x_1\cdot x_2\cdot y@3+1=\xinttheiiexpr x_1*x_2*y@3+1\relax$\newline -$\pi^{100}\approx\xintthefloatexpr Pi^100\relax$\newline -\xinttheiiexpr List\relax\ contains \xinttheiiexpr [List][7]\relax.\par -\end{everbatim*} - -For catcodes issues (particularly, for the semi-colon used to delimit the -fetched expression), see the discussion of \csbxint{exprSafeCatcodes}. -\begin{framed} - Both syntaxes |\xintdefvar foo := <expr>;| and |\xintdefvar foo = <expr>;| - are accepted. -\end{framed} -Spaces in the variable name or around the equal sign are removed and are -immaterial. +and let it be known to the parsers of \xintexprname. Since |1.2p| simultaneous +assignments are possible. +\begin{everbatim*} +\xintdefvar myPi:=3.141592653589793238462643;% +\xintdefvar x_1, x_2, x_3 := 10, 20, 30;% +\xintdefiivar List := seq(x(x+1)/2, x=0..10);% seq produces an «open» list +\xintdefiivar Nuple := ndmap(sqr, List);% ndmap produces a «bracketed» list +\xintdefiivar FourthPowers := ndmap(sqr, *Nuple);% "unpacking" is needed here. +$x_1 = \xinteval{x_1}, x_2 = \xinteval{x_2}, x_3 = \xinteval{x_3}$\newline +$\pi^{100}\approx\xintfloateval{myPi^100}$ is evaluated \fbox{after} having rounded myPi +to the prevailing float precision (which here is the default \xinttheDigits)\newline +$\xintDigits:=20\relax \pi^{100}\approx\xintfloateval{myPi^100}$ (this one first +rounded the variable to 20 digits before evaluating its 100th power)\newline +Open List: \xintiieval{List}\newline +Nuple: \xintiieval{Nuple}\newline +FourthPowers: \xintiieval{FourthPowers}\par +\end{everbatim*} + +By the way \xinttrigname defines indeed a variable |Pi|, but its value can be +modified at user level, with no impact whatsoever on the trigonometrical +functions. -As shown above a variable can be assigned a "list" value. -Simultaneous assignments are allowed: +Here is another example with simultaneous assignments: \begin{everbatim*} -\xintdefvar x1, x2, x3 := 3, 10^2, -1;% \xintdefiivar A, B := 1500, 135;% \xintloop \xintifboolexpr{B} {\xintdefiivar A, B := B, A 'mod' B;\iftrue} {\iffalse} \repeat -The last non zero remainder is \xinttheiiexpr A\relax. +The last non zero remainder is \xintiiexpr A\relax. \end{everbatim*} Note1: simultaneous assignments are more costly in terms of memory impact. -Note2:\NewWith{1.4} in case of simultaneous assignments, the right hand side will be -automatically unpacked if necessary. +Note2:\NewWith{1.4} in case of simultaneous assignments, the right hand side +will be automatically unpacked if necessary. + +For catcodes issues (particularly, for the semi-colon used to delimit the +fetched expression), see the discussion of \csbxint{exprSafeCatcodes}. +\begin{framed} + Both syntaxes |\xintdefvar foo := <expr>;| and |\xintdefvar foo = <expr>;| + are accepted. +\end{framed} +Spaces in the variable name or around the equal sign are removed and are +immaterial. The variable names are expanded in an |\edef| (and stripped of spaces). Example: \begin{everbatim} \xintdefvar x\xintListWithSep{, x}{\xintSeq{0}{10}} := seq(2**i, i = 0..10);% \end{everbatim} -This defines the variables |x0|, |x1|, \dots, |x10| for future usage. +This defines |x0|, |x1|, \dots, |x10| for future usage. Legal variable names are composed of letters, digits, |_| and |@| and characters. A variable name must start with a letter. Variable names starting with a |@| or |_| are reserved for internal usage. -|x_1x| is a licit variable name, as well as |x_1x_| and |x_1x_2| and |x_1x_2y| -etc... As the parser does not trace back its steps, it will raise an ``unknown -variable'' error in cases such as |x_1x_2| with defined variables |x_1| and -|x_2| but not |x_1x_2|. Input syntax must be |x_1*x_2| in such cases. +As |x_1x_2| or even |x_1x| are licit variable names, and as the parser does +not trace back its steps, input syntax must be |x_1*x_2| if the aim is to +multiply such variables. Single letter names |a..z| and |A..Z| are pre-declared by the package for use as special type of variables called ``dummy variables''. It is allowed to overwrite their original meanings and assign them values. See further \csbxint{unassignvar}. -The assignments are done with \csa{xintdefvar}, \csa{xintdefiivar}, or -\csa{xintdeffloatvar} and the variable value will be computed using respectively -\csbxint{expr}, \csbxint{iiexpr} or \csbxint{floatexpr}. It can then be used -in all three parsers if the parser understands the format. Currently this -means that variables using \csa{xintdefvar} or \csa{xintdeffloatvar} can not -be used in the \csbxint{iiexpr} parser, and variables defined via -\csa{xintdefiivar} can be used in all parsers. +Since |1.4| even assigned variables can be used in the signature of +function declarations. + +Using \csa{xintdefvar}, \csa{xintdefiivar}, or \csa{xintdeffloatvar} means +that the variable value will be computed using respectively \csa{xintexpr}, +\csa{xintiiexpr} or \csa{xintfloatexpr}. It can then be used in all three +parsers, as long as the parser understands the format. Currently this means +that variables using \csa{xintdefvar} or \csa{xintdeffloatvar} can be used +freely either with \csa{xintexpr} or \csa{xintfloatexpr} but not with +\csa{xintiiexpr}, and variables defined via \csa{xintdefiivar} can be used in +all parsers. When defining a variable with \csa{xintdeffloatvar}, it is important to know that the rounding to \csbxint{theDigits} digits of precision happens inside -\csa{xintfloatexpr} only if an operation is executed. Thus, for a variable -definition which uses no operations (and \emph{only} for them), the value is -recorded inside the variable with all its digits preserved. If -\csbxint{theDigits} changes afterwards, the variable will be rounded to that -precision in force at time of use. +\csa{xintfloatexpr} only if an operation is executed. Thus, for a declaration +using no operations (and \emph{only} for them), the value is recorded with all +its digits preserved. If \csbxint{theDigits} changes afterwards, the variable +will be rounded to that precision only at time of use. \begin{everbatim*} \xintdeffloatvar e:=2.7182818284590452353602874713526624977572470936999595749669676;% -\xinttheexpr e\relax\newline % shows the recorded value -\xintthefloatexpr e\relax\newline % output rounds -\xintthefloatexpr 1+e\relax\newline % the rounding was done by addition (trust me...) -\xintdeffloatvar e:=float(2.7182818284590452353602874713526624977572470936999595749669676);% -\xinttheexpr e\relax\par % use of float forced immediate rounding -\end{everbatim*} - -In the next examples we examine the effect of cumulated float operations on -rounding errors: -\begin{everbatim*} -\xintdefvar e_1:=add(1/i!, i=0..10);% exact sum -\xintdeffloatvar e_2:=add(1/i!, i=0..10);% float sum -\xintthefloatexpr e_1, e_2\relax\newline -\xintdefvar e_3:=e_1+add(1/i!, i=11..20);% exact sum -\xintdeffloatvar e_4:=e_2+add(1/i!, i=11..20);% float sum -\xintthefloatexpr e_3, e_4\relax\newline -\xintdeffloatvar e:=2.7182818284590452353602874713526624977572470936999595749669676;% -\xintDigits:=24\relax -\xintthefloatexpr[16] e, e^1000, e^1000000\relax (e rounded to 24 digits first)\newline -\xintDigits:=16\relax -\xintthefloatexpr e, e^1000, e^1000000\relax (e rounded to 16 digits first)\par -\end{everbatim*} +\xintexpr e\relax\newline % shows the recorded value +\xintfloatexpr e\relax\newline % typesetter rounds on output +\xintexpr \xintfloatexpr e\relax\relax\newline % here we see all digits again +\xintexpr \xintfloatexpr [16]e\relax\relax\newline % this forces rounding +\xintexpr \xintfloatexpr 0+e\relax\relax\newline % rounding here done by addition +\xintexpr float(e)\relax\newline % one more way to force rounding +\xintifboolfloatexpr{e == e+0}{\error}{Different! Comparisons do not pre-round.}\par +\end{everbatim*} + +% not so exciting example +% In the next examples we examine the effect of cumulated float operations on +% rounding errors: +% \begin{everbatim*} +% \xintdefvar e_1:=add(1/i!, i=0..10);% exact sum +% \xintdeffloatvar e_2:=add(1/i!, i=0..10);% float sum +% \xintthefloatexpr e_1, e_2\relax\newline +% \xintdefvar e_3:=e_1+add(1/i!, i=11..20);% exact sum +% \xintdeffloatvar e_4:=e_2+add(1/i!, i=11..20);% float sum +% \xintthefloatexpr e_3, e_4\relax\newline +% \xintdeffloatvar e:=2.7182818284590452353602874713526624977572470936999595749669676;% +% \xintDigits:=24\relax +% \xintthefloatexpr[16] e, e^1000, e^1000000\relax (e rounded to 24 digits first)\newline +% \xintDigits:=16\relax +% \xintthefloatexpr e, e^1000, e^1000000\relax (e rounded to 16 digits first)\par +% \end{everbatim*} -With |\xintverbosetrue| the values of the assigned variables will be written +With \csbxint{verbosetrue} the values of the assigned variables will be written to the log. For example like this (the line numbers here are artificial): - \begin{everbatim} -Package xintexpr Info: (on line 2875) - Variable "e" defined with value {271828182845904523536028747135266249775724 -70936999595749669676[-61]}. -Package xintexpr Info: (on line 2879) - Variable "e" defined with value {2718281828459045[-15]}. -Package xintexpr Info: (on line 2886) - Variable "e_1" defined with value {9864101/3628800[0]}. -Package xintexpr Info: (on line 2887) - Variable "e_2" defined with value {2718281801146385[-15]}. -Package xintexpr Info: (on line 2889) - Variable "e_3" defined with value {6613313319248080001/2432902008176640000[ -0]}. -Package xintexpr Info: (on line 2890) - Variable "e_4" defined with value {2718281828459046[-15]}. -Package xintexpr Info: (on line 2892) - Variable "e" defined with value {271828182845904523536028747135266249775724 -70936999595749669676[-61]}. +Package xintexpr Info: (on line 1) + Variable "myPi" defined with value {3141592653589793238462643[-24]}. +Package xintexpr Info: (on line 2) + Variable "x_1" defined with value {10}. +Package xintexpr Info: (on line 2) + Variable "x_2" defined with value {20}. +Package xintexpr Info: (on line 2) + Variable "x_3" defined with value {30}. +Package xintexpr Info: (on line 3) + Variable "List" defined with value {0}{1}{3}{6}{10}{15}{21}{28}{36}{45}{55} +. +Package xintexpr Info: (on line 4) + Variable "Nuple" defined with value {{0}{1}{9}{36}{100}{225}{441}{784}{1296 +}{2025}{3025}}. +Package xintexpr Info: (on line 5) + Variable "FourthPowers" defined with value {{0}{1}{81}{1296}{10000}{50625}{ +194481}{614656}{1679616}{4100625}{9150625}}. \end{everbatim} +Prior to |1.4| individual (scalar) values would not have been printed to the +log with the braces. + \subsubsection{\csh{xintunassignvar}} \label{xintunassignvar} @@ -6525,7 +6867,7 @@ case that the original expression has been \emph{entirely} parsed. See The main difficulty of \csbxint{deffunc} is with the pseudo-functions \func{seq}, \func{iter}, etc..., which admit the keywords \keyword{omit}, -\keyword{abort}, \keyword{break}|()|. We have no alternative for them, if the +\keyword{abort}, \func{break}. We have no alternative for them, if the iterated over values are not entirely numerical than to postpone expansion, but this means simply storing for later a possibly big sub-expression. @@ -6950,10 +7292,11 @@ some example here... \hyperlink{ssec:dummies}{Functions with dummy variables}, \autoref{ssec:moredummies} or \hyperref[sssec:recursive]{Recursive definitions}. \end{itemize} -Almost all of the computational results interspersed throughout the -documentation are not hard-coded in the source file of this document but are -obtained via the expansion of the package macros during the \TeX{} -run.% +% ça va sans dire +% Almost all of the computational results interspersed throughout the +% documentation are not hard-coded in the source file of this document but are +% obtained via the expansion of the package macros during the \TeX{} +% run.% \clearpage @@ -7126,8 +7469,8 @@ 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; +\xintdeffloatfunc radians(x) := x * oneDegree; +\xintdeffloatfunc degrees(x) := x * oneRadian; \xintdefefunc radians(x) := float_(x * oneDegree); \xintdefefunc degrees(x) := float_(x * oneRadian); \end{everbatim} @@ -7146,7 +7489,7 @@ precision. \begin{itemize} \item The package is almost entirely implemented using the high level user interface of \xintexprname, using - \csbxint{deffloatefunc} (and \csbxint{deffloatvar}), the main two exceptions + \csbxint{deffloatefunc} (merged with \csbxint{deffloatfunc} at |1.4|) (and \csbxint{deffloatvar}), the main two exceptions being for: \begin{enumerate}[nolistsep] \item the range reduction for the |sind()| and |cosd()| functions which @@ -8657,7 +9000,7 @@ copied over from \LaTeX3's |\prg_replicate:nn| with some minor changes.% available on an online site.} And \csa{xintReplicate}|{x}| integrates the -\csa{romannumeeral} prefix.\NewWith{1.4} +\csa{romannumeral} prefix.\NewWith{1.4} It does not do any expansion of its second argument but inserts it in the upcoming @@ -9929,7 +10272,7 @@ result from \csbxint{UniformDeviate}|{100000000}| but with less overhead. \subsection{(WIP) \csh{xintXRandomDigits}}\label{xintXRandomDigits} -|\xintXRandomDigits{N}|\retype{\numx} expands under exhaustive expansion +|\xintXRandomDigits{N}|\xtype{\numx} expands under exhaustive expansion (|\edef|, |\write|, |\csname| ...) to |N| random decimal digits. The argument must be non-negative. For example: @@ -10214,25 +10557,39 @@ from removing the |[N]| part if |N=0| and removing the |B| if |B=1|. \subsection{\csh{xintFracToSci}, \csh{xintFracToSciE}}\label{xintFracToSci} \label{xintFracToSciE} -\csa{xintFracToSci}\etype{\Ff} is not really part of public interface. It is a -macro used by \csbxint{expr} for output. +% je ne dois pas mettre \Ff car la macro n'utilise pas \XINT_infrac -\noindent\csa{xintFracToSciE}\NewWith{1.4} says what to use for the scientific -notation, its default definition is -\begin{everbatim} -\def\xintFracToSciE{e} -\end{everbatim} +\csa{xintFracToSci}\NewWith{1.4} is not really part of public interface. It is +a macro used by \csbxint{expr} and \csbxint{iexpr} for output. + +\noindent It\xtype{} is expandable but not \fexpan dable. -If using directly \csa{xintFracToSci}: attention that it expects input to -already be in raw \xintfracname format, apart from denominator and |[N]| -postfix parts being optional. Its output is like \csbxint{PRaw} except for -using scientific notation in place of raw \xintfracname format. +It has specific rules regarding the input format: it expects it argument +(after \fexpan ding it) to \emph{already} be either in raw \xintfracname +format |A/B[N]| (with optional denominator and |[N]| parts) or in decimal +format |A.ddd...ddd|. It does not accept scientific notation as input (or +rather, the |e| in input must be of catcode 12). + +Its output uses scientific notation (dropping unit demoninator or zero +exponent -- but not (as alas I have to tell the whole truth) in case input was +itself in scientific notation), except for decimal numbers. The latter pass +through ``as is''. \begin{everbatim*} \xintFracToSci {\xintRaw{123e10/321e10}}, \xintFracToSci {\xintRaw{123e9/321e10}}, -\xintFracToSci {\xintIrr{861/123}} +\xintFracToSci {\xintIrr{861/123}}, +\xintFracToSci {\xintTrunc{12}{1/3}} \end{everbatim*} +Not being \fexpan dable it can not be used as argument to the other package +macros without being wrapped in |\expanded{...}|. + +\noindent\csa{xintFracToSciE}\NewWith{1.4} says what to use for the scientific +notation, its default definition is +\begin{everbatim} +\def\xintFracToSciE{e} +\end{everbatim} + \subsection{\csh{xintDecToString}}\label{xintDecToString} @@ -10298,7 +10655,7 @@ Truncation is done towards zero. \subsection{\csh{xintXTrunc}}\label{xintXTrunc} -\csa{xintXTrunc}|{x}{f}|\retype{\numx\Ff} is similar to \csbxint{Trunc} with +\csa{xintXTrunc}|{x}{f}|\xtype{\numx\Ff} is similar to \csbxint{Trunc} with the following important differences: \begin{itemize}[nosep] \item it is completely expandable but not @@ -10930,47 +11287,50 @@ $\xintIsOne {21921379213/21921379213}\neq\xintIsOne {1.0000000000000000000000000 The greatest common divisor of its two arguments, which are possibly \emph{fractions}.\etype{\Ff\Ff} -A macro of the same name existed formerly in \xintgcdname but it truncated -its arguments to integers via \csbxint{Num}. +Prior to |1.4| a macro of the same name existed in \xintgcdname. But +it truncated its two arguments to integers via \csbxint{Num}. + +See \csbxint{iiGCD} for the integer only variant. \subsection{\csh{xintLCM}}\label{xintLCM} The least common multiple of its two arguments, which are possibly \emph{fractions}.\etype{\Ff\Ff} -A macro of the same name existed formerly in \xintgcdname but it truncated -its arguments to integers via \csbxint{Num}. +Prior to |1.4| a macro of the same name existed in \xintgcdname. But +it truncated its two arguments to integers via \csbxint{Num}. + +See \csbxint{iiLCM} for the integer only variant. \subsection{\csh{xintGCDof}}\label{xintGCDof} \csa{xintGCDof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast\Ff}} computes the -greatest common divisor of a|a|, |b|, \dots{}, which are -possibly\emph{fractions} (i.e. the non-negative generator of the fractional -ideal they generate). The list argument may be a macro as it is \fexpan ded -first. It is a support macro for the |gcd()| function of -\xintexprname. +greatest common divisor of |a|, |b|, \dots{}. The arguments are allowed to be +\emph{fractions}: the macro produces the non-negative generator of the +fractional ideal they generate. The list argument may be a macro as it is +\fexpan ded first. If all arguments vanish, then also the output. -A macro of the same name existed formerly in \xintgcdname: it truncated all -its arguments to integers via \csbxint{Num}. It has now been removed and one -must load \xintfracname to get the macro. +Prior to |1.4| a macro of the same name existed in \xintgcdname. But +it truncated all its arguments to integers via \csbxint{Num} and then +proceeded with integer only computations. -Added this documentation. See \csbxint{iiGCDof} for the integer -only variant. +See \csbxint{iiGCDof} for the integer only variant (which is about |6X| faster +than this one for integer arguments). \subsection{\csh{xintLCMof}}\label{xintLCMof} \csa{xintLCMof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast\Ff}} computes the least -common multiple of |a|, |b|, \dots{}, which are possibly \emph{fractions}. The -list argument may be a macro, it is \fexpan ded first. If one of the item -vanishes, then also the output. It is a support macro for the |lcm()| function -of \xintexprname. +common multiple of |a|, |b|, \dots{}. The arguments are allowed to be +\emph{fractions}: the macro produces the non-negative generator of the +intersection of the corresponding fractional ideals. The list argument may be +a macro, it is \fexpan ded first. If one of the item vanishes, then also the +output. -A macro of the same name existed formerly in \xintgcdname: it truncated all -its arguments to integers via \csbxint{Num}. It has now been removed and one -must load \xintfracname to get the macro. +Prior to |1.4| a macro of the same name existed in \xintgcdname. But +it truncated all its arguments to integers via \csbxint{Num}. -Added this documentation. See \csbxint{iiLCMof} for the integer -only variant. +See \csbxint{iiLCMof} for the integer only variant (which is about |9X| faster +than this one for integer arguments). \subsection{\csh{xintDigits}, \csh{xinttheDigits}} \label{xintDigits} @@ -11091,48 +11451,57 @@ transitive in the number of kept digits. -\subsection{\csh{xintPFloat}}\label{xintPFloat} +\subsection{\csh{xintPFloat}, \csh{xintPFloatE}} +\label{xintPFloat} +\label{xintPFloatE} -The macro |\xintPFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} is like -\csbxint{Float} but ``pretty-prints'' the output. Its behaviour has changed -with release |1.2f|\IMPORTANT{}: there is only one simplification rule now -which is that decimal notation (with possibly needed extra zeros) is used in -place of scientific notation when the exponent would end up being between -\dtt{-5} and \dtt{5} inclusive. +|\xintPFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} is like \csbxint{Float} but +``pretty-prints'' the output. The macro applies one simple rule: |x.yz...eN| +will drop scientific notation in favor of pure decimal notation if |-5<=N<=5| +(last time I checked Maple® proceeded this way). -If the input vanishes the output will be \dtt{\xintPFloat{0}} with a a decimal -mark.% -% -\footnote{Currently there are no subnormal numbers, and no underflow - because the exponent is only limited by the maximal \TeX\ number; thus - underflow situations would manifest themselves via low-level arithmetic - overflow errors.} +Currently trailing zeros are not trimmed. And if the input vanishes the output +will be \dtt{\xintPFloat{0}} with a decimal mark. Final decision however on +how zero value should be printed is yet to arrive... -\csbxint{thefloatexpr} applies this macro to its output (or each of -its outputs, if comma separated). +\csbxint{floateval} applies (via the default definition of +\csbxint{floatexprPrintOne}) this macro to each non-empty leaf of the output +ople. This is done in an |\expanded| context, but the macro is already \fexpan +dable. -Currently trailing zeros are not trimmed. +\csa{xintPFloatE}\NewWith{1.4b} was added to allow customizing the +symbol used on output for separating the significand from the exponent, if +output uses scientific notation. The separator defaults to |e|, according to +this definition: +\begin{everbatim} +\def\xintPFloatE{e} +\end{everbatim} +See in this context \csbxint{FracToSciE} which brings the analogous +customizability to \csbxint{eval}. \begin{everbatim*} \begingroup\def\test #1{#1${}\to{}$\xintPFloat{#1}}% \string\xintDigits\ at \xinttheDigits \begin{itemize}[nosep] \item \test {0} -\item \test {1.23456789e-7} -\item \test {1.23456789e-6} -\item \test {1.23456789e-5} -\item \test {1.23456789e-4} -\item \test {1.23456789e-3} -\item \test {1.23456789e-2} -\item \test {1.23456789e-1} -\item \test {1.23456789e0} -\item \test {1.23456789e1} -\item \test {1.23456789e2} -\item \test {1.23456789e3} -\item \test {1.23456789e4} -\item \test {1.23456789e5} -\item \test {1.23456789e6} -\item \test {1.23456789e7} +\item \test {1.234e-7} +\item \test {1.234e-6} +\item \test {1.234e-5} +\item \test {1.234e-4} +\item \test {1.234e-3} +\item \test {1.234e-2} +\item \test {1.234e-1} +\end{itemize} +\def\xintPFloatE{E}% test custom separator. Should impact \xintfloateval as well +\begin{itemize}[nosep] +\item \test {1.234e0} +\item \test {1.234e1} +\item \test {1.234e2} +\item \test {1.234e3} +\item \test {1.234e4} +\item \test {1.234e5} +\item \test {1.234e6} +\item \test {1.234e7} \end{itemize} \endgroup \end{everbatim*} @@ -11148,6 +11517,9 @@ value of |\xinttheDigits|. \xintFloatE {1.23e37}{53} \end{everbatim*} +There is since |1.4b| an unfortunate proximity in name with \csbxint{PFloatE} +despite the two things having absolutely nothing in common. + \subsection{\csh{xintFloatAdd}}\label{xintFloatAdd} @@ -14112,7 +14484,7 @@ efficiently) and does not stress the input save stack. \label{xintbreakloopanddo} \label{xintloopskiptonext} -|\xintloop|\meta{stuff}|\if<test>...\repeat|\retype{} is an expandable loop +|\xintloop|\meta{stuff}|\if<test>...\repeat|\xtype{} is an expandable loop compatible with nesting. However to break out of the loop one almost always need some un-expandable step. The cousin \csbxint{iloop} is \csbxint{loop} with an embedded expandable mechanism allowing to exit from the loop. The iterated @@ -14274,7 +14646,7 @@ illustrate use of the nesting capabilities of |\xintloop|.% \label{xintiloopindex} \label{xintouteriloopindex} -\csa{xintiloop}|[start+delta]|\meta{stuff}|\if<test> ... \repeat|\retype{} is a +\csa{xintiloop}|[start+delta]|\meta{stuff}|\if<test> ... \repeat|\xtype{} is a completely expandable nestable loop. complete expandability depends naturally on the actual iterated contents, and complete expansion will not be achievable under a sole \fexpan sion, as is indicated by the hollow star in the margin; @@ -15699,8 +16071,12 @@ It converts (in two expansion steps) the expansion result of % Notice: if x goes not take exactly value 1 or -1, the origin appears slightly % off the curve, not MY fault!!! -It is currently undecided how \csa{xintthecoords} should handle -bracketed data.\UNSTABLE{} +It is currently undecided how \csa{xintthecoords} should handle bracketed +data.\UNSTABLE{} Currently, it (or |TikZ|) will break it the input contains +nested structures. One can use it with \func{flat} which removes all nesting. +And in combination with \func{zip} it is easy to plot data given by some +mechanism in separate +lists of x- and y-coordinates (see an example in next section) \subsection{The \csh{xintthespaceseparated} macro} \label{xintthespaceseparated} @@ -15708,13 +16084,37 @@ bracketed data.\UNSTABLE{} It converts (in two expansion steps)\NewWith{1.4a} the expansion result of \csbxint{floatexpr} (or \csbxint{expr} or \csbxint{iiexpr}) into the space separated format suitable for usage with |PS-Tricks| |\listplot| macro. + +Here is for example some syntax (the replacement text of |\foo|, which is used +here only to show that indeed complete expansion is attained in two steps) +which can be used as argument to |\listplot|. Using 4 fractional decimal +digits is sufficient when unit is the centimeter (it gives a fixed point +precision of one micron, amply enough for plots...). \begin{everbatim*} -\oodef\foo{\xintthespaceseparated\xintfloatexpr [4] 1..10\relax} -\meaning\foo +\oodef\foo{% +\xintthespaceseparated\xintiexpr[4]\xintfloatexpr seq((i, log10(i)), i=1..[0.5]..10)\relax\relax +}\meaning\foo \end{everbatim*} +Here we don't really need the inner |\xintfloatexpr...\relax| because the +\func{log10} function works the same in the exact parser |\xintexpr| but in +general this is recommended. + It is currently undecided how \csa{xintthespaceseparated} should handle -bracketed data.\UNSTABLE{} +bracketed data.\UNSTABLE{} Currently, it (or |\listplot|) will break if the +input contains nested structures. One can use it with \func{flat} which +removes all nesting. And in combination with \func{zip} it is easy to plot +data given by some mechanism in separate lists of x- and y-coordinates. + +\begin{everbatim*} +% let's imagine we have something like this +\def\Xcoordinates{1, 3, 5, 7, 9} +\def\Ycoordinates{1, 9, 25, 49, 81} +% then: +|\xintthespaceseparated\xintexpr flat(zip([\Xcoordinates], [\Ycoordinates]))\relax| +is suitable to use as argument to |\listplot|, as it expands to +\xintthespaceseparated\xintexpr flat(zip([\Xcoordinates], [\Ycoordinates]))\relax +\end{everbatim*} \subsection{\csh{xintifboolexpr}, \csh{xintifboolfloatexpr}, \csh{xintifbooliiexpr}} \label{xintifboolexpr} @@ -16280,13 +16680,17 @@ One more recursion: The 3x+1 problem: \syr{231}\par \end{everbatim*} -OK, a final one: +OK, a final one:% +% +\footnote{Prior to |1.4|, the \func{break} worked differently and here one + used only |break(i/2)| for the same result. In retrospect this looks like a bug of + \func{break} inside an \func{iterr}.} \begin{everbatim*} -\def\syrMax #1{\xinttheiiexpr iterr(#1,#1;even(i)? - {(@2<=1)?{break(i/2)}{odd(@2)?{3@2+1}{@2//2}}} +\def\syrMax #1{\xintiiexpr iterr(#1,#1;even(i)? + {(@2<=1)?{break(@1,i//2)}{odd(@2)?{3@2+1}{@2//2}}} {(@1>@2)?{@1}{@2}},i=0++)\relax } -With initial value 1161, the maximal number attained is \syrMax{1161} and that latter -number is the number of steps which was needed to reach 1.\par +With initial value 1161, the maximal intermediate value and the number of steps +needed to reach 1 are respectively \syrMax{1161}.\par \end{everbatim*} Look at the @@ -16653,10 +17057,7 @@ then write a very fast expandable primality test for such numbers using only % We will always use it with 1 < x < n % % With xint 1.4 we should use ? and ?? (although in the case at hand ifsgn() -% and if() are ok; 1.4 still converts them to short-circuit branchers). -% The 1.4 xint.pdf was still giving here the code with ifone() and if() -% functions (given below after the one here using ? as demanded by the -% documentation) +% and if() would be ok but I should not say that). % \xintdefiifunc powmod_a(x, m, n) := isone(m)? @@ -16739,7 +17140,11 @@ then write a very fast expandable primality test for such numbers using only \xintNewFunction{isPseudoPrime}[1]{% n = #1 (#1<49)?% use ? syntax to evaluate only what is needed - {\IsVerySmallPrime{\xintthe#1}}% macro needs to be fed with #1 unlocked. +% prior to 1.4 we had \xintthe#1 here but the actual tokens represented +% by this #1 when isPseudoPrime() function expands have changed and +% the correct way is now \xintiieval{#1} to hand over explicit digits to +% the \IsVerySmallPrime macro. + {\IsVerySmallPrime{\xintiieval{#1}}} {(even(#1))? {0} {subs(% @@ -16779,7 +17184,7 @@ then write a very fast expandable primality test for such numbers using only %\def\IsPseudoPrime #1{\xinttheiiexpr isPseudoPrime(#1)\relax} \noindent The smallest prime number at least equal to 3141592653589 is -\xinttheiiexpr +\xintiiexpr seq(isPseudoPrime(3141592653589+n)? {break(3141592653589+n)}{omit}, n=0++)\relax. % we could not use 3141592653589++ syntax because it works only with TeX numbers @@ -17629,22 +18034,21 @@ currently this is implemented by using either |\xintifForFirst| or \makeatother -\section{History timeline} +\section{Timeline (in brief)} This is \expandafter|\xintbndlversion| of \expandafter|\xintbndldate|. -Please refer |CHANGES.html| for a (much more) detailed history. +Please refer to |CHANGES.html| for a (very) detailed history. \centeredline{Internet: \url{http://mirrors.ctan.org/macros/generic/xint/CHANGES.html}} \begin{itemize} -\item Release |1.4a| of |2020/02/19|: - fixes |1.4| known bugs. Improves documentation. \item Release |1.4| of |2020/01/31|: \xintexprnameimp overhaul to use - |\expanded| based expansion control. Many new features, in particular support - for input and output of nested structures. Breaking changes, main ones - being the (provisory) drop of |x*[a, b,...]|, |x+[a, b,...]| et al.\@ syntax and the - requirement of |\expanded| primitive (currently required only by \xintexprnameimp). + |\expanded| based expansion control. Many new features, in particular + support for input and output of nested structures. Breaking changes, main + ones being the (provisory) drop of |x*[a, b,...]|, |x+[a, b,...]| et al.\@ + syntax and the requirement of |\expanded| primitive (currently required only + by \xintexprnameimp). \item Release |1.3f| of |2019/09/10|: starred variant \csbxint{Digits*}. \item Release |1.3e| of |2019/04/05|: packages \xinttrignameimp, \xintlognameimp; \csa{xintdefefunc} ``non-protected'' variant of \csbxint{deffunc} (at |1.4| @@ -17914,7 +18318,7 @@ math shift catcode. \fi \XINT_providespackage \ProvidesPackage {xintkernel}% - [2020/02/19 v1.4a Paraphernalia for the xint packages (JFB)]% + [2020/02/25 v1.4b Paraphernalia for the xint packages (JFB)]% % \end{macrocode} % \subsection{Constants} % \begin{macrocode} @@ -18700,7 +19104,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xinttools}% - [2020/02/19 v1.4a Expandable and non-expandable utilities (JFB)]% + [2020/02/25 v1.4b 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.| @@ -19424,50 +19828,91 @@ math shift catcode. \long\def\XINT_apply_end\xint_bye\expandafter\XINT_apply_loop_b \expandafter #1#2#3{ #2}% % \end{macrocode} -% \subsection{\csh{xintApply:x} (not public)} -% \lverb|Done for 1.4, 2020/01/27. For usage in the NumPy-like slicing routines. +% \subsection{\csh{xintApply:x} (WIP, commented-out)} +% \lverb|Done for 1.4 (2020/01/27). For usage in the NumPy-like slicing +% routines. Well, actually, in the end I sticked with old-fashioned (quadratic +% cost) \xintApply for 1.4 2020/01/31 release. See comments there. % -% Supposed to expand in an \expanded context, does not need to +% (Comments mainly from 2020/01/27, but on 2020/02/24 I comment out +% the code and add an alternative) +% +% To expand in \expanded context, and does not need to % do any expansion of its second argument. % -% Uses techniques I had developed for 1.2i/1.2j Keep, Trim, Length, LastItem like -% macros, and I should revamp venerable \xintApply probably too. But the latter -% f-expandability (if it does not have \expanded at disposal) complicates -% significantly matters as it has to store material and release at very end. +% This uses techniques I had developed for 1.2i/1.2j Keep, Trim, Length, +% LastItem like macros, and I should revamp venerable \xintApply probably too. +% But the latter f-expandability (if it does not have \expanded at disposal) +% complicates significantly matters as it has to store material and release at +% very end. % % Here it is simpler and I am doing it quickly as I really want to release % 1.4. The \xint: token should not be located in looped over items. I could % use something more exotic like the null char with catcode 3... % -% Could be however that picking one by one would be better for small -% number of items. +%( \long\def\xintApply:x #1#2$% +%: {$% +%: \XINT_apply:x_loop {#1}#2$% +%: {\xint:\XINT_apply:x_loop_enda}{\xint:\XINT_apply:x_loop_endb}$% +%: {\xint:\XINT_apply:x_loop_endc}{\xint:\XINT_apply:x_loop_endd}$% +%: {\xint:\XINT_apply:x_loop_ende}{\xint:\XINT_apply:x_loop_endf}$% +%: {\xint:\XINT_apply:x_loop_endg}{\xint:\XINT_apply:x_loop_endh}\xint_bye +%: }$% +%: \long\def\XINT_apply:x_loop #1#2#3#4#5#6#7#8#9$% +%: {$% +%: \xint_gob_til_xint: #9\xint: +%: {#1{#2}}{#1{#3}}{#1{#4}}{#1{#5}}{#1{#6}}{#1{#7}}{#1{#8}}{#1{#9}}$% +%: \XINT_apply:x_loop {#1}$% +%: }$% +%: \long\def\XINT_apply:x_loop_endh\xint: #1\xint_bye{}$% +%: \long\def\XINT_apply:x_loop_endg\xint: #1#2\xint_bye{{#1}}$% +%: \long\def\XINT_apply:x_loop_endf\xint: #1#2#3\xint_bye{{#1}{#2}}$% +%: \long\def\XINT_apply:x_loop_ende\xint: #1#2#3#4\xint_bye{{#1}{#2}{#3}}$% +%: \long\def\XINT_apply:x_loop_endd\xint: #1#2#3#4#5\xint_bye{{#1}{#2}{#3}{#4}}$% +%: \long\def\XINT_apply:x_loop_endc\xint: #1#2#3#4#5#6\xint_bye{{#1}{#2}{#3}{#4}{#5}}$% +%: \long\def\XINT_apply:x_loop_endb\xint: #1#2#3#4#5#6#7\xint_bye{{#1}{#2}{#3}{#4}{#5}{#6}}$% +%: \long\def\XINT_apply:x_loop_enda\xint: #1#2#3#4#5#6#7#8\xint_bye{{#1}{#2}{#3}{#4}{#5}{#6}{#7}}$% +%) % -% And anyhow for small number of items gain with respect to \xintApply is little -% if any (might even be a loss).| -% \begin{macrocode} -\long\def\xintApply:x #1#2% -{% - \XINT_apply:x_loop {#1}#2% - {\xint:\XINT_apply:x_loop_enda}{\xint:\XINT_apply:x_loop_endb}% - {\xint:\XINT_apply:x_loop_endc}{\xint:\XINT_apply:x_loop_endd}% - {\xint:\XINT_apply:x_loop_ende}{\xint:\XINT_apply:x_loop_endf}% - {\xint:\XINT_apply:x_loop_endg}{\xint:\XINT_apply:x_loop_endh}\xint_bye -}% -\long\def\XINT_apply:x_loop #1#2#3#4#5#6#7#8#9% -{% - \xint_gob_til_xint: #9\xint: - {#1{#2}}{#1{#3}}{#1{#4}}{#1{#5}}{#1{#6}}{#1{#7}}{#1{#8}}{#1{#9}}% - \XINT_apply:x_loop {#1}% -}% -\long\def\XINT_apply:x_loop_endh\xint: #1\xint_bye{}% -\long\def\XINT_apply:x_loop_endg\xint: #1#2\xint_bye{{#1}}% -\long\def\XINT_apply:x_loop_endf\xint: #1#2#3\xint_bye{{#1}{#2}}% -\long\def\XINT_apply:x_loop_ende\xint: #1#2#3#4\xint_bye{{#1}{#2}{#3}}% -\long\def\XINT_apply:x_loop_endd\xint: #1#2#3#4#5\xint_bye{{#1}{#2}{#3}{#4}}% -\long\def\XINT_apply:x_loop_endc\xint: #1#2#3#4#5#6\xint_bye{{#1}{#2}{#3}{#4}{#5}}% -\long\def\XINT_apply:x_loop_endb\xint: #1#2#3#4#5#6#7\xint_bye{{#1}{#2}{#3}{#4}{#5}{#6}}% -\long\def\XINT_apply:x_loop_enda\xint: #1#2#3#4#5#6#7#8\xint_bye{{#1}{#2}{#3}{#4}{#5}{#6}{#7}}% -% \end{macrocode} +% For small number of items gain with respect to \xintApply is little if any +% (might even be a loss). +% +% Picking one by one is possibly better for small number of items. Like +% this for example, the natural simple minded thing: +% +%(\long\def\xintApply:x #1#2$% +%: {$% +%: \XINT_apply:x_loop {#1}#2\xint_bye\xint_bye +%: }$% +%: \long\def\XINT_apply:x_loop #1#2$% +%: {$% +%: \xint_bye #2\xint_bye {#1{#2}}$% +%: \XINT_apply:x_loop {#1}$% +%: }$% +%) +% +% Some variant on 2020/02/24 +% +%( \long\def\xint_Bbye#1\xint_Bye{}$% +%: \long\def\xintApply:x #1#2$% +%: {$% +%: \XINT_apply:x_loop {#1}#2$% +%: {\xint_bye}{\xint_bye}{\xint_bye}{\xint_bye}$% +%: {\xint_bye}{\xint_bye}{\xint_bye}{\xint_bye}\xint_bye +%: }$% +%: \long\def\XINT_apply:x_loop #1#2#3#4#5#6#7#8#9$% +%: {$% +%: \xint_Bye #2\xint_bye {#1{#2}}$% +%: \xint_Bye #3\xint_bye {#1{#3}}$% +%: \xint_Bye #4\xint_bye {#1{#4}}$% +%: \xint_Bye #5\xint_bye {#1{#5}}$% +%: \xint_Bye #6\xint_bye {#1{#6}}$% +%: \xint_Bye #7\xint_bye {#1{#7}}$% +%: \xint_Bye #8\xint_bye {#1{#8}}$% +%: \xint_Bye #9\xint_bye {#1{#9}}$% +%: \XINT_apply:x_loop {#1}$% +%: }$% +%) +% | % \subsection{\csh{xintApplyUnbraced}} % \lverb|\xintApplyUnbraced {\macro}{{a}{b}...{z}} returns \macro{a}...\macro{z} % where each instance of \macro is f-expanded using \romannumeral-`0. The second @@ -19495,63 +19940,187 @@ math shift catcode. \long\def\XINT_applyunbr_end\xint_bye\expandafter\XINT_applyunbr_loop_b \expandafter #1#2#3{ #2}% % \end{macrocode} -% \subsection{\csh{xintApplyUnbraced:x} (not public)} +% \subsection{\csh{xintApplyUnbraced:x} (WIP, commented-out)} % \lverb|Done for 1.4, 2020/01/27. For usage in the NumPy-like slicing % routines. % % The items should not contain \xint: and the applied macro should not contain -% \empty.| -% \begin{macrocode} -\long\def\xintApplyUnbraced:x #1#2% -{% - \XINT_applyunbraced:x_loop {#1}#2% - {\xint:\XINT_applyunbraced:x_loop_enda}{\xint:\XINT_applyunbraced:x_loop_endb}% - {\xint:\XINT_applyunbraced:x_loop_endc}{\xint:\XINT_applyunbraced:x_loop_endd}% - {\xint:\XINT_applyunbraced:x_loop_ende}{\xint:\XINT_applyunbraced:x_loop_endf}% - {\xint:\XINT_applyunbraced:x_loop_endg}{\xint:\XINT_applyunbraced:x_loop_endh}\xint_bye -}% -\long\def\XINT_applyunbraced:x_loop #1#2#3#4#5#6#7#8#9% -{% - \xint_gob_til_xint: #9\xint: - #1{#2}% - \empty#1{#3}% - \empty#1{#4}% - \empty#1{#5}% - \empty#1{#6}% - \empty#1{#7}% - \empty#1{#8}% - \empty#1{#9}% - \XINT_applyunbraced:x_loop {#1}% -}% -\long\def\XINT_applyunbraced:x_loop_endh\xint: #1\xint_bye{}% -\long\def\XINT_applyunbraced:x_loop_endg\xint: #1\empty#2\xint_bye{#1}% -\long\def\XINT_applyunbraced:x_loop_endf\xint: #1\empty - #2\empty#3\xint_bye{#1#2}% -\long\def\XINT_applyunbraced:x_loop_ende\xint: #1\empty - #2\empty - #3\empty#4\xint_bye{#1#2#3}% -\long\def\XINT_applyunbraced:x_loop_endd\xint: #1\empty - #2\empty - #3\empty - #4\empty#5\xint_bye{#1#2#3#4}% -\long\def\XINT_applyunbraced:x_loop_endc\xint: #1\empty - #2\empty - #3\empty - #4\empty - #5\empty#6\xint_bye{#1#2#3#4#5}% -\long\def\XINT_applyunbraced:x_loop_endb\xint: #1\empty - #2\empty - #3\empty - #4\empty - #5\empty - #6\empty#7\xint_bye{#1#2#3#4#5#6}% -\long\def\XINT_applyunbraced:x_loop_enda\xint: #1\empty - #2\empty - #3\empty - #4\empty - #5\empty - #6\empty - #7\empty#8\xint_bye{#1#2#3#4#5#6#7}% +% \empty. +% +% Finally, xintexpr.sty 1.4 code did not use this macro but the f-expandable +% one \xintApplyUnbraced. +% +% For 1.4b I prefer leave the code commented out, and classify it as WIP. +%( \long\def\xintApplyUnbraced:x #1#2$% +%: {$% +%: \XINT_applyunbraced:x_loop {#1}#2$% +%: {\xint:\XINT_applyunbraced:x_loop_enda}{\xint:\XINT_applyunbraced:x_loop_endb}$% +%: {\xint:\XINT_applyunbraced:x_loop_endc}{\xint:\XINT_applyunbraced:x_loop_endd}$% +%: {\xint:\XINT_applyunbraced:x_loop_ende}{\xint:\XINT_applyunbraced:x_loop_endf}$% +%: {\xint:\XINT_applyunbraced:x_loop_endg}{\xint:\XINT_applyunbraced:x_loop_endh}\xint_bye +%: }$% +%: \long\def\XINT_applyunbraced:x_loop #1#2#3#4#5#6#7#8#9$% +%: {$% +%: \xint_gob_til_xint: #9\xint: +%: #1{#2}$% +%: \empty#1{#3}$% +%: \empty#1{#4}$% +%: \empty#1{#5}$% +%: \empty#1{#6}$% +%: \empty#1{#7}$% +%: \empty#1{#8}$% +%: \empty#1{#9}$% +%: \XINT_applyunbraced:x_loop {#1}$% +%: }$% +%: \long\def\XINT_applyunbraced:x_loop_endh\xint: #1\xint_bye{}$% +%: \long\def\XINT_applyunbraced:x_loop_endg\xint: #1\empty#2\xint_bye{#1}$% +%: \long\def\XINT_applyunbraced:x_loop_endf\xint: #1\empty +%: #2\empty#3\xint_bye{#1#2}$% +%: \long\def\XINT_applyunbraced:x_loop_ende\xint: #1\empty +%: #2\empty +%: #3\empty#4\xint_bye{#1#2#3}$% +%: \long\def\XINT_applyunbraced:x_loop_endd\xint: #1\empty +%: #2\empty +%: #3\empty +%: #4\empty#5\xint_bye{#1#2#3#4}$% +%: \long\def\XINT_applyunbraced:x_loop_endc\xint: #1\empty +%: #2\empty +%: #3\empty +%: #4\empty +%: #5\empty#6\xint_bye{#1#2#3#4#5}$% +%: \long\def\XINT_applyunbraced:x_loop_endb\xint: #1\empty +%: #2\empty +%: #3\empty +%: #4\empty +%: #5\empty +%: #6\empty#7\xint_bye{#1#2#3#4#5#6}$% +%: \long\def\XINT_applyunbraced:x_loop_enda\xint: #1\empty +%: #2\empty +%: #3\empty +%: #4\empty +%: #5\empty +%: #6\empty +%: #7\empty#8\xint_bye{#1#2#3#4#5#6#7}$% +%) +% | +% \subsection{\csh{xintZip} (WIP, not public)} +% \lverb|1.4b. (2020/02/25) +% +% Support for zip(). Requires \expanded. +% +% The implementation here thus considers the argument is already completely +% expanded and is a sequence of nut-ples. I will come back at later date for +% more generic macros. +% +% Consider even the name of the function zip() as WIP. +% +% As per what this does, it imitates the zip() function. See xint-manual.pdf. +% +% I use lame terminators. Will think again later on this. I have to be careful +% with the used terminators, in particular with the NE context in mind. +% +% Generally speaking I will think another day about efficiency else I will +% never start this. +% +% OK, done. More compact than I initially thought. Various things should be +% commented upon here. Well, actually not so compact in the end as I basically +% had to double the whole thing simply to avoid the overhead of having to grab +% the final result delimited by some +% \xint_bye\xint_bye\xint_bye\xint_bye\empty terminator. Now actually rather +% \xint_bye\xint_bye\xint_bye\xint_bye\xint: | +% \begin{macrocode} +\def\xintZip #1{\expanded\XINT_zip_A#1\xint_bye\xint_bye}% +\def\XINT_zip_A#1% +{% + \xint_bye#1{\expandafter}\xint_bye + \expanded{\unexpanded{\XINT_ziptwo_A + #1\xint_bye\xint_bye\xint_bye\xint_bye\xint:}\expandafter}% + \expanded\XINT_zip_a +}% +\def\XINT_zip_a#1% +{% + \xint_bye#1\XINT_zip_terminator\xint_bye + \expanded{\unexpanded{\XINT_ziptwo_a + #1\xint_bye\xint_bye\xint_bye\xint_bye\xint:}\expandafter}% + \expanded\XINT_zip_a +}% +\def\XINT_zip_terminator\xint_bye#1\xint_bye{{}\empty\empty\empty\empty\xint:}% +\def\XINT_ziptwo_a #1#2#3#4#5\xint:#6#7#8#9% +{% + \bgroup + \xint_bye #1\XINT_ziptwo_e \xint_bye + \xint_bye #6\XINT_ziptwo_e \xint_bye {{#1}#6}% + \xint_bye #2\XINT_ziptwo_e \xint_bye + \xint_bye #7\XINT_ziptwo_e \xint_bye {{#2}#7}% + \xint_bye #3\XINT_ziptwo_e \xint_bye + \xint_bye #8\XINT_ziptwo_e \xint_bye {{#3}#8}% + \xint_bye #4\XINT_ziptwo_e \xint_bye + \xint_bye #9\XINT_ziptwo_e \xint_bye {{#4}#9}% + \ifx \empty#6\expandafter\XINT_zipone_a\fi + \XINT_ziptwo_b #5\xint: +}% +\def\XINT_zipone_a\XINT_ziptwo_b{\XINT_zipone_b}% +\def\XINT_ziptwo_b #1#2#3#4#5\xint:#6#7#8#9% +{% + \xint_bye #1\XINT_ziptwo_e \xint_bye + \xint_bye #6\XINT_ziptwo_e \xint_bye {{#1}#6}% + \xint_bye #2\XINT_ziptwo_e \xint_bye + \xint_bye #7\XINT_ziptwo_e \xint_bye {{#2}#7}% + \xint_bye #3\XINT_ziptwo_e \xint_bye + \xint_bye #8\XINT_ziptwo_e \xint_bye {{#3}#8}% + \xint_bye #4\XINT_ziptwo_e \xint_bye + \xint_bye #9\XINT_ziptwo_e \xint_bye {{#4}#9}% + \XINT_ziptwo_b #5\xint: +}% +\def\XINT_ziptwo_e #1\XINT_ziptwo_b #2\xint:#3\xint: + {\iffalse{\fi}\xint_bye\xint_bye\xint_bye\xint_bye\xint:}% +\def\XINT_zipone_b #1#2#3#4% +{% + \xint_bye #1\XINT_zipone_e \xint_bye {{#1}}% + \xint_bye #2\XINT_zipone_e \xint_bye {{#2}}% + \xint_bye #3\XINT_zipone_e \xint_bye {{#3}}% + \xint_bye #4\XINT_zipone_e \xint_bye {{#4}}% + \XINT_zipone_b +}% +\def\XINT_zipone_e #1\XINT_zipone_b #2\xint: + {\iffalse{\fi}\xint_bye\xint_bye\xint_bye\xint_bye\empty}% +\def\XINT_ziptwo_A #1#2#3#4#5\xint:#6#7#8#9% +{% + \bgroup + \xint_bye #1\XINT_ziptwo_end \xint_bye + \xint_bye #6\XINT_ziptwo_end \xint_bye {{#1}#6}% + \xint_bye #2\XINT_ziptwo_end \xint_bye + \xint_bye #7\XINT_ziptwo_end \xint_bye {{#2}#7}% + \xint_bye #3\XINT_ziptwo_end \xint_bye + \xint_bye #8\XINT_ziptwo_end \xint_bye {{#3}#8}% + \xint_bye #4\XINT_ziptwo_end \xint_bye + \xint_bye #9\XINT_ziptwo_end \xint_bye {{#4}#9}% + \ifx \empty#6\expandafter\XINT_zipone_A\fi + \XINT_ziptwo_B #5\xint: +}% +\def\XINT_zipone_A\XINT_ziptwo_B{\XINT_zipone_B}% +\def\XINT_ziptwo_B #1#2#3#4#5\xint:#6#7#8#9% +{% + \xint_bye #1\XINT_ziptwo_end \xint_bye + \xint_bye #6\XINT_ziptwo_end \xint_bye {{#1}#6}% + \xint_bye #2\XINT_ziptwo_end \xint_bye + \xint_bye #7\XINT_ziptwo_end \xint_bye {{#2}#7}% + \xint_bye #3\XINT_ziptwo_end \xint_bye + \xint_bye #8\XINT_ziptwo_end \xint_bye {{#3}#8}% + \xint_bye #4\XINT_ziptwo_end \xint_bye + \xint_bye #9\XINT_ziptwo_end \xint_bye {{#4}#9}% + \XINT_ziptwo_B #5\xint: +}% +\def\XINT_ziptwo_end #1\XINT_ziptwo_B #2\xint:#3\xint:{\iffalse{\fi}}% +\def\XINT_zipone_B #1#2#3#4% +{% + \xint_bye #1\XINT_zipone_end \xint_bye {{#1}}% + \xint_bye #2\XINT_zipone_end \xint_bye {{#2}}% + \xint_bye #3\XINT_zipone_end \xint_bye {{#3}}% + \xint_bye #4\XINT_zipone_end \xint_bye {{#4}}% + \XINT_zipone_B +}% +\def\XINT_zipone_end #1\XINT_zipone_B #2\xint:#3\xint:{\iffalse{\fi}}% % \end{macrocode} % \subsection{\csh{xintSeq}} % \lverb|1.09c. Without the optional argument puts stress on the input stack, @@ -20864,7 +21433,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintcore}% - [2020/02/19 v1.4a Expandable arithmetic on big integers (JFB)]% + [2020/02/25 v1.4b 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 @@ -24166,7 +24735,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xint}% - [2020/02/19 v1.4a Expandable operations on big integers (JFB)]% + [2020/02/25 v1.4b Expandable operations on big integers (JFB)]% % \end{macrocode} % \subsection{More token management} % \begin{macrocode} @@ -26732,7 +27301,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintbinhex}% - [2020/02/19 v1.4a Expandable binary and hexadecimal conversions (JFB)]% + [2020/02/25 v1.4b Expandable binary and hexadecimal conversions (JFB)]% % \end{macrocode} % \subsection{Constants, etc...} % \lverb|1.2n switches to \csname-governed expansion at various places.| @@ -27404,7 +27973,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintgcd}% - [2020/02/19 v1.4a Euclide algorithm with xint package (JFB)]% + [2020/02/25 v1.4b Euclide algorithm with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintBezout}} % \lverb|& @@ -28004,7 +28573,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintfrac}% - [2020/02/19 v1.4a Expandable operations on fractions (JFB)]% + [2020/02/25 v1.4b 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 @@ -28563,32 +29132,17 @@ math shift catcode. \fi { #2}{ #2/#3}% }% % \end{macrocode} -% \subsection{\csh{xintSPRaw}, \csh{xintFracToSci}} +% \subsection{\csh{xintSPRaw}} % \lverb|This private macro was for usage by \xinttheexpr. It got moved here -% at 1.4. -% -% Attention that \xintSPRaw assumes that if the number has no [N] -% part it does not have a fraction part /B either. Indeed this was -% the case always with 1.3f (parsing of an integer by \xintexpr -% does not add the [0] because the code is shared with \xintiiexpr -% and when there is /B, \xintexpr always adds [0]; even qfrac() -% parses via \xintRaw; and reduce() internally uses \xintIrr -% whose outputs is A/B but it add [0]). -% -% \xintFracToSci is now used in its place. As reduce() does -% not anymore append the [0] at 1.4, \xintFracToSci has to recognize -% A, A[N], A/B and A/B[N] but does not have to parse multiple plus -% or minus signs or scientific part etc like \xintRaw knows. -% It has to identify say 0/5 (although I don't think that can -% arise) and -0 is never occuring. -% -% The difference with former case is that it outputs AeN/B hence -% does not anymore use the xintfrac.sty raw format. -% It will not printe the /B if B=1 and not print the «eN» if N is zero. -% -% If input is empty \xintFracToSci output is also empty, -% whereas \xintRaw produces 0/1[0] out of empty. But \XINTexprprint -% anyhow has it own special routine for empty input. +% at 1.4 and is not used anymore by the package. +% +% Attention that \xintSPRaw assumed that if the number has no [N] +% part it did not have a fraction part /B either. Indeed this was +% the case always with 1.3f: parsing of an integer by \xintexpr +% does not add the [0] as the code is shared with \xintiiexpr, +% and when there was /B \xintexpr always added postfix [0]; even qfrac() +% parses via \xintRaw; and reduce() internally used \xintIrr +% which outputs A/B but it added [0]. % | % % \begin{macrocode} @@ -28597,8 +29151,48 @@ math shift catcode. \def\XINT_spraw #1[#2#3]{\xint_gob_til_W #2\XINT_spraw_a\W\XINT_spraw_p #1[#2#3]}% \def\XINT_spraw_a\W\XINT_spraw_p #1[\W]{ #1}% \def\XINT_spraw_p #1[\W]{\xintpraw {#1}}% -\def\xintFracToSci #1% - {\expandafter\XINT_FracToSci\romannumeral`&&@#1/\W[\R]}% +% \end{macrocode} +% \subsection{\csh{xintFracToSci}, \csh{xintFracToSciE}} +% \lverb|1.4 +% +% This is the new macro used in place of \xintSPRaw (which basically was +% \xintPRaw) by \xintexpr typesetter. Attention that it is also used by +% \xintiexpr with inputs having being already converted to decimal form, hence +% must understand this input form. This means it must for example not think +% 0.123 is 0 because it starts with 0. +% +% And indeed the code here lets 0.123 go through as is. Identification of 0 as +% first digit is done only in case of A[N], A/B, and A/B[N] formats. +% +% As reduce() does not anymore append the [0] at 1.4, \xintFracToSci has +% indeed to recognize A, A[N], A/B and A/B[N] but does not have to parse +% multiple plus or minus signs or scientific part etc like \xintRaw does +% (delegating to \XINT_infrac like all other xintfrac macros). It has to +% identify say 0/5 (although I don't think that can arise) and -0 is never +% occuring. +% +% The difference with \xintSPRaw is that it outputs AeN/B. It will not print +% the /B if B=1 and eN if N is zero. +% +% If input is empty \xintFracToSci output is also empty, whereas \xintRaw +% produces 0/1[0] out of empty. But \XINTexprprint anyhow has it own special +% routine for empty input. +% +% 1.4b extends the macro to intercept scientific notation and thus allow +% customizability of the «e» via \xintFracToSciE. Without this \xintieval with +% a negative optional argument uses «e» in output with no possibility to +% modify it. +% +% The expansion context from \xinttheexpr, \xinttheiexpr, \xinteval, +% \xintieval is the scope of one \expanded. +% +% Attention indeed that this macro is not f-expandable only x-expandable. +% | +% +% \begin{macrocode} +\edef\xintFracToSci #1% + {\unexpanded{\expandafter\XINT_FracToSci\romannumeral`&&@}#1\string e% + \unexpanded{\Z/\W[\R]}}% \def\XINT_FracToSci #1/#2#3[#4% {% \xint_gob_til_W #2\XINT_FracToSci_no\W @@ -28610,18 +29204,39 @@ math shift catcode. \xint_gob_til_R #3\XINT_FracToSci_nono\R \XINT_FracToSci_noyes #2[#3% }% -\def\XINT_FracToSci_nono\R\XINT_FracToSci_noyes #1/\W[\R]{#1}% -\def\XINT_FracToSci_noyes #1#2[#3]/\W[\R]% +\edef\XINT_tmpa{##1\string e##2}% +\def\XINT_tmpb{\def\XINT_FracToSci_nono\R\XINT_FracToSci_noyes}% +\expandafter +\XINT_tmpb\XINT_tmpa +{% + #1\xint_gob_til_Z #2\XINT_FracToSci_nonono\Z + \XINT_FracToSci_nonoyes #2% +}% +\edef\XINT_tmpa{##1\string e}% + \def\XINT_tmpb{\def\XINT_FracToSci_nonoyes}% +\expandafter +\XINT_tmpb\XINT_tmpa\Z/\W[\R]{\xintFracToSciE#1}% +\def\XINT_FracToSci_nonono\Z\XINT_FracToSci_nonoyes\Z/\W[\R]{}% +\edef\XINT_tmpa{##1##2[##3]\string e}% + \def\XINT_tmpb{\def\XINT_FracToSci_noyes}% +\expandafter +\XINT_tmpb\XINT_tmpa\Z/\W[\R]% {% #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue #2\ifnum #3=\xint_c_\else\xintFracToSciE#3\fi\fi }% -\def\XINT_FracToSci_yesno\R\XINT_FracToSci_yesyes #1#2/#3/\W[\R]% +\edef\XINT_tmpa{##1##2/##3\string e}% + \def\XINT_tmpb{\def\XINT_FracToSci_yesno\R\XINT_FracToSci_yesyes}% +\expandafter +\XINT_tmpb\XINT_tmpa\Z/\W[\R]% {% #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue #2\if\XINT_isOne{#3}1\else/#3\fi\fi }% -\def\XINT_FracToSci_yesyes #1#2/#3[#4]/\W[\R]% +\edef\XINT_tmpa{##1##2/##3[##4]\string e}% + \def\XINT_tmpb{\def\XINT_FracToSci_yesyes}% +\expandafter +\XINT_tmpb\XINT_tmpa\Z/\W[\R]% {% #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue #2\ifnum #4=\xint_c_\else\xintFracToSciE#4\fi @@ -31224,10 +31839,9 @@ math shift catcode. }% \def\XINT_infloat_ZZ #1.#2.{ 1#2[#1]}% % \end{macrocode} -% \subsection{\csh{xintPFloat}} +% \subsection{\csh{xintPFloat}, \csh{xintPFloatE}} % \lverb|1.1. This is a prettifying printing macro for floats. % -% % The macro applies one simple rule: x.yz...eN will drop scientific notation in % favor of pure decimal notation if -5<=N<=5. This is the default behaviour of % Maple. The N here is as produced on output by \xintFloat. @@ -31237,6 +31851,16 @@ math shift catcode. % The coding got simpler with 1.2k as its \xintFloat always produces % a mantissa with exactly P digits (no more 10.0...0eN annoying exception). % +% 1.4b adds \xintPFloatE allowing to customize whether to use e or E (or +% something else). For usage with \xintfloateval{} (anyhow only catcode 11 e +% is recognized by xintfrac macros proper), and to match similar +% \xintFracToSciE. For reasons commented upon in user manual (section «The +% three parsers»), I did not make an effort to let the macro be usable as a +% hook to grab the exponent. +% +% Althout \xintfloateval{} will use \xintPFloat in an \expanded context +% we have to maintain f-expandability here. +% % | % \begin{macrocode} \def\xintPFloat {\romannumeral0\xintpfloat }% @@ -31280,6 +31904,8 @@ math shift catcode. \def\XINT_pfloat_neg-{\expandafter-\romannumeral0\XINT_pfloat_pos }% % \end{macrocode} % \lverb|& +% 1.4b modifies the replacement pattern here #1{#2}{#3} in order to +% facilitate injection of once-expanded \xintPFloatE. % | % \begin{macrocode} \def\XINT_pfloat_pos #1.#2e#3;#4.% @@ -31288,17 +31914,22 @@ math shift catcode. \ifnum #3<-\xint_c_v \xint_dothis\XINT_pfloat_no\fi \ifnum #3<\xint_c_ \xint_dothis\XINT_pfloat_N\fi \ifnum #3>\numexpr #4-\xint_c_i\relax \xint_dothis\XINT_pfloat_Ps\fi - \xint_orthat\XINT_pfloat_P #1#2e#3;% + \xint_orthat\XINT_pfloat_P #1{#2}{#3}% +}% +\def\XINT_pfloat_no +{% + \expandafter\XINT_pfloat_no_e\expandafter{\xintPFloatE}% }% -\def\XINT_pfloat_no #1#2;{ #1.#2}% +\def\XINT_pfloat_no_e #1#2#3#4{ #2.#3#1#4}% +\def\xintPFloatE{e}% % \end{macrocode} % \lverb|This is all simpler coded, now that 1.2k's \xintFloat always % outputs a mantissa with exactly one digits before decimal mark always. % | % \begin{macrocode} -\def\XINT_pfloat_N #1e-#2;% +\def\XINT_pfloat_N #1#2#3% {% - \csname XINT_pfloat_N_\romannumeral#2\endcsname #1% + \csname XINT_pfloat_N_\romannumeral-#3\endcsname #1#2% }% \def\XINT_pfloat_N_i { 0.}% \def\XINT_pfloat_N_ii { 0.0}% @@ -31309,9 +31940,9 @@ math shift catcode. % \lverb|& % | % \begin{macrocode} -\def\XINT_pfloat_P #1e#2;% +\def\XINT_pfloat_P #1#2#3% {% - \csname XINT_pfloat_P_\romannumeral#2\endcsname #1% + \csname XINT_pfloat_P_\romannumeral#3\endcsname #1#2% }% \def\XINT_pfloat_P_ #1{ #1.}% \def\XINT_pfloat_P_i #1#2{ #1#2.}% @@ -31323,9 +31954,9 @@ math shift catcode. % \lverb|& % | % \begin{macrocode} -\def\XINT_pfloat_Ps #1e#2;% +\def\XINT_pfloat_Ps #1#2#3% {% - \csname XINT_pfloat_Ps\romannumeral#2\endcsname #100000;% + \csname XINT_pfloat_Ps\romannumeral#3\endcsname #1#200000;% }% \def\XINT_pfloat_Psi #1#2#3;{ #1#2.}% \def\XINT_pfloat_Psii #1#2#3#4;{ #1#2#3.}% @@ -33131,7 +33762,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintseries}% - [2020/02/19 v1.4a Expandable partial sums with xint package (JFB)]% + [2020/02/25 v1.4b Expandable partial sums with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintSeries}} % \begin{macrocode} @@ -33632,7 +34263,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintcfrac}% - [2020/02/19 v1.4a Expandable continued fractions with xint package (JFB)]% + [2020/02/25 v1.4b Expandable continued fractions with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintCFrac}} % \begin{macrocode} @@ -34771,7 +35402,7 @@ math shift catcode. % \expanded primitive. This means that there is no more impact on the string % pool. And as internal storage now uses simply core \TeX{} syntax with braces % rather than comma separated items inside a csname dummy control sequence, -% it became possible to let the [...] syntax be associated to a true internal type of «tuple» +% it became much easier to let the [...] syntax be associated to a true internal type of «tuple» % or «list». % % The output of \xintexpr (after \romannumeral0 or \romannumeral-`0 triggered @@ -34797,10 +35428,11 @@ math shift catcode. % $xintcorenameimp macros supporting \xintiiexpr, they usually break if % exercised on some empty argument. % -% The above expansion result uses thus only normal catcodes are output, i.e. -% the backslash, regular braces, and catcode 12 characters (scientific +% The above expansion result \XINTfstop \XINTexprprint .{{<num1>}{<num2}...} +% uses only normal catcodes: +% the backslash, regular braces, and catcode 12 characters. Scientific % notation is internally converted to raw $xintfracnameimp representation -% [N]). +% [N]. % % Additional data may be located before the dot; this is the case only for % \xintfloatexpr currently. As @@ -34879,7 +35511,7 @@ math shift catcode. % because such things were only a single token! I do not describe here how % this is all articulated but it is not hard to see it from the code (the % hardest thing in all such matter was in 2013 to actually write how the -% expansion would be intially launched becasue to do that one basically has to +% expansion would be initially launched because to do that one basically has to % understand the mechanism in its whole and such things are not easy to % develop piecemeal). Another thing to keep in mind is that operators in truth % have a left precedence (i.e. the precedence they show to operators arising @@ -35023,7 +35655,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintexpr}% - [2020/02/19 v1.4a Expandable expression parser (JFB)]% + [2020/02/25 v1.4b Expandable expression parser (JFB)]% \catcode`! 11 \let\XINT_Cmp \xintiiCmp \def\XINTfstop{\noexpand\XINTfstop}% @@ -35045,7 +35677,8 @@ math shift catcode. % technique made very difficult implementation of nested structures. % \subsubsection{Bracketed list rendering with prettifying of leaves from nested % braced contents} -% \lverb|1.4| +% \lverb|1.4 The braces in \XINT:expr:toblistwith are there because there is +% an \expanded trigger.| % \begin{macrocode} \def\XINT:expr:toblistwith#1#2% {% @@ -35075,6 +35708,48 @@ math shift catcode. >% \catcode`{ 1 \catcode`} 2 \catcode`< 12 \catcode`> 12 % \end{macrocode} +% \subsubsection{Flattening nested +% braced contents} +% \lverb|1.4b I hesitated whether using this technique or some variation of +% the method of the ListSel macros. I chose this one which I downscaled from +% toblistwith, I will revisit later. I only have a few minutes right now. +% +% Call form is \expanded\XINT:expr:flatten +% +% See \XINT_expr_func_flat. I hesitated with «flattened», but short names +% are faster parsed. +% | +% \begin{macrocode} +\def\XINT:expr:flatten#1% +{% + {{\expandafter\XINT:expr:flatten_checkempty\detokenize{#1}^}}% +}% +\def\XINT:expr:flatten_checkempty #1% +{% + \if ^#1\expandafter\xint_gobble_i\else\expandafter\XINT:expr:flatten_a\fi + #1% +}% +\begingroup % should I check lccode s generally if corrupted context at load? +\catcode`[ 1 \catcode`] 2 \lccode`[`{ \lccode`]`} +\catcode`< 1 \catcode`> 2 \catcode`{ 12 \catcode`} 12 +\lowercase<\endgroup +\def\XINT:expr:flatten_a {#1% +<% + \if{#1\xint_dothis<\XINT:expr:flatten_a>\fi + \xint_orthat\XINT:expr:flatten_b #1% +>% +\def\XINT:expr:flatten_b #1}% +<% + [#1]\XINT:expr:flatten_c }% +>% +\def\XINT:expr:flatten_c }#1% +<% + \if ^#1\xint_dothis<\xint_gobble_i>\fi + \if{#1\xint_dothis<\XINT:expr:flatten_a>\fi + \xint_orthat<\XINT:expr:flatten_c>#1% +>% +>% back to normal catcodes +% \end{macrocode} % \subsubsection{Braced contents rendering via a \TeX{} alignment with prettifying of leaves} % \lverb|1.4. % @@ -35360,7 +36035,7 @@ math shift catcode. % \lverb|New with 1.2h. I have been for the last three years very strict % regarding macros with \xint or \XINT, but well. % -% 1.4. Definitely I don't like those. Don't use them, I will remove one day!| +% 1.4. Definitely I don't like those. I will remove them at 1.5.| % \begin{macrocode} \let\thexintexpr \xinttheexpr \let\thexintiexpr \xinttheiexpr @@ -35505,7 +36180,6 @@ math shift catcode. % «Mysterious stuff». % | % \begin{macrocode} -\def\XINT:NEhook:unpack{\xint_stop_atfirstofone}% \let\XINT:NEhook:f:one:from:one\expandafter \let\XINT:NEhook:f:one:from:one:direct\empty \let\XINT:NEhook:f:one:from:two\expandafter @@ -36579,6 +37253,7 @@ math shift catcode. \fi }% }% +\def\XINT:NEhook:unpack{\xint_stop_atfirstofone}% \xintFor* #1 in {{expr}{flexpr}{iiexpr}}: {\expandafter\XINT_tmpa\csname XINT_#1_op_0\expandafter\endcsname \csname XINT_#1_until_unpack\endcsname {#1}}% @@ -36588,25 +37263,34 @@ math shift catcode. % \localtableofcontents % % \lverb|1.2d adds the *** for tying via tacit multiplication, for example -% x/2y. Actually I don't need the _itself mechanism for ***, only a precedence.| +% x/2y. Actually I don't need the _itself mechanism for ***, only a +% precedence. +% +% 1.4b subtlety with catcode of ! in \XINT_expr_itself_!=, +% due to chaining of comparison operators +% which use it to reinject into stream, but we must then have it of catcode +% 12 there, whereas so far the itself macros were only expanded in csname context.| % \begin{macrocode} \catcode`& 12 -\xintFor* #1 in {{==}{<=}{>=}{!=}{&&}{||}{**}{//}{/:}{..}{..[}{].}{]..}}% +\xintFor* #1 in {{==}{<=}{>=}{&&}{||}{**}{//}{/:}{..}{..[}{].}{]..}}% \do {\expandafter\def\csname XINT_expr_itself_#1\endcsname {#1}}% \catcode`& 7 +\expandafter\edef\csname XINT_expr_itself_!=\endcsname{\string !=}% \expandafter\let\csname XINT_expr_precedence_***\endcsname \xint_c_xvi % \end{macrocode} -% \subsubsection{\&\&, \textbar\textbar, <, >, ==, <=, >=, !=, //, /:, +, +% \subsubsection{\&\&, \textbar\textbar, //, /:, +, % \textendash, \texorpdfstring{\protect\lowast}{*}, /, \textasciicircum, % \texorpdfstring{\protect\lowast\protect\lowast}{**}{}, \textquotesingle and\textquotesingle, \textquotesingle % or\textquotesingle, \textquotesingle xor\textquotesingle, and % \textquotesingle mod\textquotesingle} % % \lverb@& -% Usage of $& and | is deprecated and only $&$& and || should be used. +% Usage of single character Boolean operators $& and | is deprecated +% (for many years) and only $&$& and || should be used. $& and | will be removed +% at next major release after 1.4. % @ % \begin{macrocode} -\def\XINT_expr_defbin_c #1#2#3#4#5#6#7#8#9% +\def\XINT_expr_defbin_c #1#2#3#4#5#6#7#8% {% \def #1##1% \XINT_expr_op_<op> {% @@ -36616,7 +37300,7 @@ math shift catcode. \def #2##1##2##3##4% \XINT_expr_exec_<op> {% \expandafter##2\expandafter##3\expandafter - {#9{\romannumeral`&&@#6##1##4}}% + {\romannumeral`&&@\XINT:NEhook:f:one:from:two{\romannumeral`&&@#6##1##4}}% }% \def #3##1% \XINT_expr_check-_<op> {% @@ -36645,60 +37329,44 @@ math shift catcode. \csname XINT_#1_op_-#4\expandafter\endcsname \csname #5\expandafter\endcsname \csname XINT_expr_precedence_#2\endcsname - {#1}{\romannumeral`&&@\XINT:NEhook:f:one:from:two}% + {#1}% \expandafter % done 3 times but well \let\csname XINT_expr_precedence_#2\expandafter\endcsname \csname xint_c_#3\endcsname }% -\catcode`& 12 \XINT_expr_defbin_b {expr} {||} {vi}{xii} {xintOR}% \XINT_expr_defbin_b {flexpr}{||} {vi}{xii} {xintOR}% \XINT_expr_defbin_b {iiexpr}{||} {vi}{xii} {xintOR}% +\catcode`& 12 \XINT_expr_defbin_b {expr} {&&} {viii}{xii} {xintAND}% \XINT_expr_defbin_b {flexpr}{&&} {viii}{xii} {xintAND}% \XINT_expr_defbin_b {iiexpr}{&&} {viii}{xii} {xintAND}% +\catcode`& 7 \XINT_expr_defbin_b {expr} {xor}{vi}{xii} {xintXOR}% \XINT_expr_defbin_b {flexpr}{xor}{vi}{xii} {xintXOR}% \XINT_expr_defbin_b {iiexpr}{xor}{vi}{xii} {xintXOR}% -\XINT_expr_defbin_b {expr} < {x}{xii} {xintLt}% -\XINT_expr_defbin_b {flexpr} < {x}{xii} {xintLt}% -\XINT_expr_defbin_b {iiexpr} < {x}{xii} {xintiiLt}% -\XINT_expr_defbin_b {expr} > {x}{xii} {xintGt}% -\XINT_expr_defbin_b {flexpr} > {x}{xii} {xintGt}% -\XINT_expr_defbin_b {iiexpr} > {x}{xii} {xintiiGt}% -\XINT_expr_defbin_b {expr} {==} {x}{xii} {xintEq}% -\XINT_expr_defbin_b {flexpr}{==} {x}{xii} {xintEq}% -\XINT_expr_defbin_b {iiexpr}{==} {x}{xii} {xintiiEq}% -\XINT_expr_defbin_b {expr} {<=} {x}{xii} {xintLtorEq}% -\XINT_expr_defbin_b {flexpr}{<=} {x}{xii} {xintLtorEq}% -\XINT_expr_defbin_b {iiexpr}{<=} {x}{xii} {xintiiLtorEq}% -\XINT_expr_defbin_b {expr} {>=} {x}{xii} {xintGtorEq}% -\XINT_expr_defbin_b {flexpr}{>=} {x}{xii} {xintGtorEq}% -\XINT_expr_defbin_b {iiexpr}{>=} {x}{xii} {xintiiGtorEq}% -\XINT_expr_defbin_b {expr} {!=} {x}{xii} {xintNotEq}% -\XINT_expr_defbin_b {flexpr}{!=} {x}{xii} {xintNotEq}% -\XINT_expr_defbin_b {iiexpr}{!=} {x}{xii} {xintiiNotEq}% -\XINT_expr_defbin_b {expr} {//} {xiv}{xiv}{xintDivFloor}% CHANGED IN 1.2p! +\XINT_expr_defbin_b {expr} {//} {xiv}{xiv}{xintDivFloor}% \XINT_expr_defbin_b {flexpr}{//} {xiv}{xiv}{XINTinFloatDivFloor}% " \XINT_expr_defbin_b {iiexpr}{//} {xiv}{xiv}{xintiiDivFloor}% " \XINT_expr_defbin_b {expr} {/:} {xiv}{xiv}{xintMod}% " \XINT_expr_defbin_b {flexpr}{/:} {xiv}{xiv}{XINTinFloatMod}% " \XINT_expr_defbin_b {iiexpr}{/:} {xiv}{xiv}{xintiiMod}% " -\XINT_expr_defbin_b {expr} + {xii}{xii} {xintAdd}% -\XINT_expr_defbin_b {flexpr} + {xii}{xii} {XINTinFloatAdd}% -\XINT_expr_defbin_b {iiexpr} + {xii}{xii} {xintiiAdd}% -\XINT_expr_defbin_b {expr} - {xii}{xii} {xintSub}% -\XINT_expr_defbin_b {flexpr} - {xii}{xii} {XINTinFloatSub}% -\XINT_expr_defbin_b {iiexpr} - {xii}{xii} {xintiiSub}% +\XINT_expr_defbin_b {expr} + {xii}{xii}{xintAdd}% +\XINT_expr_defbin_b {flexpr} + {xii}{xii}{XINTinFloatAdd}% +\XINT_expr_defbin_b {iiexpr} + {xii}{xii}{xintiiAdd}% +\XINT_expr_defbin_b {expr} - {xii}{xii}{xintSub}% +\XINT_expr_defbin_b {flexpr} - {xii}{xii}{XINTinFloatSub}% +\XINT_expr_defbin_b {iiexpr} - {xii}{xii}{xintiiSub}% \XINT_expr_defbin_b {expr} * {xiv}{xiv}{xintMul}% \XINT_expr_defbin_b {flexpr} * {xiv}{xiv}{XINTinFloatMul}% \XINT_expr_defbin_b {iiexpr} * {xiv}{xiv}{xintiiMul}% \XINT_expr_defbin_b {expr} / {xiv}{xiv}{xintDiv}% \XINT_expr_defbin_b {flexpr} / {xiv}{xiv}{XINTinFloatDiv}% -\XINT_expr_defbin_b {iiexpr} / {xiv}{xiv}{xintiiDivRound}% CHANGED IN 1.1! -\XINT_expr_defbin_b {expr} ^ {xviii}{xviii} {xintPow}% -\XINT_expr_defbin_b {flexpr} ^ {xviii}{xviii} {XINTinFloatPowerH}% -\XINT_expr_defbin_b {iiexpr} ^ {xviii}{xviii} {xintiiPow}% +\XINT_expr_defbin_b {iiexpr} / {xiv}{xiv}{xintiiDivRound}% +\XINT_expr_defbin_b {expr} ^ {xviii}{xviii}{xintPow}% +\XINT_expr_defbin_b {flexpr} ^ {xviii}{xviii}{XINTinFloatPowerH}% +\XINT_expr_defbin_b {iiexpr} ^ {xviii}{xviii}{xintiiPow}% +\catcode`& 12 \xintFor #1 in {and,or,xor,mod} \do {% \expandafter\def\csname XINT_expr_itself_#1\endcsname {#1}% @@ -36718,8 +37386,6 @@ math shift catcode. \expandafter\let\csname XINT_#1_op_mod\expandafter\endcsname \csname XINT_#1_op_/:\endcsname }% -\expandafter\let\csname XINT_expr_precedence_=\expandafter\endcsname - \csname XINT_expr_precedence_==\endcsname \expandafter\let\csname XINT_expr_precedence_&\expandafter\endcsname \csname XINT_expr_precedence_&&\endcsname \expandafter\let\csname XINT_expr_precedence_|\expandafter\endcsname @@ -36728,8 +37394,6 @@ math shift catcode. \csname XINT_expr_precedence_^\endcsname \xintFor #1 in {expr, flexpr, iiexpr} \do {% - \expandafter\let\csname XINT_#1_op_=\expandafter\endcsname - \csname XINT_#1_op_==\endcsname \expandafter\let\csname XINT_#1_op_&\expandafter\endcsname \csname XINT_#1_op_&&\endcsname \expandafter\let\csname XINT_#1_op_|\expandafter\endcsname @@ -36739,39 +37403,133 @@ math shift catcode. }% \catcode`& 7 % \end{macrocode} -% \subsubsection{.., ..[, and ].. as infix operators} -% \lverb|1.2d needed some room between /, * and ^. Hence precedence for ^ -% is now at 9| +% \subsubsection{.., ..[, and ].. for a..b and a..[b]..c syntax} +% \lverb|The 1.4 exec_..[ macros (which do no further expansion!) had silly +% \expandafter doing nothing for the sole reason of sharing a common +% \XINT_expr_defbin_c as used previously for the +, - etc... operators. At +% 1.4b we take the time to set things straight and do other similar +% simplifications.| % \begin{macrocode} -\def\XINT_expr_defbin_b #1#2#3#4% +\def\XINT_expr_defbin_c #1#2#3#4#5#6#7% +{% + \def #1##1% \XINT_expr_op_..[ + {% + \expanded{\unexpanded{#2{##1}}\expandafter}% + \romannumeral`&&@\expandafter#3\romannumeral`&&@\XINT_expr_getnext + }% + \def #2##1##2##3##4% \XINT_expr_exec_..[ + {% + ##2##3{{##1##4}}% + }% + \def #3##1% \XINT_expr_check-_..[ + {% + \xint_UDsignfork + ##1{\expandafter#4\romannumeral`&&@#5}% + -{#4##1}% + \krof + }% + \def #4##1##2% \XINT_expr_checkp_..[ + {% + \ifnum ##1>#6% + \expandafter#4% + \romannumeral`&&@\csname XINT_#7_op_##2\expandafter\endcsname + \else + \expandafter ##1\expandafter ##2% + \fi + }% +}% +\def\XINT_expr_defbin_b #1% +{% + \expandafter\XINT_expr_defbin_c + \csname XINT_#1_op_..[\expandafter\endcsname + \csname XINT_#1_exec_..[\expandafter\endcsname + \csname XINT_#1_check-_..[\expandafter\endcsname + \csname XINT_#1_checkp_..[\expandafter\endcsname + \csname XINT_#1_op_-xii\expandafter\endcsname + \csname XINT_expr_precedence_..[\endcsname + {#1}% +}% +\XINT_expr_defbin_b {expr}% +\XINT_expr_defbin_b {flexpr}% +\XINT_expr_defbin_b {iiexpr}% +\expandafter\let\csname XINT_expr_precedence_..[\endcsname\xint_c_vi +\def\XINT_expr_defbin_c #1#2#3#4#5#6#7#8% +{% + \def #1##1% \XINT_expr_op_<op> + {% + \expanded{\unexpanded{#2{##1}}\expandafter}% + \romannumeral`&&@\expandafter#3\romannumeral`&&@\XINT_expr_getnext + }% + \def #2##1##2##3##4% \XINT_expr_exec_<op> + {% + \expandafter##2\expandafter##3\expanded + {{\XINT:NEhook:x:one:from:two#8##1##4}}% + }% + \def #3##1% \XINT_expr_check-_<op> + {% + \xint_UDsignfork + ##1{\expandafter#4\romannumeral`&&@#5}% + -{#4##1}% + \krof + }% + \def #4##1##2% \XINT_expr_checkp_<op> + {% + \ifnum ##1>#6% + \expandafter#4% + \romannumeral`&&@\csname XINT_#7_op_##2\expandafter\endcsname + \else + \expandafter ##1\expandafter ##2% + \fi + }% +}% +\def\XINT_expr_defbin_b #1#2#3% {% \expandafter\XINT_expr_defbin_c \csname XINT_#1_op_#2\expandafter\endcsname \csname XINT_#1_exec_#2\expandafter\endcsname \csname XINT_#1_check-_#2\expandafter\endcsname \csname XINT_#1_checkp_#2\expandafter\endcsname - \csname XINT_#1_op_-#4\expandafter\endcsname - \expandafter{\expandafter}% + \csname XINT_#1_op_-xii\expandafter\endcsname \csname XINT_expr_precedence_#2\endcsname - {#1}{\expandafter}% REVOIR - \expandafter - \let\csname XINT_expr_precedence_#2\expandafter\endcsname - \csname xint_c_#3\endcsname + {#1}#3% + \expandafter\let + \csname XINT_expr_precedence_#2\expandafter\endcsname\xint_c_vi +}% +\XINT_expr_defbin_b {expr} {..}\xintSeq:tl:x +\XINT_expr_defbin_b {flexpr} {..}\xintSeq:tl:x +\XINT_expr_defbin_b {iiexpr} {..}\xintiiSeq:tl:x +\XINT_expr_defbin_b {expr} {]..}\xintSeqB:tl:x +\XINT_expr_defbin_b {flexpr}{]..}\xintSeqB:tl:x +\XINT_expr_defbin_b {iiexpr}{]..}\xintiiSeqB:tl:x +% \end{macrocode} +% \subsubsection{<, >, ==, <=, >=, != with Python-like chaining} +% \lverb| +% Usage of single character comparison operator = is deprecated (since +% many years) and only == should be used. = will be removed at next major +% release after 1.4. +% | +% \lverb|1.4b +% This is preliminary implementation of chaining of comparison +% operators like Python and (I think) l3fp do. I am not too happy +% with how many times the (second) operand (already evaluated) is fetched. +% | +% \begin{macrocode} +\def\XINT_expr_defbin_d #1#2% +{% + \def #1##1##2##3##4% \XINT_expr_exec_<op> + {% + \expandafter##2\expandafter##3\expandafter + {\romannumeral`&&@\XINT:NEhook:f:one:from:two{\romannumeral`&&@#2##1##4}}% + }% }% -\XINT_expr_defbin_b {expr} {..[}{vi}{xii}% -\XINT_expr_defbin_b {flexpr}{..[}{vi}{xii}% -\XINT_expr_defbin_b {iiexpr}{..[}{vi}{xii}% \def\XINT_expr_defbin_c #1#2#3#4#5#6#7#8#9% {% \def #1##1% \XINT_expr_op_<op> {% \expanded{\unexpanded{#2{##1}}\expandafter}% + \romannumeral`&&@\expandafter#7% \romannumeral`&&@\expandafter#3\romannumeral`&&@\XINT_expr_getnext }% - \def #2##1##2##3##4% \XINT_expr_exec_<op> - {% - \expandafter##2\expandafter##3\expanded{{#9#6##1##4}}% - }% \def #3##1% \XINT_expr_check-_<op> {% \xint_UDsignfork @@ -36781,34 +37539,70 @@ math shift catcode. }% \def #4##1##2% \XINT_expr_checkp_<op> {% - \ifnum ##1>#7% + \ifnum ##1>#6% \expandafter#4% - \romannumeral`&&@\csname XINT_#8_op_##2\expandafter\endcsname - \else + \romannumeral`&&@\csname XINT_#9_op_##2\expandafter\endcsname + \else \expandafter ##1\expandafter ##2% \fi }% + \let #6\xint_c_x + \def #7##1% \XINT_expr_checkc_<op> + {% + \ifnum ##1=\xint_c_x\expandafter#8\fi ##1% + }% + \edef #8##1##2##3% \XINT_expr_execc_<op> + {% + \csname XINT_#9_precedence_\string&\string&\endcsname + \expandafter\noexpand\csname XINT_#9_itself_\string&\string&\endcsname + {##3}% + \XINTfstop.{##3}##2% + }% + \XINT_expr_defbin_d #2% \XINT_expr_exec_<op> }% -\def\XINT_expr_defbin_b #1#2#3#4#5#6% +\def\XINT_expr_defbin_b #1#2%#3% {% \expandafter\XINT_expr_defbin_c \csname XINT_#1_op_#2\expandafter\endcsname \csname XINT_#1_exec_#2\expandafter\endcsname \csname XINT_#1_check-_#2\expandafter\endcsname \csname XINT_#1_checkp_#2\expandafter\endcsname - \csname XINT_#1_op_-#4\expandafter\endcsname - \csname #5\expandafter\endcsname - \csname XINT_expr_precedence_#2\endcsname {#1}#6% - \expandafter\let + \csname XINT_#1_op_-xii\expandafter\endcsname \csname XINT_expr_precedence_#2\expandafter\endcsname - \csname xint_c_#3\endcsname + \csname XINT_#1_checkc_#2\expandafter\endcsname + \csname XINT_#1_execc_#2\endcsname + {#1}%#3% +}% +% \end{macrocode} +% \lverb|Attention that third token here is left in stream by defbin_b, then +% also by defbin_c and is picked up as #2 of defbin_d. Had to work around TeX +% accepting only 9 arguments. Why did it not start counting at #0 like all +% decent mathematicians do?| +% \begin{macrocode} +\XINT_expr_defbin_b {expr} <\xintLt +\XINT_expr_defbin_b {flexpr}<\xintLt +\XINT_expr_defbin_b {iiexpr}<\xintiiLt +\XINT_expr_defbin_b {expr} >\xintGt +\XINT_expr_defbin_b {flexpr}>\xintGt +\XINT_expr_defbin_b {iiexpr}>\xintiiGt +\XINT_expr_defbin_b {expr} {==}\xintEq +\XINT_expr_defbin_b {flexpr}{==}\xintEq +\XINT_expr_defbin_b {iiexpr}{==}\xintiiEq +\XINT_expr_defbin_b {expr} {<=}\xintLtorEq +\XINT_expr_defbin_b {flexpr}{<=}\xintLtorEq +\XINT_expr_defbin_b {iiexpr}{<=}\xintiiLtorEq +\XINT_expr_defbin_b {expr} {>=}\xintGtorEq +\XINT_expr_defbin_b {flexpr}{>=}\xintGtorEq +\XINT_expr_defbin_b {iiexpr}{>=}\xintiiGtorEq +\XINT_expr_defbin_b {expr} {!=}\xintNotEq +\XINT_expr_defbin_b {flexpr}{!=}\xintNotEq +\XINT_expr_defbin_b {iiexpr}{!=}\xintiiNotEq +\expandafter\let\csname XINT_expr_precedence_=\endcsname\xint_c_x +\xintFor #1 in {expr, flexpr, iiexpr} \do +{% + \expandafter\let\csname XINT_#1_op_=\expandafter\endcsname + \csname XINT_#1_op_==\endcsname }% -\XINT_expr_defbin_b {expr} {..} {vi}{xii}{xintSeq:tl:x}\XINT:NEhook:x:one:from:two -\XINT_expr_defbin_b {flexpr}{..} {vi}{xii}{xintSeq:tl:x}\XINT:NEhook:x:one:from:two -\XINT_expr_defbin_b {iiexpr}{..} {vi}{xii}{xintiiSeq:tl:x}\XINT:NEhook:x:one:from:two -\XINT_expr_defbin_b {expr} {]..}{vi}{xii}{xintSeqB:tl:x}\XINT:NEhook:x:one:from:twoandone -\XINT_expr_defbin_b {flexpr}{]..}{vi}{xii}{xintSeqB:tl:x}\XINT:NEhook:x:one:from:twoandone -\XINT_expr_defbin_b {iiexpr}{]..}{vi}{xii}{xintiiSeqB:tl:x}\XINT:NEhook:x:one:from:twoandone % \end{macrocode} % \subsubsection{Support macros for .., ..[ and ]..} % @@ -36970,7 +37764,7 @@ math shift catcode. % \begin{macrocode} \def\XINT_expr_itself_obracket{obracket}% \catcode`] 11 \catcode`[ 11 -\def\XINT_tmpa #1#2#3#4#5#6% +\def\XINT_expr_defbin_c #1#2#3#4#5#6% {% \def #1##1% {% @@ -36999,8 +37793,9 @@ math shift catcode. \fi }% }% -\xintFor #1 in {expr,flexpr,iiexpr} \do {% - \expandafter\XINT_tmpa +\def\XINT_expr_defbin_b #1% +{% + \expandafter\XINT_expr_defbin_c \csname XINT_#1_op_obracket\expandafter\endcsname \csname XINT_#1_op_]\expandafter\endcsname \csname XINT_#1_until_cbracket_a\expandafter\endcsname @@ -37008,6 +37803,9 @@ math shift catcode. \csname XINT_#1_op_-xii\endcsname {#1}% }% +\XINT_expr_defbin_b {expr}% +\XINT_expr_defbin_b {flexpr}% +\XINT_expr_defbin_b {iiexpr}% \def\XINT_expr_missing_] {\XINT_expandableerror{Ooops, looks like we are missing a ] here. Goodbye!}% \xint_c_ \XINT_expr_done}% @@ -37039,7 +37837,7 @@ math shift catcode. % There are some subtle things here with possibility of variables been passed % by reference.| % \begin{macrocode} -\def\XINT_tmpa #1#2#3#4#5#6% +\def\XINT_expr_defbin_c #1#2#3#4#5#6% {% \def #1##1% \XINT_expr_op_[ {% @@ -37074,8 +37872,9 @@ math shift catcode. }% }% \let\XINT_expr_precedence_[ \xint_c_xx -\xintFor #1 in {expr,flexpr,iiexpr} \do {% -\expandafter\XINT_tmpa +\def\XINT_expr_defbin_b #1% +{% + \expandafter\XINT_expr_defbin_c \csname XINT_#1_op_[\expandafter\endcsname \csname XINT_#1_exec_]\expandafter\endcsname \csname XINT_#1_check-_]\expandafter\endcsname @@ -37083,6 +37882,9 @@ math shift catcode. \csname XINT_#1_op_-xii\endcsname {#1}% }% +\XINT_expr_defbin_b {expr}% +\XINT_expr_defbin_b {flexpr}% +\XINT_expr_defbin_b {iiexpr}% \catcode`] 12 \catcode`[ 12 % \end{macrocode} % \lverb|At 1.4 the getnext, scanint, scanfunc, getop chain got revisited to @@ -37092,7 +37894,7 @@ math shift catcode. % also «:,» for example. Thus here we simply have to define the sole operator % «:» and it will be some sort of inert joiner preparing a slicing spec.| % \begin{macrocode} -\def\XINT_tmpa #1#2#3#4#5#6% +\def\XINT_expr_defbin_c #1#2#3#4#5#6% {% \def #1##1% \XINT_expr_op_: {% @@ -37120,14 +37922,18 @@ math shift catcode. }% }% \let\XINT_expr_precedence_: \xint_c_vi -\xintFor #1 in {expr,flexpr,iiexpr} \do {% -\expandafter\XINT_tmpa +\def\XINT_expr_defbin_b #1% +{% + \expandafter\XINT_expr_defbin_c \csname XINT_#1_op_:\expandafter\endcsname \csname XINT_#1_exec_:\expandafter\endcsname \csname XINT_#1_check-_:\expandafter\endcsname \csname XINT_#1_checkp_:\expandafter\endcsname \csname XINT_#1_op_-xii\endcsname {#1}% }% +\XINT_expr_defbin_b {expr}% +\XINT_expr_defbin_b {flexpr}% +\XINT_expr_defbin_b {iiexpr}% % \end{macrocode} % \subsubsection{Macro layer implementing indexing and slicing} % \lverb|xintexpr applies slicing not only to «objects» (which can be passed @@ -38934,8 +39740,8 @@ math shift catcode. % {all}{any}{xor} % {len}{first}{last}{reversed} % {if}{ifint}{ifone}{ifsgn} -% {nuple}}} -% and \noexpand\cshn{unpack()}} +% {nuple}{unpack}{flat}}} +% and \noexpand\cshn{zip()}} % \expandafter\subsection\expandafter{\zzz} % \begin{macrocode} \def\XINT:expr:f:one:and:opt #1#2#3!#4#5% @@ -39634,6 +40440,23 @@ math shift catcode. {\expandafter#1\expandafter#2\romannumeral0\XINT:NEhook:unpack}% \let\XINT_flexpr_func_unpack\XINT_expr_func_unpack \let\XINT_iiexpr_func_unpack\XINT_expr_func_unpack +\def\XINT_expr_func_flat #1#2%#3% +{% + \expandafter#1\expandafter#2\expanded + \XINT:NEhook:x:flatten\XINT:expr:flatten +}% +\let\XINT_flexpr_func_flat\XINT_expr_func_flat +\let\XINT_iiexpr_func_flat\XINT_expr_func_flat +\let\XINT:NEhook:x:flatten\empty +\def\XINT_expr_func_zip #1#2%#3% +{% + \expandafter#1\expandafter#2\romannumeral`&&@% + \XINT:NEhook:x:zip\XINT:expr:zip +}% +\let\XINT_flexpr_func_zip\XINT_expr_func_zip +\let\XINT_iiexpr_func_zip\XINT_expr_func_zip +\let\XINT:NEhook:x:zip\empty +\def\XINT:expr:zip#1{\expandafter{\expanded\XINT_zip_A#1\xint_bye\xint_bye}}% % \end{macrocode} % \subsection{User declared functions} % \lverb|& @@ -40458,6 +41281,43 @@ math shift catcode. \fi \XINT:expr:toblistwith{##1}{##2}% }}\expandafter\XINT:NE:x:toblist\string#% \def\XINT:NE:x:toblist:p\XINT:expr:toblistwith #1#2{{\XINTfstop.{#2}}}% +\def\XINT:NE:x:flatten#1{% +\def\XINT:NE:x:flatten\XINT:expr:flatten##1% +{% + \if 0\expandafter\XINT:NE:hastilde\detokenize{##1}~!\relax + \expandafter\XINT:NE:hashash \detokenize{##1}#1!\relax 0% + \else + \expandafter\XINT:NE:x:flatten:p + \fi \XINT:expr:flatten{##1}% +}}\expandafter\XINT:NE:x:flatten\string#% +\def\XINT:NE:x:flatten:p\XINT:expr:flatten #1% +{% + {{% + \detokenize + {% + \expandafter\XINT:expr:flatten_checkempty + \detokenize\expandafter{\expanded{#1}}$XINT_expr_caret%$ + }% + }}% +}% +\def\XINT:NE:x:zip#1{% +\def\XINT:NE:x:zip\XINT:expr:zip##1% +{% + \if 0\expandafter\XINT:NE:hastilde\detokenize{##1}~!\relax + \expandafter\XINT:NE:hashash \detokenize{##1}#1!\relax 0% + \else + \expandafter\XINT:NE:x:zip:p + \fi \XINT:expr:zip{##1}% +}}\expandafter\XINT:NE:x:zip\string#% +\def\XINT:NE:x:zip:p\XINT:expr:zip #1% +{% + \expandafter{% + \detokenize + {% + \expanded\expandafter\XINT_zip_A\expanded{#1}\xint_bye\xint_bye + }% + }% +}% \def\XINT:NE:x:mapwithin#1{% \def\XINT:NE:x:mapwithin\XINT:expr:mapwithin ##1##2% {% @@ -40608,6 +41468,8 @@ math shift catcode. \let\XINT:NEhook:rrseq \XINT:NE:rrseq \let\XINT:NEhook:iterr \XINT:NE:iterr \let\XINT:NEhook:x:toblist \XINT:NE:x:toblist + \let\XINT:NEhook:x:flatten \XINT:NE:x:flatten + \let\XINT:NEhook:x:zip \XINT:NE:x:zip \let\XINT:NEhook:x:mapwithin \XINT:NE:x:mapwithin \let\XINT:NEhook:x:ndmapx \XINT:NE:x:ndmapx \let\XINT:NEhook:userfunc \XINT:NE:userfunc @@ -40941,10 +41803,10 @@ math shift catcode. \expandafter\xint_secondoftwo \fi {\immediate\write-1{Reloading xinttrig library using Digits=\xinttheDigits.}}% -{\expandafter\gdef\csname xintlibver@trig\endcsname{2020/02/19 v1.4a}% +{\expandafter\gdef\csname xintlibver@trig\endcsname{2020/02/25 v1.4b}% \XINT_providespackage \ProvidesPackage{xinttrig}% -[2020/02/19 v1.4a Trigonometrical functions for xintexpr (JFB)]% +[2020/02/25 v1.4b Trigonometrical functions for xintexpr (JFB)]% }% % \end{macrocode} % \subsection{Ensure used letters are dummy letters} @@ -40991,59 +41853,25 @@ math shift catcode. % \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 have to be careful that 1/i! in a float expression first evaluates i! +% as a floating point number then computes the inverse. Even if i! was +% computed exactly before being float-rounded, this process would not +% necessarily lead to the correct rounding of the exact fraction 1/i!. % -% 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 \xintdeffloatfunc of -% sin_aux(X) and cos_aux(X) we would have this problem. +% We could use \xintexpr1/i!\relax encapsulation but then the actual +% rounding is delayed to the time when functions are used... this is bad. % -% 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. +% We need to get now the correct rounding of the exact 1/i!. % % 1.4 update: use \xintfloatexpr with optional argument for the rounding -% rather than «0+x» method. +% rather than «0+x» method. And there is no need now to hide within braces +% the inner semi-colon. % | % \begin{macrocode} \xintdeffloatvar invfact\xintListWithSep{, invfact}{\xintSeq{2}{44}}% := \xintfloatexpr [\XINTdigits] % force float rounding after exact evaluations - \xintexpr rseq(1/2{;}@/i, i=3..44)\relax % need to hide inner ; from \xintdeffloatvar + \xintexpr rseq(1/2; @/i, i=3..44)\relax % no need to hide this inner ; \relax;% % \end{macrocode} % \subsection{The sine and cosine series} @@ -41974,7 +42802,7 @@ math shift catcode. \xintexprSafeCatcodes\catcode`_ 11 \XINT_providespackage \ProvidesPackage{xintlog}% -[2020/02/19 v1.4a Logarithms and exponentials for xintexpr (JFB)]% +[2020/02/25 v1.4b Logarithms and exponentials for xintexpr (JFB)]% % \end{macrocode} % \subsection{Loading of \cshn{poormanlog} package} % \lverb|Attention to catcode regime when loading poormanlog. It matters less @@ -42171,34 +42999,34 @@ xint.sty:205 xintbinhex.sty:53 xintcfrac.sty:183 xintcore.sty:271 -xintexpr.sty:414 -xintfrac.sty:494 +xintexpr.sty:430 +xintfrac.sty:496 xintgcd.sty:41 xintkernel.sty:17 xintlog.sty:9 xintseries.sty:48 -xinttools.sty:153 +xinttools.sty:157 xinttrig.sty:31 \fi % grep -o "^{%" xint*sty | wc -l -\def\totala{ 1919} +\def\totala{ 1941} \iffalse % grep -c -e "^}%" xint*sty xint.sty:204 xintbinhex.sty:52 xintcfrac.sty:183 xintcore.sty:268 -xintexpr.sty:402 -xintfrac.sty:497 +xintexpr.sty:413 +xintfrac.sty:499 xintgcd.sty:43 xintkernel.sty:18 xintlog.sty:9 xintseries.sty:48 -xinttools.sty:152 +xinttools.sty:156 xinttrig.sty:32 \fi % grep -o "^}%" xint*sty | wc -l -\def\totalb{ 1908} +\def\totalb{ 1925} \cleardoublepage \section{Cumulative line count} @@ -42222,8 +43050,8 @@ xinttrig.sty:32 \TeX\strut. Version {\xintbndlversion} of {\xintbndldate}.\par } -\CheckSum {34648}% 1.4a -% 34575 pour 1.4 +\CheckSum {35103}% 1.4b +% 34648 pour 1.4a, 34575 pour 1.4 % 33497 pour 1.3f, 33274 pour 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, diff --git a/Master/texmf-dist/tex/generic/xint/xint.sty b/Master/texmf-dist/tex/generic/xint/xint.sty index 68d37b63ea7..17115294aac 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.4a 2020/02/19 +%% The xint bundle 1.4b 2020/02/25 %% Copyright (C) 2013-2020 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}% - [2020/02/19 v1.4a Expandable operations on big integers (JFB)]% + [2020/02/25 v1.4b 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}% diff --git a/Master/texmf-dist/tex/generic/xint/xintbinhex.sty b/Master/texmf-dist/tex/generic/xint/xintbinhex.sty index dd03a0f5378..22aac49ae40 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.4a 2020/02/19 +%% The xint bundle 1.4b 2020/02/25 %% Copyright (C) 2013-2020 by Jean-Francois Burnol %% xintbinhex: Expandable binary and hexadecimal conversions %% --------------------------------------------------------------- @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintbinhex}% - [2020/02/19 v1.4a Expandable binary and hexadecimal conversions (JFB)]% + [2020/02/25 v1.4b 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 8d82132fcd0..4be57daef06 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.4a 2020/02/19 +%% The xint bundle 1.4b 2020/02/25 %% Copyright (C) 2013-2020 by Jean-Francois Burnol %% xintcfrac: Expandable continued fractions with xint package %% --------------------------------------------------------------- @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintcfrac}% - [2020/02/19 v1.4a Expandable continued fractions with xint package (JFB)]% + [2020/02/25 v1.4b 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 909eabff017..59aa7106101 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.4a 2020/02/19 +%% The xint bundle 1.4b 2020/02/25 %% Copyright (C) 2013-2020 by Jean-Francois Burnol %% xintcore: Expandable arithmetic on big integers %% --------------------------------------------------------------- @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintcore}% - [2020/02/19 v1.4a Expandable arithmetic on big integers (JFB)]% + [2020/02/25 v1.4b 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 2d8a4df7af5..889e3e521b9 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.4a 2020/02/19 +%% The xint bundle 1.4b 2020/02/25 %% Copyright (C) 2013-2020 by Jean-Francois Burnol %% xintexpr: Expandable expression parser %% --------------------------------------------------------------- @@ -82,7 +82,7 @@ \XINTsetupcatcodes% \XINT_providespackage \ProvidesPackage{xintexpr}% - [2020/02/19 v1.4a Expandable expression parser (JFB)]% + [2020/02/25 v1.4b Expandable expression parser (JFB)]% \catcode`! 11 \let\XINT_Cmp \xintiiCmp \def\XINTfstop{\noexpand\XINTfstop}% @@ -120,6 +120,35 @@ \xint_orthat<]\XINT:expr:toblist_c>#1#2% >% \catcode`{ 1 \catcode`} 2 \catcode`< 12 \catcode`> 12 +\def\XINT:expr:flatten#1% +{% + {{\expandafter\XINT:expr:flatten_checkempty\detokenize{#1}^}}% +}% +\def\XINT:expr:flatten_checkempty #1% +{% + \if ^#1\expandafter\xint_gobble_i\else\expandafter\XINT:expr:flatten_a\fi + #1% +}% +\begingroup % should I check lccode s generally if corrupted context at load? +\catcode`[ 1 \catcode`] 2 \lccode`[`{ \lccode`]`} +\catcode`< 1 \catcode`> 2 \catcode`{ 12 \catcode`} 12 +\lowercase<\endgroup +\def\XINT:expr:flatten_a {#1% +<% + \if{#1\xint_dothis<\XINT:expr:flatten_a>\fi + \xint_orthat\XINT:expr:flatten_b #1% +>% +\def\XINT:expr:flatten_b #1}% +<% + [#1]\XINT:expr:flatten_c }% +>% +\def\XINT:expr:flatten_c }#1% +<% + \if ^#1\xint_dothis<\xint_gobble_i>\fi + \if{#1\xint_dothis<\XINT:expr:flatten_a>\fi + \xint_orthat<\XINT:expr:flatten_c>#1% +>% +>% back to normal catcodes \catcode`& 4 \protected\def\xintexpralignbegin {\halign\bgroup\tabskip2ex\hfil##&&##\hfil\cr}% \protected\def\xintexpralignend {\crcr\egroup}% @@ -354,7 +383,6 @@ #1#2#3#4#5#6#7#8#9% \xintthespaceseparated_b}% \def\xintthespaceseparated_c !#1!#2^{#1}% -\def\XINT:NEhook:unpack{\xint_stop_atfirstofone}% \let\XINT:NEhook:f:one:from:one\expandafter \let\XINT:NEhook:f:one:from:one:direct\empty \let\XINT:NEhook:f:one:from:two\expandafter @@ -1018,15 +1046,17 @@ \fi }% }% +\def\XINT:NEhook:unpack{\xint_stop_atfirstofone}% \xintFor* #1 in {{expr}{flexpr}{iiexpr}}: {\expandafter\XINT_tmpa\csname XINT_#1_op_0\expandafter\endcsname \csname XINT_#1_until_unpack\endcsname {#1}}% \catcode`& 12 -\xintFor* #1 in {{==}{<=}{>=}{!=}{&&}{||}{**}{//}{/:}{..}{..[}{].}{]..}}% +\xintFor* #1 in {{==}{<=}{>=}{&&}{||}{**}{//}{/:}{..}{..[}{].}{]..}}% \do {\expandafter\def\csname XINT_expr_itself_#1\endcsname {#1}}% \catcode`& 7 +\expandafter\edef\csname XINT_expr_itself_!=\endcsname{\string !=}% \expandafter\let\csname XINT_expr_precedence_***\endcsname \xint_c_xvi -\def\XINT_expr_defbin_c #1#2#3#4#5#6#7#8#9% +\def\XINT_expr_defbin_c #1#2#3#4#5#6#7#8% {% \def #1##1% \XINT_expr_op_<op> {% @@ -1036,7 +1066,7 @@ \def #2##1##2##3##4% \XINT_expr_exec_<op> {% \expandafter##2\expandafter##3\expandafter - {#9{\romannumeral`&&@#6##1##4}}% + {\romannumeral`&&@\XINT:NEhook:f:one:from:two{\romannumeral`&&@#6##1##4}}% }% \def #3##1% \XINT_expr_check-_<op> {% @@ -1065,60 +1095,44 @@ \csname XINT_#1_op_-#4\expandafter\endcsname \csname #5\expandafter\endcsname \csname XINT_expr_precedence_#2\endcsname - {#1}{\romannumeral`&&@\XINT:NEhook:f:one:from:two}% + {#1}% \expandafter % done 3 times but well \let\csname XINT_expr_precedence_#2\expandafter\endcsname \csname xint_c_#3\endcsname }% -\catcode`& 12 \XINT_expr_defbin_b {expr} {||} {vi}{xii} {xintOR}% \XINT_expr_defbin_b {flexpr}{||} {vi}{xii} {xintOR}% \XINT_expr_defbin_b {iiexpr}{||} {vi}{xii} {xintOR}% +\catcode`& 12 \XINT_expr_defbin_b {expr} {&&} {viii}{xii} {xintAND}% \XINT_expr_defbin_b {flexpr}{&&} {viii}{xii} {xintAND}% \XINT_expr_defbin_b {iiexpr}{&&} {viii}{xii} {xintAND}% +\catcode`& 7 \XINT_expr_defbin_b {expr} {xor}{vi}{xii} {xintXOR}% \XINT_expr_defbin_b {flexpr}{xor}{vi}{xii} {xintXOR}% \XINT_expr_defbin_b {iiexpr}{xor}{vi}{xii} {xintXOR}% -\XINT_expr_defbin_b {expr} < {x}{xii} {xintLt}% -\XINT_expr_defbin_b {flexpr} < {x}{xii} {xintLt}% -\XINT_expr_defbin_b {iiexpr} < {x}{xii} {xintiiLt}% -\XINT_expr_defbin_b {expr} > {x}{xii} {xintGt}% -\XINT_expr_defbin_b {flexpr} > {x}{xii} {xintGt}% -\XINT_expr_defbin_b {iiexpr} > {x}{xii} {xintiiGt}% -\XINT_expr_defbin_b {expr} {==} {x}{xii} {xintEq}% -\XINT_expr_defbin_b {flexpr}{==} {x}{xii} {xintEq}% -\XINT_expr_defbin_b {iiexpr}{==} {x}{xii} {xintiiEq}% -\XINT_expr_defbin_b {expr} {<=} {x}{xii} {xintLtorEq}% -\XINT_expr_defbin_b {flexpr}{<=} {x}{xii} {xintLtorEq}% -\XINT_expr_defbin_b {iiexpr}{<=} {x}{xii} {xintiiLtorEq}% -\XINT_expr_defbin_b {expr} {>=} {x}{xii} {xintGtorEq}% -\XINT_expr_defbin_b {flexpr}{>=} {x}{xii} {xintGtorEq}% -\XINT_expr_defbin_b {iiexpr}{>=} {x}{xii} {xintiiGtorEq}% -\XINT_expr_defbin_b {expr} {!=} {x}{xii} {xintNotEq}% -\XINT_expr_defbin_b {flexpr}{!=} {x}{xii} {xintNotEq}% -\XINT_expr_defbin_b {iiexpr}{!=} {x}{xii} {xintiiNotEq}% -\XINT_expr_defbin_b {expr} {//} {xiv}{xiv}{xintDivFloor}% CHANGED IN 1.2p! +\XINT_expr_defbin_b {expr} {//} {xiv}{xiv}{xintDivFloor}% \XINT_expr_defbin_b {flexpr}{//} {xiv}{xiv}{XINTinFloatDivFloor}% " \XINT_expr_defbin_b {iiexpr}{//} {xiv}{xiv}{xintiiDivFloor}% " \XINT_expr_defbin_b {expr} {/:} {xiv}{xiv}{xintMod}% " \XINT_expr_defbin_b {flexpr}{/:} {xiv}{xiv}{XINTinFloatMod}% " \XINT_expr_defbin_b {iiexpr}{/:} {xiv}{xiv}{xintiiMod}% " -\XINT_expr_defbin_b {expr} + {xii}{xii} {xintAdd}% -\XINT_expr_defbin_b {flexpr} + {xii}{xii} {XINTinFloatAdd}% -\XINT_expr_defbin_b {iiexpr} + {xii}{xii} {xintiiAdd}% -\XINT_expr_defbin_b {expr} - {xii}{xii} {xintSub}% -\XINT_expr_defbin_b {flexpr} - {xii}{xii} {XINTinFloatSub}% -\XINT_expr_defbin_b {iiexpr} - {xii}{xii} {xintiiSub}% +\XINT_expr_defbin_b {expr} + {xii}{xii}{xintAdd}% +\XINT_expr_defbin_b {flexpr} + {xii}{xii}{XINTinFloatAdd}% +\XINT_expr_defbin_b {iiexpr} + {xii}{xii}{xintiiAdd}% +\XINT_expr_defbin_b {expr} - {xii}{xii}{xintSub}% +\XINT_expr_defbin_b {flexpr} - {xii}{xii}{XINTinFloatSub}% +\XINT_expr_defbin_b {iiexpr} - {xii}{xii}{xintiiSub}% \XINT_expr_defbin_b {expr} * {xiv}{xiv}{xintMul}% \XINT_expr_defbin_b {flexpr} * {xiv}{xiv}{XINTinFloatMul}% \XINT_expr_defbin_b {iiexpr} * {xiv}{xiv}{xintiiMul}% \XINT_expr_defbin_b {expr} / {xiv}{xiv}{xintDiv}% \XINT_expr_defbin_b {flexpr} / {xiv}{xiv}{XINTinFloatDiv}% -\XINT_expr_defbin_b {iiexpr} / {xiv}{xiv}{xintiiDivRound}% CHANGED IN 1.1! -\XINT_expr_defbin_b {expr} ^ {xviii}{xviii} {xintPow}% -\XINT_expr_defbin_b {flexpr} ^ {xviii}{xviii} {XINTinFloatPowerH}% -\XINT_expr_defbin_b {iiexpr} ^ {xviii}{xviii} {xintiiPow}% +\XINT_expr_defbin_b {iiexpr} / {xiv}{xiv}{xintiiDivRound}% +\XINT_expr_defbin_b {expr} ^ {xviii}{xviii}{xintPow}% +\XINT_expr_defbin_b {flexpr} ^ {xviii}{xviii}{XINTinFloatPowerH}% +\XINT_expr_defbin_b {iiexpr} ^ {xviii}{xviii}{xintiiPow}% +\catcode`& 12 \xintFor #1 in {and,or,xor,mod} \do {% \expandafter\def\csname XINT_expr_itself_#1\endcsname {#1}% @@ -1138,8 +1152,6 @@ \expandafter\let\csname XINT_#1_op_mod\expandafter\endcsname \csname XINT_#1_op_/:\endcsname }% -\expandafter\let\csname XINT_expr_precedence_=\expandafter\endcsname - \csname XINT_expr_precedence_==\endcsname \expandafter\let\csname XINT_expr_precedence_&\expandafter\endcsname \csname XINT_expr_precedence_&&\endcsname \expandafter\let\csname XINT_expr_precedence_|\expandafter\endcsname @@ -1148,8 +1160,6 @@ \csname XINT_expr_precedence_^\endcsname \xintFor #1 in {expr, flexpr, iiexpr} \do {% - \expandafter\let\csname XINT_#1_op_=\expandafter\endcsname - \csname XINT_#1_op_==\endcsname \expandafter\let\csname XINT_#1_op_&\expandafter\endcsname \csname XINT_#1_op_&&\endcsname \expandafter\let\csname XINT_#1_op_|\expandafter\endcsname @@ -1158,35 +1168,113 @@ \csname XINT_#1_op_^\endcsname }% \catcode`& 7 -\def\XINT_expr_defbin_b #1#2#3#4% +\def\XINT_expr_defbin_c #1#2#3#4#5#6#7% +{% + \def #1##1% \XINT_expr_op_..[ + {% + \expanded{\unexpanded{#2{##1}}\expandafter}% + \romannumeral`&&@\expandafter#3\romannumeral`&&@\XINT_expr_getnext + }% + \def #2##1##2##3##4% \XINT_expr_exec_..[ + {% + ##2##3{{##1##4}}% + }% + \def #3##1% \XINT_expr_check-_..[ + {% + \xint_UDsignfork + ##1{\expandafter#4\romannumeral`&&@#5}% + -{#4##1}% + \krof + }% + \def #4##1##2% \XINT_expr_checkp_..[ + {% + \ifnum ##1>#6% + \expandafter#4% + \romannumeral`&&@\csname XINT_#7_op_##2\expandafter\endcsname + \else + \expandafter ##1\expandafter ##2% + \fi + }% +}% +\def\XINT_expr_defbin_b #1% +{% + \expandafter\XINT_expr_defbin_c + \csname XINT_#1_op_..[\expandafter\endcsname + \csname XINT_#1_exec_..[\expandafter\endcsname + \csname XINT_#1_check-_..[\expandafter\endcsname + \csname XINT_#1_checkp_..[\expandafter\endcsname + \csname XINT_#1_op_-xii\expandafter\endcsname + \csname XINT_expr_precedence_..[\endcsname + {#1}% +}% +\XINT_expr_defbin_b {expr}% +\XINT_expr_defbin_b {flexpr}% +\XINT_expr_defbin_b {iiexpr}% +\expandafter\let\csname XINT_expr_precedence_..[\endcsname\xint_c_vi +\def\XINT_expr_defbin_c #1#2#3#4#5#6#7#8% +{% + \def #1##1% \XINT_expr_op_<op> + {% + \expanded{\unexpanded{#2{##1}}\expandafter}% + \romannumeral`&&@\expandafter#3\romannumeral`&&@\XINT_expr_getnext + }% + \def #2##1##2##3##4% \XINT_expr_exec_<op> + {% + \expandafter##2\expandafter##3\expanded + {{\XINT:NEhook:x:one:from:two#8##1##4}}% + }% + \def #3##1% \XINT_expr_check-_<op> + {% + \xint_UDsignfork + ##1{\expandafter#4\romannumeral`&&@#5}% + -{#4##1}% + \krof + }% + \def #4##1##2% \XINT_expr_checkp_<op> + {% + \ifnum ##1>#6% + \expandafter#4% + \romannumeral`&&@\csname XINT_#7_op_##2\expandafter\endcsname + \else + \expandafter ##1\expandafter ##2% + \fi + }% +}% +\def\XINT_expr_defbin_b #1#2#3% {% \expandafter\XINT_expr_defbin_c \csname XINT_#1_op_#2\expandafter\endcsname \csname XINT_#1_exec_#2\expandafter\endcsname \csname XINT_#1_check-_#2\expandafter\endcsname \csname XINT_#1_checkp_#2\expandafter\endcsname - \csname XINT_#1_op_-#4\expandafter\endcsname - \expandafter{\expandafter}% + \csname XINT_#1_op_-xii\expandafter\endcsname \csname XINT_expr_precedence_#2\endcsname - {#1}{\expandafter}% REVOIR - \expandafter - \let\csname XINT_expr_precedence_#2\expandafter\endcsname - \csname xint_c_#3\endcsname + {#1}#3% + \expandafter\let + \csname XINT_expr_precedence_#2\expandafter\endcsname\xint_c_vi +}% +\XINT_expr_defbin_b {expr} {..}\xintSeq:tl:x +\XINT_expr_defbin_b {flexpr} {..}\xintSeq:tl:x +\XINT_expr_defbin_b {iiexpr} {..}\xintiiSeq:tl:x +\XINT_expr_defbin_b {expr} {]..}\xintSeqB:tl:x +\XINT_expr_defbin_b {flexpr}{]..}\xintSeqB:tl:x +\XINT_expr_defbin_b {iiexpr}{]..}\xintiiSeqB:tl:x +\def\XINT_expr_defbin_d #1#2% +{% + \def #1##1##2##3##4% \XINT_expr_exec_<op> + {% + \expandafter##2\expandafter##3\expandafter + {\romannumeral`&&@\XINT:NEhook:f:one:from:two{\romannumeral`&&@#2##1##4}}% + }% }% -\XINT_expr_defbin_b {expr} {..[}{vi}{xii}% -\XINT_expr_defbin_b {flexpr}{..[}{vi}{xii}% -\XINT_expr_defbin_b {iiexpr}{..[}{vi}{xii}% \def\XINT_expr_defbin_c #1#2#3#4#5#6#7#8#9% {% \def #1##1% \XINT_expr_op_<op> {% \expanded{\unexpanded{#2{##1}}\expandafter}% + \romannumeral`&&@\expandafter#7% \romannumeral`&&@\expandafter#3\romannumeral`&&@\XINT_expr_getnext }% - \def #2##1##2##3##4% \XINT_expr_exec_<op> - {% - \expandafter##2\expandafter##3\expanded{{#9#6##1##4}}% - }% \def #3##1% \XINT_expr_check-_<op> {% \xint_UDsignfork @@ -1196,34 +1284,64 @@ }% \def #4##1##2% \XINT_expr_checkp_<op> {% - \ifnum ##1>#7% + \ifnum ##1>#6% \expandafter#4% - \romannumeral`&&@\csname XINT_#8_op_##2\expandafter\endcsname + \romannumeral`&&@\csname XINT_#9_op_##2\expandafter\endcsname \else \expandafter ##1\expandafter ##2% \fi }% + \let #6\xint_c_x + \def #7##1% \XINT_expr_checkc_<op> + {% + \ifnum ##1=\xint_c_x\expandafter#8\fi ##1% + }% + \edef #8##1##2##3% \XINT_expr_execc_<op> + {% + \csname XINT_#9_precedence_\string&\string&\endcsname + \expandafter\noexpand\csname XINT_#9_itself_\string&\string&\endcsname + {##3}% + \XINTfstop.{##3}##2% + }% + \XINT_expr_defbin_d #2% \XINT_expr_exec_<op> }% -\def\XINT_expr_defbin_b #1#2#3#4#5#6% +\def\XINT_expr_defbin_b #1#2%#3% {% \expandafter\XINT_expr_defbin_c \csname XINT_#1_op_#2\expandafter\endcsname \csname XINT_#1_exec_#2\expandafter\endcsname \csname XINT_#1_check-_#2\expandafter\endcsname \csname XINT_#1_checkp_#2\expandafter\endcsname - \csname XINT_#1_op_-#4\expandafter\endcsname - \csname #5\expandafter\endcsname - \csname XINT_expr_precedence_#2\endcsname {#1}#6% - \expandafter\let + \csname XINT_#1_op_-xii\expandafter\endcsname \csname XINT_expr_precedence_#2\expandafter\endcsname - \csname xint_c_#3\endcsname -}% -\XINT_expr_defbin_b {expr} {..} {vi}{xii}{xintSeq:tl:x}\XINT:NEhook:x:one:from:two -\XINT_expr_defbin_b {flexpr}{..} {vi}{xii}{xintSeq:tl:x}\XINT:NEhook:x:one:from:two -\XINT_expr_defbin_b {iiexpr}{..} {vi}{xii}{xintiiSeq:tl:x}\XINT:NEhook:x:one:from:two -\XINT_expr_defbin_b {expr} {]..}{vi}{xii}{xintSeqB:tl:x}\XINT:NEhook:x:one:from:twoandone -\XINT_expr_defbin_b {flexpr}{]..}{vi}{xii}{xintSeqB:tl:x}\XINT:NEhook:x:one:from:twoandone -\XINT_expr_defbin_b {iiexpr}{]..}{vi}{xii}{xintiiSeqB:tl:x}\XINT:NEhook:x:one:from:twoandone + \csname XINT_#1_checkc_#2\expandafter\endcsname + \csname XINT_#1_execc_#2\endcsname + {#1}%#3% +}% +\XINT_expr_defbin_b {expr} <\xintLt +\XINT_expr_defbin_b {flexpr}<\xintLt +\XINT_expr_defbin_b {iiexpr}<\xintiiLt +\XINT_expr_defbin_b {expr} >\xintGt +\XINT_expr_defbin_b {flexpr}>\xintGt +\XINT_expr_defbin_b {iiexpr}>\xintiiGt +\XINT_expr_defbin_b {expr} {==}\xintEq +\XINT_expr_defbin_b {flexpr}{==}\xintEq +\XINT_expr_defbin_b {iiexpr}{==}\xintiiEq +\XINT_expr_defbin_b {expr} {<=}\xintLtorEq +\XINT_expr_defbin_b {flexpr}{<=}\xintLtorEq +\XINT_expr_defbin_b {iiexpr}{<=}\xintiiLtorEq +\XINT_expr_defbin_b {expr} {>=}\xintGtorEq +\XINT_expr_defbin_b {flexpr}{>=}\xintGtorEq +\XINT_expr_defbin_b {iiexpr}{>=}\xintiiGtorEq +\XINT_expr_defbin_b {expr} {!=}\xintNotEq +\XINT_expr_defbin_b {flexpr}{!=}\xintNotEq +\XINT_expr_defbin_b {iiexpr}{!=}\xintiiNotEq +\expandafter\let\csname XINT_expr_precedence_=\endcsname\xint_c_x +\xintFor #1 in {expr, flexpr, iiexpr} \do +{% + \expandafter\let\csname XINT_#1_op_=\expandafter\endcsname + \csname XINT_#1_op_==\endcsname +}% \def\xintSeq:tl:x #1#2% {% \expandafter\XINT_Seq:tl:x @@ -1332,7 +1450,7 @@ }% \def\XINT_expr_itself_obracket{obracket}% \catcode`] 11 \catcode`[ 11 -\def\XINT_tmpa #1#2#3#4#5#6% +\def\XINT_expr_defbin_c #1#2#3#4#5#6% {% \def #1##1% {% @@ -1361,8 +1479,9 @@ \fi }% }% -\xintFor #1 in {expr,flexpr,iiexpr} \do {% - \expandafter\XINT_tmpa +\def\XINT_expr_defbin_b #1% +{% + \expandafter\XINT_expr_defbin_c \csname XINT_#1_op_obracket\expandafter\endcsname \csname XINT_#1_op_]\expandafter\endcsname \csname XINT_#1_until_cbracket_a\expandafter\endcsname @@ -1370,11 +1489,14 @@ \csname XINT_#1_op_-xii\endcsname {#1}% }% +\XINT_expr_defbin_b {expr}% +\XINT_expr_defbin_b {flexpr}% +\XINT_expr_defbin_b {iiexpr}% \def\XINT_expr_missing_] {\XINT_expandableerror{Ooops, looks like we are missing a ] here. Goodbye!}% \xint_c_ \XINT_expr_done}% \let\XINT_expr_precedence_]\xint_c_ii -\def\XINT_tmpa #1#2#3#4#5#6% +\def\XINT_expr_defbin_c #1#2#3#4#5#6% {% \def #1##1% \XINT_expr_op_[ {% @@ -1409,8 +1531,9 @@ }% }% \let\XINT_expr_precedence_[ \xint_c_xx -\xintFor #1 in {expr,flexpr,iiexpr} \do {% -\expandafter\XINT_tmpa +\def\XINT_expr_defbin_b #1% +{% + \expandafter\XINT_expr_defbin_c \csname XINT_#1_op_[\expandafter\endcsname \csname XINT_#1_exec_]\expandafter\endcsname \csname XINT_#1_check-_]\expandafter\endcsname @@ -1418,8 +1541,11 @@ \csname XINT_#1_op_-xii\endcsname {#1}% }% +\XINT_expr_defbin_b {expr}% +\XINT_expr_defbin_b {flexpr}% +\XINT_expr_defbin_b {iiexpr}% \catcode`] 12 \catcode`[ 12 -\def\XINT_tmpa #1#2#3#4#5#6% +\def\XINT_expr_defbin_c #1#2#3#4#5#6% {% \def #1##1% \XINT_expr_op_: {% @@ -1447,14 +1573,18 @@ }% }% \let\XINT_expr_precedence_: \xint_c_vi -\xintFor #1 in {expr,flexpr,iiexpr} \do {% -\expandafter\XINT_tmpa +\def\XINT_expr_defbin_b #1% +{% + \expandafter\XINT_expr_defbin_c \csname XINT_#1_op_:\expandafter\endcsname \csname XINT_#1_exec_:\expandafter\endcsname \csname XINT_#1_check-_:\expandafter\endcsname \csname XINT_#1_checkp_:\expandafter\endcsname \csname XINT_#1_op_-xii\endcsname {#1}% }% +\XINT_expr_defbin_b {expr}% +\XINT_expr_defbin_b {flexpr}% +\XINT_expr_defbin_b {iiexpr}% \def\XINT_ListSel_deeper #1% {% \if :#1\xint_dothis\XINT_ListSel_slice_next\fi @@ -3249,6 +3379,23 @@ {\expandafter#1\expandafter#2\romannumeral0\XINT:NEhook:unpack}% \let\XINT_flexpr_func_unpack\XINT_expr_func_unpack \let\XINT_iiexpr_func_unpack\XINT_expr_func_unpack +\def\XINT_expr_func_flat #1#2%#3% +{% + \expandafter#1\expandafter#2\expanded + \XINT:NEhook:x:flatten\XINT:expr:flatten +}% +\let\XINT_flexpr_func_flat\XINT_expr_func_flat +\let\XINT_iiexpr_func_flat\XINT_expr_func_flat +\let\XINT:NEhook:x:flatten\empty +\def\XINT_expr_func_zip #1#2%#3% +{% + \expandafter#1\expandafter#2\romannumeral`&&@% + \XINT:NEhook:x:zip\XINT:expr:zip +}% +\let\XINT_flexpr_func_zip\XINT_expr_func_zip +\let\XINT_iiexpr_func_zip\XINT_expr_func_zip +\let\XINT:NEhook:x:zip\empty +\def\XINT:expr:zip#1{\expandafter{\expanded\XINT_zip_A#1\xint_bye\xint_bye}}% \def\XINT_tmpa #1#2#3#4#5% {% \def #1##1(##2)##3={% @@ -3920,6 +4067,43 @@ \fi \XINT:expr:toblistwith{##1}{##2}% }}\expandafter\XINT:NE:x:toblist\string#% \def\XINT:NE:x:toblist:p\XINT:expr:toblistwith #1#2{{\XINTfstop.{#2}}}% +\def\XINT:NE:x:flatten#1{% +\def\XINT:NE:x:flatten\XINT:expr:flatten##1% +{% + \if 0\expandafter\XINT:NE:hastilde\detokenize{##1}~!\relax + \expandafter\XINT:NE:hashash \detokenize{##1}#1!\relax 0% + \else + \expandafter\XINT:NE:x:flatten:p + \fi \XINT:expr:flatten{##1}% +}}\expandafter\XINT:NE:x:flatten\string#% +\def\XINT:NE:x:flatten:p\XINT:expr:flatten #1% +{% + {{% + \detokenize + {% + \expandafter\XINT:expr:flatten_checkempty + \detokenize\expandafter{\expanded{#1}}$XINT_expr_caret%$ + }% + }}% +}% +\def\XINT:NE:x:zip#1{% +\def\XINT:NE:x:zip\XINT:expr:zip##1% +{% + \if 0\expandafter\XINT:NE:hastilde\detokenize{##1}~!\relax + \expandafter\XINT:NE:hashash \detokenize{##1}#1!\relax 0% + \else + \expandafter\XINT:NE:x:zip:p + \fi \XINT:expr:zip{##1}% +}}\expandafter\XINT:NE:x:zip\string#% +\def\XINT:NE:x:zip:p\XINT:expr:zip #1% +{% + \expandafter{% + \detokenize + {% + \expanded\expandafter\XINT_zip_A\expanded{#1}\xint_bye\xint_bye + }% + }% +}% \def\XINT:NE:x:mapwithin#1{% \def\XINT:NE:x:mapwithin\XINT:expr:mapwithin ##1##2% {% @@ -4040,6 +4224,8 @@ \let\XINT:NEhook:rrseq \XINT:NE:rrseq \let\XINT:NEhook:iterr \XINT:NE:iterr \let\XINT:NEhook:x:toblist \XINT:NE:x:toblist + \let\XINT:NEhook:x:flatten \XINT:NE:x:flatten + \let\XINT:NEhook:x:zip \XINT:NE:x:zip \let\XINT:NEhook:x:mapwithin \XINT:NE:x:mapwithin \let\XINT:NEhook:x:ndmapx \XINT:NE:x:ndmapx \let\XINT:NEhook:userfunc \XINT:NE:userfunc diff --git a/Master/texmf-dist/tex/generic/xint/xintfrac.sty b/Master/texmf-dist/tex/generic/xint/xintfrac.sty index d6e79408cc9..a9218952fd0 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.4a 2020/02/19 +%% The xint bundle 1.4b 2020/02/25 %% Copyright (C) 2013-2020 by Jean-Francois Burnol %% xintfrac: Expandable operations on fractions %% --------------------------------------------------------------- @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintfrac}% - [2020/02/19 v1.4a Expandable operations on fractions (JFB)]% + [2020/02/25 v1.4b Expandable operations on fractions (JFB)]% \def\XINT_cntSgnFork #1% {% \ifcase #1\expandafter\xint_secondofthree @@ -458,8 +458,9 @@ \def\XINT_spraw #1[#2#3]{\xint_gob_til_W #2\XINT_spraw_a\W\XINT_spraw_p #1[#2#3]}% \def\XINT_spraw_a\W\XINT_spraw_p #1[\W]{ #1}% \def\XINT_spraw_p #1[\W]{\xintpraw {#1}}% -\def\xintFracToSci #1% - {\expandafter\XINT_FracToSci\romannumeral`&&@#1/\W[\R]}% +\edef\xintFracToSci #1% + {\unexpanded{\expandafter\XINT_FracToSci\romannumeral`&&@}#1\string e% + \unexpanded{\Z/\W[\R]}}% \def\XINT_FracToSci #1/#2#3[#4% {% \xint_gob_til_W #2\XINT_FracToSci_no\W @@ -471,18 +472,39 @@ \xint_gob_til_R #3\XINT_FracToSci_nono\R \XINT_FracToSci_noyes #2[#3% }% -\def\XINT_FracToSci_nono\R\XINT_FracToSci_noyes #1/\W[\R]{#1}% -\def\XINT_FracToSci_noyes #1#2[#3]/\W[\R]% +\edef\XINT_tmpa{##1\string e##2}% +\def\XINT_tmpb{\def\XINT_FracToSci_nono\R\XINT_FracToSci_noyes}% +\expandafter +\XINT_tmpb\XINT_tmpa +{% + #1\xint_gob_til_Z #2\XINT_FracToSci_nonono\Z + \XINT_FracToSci_nonoyes #2% +}% +\edef\XINT_tmpa{##1\string e}% + \def\XINT_tmpb{\def\XINT_FracToSci_nonoyes}% +\expandafter +\XINT_tmpb\XINT_tmpa\Z/\W[\R]{\xintFracToSciE#1}% +\def\XINT_FracToSci_nonono\Z\XINT_FracToSci_nonoyes\Z/\W[\R]{}% +\edef\XINT_tmpa{##1##2[##3]\string e}% + \def\XINT_tmpb{\def\XINT_FracToSci_noyes}% +\expandafter +\XINT_tmpb\XINT_tmpa\Z/\W[\R]% {% #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue #2\ifnum #3=\xint_c_\else\xintFracToSciE#3\fi\fi }% -\def\XINT_FracToSci_yesno\R\XINT_FracToSci_yesyes #1#2/#3/\W[\R]% +\edef\XINT_tmpa{##1##2/##3\string e}% + \def\XINT_tmpb{\def\XINT_FracToSci_yesno\R\XINT_FracToSci_yesyes}% +\expandafter +\XINT_tmpb\XINT_tmpa\Z/\W[\R]% {% #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue #2\if\XINT_isOne{#3}1\else/#3\fi\fi }% -\def\XINT_FracToSci_yesyes #1#2/#3[#4]/\W[\R]% +\edef\XINT_tmpa{##1##2/##3[##4]\string e}% + \def\XINT_tmpb{\def\XINT_FracToSci_yesyes}% +\expandafter +\XINT_tmpb\XINT_tmpa\Z/\W[\R]% {% #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue #2\ifnum #4=\xint_c_\else\xintFracToSciE#4\fi @@ -2299,21 +2321,26 @@ \ifnum #3<-\xint_c_v \xint_dothis\XINT_pfloat_no\fi \ifnum #3<\xint_c_ \xint_dothis\XINT_pfloat_N\fi \ifnum #3>\numexpr #4-\xint_c_i\relax \xint_dothis\XINT_pfloat_Ps\fi - \xint_orthat\XINT_pfloat_P #1#2e#3;% + \xint_orthat\XINT_pfloat_P #1{#2}{#3}% +}% +\def\XINT_pfloat_no +{% + \expandafter\XINT_pfloat_no_e\expandafter{\xintPFloatE}% }% -\def\XINT_pfloat_no #1#2;{ #1.#2}% -\def\XINT_pfloat_N #1e-#2;% +\def\XINT_pfloat_no_e #1#2#3#4{ #2.#3#1#4}% +\def\xintPFloatE{e}% +\def\XINT_pfloat_N #1#2#3% {% - \csname XINT_pfloat_N_\romannumeral#2\endcsname #1% + \csname XINT_pfloat_N_\romannumeral-#3\endcsname #1#2% }% \def\XINT_pfloat_N_i { 0.}% \def\XINT_pfloat_N_ii { 0.0}% \def\XINT_pfloat_N_iii{ 0.00}% \def\XINT_pfloat_N_iv { 0.000}% \def\XINT_pfloat_N_v { 0.0000}% -\def\XINT_pfloat_P #1e#2;% +\def\XINT_pfloat_P #1#2#3% {% - \csname XINT_pfloat_P_\romannumeral#2\endcsname #1% + \csname XINT_pfloat_P_\romannumeral#3\endcsname #1#2% }% \def\XINT_pfloat_P_ #1{ #1.}% \def\XINT_pfloat_P_i #1#2{ #1#2.}% @@ -2321,9 +2348,9 @@ \def\XINT_pfloat_P_iii#1#2#3#4{ #1#2#3#4.}% \def\XINT_pfloat_P_iv #1#2#3#4#5{ #1#2#3#4#5.}% \def\XINT_pfloat_P_v #1#2#3#4#5#6{ #1#2#3#4#5#6.}% -\def\XINT_pfloat_Ps #1e#2;% +\def\XINT_pfloat_Ps #1#2#3% {% - \csname XINT_pfloat_Ps\romannumeral#2\endcsname #100000;% + \csname XINT_pfloat_Ps\romannumeral#3\endcsname #1#200000;% }% \def\XINT_pfloat_Psi #1#2#3;{ #1#2.}% \def\XINT_pfloat_Psii #1#2#3#4;{ #1#2#3.}% diff --git a/Master/texmf-dist/tex/generic/xint/xintgcd.sty b/Master/texmf-dist/tex/generic/xint/xintgcd.sty index d6afd5f3cbd..e80299dd21a 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.4a 2020/02/19 +%% The xint bundle 1.4b 2020/02/25 %% Copyright (C) 2013-2020 by Jean-Francois Burnol %% xintgcd: Euclidean algorithm with xint package %% --------------------------------------------------------------- @@ -77,7 +77,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintgcd}% - [2020/02/19 v1.4a Euclide algorithm with xint package (JFB)]% + [2020/02/25 v1.4b Euclide algorithm with xint package (JFB)]% \def\xintBezout {\romannumeral0\xintbezout }% \def\xintbezout #1% {% diff --git a/Master/texmf-dist/tex/generic/xint/xintkernel.sty b/Master/texmf-dist/tex/generic/xint/xintkernel.sty index 7ff6d800034..29a8b3a05f2 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.4a 2020/02/19 +%% The xint bundle 1.4b 2020/02/25 %% Copyright (C) 2013-2020 by Jean-Francois Burnol %% xintkernel: Paraphernalia for the xint packages %% --------------------------------------------------------------- @@ -157,7 +157,7 @@ \fi \XINT_providespackage \ProvidesPackage {xintkernel}% - [2020/02/19 v1.4a Paraphernalia for the xint packages (JFB)]% + [2020/02/25 v1.4b Paraphernalia for the xint packages (JFB)]% \chardef\xint_c_ 0 \chardef\xint_c_i 1 \chardef\xint_c_ii 2 diff --git a/Master/texmf-dist/tex/generic/xint/xintlog.sty b/Master/texmf-dist/tex/generic/xint/xintlog.sty index 8b900fff49a..ddf209338a4 100644 --- a/Master/texmf-dist/tex/generic/xint/xintlog.sty +++ b/Master/texmf-dist/tex/generic/xint/xintlog.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4a 2020/02/19 +%% The xint bundle 1.4b 2020/02/25 %% Copyright (C) 2013-2020 by Jean-Francois Burnol %% xintlog: Logarithms and exponentials for xintexpr %% --------------------------------------------------------------- @@ -74,7 +74,7 @@ \xintexprSafeCatcodes\catcode`_ 11 \XINT_providespackage \ProvidesPackage{xintlog}% -[2020/02/19 v1.4a Logarithms and exponentials for xintexpr (JFB)]% +[2020/02/25 v1.4b Logarithms and exponentials for xintexpr (JFB)]% \ifdefined\RequirePackage \RequirePackage{poormanlog}% \else diff --git a/Master/texmf-dist/tex/generic/xint/xintseries.sty b/Master/texmf-dist/tex/generic/xint/xintseries.sty index 1c391526cc6..76608a2239b 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.4a 2020/02/19 +%% The xint bundle 1.4b 2020/02/25 %% Copyright (C) 2013-2020 by Jean-Francois Burnol %% xintseries: Expandable partial sums with xint package %% --------------------------------------------------------------- @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintseries}% - [2020/02/19 v1.4a Expandable partial sums with xint package (JFB)]% + [2020/02/25 v1.4b 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 b0806b12848..0aeffe17888 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.4a 2020/02/19 +%% The xint bundle 1.4b 2020/02/25 %% Copyright (C) 2013-2020 by Jean-Francois Burnol %% xinttools: Expandable and non-expandable utilities %% --------------------------------------------------------------- @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xinttools}% - [2020/02/19 v1.4a Expandable and non-expandable utilities (JFB)]% + [2020/02/25 v1.4b Expandable and non-expandable utilities (JFB)]% \newtoks\XINT_toks \xint_firstofone{\let\XINT_sptoken= } %<- space here! \def\xintgodef {\global\xintodef }% @@ -578,28 +578,6 @@ \long\def\XINT_apply_loop_b #1#2{\XINT_apply_loop_a {#2{#1}}}% \long\def\XINT_apply_end\xint_bye\expandafter\XINT_apply_loop_b \expandafter #1#2#3{ #2}% -\long\def\xintApply:x #1#2% -{% - \XINT_apply:x_loop {#1}#2% - {\xint:\XINT_apply:x_loop_enda}{\xint:\XINT_apply:x_loop_endb}% - {\xint:\XINT_apply:x_loop_endc}{\xint:\XINT_apply:x_loop_endd}% - {\xint:\XINT_apply:x_loop_ende}{\xint:\XINT_apply:x_loop_endf}% - {\xint:\XINT_apply:x_loop_endg}{\xint:\XINT_apply:x_loop_endh}\xint_bye -}% -\long\def\XINT_apply:x_loop #1#2#3#4#5#6#7#8#9% -{% - \xint_gob_til_xint: #9\xint: - {#1{#2}}{#1{#3}}{#1{#4}}{#1{#5}}{#1{#6}}{#1{#7}}{#1{#8}}{#1{#9}}% - \XINT_apply:x_loop {#1}% -}% -\long\def\XINT_apply:x_loop_endh\xint: #1\xint_bye{}% -\long\def\XINT_apply:x_loop_endg\xint: #1#2\xint_bye{{#1}}% -\long\def\XINT_apply:x_loop_endf\xint: #1#2#3\xint_bye{{#1}{#2}}% -\long\def\XINT_apply:x_loop_ende\xint: #1#2#3#4\xint_bye{{#1}{#2}{#3}}% -\long\def\XINT_apply:x_loop_endd\xint: #1#2#3#4#5\xint_bye{{#1}{#2}{#3}{#4}}% -\long\def\XINT_apply:x_loop_endc\xint: #1#2#3#4#5#6\xint_bye{{#1}{#2}{#3}{#4}{#5}}% -\long\def\XINT_apply:x_loop_endb\xint: #1#2#3#4#5#6#7\xint_bye{{#1}{#2}{#3}{#4}{#5}{#6}}% -\long\def\XINT_apply:x_loop_enda\xint: #1#2#3#4#5#6#7#8\xint_bye{{#1}{#2}{#3}{#4}{#5}{#6}{#7}}% \def\xintApplyUnbraced {\romannumeral0\xintapplyunbraced }% \def\xintApplyUnbracedNoExpand {\romannumeral0\xintapplyunbracednoexpand }% \long\def\xintapplyunbraced #1#2% @@ -619,56 +597,98 @@ \long\def\XINT_applyunbr_loop_b #1#2{\XINT_applyunbr_loop_a {#2#1}}% \long\def\XINT_applyunbr_end\xint_bye\expandafter\XINT_applyunbr_loop_b \expandafter #1#2#3{ #2}% -\long\def\xintApplyUnbraced:x #1#2% -{% - \XINT_applyunbraced:x_loop {#1}#2% - {\xint:\XINT_applyunbraced:x_loop_enda}{\xint:\XINT_applyunbraced:x_loop_endb}% - {\xint:\XINT_applyunbraced:x_loop_endc}{\xint:\XINT_applyunbraced:x_loop_endd}% - {\xint:\XINT_applyunbraced:x_loop_ende}{\xint:\XINT_applyunbraced:x_loop_endf}% - {\xint:\XINT_applyunbraced:x_loop_endg}{\xint:\XINT_applyunbraced:x_loop_endh}\xint_bye -}% -\long\def\XINT_applyunbraced:x_loop #1#2#3#4#5#6#7#8#9% -{% - \xint_gob_til_xint: #9\xint: - #1{#2}% - \empty#1{#3}% - \empty#1{#4}% - \empty#1{#5}% - \empty#1{#6}% - \empty#1{#7}% - \empty#1{#8}% - \empty#1{#9}% - \XINT_applyunbraced:x_loop {#1}% -}% -\long\def\XINT_applyunbraced:x_loop_endh\xint: #1\xint_bye{}% -\long\def\XINT_applyunbraced:x_loop_endg\xint: #1\empty#2\xint_bye{#1}% -\long\def\XINT_applyunbraced:x_loop_endf\xint: #1\empty - #2\empty#3\xint_bye{#1#2}% -\long\def\XINT_applyunbraced:x_loop_ende\xint: #1\empty - #2\empty - #3\empty#4\xint_bye{#1#2#3}% -\long\def\XINT_applyunbraced:x_loop_endd\xint: #1\empty - #2\empty - #3\empty - #4\empty#5\xint_bye{#1#2#3#4}% -\long\def\XINT_applyunbraced:x_loop_endc\xint: #1\empty - #2\empty - #3\empty - #4\empty - #5\empty#6\xint_bye{#1#2#3#4#5}% -\long\def\XINT_applyunbraced:x_loop_endb\xint: #1\empty - #2\empty - #3\empty - #4\empty - #5\empty - #6\empty#7\xint_bye{#1#2#3#4#5#6}% -\long\def\XINT_applyunbraced:x_loop_enda\xint: #1\empty - #2\empty - #3\empty - #4\empty - #5\empty - #6\empty - #7\empty#8\xint_bye{#1#2#3#4#5#6#7}% +\def\xintZip #1{\expanded\XINT_zip_A#1\xint_bye\xint_bye}% +\def\XINT_zip_A#1% +{% + \xint_bye#1{\expandafter}\xint_bye + \expanded{\unexpanded{\XINT_ziptwo_A + #1\xint_bye\xint_bye\xint_bye\xint_bye\xint:}\expandafter}% + \expanded\XINT_zip_a +}% +\def\XINT_zip_a#1% +{% + \xint_bye#1\XINT_zip_terminator\xint_bye + \expanded{\unexpanded{\XINT_ziptwo_a + #1\xint_bye\xint_bye\xint_bye\xint_bye\xint:}\expandafter}% + \expanded\XINT_zip_a +}% +\def\XINT_zip_terminator\xint_bye#1\xint_bye{{}\empty\empty\empty\empty\xint:}% +\def\XINT_ziptwo_a #1#2#3#4#5\xint:#6#7#8#9% +{% + \bgroup + \xint_bye #1\XINT_ziptwo_e \xint_bye + \xint_bye #6\XINT_ziptwo_e \xint_bye {{#1}#6}% + \xint_bye #2\XINT_ziptwo_e \xint_bye + \xint_bye #7\XINT_ziptwo_e \xint_bye {{#2}#7}% + \xint_bye #3\XINT_ziptwo_e \xint_bye + \xint_bye #8\XINT_ziptwo_e \xint_bye {{#3}#8}% + \xint_bye #4\XINT_ziptwo_e \xint_bye + \xint_bye #9\XINT_ziptwo_e \xint_bye {{#4}#9}% + \ifx \empty#6\expandafter\XINT_zipone_a\fi + \XINT_ziptwo_b #5\xint: +}% +\def\XINT_zipone_a\XINT_ziptwo_b{\XINT_zipone_b}% +\def\XINT_ziptwo_b #1#2#3#4#5\xint:#6#7#8#9% +{% + \xint_bye #1\XINT_ziptwo_e \xint_bye + \xint_bye #6\XINT_ziptwo_e \xint_bye {{#1}#6}% + \xint_bye #2\XINT_ziptwo_e \xint_bye + \xint_bye #7\XINT_ziptwo_e \xint_bye {{#2}#7}% + \xint_bye #3\XINT_ziptwo_e \xint_bye + \xint_bye #8\XINT_ziptwo_e \xint_bye {{#3}#8}% + \xint_bye #4\XINT_ziptwo_e \xint_bye + \xint_bye #9\XINT_ziptwo_e \xint_bye {{#4}#9}% + \XINT_ziptwo_b #5\xint: +}% +\def\XINT_ziptwo_e #1\XINT_ziptwo_b #2\xint:#3\xint: + {\iffalse{\fi}\xint_bye\xint_bye\xint_bye\xint_bye\xint:}% +\def\XINT_zipone_b #1#2#3#4% +{% + \xint_bye #1\XINT_zipone_e \xint_bye {{#1}}% + \xint_bye #2\XINT_zipone_e \xint_bye {{#2}}% + \xint_bye #3\XINT_zipone_e \xint_bye {{#3}}% + \xint_bye #4\XINT_zipone_e \xint_bye {{#4}}% + \XINT_zipone_b +}% +\def\XINT_zipone_e #1\XINT_zipone_b #2\xint: + {\iffalse{\fi}\xint_bye\xint_bye\xint_bye\xint_bye\empty}% +\def\XINT_ziptwo_A #1#2#3#4#5\xint:#6#7#8#9% +{% + \bgroup + \xint_bye #1\XINT_ziptwo_end \xint_bye + \xint_bye #6\XINT_ziptwo_end \xint_bye {{#1}#6}% + \xint_bye #2\XINT_ziptwo_end \xint_bye + \xint_bye #7\XINT_ziptwo_end \xint_bye {{#2}#7}% + \xint_bye #3\XINT_ziptwo_end \xint_bye + \xint_bye #8\XINT_ziptwo_end \xint_bye {{#3}#8}% + \xint_bye #4\XINT_ziptwo_end \xint_bye + \xint_bye #9\XINT_ziptwo_end \xint_bye {{#4}#9}% + \ifx \empty#6\expandafter\XINT_zipone_A\fi + \XINT_ziptwo_B #5\xint: +}% +\def\XINT_zipone_A\XINT_ziptwo_B{\XINT_zipone_B}% +\def\XINT_ziptwo_B #1#2#3#4#5\xint:#6#7#8#9% +{% + \xint_bye #1\XINT_ziptwo_end \xint_bye + \xint_bye #6\XINT_ziptwo_end \xint_bye {{#1}#6}% + \xint_bye #2\XINT_ziptwo_end \xint_bye + \xint_bye #7\XINT_ziptwo_end \xint_bye {{#2}#7}% + \xint_bye #3\XINT_ziptwo_end \xint_bye + \xint_bye #8\XINT_ziptwo_end \xint_bye {{#3}#8}% + \xint_bye #4\XINT_ziptwo_end \xint_bye + \xint_bye #9\XINT_ziptwo_end \xint_bye {{#4}#9}% + \XINT_ziptwo_B #5\xint: +}% +\def\XINT_ziptwo_end #1\XINT_ziptwo_B #2\xint:#3\xint:{\iffalse{\fi}}% +\def\XINT_zipone_B #1#2#3#4% +{% + \xint_bye #1\XINT_zipone_end \xint_bye {{#1}}% + \xint_bye #2\XINT_zipone_end \xint_bye {{#2}}% + \xint_bye #3\XINT_zipone_end \xint_bye {{#3}}% + \xint_bye #4\XINT_zipone_end \xint_bye {{#4}}% + \XINT_zipone_B +}% +\def\XINT_zipone_end #1\XINT_zipone_B #2\xint:#3\xint:{\iffalse{\fi}}% \def\xintSeq {\romannumeral0\xintseq }% \def\xintseq #1{\XINT_seq_chkopt #1\xint_bye }% \def\XINT_seq_chkopt #1% diff --git a/Master/texmf-dist/tex/generic/xint/xinttrig.sty b/Master/texmf-dist/tex/generic/xint/xinttrig.sty index 4fe1f6170c3..8eacf2dce04 100644 --- a/Master/texmf-dist/tex/generic/xint/xinttrig.sty +++ b/Master/texmf-dist/tex/generic/xint/xinttrig.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4a 2020/02/19 +%% The xint bundle 1.4b 2020/02/25 %% Copyright (C) 2013-2020 by Jean-Francois Burnol %% xinttrig: Trigonometry for the xintexpr package %% --------------------------------------------------------------- @@ -68,10 +68,10 @@ \expandafter\xint_secondoftwo \fi {\immediate\write-1{Reloading xinttrig library using Digits=\xinttheDigits.}}% -{\expandafter\gdef\csname xintlibver@trig\endcsname{2020/02/19 v1.4a}% +{\expandafter\gdef\csname xintlibver@trig\endcsname{2020/02/25 v1.4b}% \XINT_providespackage \ProvidesPackage{xinttrig}% -[2020/02/19 v1.4a Trigonometrical functions for xintexpr (JFB)]% +[2020/02/25 v1.4b Trigonometrical functions for xintexpr (JFB)]% }% \xintFor* #1 in {iDTVtuwxyzX}\do{\xintensuredummy{#1}}% \def\xintreloadxinttrig @@ -93,7 +93,7 @@ 57.2957795130823208767981548141051703324054724665643215491602;% 180/Pi \xintdeffloatvar invfact\xintListWithSep{, invfact}{\xintSeq{2}{44}}% := \xintfloatexpr [\XINTdigits] % force float rounding after exact evaluations - \xintexpr rseq(1/2{;}@/i, i=3..44)\relax % need to hide inner ; from \xintdeffloatvar + \xintexpr rseq(1/2; @/i, i=3..44)\relax % no need to hide this inner ; \relax;% \xintdeffloatfunc sin_aux(X) := 1 - X(invfact3 - X(invfact5 \ifnum\XINTdigits>4 |