diff options
Diffstat (limited to 'Master')
19 files changed, 8280 insertions, 6227 deletions
diff --git a/Master/texmf-dist/doc/generic/xint/CHANGES.html b/Master/texmf-dist/doc/generic/xint/CHANGES.html index b54ce1b27ec..0c940990e9b 100644 --- a/Master/texmf-dist/doc/generic/xint/CHANGES.html +++ b/Master/texmf-dist/doc/generic/xint/CHANGES.html @@ -4,7 +4,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <meta name="generator" content="pandoc" /> - <meta name="author" content="xint v1.2e" /> + <meta name="author" content="xint 1.2f" /> <title>CHANGE LOG</title> <style type="text/css">code{white-space: pre;}</style> <style type="text/css"> @@ -17,17 +17,38 @@ <body> <div id="header"> <h1 class="title">CHANGE LOG</h1> -<h2 class="author">xint v1.2e</h2> -<h3 class="date">2015/11/22</h3> +<h2 class="author">xint 1.2f</h2> +<h3 class="date">2016/03/12</h3> </div> <div id="TOC"> <ul> -<li><a href="#e-20151122"><code>1.2e (2015/11/22)</code></a></li> -<li><a href="#d-20151118"><code>1.2d (2015/11/18)</code></a></li> -<li><a href="#c-20151116"><code>1.2c (2015/11/16)</code></a></li> -<li><a href="#b-20151029"><code>1.2b (2015/10/29)</code></a></li> -<li><a href="#a-20151019"><code>1.2a (2015/10/19)</code></a></li> -<li><a href="#section"><code>1.2 (2015/10/10)</code></a></li> +<li><a href="#f-20160312"><code>1.2f (2016/03/12)</code></a><ul> +<li><a href="#incompatible-changes">Incompatible changes</a></li> +<li><a href="#bug-fixes">Bug fixes</a></li> +<li><a href="#improvements-and-new-features">Improvements and new features</a></li> +</ul></li> +<li><a href="#e-20151122"><code>1.2e (2015/11/22)</code></a><ul> +<li><a href="#bug-fixes-1">Bug fixes</a></li> +<li><a href="#improvements-and-new-features-1">Improvements and new features</a></li> +</ul></li> +<li><a href="#d-20151118"><code>1.2d (2015/11/18)</code></a><ul> +<li><a href="#bug-fixes-2">Bug fixes</a></li> +<li><a href="#improvements-and-new-features-2">Improvements and new features</a></li> +</ul></li> +<li><a href="#c-20151116"><code>1.2c (2015/11/16)</code></a><ul> +<li><a href="#bug-fixes-3">Bug fixes</a></li> +<li><a href="#improvements-and-new-features-3">Improvements and new features</a></li> +</ul></li> +<li><a href="#b-20151029"><code>1.2b (2015/10/29)</code></a><ul> +<li><a href="#bug-fixes-4">Bug fixes</a></li> +</ul></li> +<li><a href="#a-20151019"><code>1.2a (2015/10/19)</code></a><ul> +<li><a href="#bug-fixes-5">Bug fixes</a></li> +<li><a href="#improvements-and-new-features-4">Improvements and new features</a></li> +</ul></li> +<li><a href="#section"><code>1.2 (2015/10/10)</code></a><ul> +<li><a href="#improvements-and-new-features-5">Improvements and new features</a></li> +</ul></li> <li><a href="#c-20150912"><code>1.1c (2015/09/12)</code></a></li> <li><a href="#b-20150831"><code>1.1b (2015/08/31)</code></a></li> <li><a href="#a-20141107"><code>1.1a (2014/11/07)</code></a></li> @@ -58,51 +79,94 @@ <li><a href="#section-8"><code>1.0 (2013/03/28)</code></a></li> </ul> </div> -<pre><code>Source: xint.dtx v1.2e 2015/11/22 (doc 2015/11/22) +<pre><code>Source: xint.dtx 1.2f 2016/03/12 (doc 2016/03/12) Author: Jean-Francois Burnol Info: Expandable operations on big integers, decimals, fractions License: LPPL 1.3c</code></pre> +<h2 id="f-20160312"><code>1.2f (2016/03/12)</code></h2> +<h3 id="incompatible-changes">Incompatible changes</h3> +<ul> +<li>no more <code>\xintFac</code> macro but <code>\xintiFac/\xintiiFac/\xintFloatFac</code>.</li> +</ul> +<h3 id="bug-fixes">Bug fixes</h3> +<ul> +<li><p>squaring macro <code>\xintSqr</code> from <strong>xintfrac.sty</strong> was broken due to a misspelled sub-macro name. Dates back to <code>1.1</code> release of <code>2014/10/28</code> <code>:-((</code>.</p></li> +<li><p><code>1.2c</code>'s fix to the subtraction bug from <code>1.2</code> introduced another bug, which in some cases could create leading zeroes in the output, or even worse. This could invalidate other routines using subtractions, like <code>\xintiiSquareRoot</code>.</p></li> +<li><p>the comparison operators were not recognized by <code>\xintNewIIExpr</code> and <code>\xintdefiifunc</code> constructs.</p></li> +</ul> +<h3 id="improvements-and-new-features">Improvements and new features</h3> +<ul> +<li><p>functions <code>binomial</code>, <code>pfactorial</code> and <code>factorial</code> in both integer and float versions.</p></li> +<li><p>macros <code>\xintiiBinomial</code>, <code>\xintiiPFactorial</code> (<strong>xint.sty</strong>) and <code>\xintFloatBinomial</code>, <code>\xintFloatPFactorial</code> (<strong>xintfrac.sty</strong>). Improvements to <code>\xintFloatFac</code>.</p></li> +<li><p>faster implementation and increased accuracy of float power macros. Half-integer exponents are now accepted inside float expressions.</p></li> +<li><p>faster implementation of both integral and float square root macros.</p></li> +<li><p>the float square root achieves <em>correct</em> (aka <em>exact</em>) rounding in arbitrary precision.</p></li> +<li><p>modified behaviour for the <code>\xintPFloat</code> macro, used by <code>\xintthefloatexpr</code> to prettify its output. It now opts for decimal notation if and only if scientific notation would use an exponent between <code>-5</code> and <code>5</code> inclusive. The zero value is printed <code>0.</code> with a dot.</p></li> +<li><p>the float macros for addition, subtraction, multiplication, division now first round their two operands to P, not P+2, significant places before doing the actual computation (P being the target precision). The same applies to the power macros and to the square root macro.</p></li> +<li><p>the documentation offers a more precise (and accurate) discussion of floating point issues.</p></li> +<li><p>various under-the-hood code improvements; the floatexpr operations are chained in a faster way, from skipping some unneeded parsing on results of earlier computations. The absence of a real inner data structure for floats (incorporating their precisions, for one) is however still a bit hair rising: currently the lengths of the mantissas of the operands are computed again by each float macro or expression operation.</p></li> +<li><p>(TeXperts only) the macros defined (internally) from <code>\xintdeffunc</code> et al. constructs do not incorporate an initial <code>\romannumeral</code> anymore.</p></li> +<li><p>renewed desperate efforts at improving the documentation by random shuffling of sections and well thought additions; cuts were considered and even performed.</p></li> +</ul> <h2 id="e-20151122"><code>1.2e (2015/11/22)</code></h2> +<h3 id="bug-fixes-1">Bug fixes</h3> +<ul> +<li><p>in <strong>xintfrac</strong>: the <code>\xintFloatFac</code> from release <code>1.2</code> parsed its argument only through <code>\numexpr</code> but it should have used <code>\xintNum</code>.</p></li> +<li><p>in <strong>xintexpr</strong>: release <code>1.2d</code> had broken the recognition of sub-expressions immediately after variable names (with tacit multiplication).</p></li> +<li><p>in <strong>xintexpr</strong>: contrarily to what <code>1.2d</code> documentation said, tacit multiplication was not yet always done with enhanced precedence. Now yes.</p></li> +</ul> +<h3 id="improvements-and-new-features-1">Improvements and new features</h3> <ul> -<li><p>bugfix 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>bugfix in <strong>xintexpr</strong>: release <code>1.2d</code> had broken the recognition of sub-expressions immediately after variable names (with tacit multiplication).</p></li> -<li><p>new macro <code>\xintunassignvar</code>.</p></li> +<li><p>macro <code>\xintunassignvar</code>.</p></li> <li><p>slight modifications of the logged messages in case of <code>\xintverbosetrue</code>.</p></li> <li><p>a space in <code>\xintdeffunc f(x)<space>:= expression ;</code> is now accepted.</p></li> -<li><p>contrarily to what <code>1.2d</code> documentation said, tacit multiplication was not yet always done with enhanced precedence. Now yes.</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> <h2 id="d-20151118"><code>1.2d (2015/11/18)</code></h2> +<h3 id="bug-fixes-2">Bug fixes</h3> +<ul> +<li>in <strong>xintcore</strong>: release <code>1.2c</code> had inadvertently broken the <code>\xintiiDivRound</code> macro.</li> +</ul> +<h3 id="improvements-and-new-features-2">Improvements and new features</h3> <ul> -<li><p>bugfix in <strong>xintcore</strong>: release <code>1.2c</code> had inadvertently broken the <code>\xintiiDivRound</code> macro.</p></li> <li><p>the function definitions done by <code>\xintdeffunc</code> et al., as well as the macro declarations by <code>\xintNewExpr</code> et al. now have only local scope.</p></li> <li><p>tacit multiplication applies to more cases, for example (x+y)z, and always ties more than standard * infix operator, e.g. x/2y is like x/(2*y).</p></li> <li><p>some documentation enhancements, particularly in the chapter on xintexpr.sty, and also in the code source comments.</p></li> </ul> <h2 id="c-20151116"><code>1.2c (2015/11/16)</code></h2> +<h3 id="bug-fixes-3">Bug fixes</h3> <ul> -<li><p>bugfix 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).</p></li> -<li><p>new macros <code>\xintdeffunc</code>, <code>\xintdefiifunc</code>, <code>\xintdeffloatfunc</code> and boolean <code>\ifxintverbose</code>.</p></li> +<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> +<h3 id="improvements-and-new-features-3">Improvements and new features</h3> +<ul> +<li><p>macros <code>\xintdeffunc</code>, <code>\xintdefiifunc</code>, <code>\xintdeffloatfunc</code> and boolean <code>\ifxintverbose</code>.</p></li> <li><p>on-going code improvements and documentation enhancements, but stopped in order to issue this bugfix release.</p></li> </ul> <h2 id="b-20151029"><code>1.2b (2015/10/29)</code></h2> +<h3 id="bug-fixes-4">Bug fixes</h3> <ul> -<li>bugfix 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> +<li>in <strong>xintcore</strong>: recent release <code>1.2</code> introduced a bug in the division macros, causing a crash when the divisor started with 99999999 (it was attempted to use with 1+99999999 a subroutine expecting only 8-digits numbers).</li> </ul> <h2 id="a-20151019"><code>1.2a (2015/10/19)</code></h2> +<h3 id="bug-fixes-5">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> +<h3 id="improvements-and-new-features-4">Improvements and new features</h3> <ul> -<li><p>bugfix 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...)</p></li> <li><p>added <code>\xintKeepUnbraced</code>, <code>\xintTrimUnbraced</code> (<strong>xinttools</strong>) and fixed documentation of <code>\xintKeep</code> and <code>\xintTrim</code> regarding brace stripping.</p></li> <li><p>added <code>\xintiiMaxof/\xintiiMinof</code> (<strong>xint</strong>).</p></li> <li><p>TeX hackers only: replaced all code uses of <code>\romannumeral-`0</code> by the quicker <code>\romannumeral`&&@</code> (<code>^</code> being used as letter, had to find another character usable with catcode 7).</p></li> </ul> <h2 id="section"><code>1.2 (2015/10/10)</code></h2> +<h3 id="improvements-and-new-features-5">Improvements and new features</h3> <ul> <li><p>the basic arithmetic implemented in <strong>xintcore</strong> has been entirely rewritten. The mathematics remains the elementary school one, but the <code>TeX</code> implementation achieves higher speed (except, regarding addition/subtraction, for numbers up to about thirty digits), the gains becoming quite significant for numbers with hundreds of digits.</p></li> <li><p>the inputs must have less than 19959 digits. But computations with thousands of digits take time.</p></li> <li><p>a previously standing limitation of <code>\xintexpr</code>, <code>\xintiiexpr</code>, and of <code>\xintfloatexpr</code> to numbers of less than 5000 digits has been lifted.</p></li> <li><p>a <em>qint</em> function is provided to help the parser gather huge integers in one-go, as an exception to its normal mode of operation which expands token by token.</p></li> -<li><p>new <code>\xintFloatFac</code> macro for computing the factorials of integers as floating point numbers to a given precision. The <code>!</code> postfix operator inside <code>\xintfloatexpr</code> maps to this new macro rather than to the exact factorial as used by <code>\xintexpr</code> and <code>\xintiiexpr</code>.</p></li> +<li><p><code>\xintFloatFac</code> macro for computing the factorials of integers as floating point numbers to a given precision. The <code>!</code> postfix operator inside <code>\xintfloatexpr</code> maps to this new macro rather than to the exact factorial as used by <code>\xintexpr</code> and <code>\xintiiexpr</code>.</p></li> <li><p>the macros <code>\xintAdd</code>, <code>\xintSub</code>, ..., now require package <strong>xintfrac</strong>. With only <strong>xintcore</strong> or <strong>xint</strong> loaded, one <em>must</em> use <code>\xintiiAdd</code>, <code>\xintiiSub</code>, ..., or <code>\xintiAdd</code>, <code>\xintiSub</code>, etc...</p></li> <li><p>there is more flexibility in the parsing done by the macros from <strong>xintfrac</strong> on fractional input: the decimal parts of both the numerator and the denominator may arise from a separate expansion via <code>\romannumeral-`0</code>. Also the strict <code>A/B[N]</code> format is a bit relaxed: <code>N</code> may be empty or anything understood by <code>\numexpr</code>.</p></li> <li><p>on the other hand an isolated dot <code>.</code> is not legal syntax anymore inside the expression parsers: there must be digits either before or after. It remains legal input for the macros of <strong>xintfrac</strong>.</p></li> @@ -123,11 +187,11 @@ License: LPPL 1.3c</code></pre> <h2 id="a-20141107"><code>1.1a (2014/11/07)</code></h2> <ul> <li><p>fixed a bug which prevented <code>\xintNewExpr</code> from producing correctly working macros from a comma separated replacement text.</p></li> -<li><p>new <code>\xintiiSqrtR</code> for rounded integer square root; former <code>\xintiiSqrt</code> already produced truncated integer square root; corresponding function <code>sqrtr</code> added to <code>\xintiiexpr..\relax</code> syntax.</p></li> +<li><p><code>\xintiiSqrtR</code> for rounded integer square root; former <code>\xintiiSqrt</code> already produced truncated integer square root; corresponding function <code>sqrtr</code> added to <code>\xintiiexpr..\relax</code> syntax.</p></li> <li><p>use of straight quotes in the documentation for better legibility.</p></li> <li><p>added <code>\xintiiIsOne</code>, <code>\xintiiifOne</code>, <code>\xintiiifCmp</code>, <code>\xintiiifEq</code>, <code>\xintiiifGt</code>, <code>\xintiiifLt</code>, <code>\xintiiifOdd</code>, <code>\xintiiCmp</code>, <code>\xintiiEq</code>, <code>\xintiiGt</code>, <code>\xintiiLt</code>, <code>\xintiiLtorEq</code>, <code>\xintiiGtorEq</code>, <code>\xintiiNeq</code>, mainly for efficiency of <code>\xintiiexpr</code>.</p></li> <li><p>for the same reason, added <code>\xintiiGCD</code> and <code>\xintiiLCM</code>.</p></li> -<li><p>added the previously mentioned <code>ii</code> macros, and some others from <code>v1.1</code>, to the user manual. But their main usage is internal to <code>\xintiiexpr</code>, to skip unnecessary overheads.</p></li> +<li><p>added the previously mentioned <code>ii</code> macros, and some others from <code>1.1</code>, to the user manual. But their main usage is internal to <code>\xintiiexpr</code>, to skip unnecessary overheads.</p></li> <li><p>various typographical fixes throughout the documentation, and a bit of clean up of the code comments. Improved <code>\Factors</code> example of nested <code>subs</code>, <code>rseq</code>, <code>iter</code> in <code>\xintiiexpr</code>.</p></li> </ul> <h2 id="section-1"><code>1.1 (2014/10/28)</code></h2> @@ -143,7 +207,7 @@ License: LPPL 1.3c</code></pre> </dd> <dt>breaking changes</dt> <dd><ul> -<li><p>in <code>\xintiiexpr</code>, <code>/</code> does <em>rounded</em> division, rather than the Euclidean division (for positive arguments, this is truncated division). The new <code>//</code> operator does truncated division,</p></li> +<li><p>in <code>\xintiiexpr</code>, <code>/</code> does <em>rounded</em> division, rather than the Euclidean division (for positive arguments, this is truncated division). The <code>//</code> operator does truncated division,</p></li> <li><p>the <code>:</code> operator for three-way branching is gone, replaced with <code>??</code>,</p></li> <li><p><code>1e(3+5)</code> is now illegal. The number parser identifies <code>e</code> and <code>E</code> in the same way it does for the decimal mark, earlier versions treated <code>e</code> as <code>E</code> rather as infix operators of highest precedence,</p></li> <li><p>the <code>add</code> and <code>mul</code> have a new syntax, old syntax is with <code>`+`</code> and <code>`*`</code> (left quotes mandatory), <code>sum</code> and <code>prd</code> are gone,</p></li> @@ -163,9 +227,9 @@ License: LPPL 1.3c</code></pre> <li><p>faster handling by <code>\xintAdd</code>, <code>\xintSub</code>, <code>\xintMul</code>, ... of the case where one of the arguments is zero,</p></li> <li><p>the <code>\xintAdd</code> and <code>\xintSub</code> macros from package <strong>xintfrac</strong> check if one of the denominators is a multiple of the other, and only if this is not the case do they multiply the denominators. But systematic reduction would be too costly,</p></li> <li><p>this naturally will be also the case for the <code>+</code> and <code>-</code> operations in <code>\xintexpr</code>,</p></li> -<li><p>new macros <code>\xintiiDivRound</code>, <code>\xintiiDivTrunc</code> and <code>\xintiiMod</code> for rounded and truncated division of big integers (now in <strong>xintcore</strong>), alongside the earlier <code>\xintiiQuo</code> and <code>\xintiiRem</code>,</p></li> +<li><p>macros <code>\xintiiDivRound</code>, <code>\xintiiDivTrunc</code> and <code>\xintiiMod</code> for rounded and truncated division of big integers (now in <strong>xintcore</strong>), alongside the earlier <code>\xintiiQuo</code> and <code>\xintiiRem</code>,</p></li> <li><p>with <strong>xintfrac</strong> loaded, the <code>\xintNum</code> macro does <code>\xintTTrunc</code> (which is truncation to an integer, same as <code>\xintiTrunc {0}</code>),</p></li> -<li><p>new macro <code>\xintMod</code> in <strong>xintfrac</strong> for modulo operation with fractional numbers,</p></li> +<li><p>macro <code>\xintMod</code> in <strong>xintfrac</strong> for modulo operation with fractional numbers,</p></li> <li><p><code>\xintiexpr</code>, <code>\xinttheiexpr</code> admit an optional argument within brackets <code>[d]</code>, they round the computation result (or results, if comma separated) to <code>d</code> digits after decimal mark, (the whole computation is done exactly, as in <code>xintexpr</code>),</p></li> <li><p><code>\xintfloatexpr</code>, <code>\xintthefloatexpr</code> similarly admit an optional argument which serves to keep only <code>d</code> digits of precision, getting rid of cumulated uncertainties in the last digits (the whole computation is done according to the precision set via <code>\xintDigits</code>),</p></li> <li><p><code>\xinttheexpr</code> and <code>\xintthefloatexpr</code> <em>pretty-print</em> if possible, the former removing unit denominator or <code>[0]</code> brackets, the latter avoiding scientific notation if decimal notation is practical,</p></li> @@ -217,7 +281,7 @@ License: LPPL 1.3c</code></pre> <ul> <li><p>(<strong>xint</strong>) the core division routines have been re-written for some (limited) efficiency gain, more pronounced for small divisors. As a result the <em>computation of one thousand digits of <span class="math"><em>Ï€</em></span></em> is close to three times faster than with earlier releases.</p></li> <li><p>some various other small improvements, particularly in the power routines.</p></li> -<li><p>(<strong>xintfrac</strong>) a new macro <code>\xintXTrunc</code> is designed to produce thousands or even tens of thousands of digits of the decimal expansion of a fraction. Although completely expandable it has its use limited to inside an <code>\edef</code>, <code>\write</code>, <code>\message</code>, . It can thus not be nested as argument to another package macro.</p></li> +<li><p>(<strong>xintfrac</strong>) a macro <code>\xintXTrunc</code> is designed to produce thousands or even tens of thousands of digits of the decimal expansion of a fraction. Although completely expandable it has its use limited to inside an <code>\edef</code>, <code>\write</code>, <code>\message</code>, . It can thus not be nested as argument to another package macro.</p></li> <li><p>(<strong>xintexpr</strong>) the tacit multiplication done in <code>\xintexpr..\relax</code> on encountering a count register or variable, or a <code>\numexpr</code>, while scanning a (decimal) number, is extended to the case of a sub <code>\xintexpr</code>-ession.</p></li> <li><p><code>\xintexpr</code> can now be used in an <code>\edef</code> with no <code>\xintthe</code> prefix; it will execute completely the computation, and the error message about a missing <code>\xintthe</code> will be inhibited. Previously, in the absence of <code>\xintthe</code>, expansion could only be a full one (with <code>\romannumeral-`0</code>), not a complete one (with <code>\edef</code>). Note that this differs from the behavior of the non-expandable <code>\numexpr</code>: <code>\the</code> or <code>\number</code> (or <code>\romannumeral</code>) are needed not only to print but also to trigger the computation, whereas <code>\xintthe</code> is mandatory only for the printing step.</p></li> <li><p>the default behavior of <code>\xintAssign</code> is changed, it now does not do any further expansion beyond the initial full-expansion which provided the list of items to be assigned to macros.</p></li> @@ -229,7 +293,7 @@ License: LPPL 1.3c</code></pre> <li><p>(<strong>xintexpr</strong>) <code>\xintiiexpr</code> is a variant of <code>\xintexpr</code> which is optimized to deal only with (long) integers, <code>/</code> does a euclidean quotient.</p></li> <li><p><code>\xintnumexpr</code>, <code>\xintthenumexpr</code>, <code>\xintNewNumExpr</code> are renamed, respectively, <code>\xintiexpr</code>, <code>\xinttheiexpr</code>, <code>\xintNewIExpr</code>. The earlier denominations are kept but to be removed at some point.</p></li> <li><p>it is now possible within <code>\xintexpr...\relax</code> and its variants to use count, dimen, and skip registers or variables without explicit <code>\the/\number</code>: the parser inserts automatically <code>\number</code> and a tacit multiplication is implied when a register or variable immediately follows a number or fraction. Regarding dimensions and <code>\number</code>, see the further discussion in <em>Dimensions</em>.</p></li> -<li><p>(<strong>xintfrac</strong>) new conditional <code>\xintifOne</code>; <code>\xintifTrueFalse</code> renamed to <code>\xintifTrueAelseB</code>; new macros <code>\xintTFrac</code> (<code>fractional part</code>, mapped to function <code>frac</code> in <code>\xintexpr</code>-essions), <code>\xintFloatE</code>.</p></li> +<li><p>(<strong>xintfrac</strong>) conditional <code>\xintifOne</code>; <code>\xintifTrueFalse</code> renamed to <code>\xintifTrueAelseB</code>; macros <code>\xintTFrac</code> (<code>fractional part</code>, mapped to function <code>frac</code> in <code>\xintexpr</code>-essions), <code>\xintFloatE</code>.</p></li> <li><p>(<strong>xinttools</strong>) <code>\xintAssign</code> admits an optional argument to specify the expansion type to be used: <code>[]</code> (none, default), <code>[o]</code> (once), <code>[oo]</code> (twice), <code>[f]</code> (full), <code>[e]</code> (<code>\edef</code>),... to define the macros</p></li> <li><p><strong>xinttools</strong> defines <code>\odef</code>, <code>\oodef</code>, <code>\fdef</code> (if the names have already been assigned, it uses <code>\xintoodef</code> etc...). These tools are provided for the case one uses the package macros in a non-expandable context. <code>\oodef</code> expands twice the macro replacement text, and <code>\fdef</code> applies full expansion. They are useful in situations where one does not want a full <code>\edef</code>. <code>\fdef</code> appears to be faster than <code>\oodef</code> in almost all cases (with less than thousand digits in the result), and even faster than <code>\edef</code> for expanding the package macros when the result has a few dozens of digits. <code>\oodef</code> needs that expansion ends up in thousands of digits to become competitive with the other two.</p></li> <li><p>some across the board slight efficiency improvement as a result of modifications of various types to <em>fork macros</em> and <em>branching conditionals</em> which are used internally.</p></li> @@ -250,12 +314,12 @@ License: LPPL 1.3c</code></pre> <h2 id="g-20131122"><code>1.09g (2013/11/22)</code></h2> <ul> <li><p>a package <strong>xinttools</strong> is detached from <strong>xint</strong>, to make tools such as <code>\xintFor</code>, <code>\xintApplyUnbraced</code>, and <code>\xintiloop</code> available without the <strong>xint</strong> overhead.</p></li> -<li><p>new expandable nestable loops <code>\xintloop</code> and <code>\xintiloop</code>.</p></li> +<li><p>expandable nestable loops <code>\xintloop</code> and <code>\xintiloop</code>.</p></li> <li><p>bugfix: <code>\xintFor</code> and <code>\xintFor*</code> do not modify anymore the value of <code>\count 255</code>.</p></li> </ul> <h2 id="f-20131104"><code>1.09f (2013/11/04)</code></h2> <ul> -<li><p>(<strong>xint</strong>) new <code>\xintZapFirstSpaces</code>, <code>\xintZapLastSpaces</code>, <code>\xintZapSpaces</code>, <code>\xintZapSpacesB</code>, for expandably stripping away leading and/or ending spaces.</p></li> +<li><p>(<strong>xint</strong>) <code>\xintZapFirstSpaces</code>, <code>\xintZapLastSpaces</code>, <code>\xintZapSpaces</code>, <code>\xintZapSpacesB</code>, for expandably stripping away leading and/or ending spaces.</p></li> <li><p><code>\xintCSVtoList</code> by default uses <code>\xintZapSpacesB</code> to strip away spaces around commas (or at the start and end of the comma separated list).</p></li> <li><p>also the <code>\xintFor</code> loop will strip out all spaces around commas and at the start and the end of its list argument; and similarly for <code>\xintForpair</code>, <code>\xintForthree</code>, <code>\xintForfour</code>.</p></li> <li><p><code>\xintFor</code> <em>et al.</em> accept all macro parameters from <code>#1</code> to <code>#9</code>.</p></li> @@ -263,10 +327,10 @@ License: LPPL 1.3c</code></pre> </ul> <h2 id="e-20131029"><code>1.09e (2013/10/29)</code></h2> <ul> -<li><p>(<strong>xint</strong>) new <code>\xintintegers</code>, <code>\xintdimensions</code>, <code>\xintrationals</code> for infinite <code>\xintFor</code> loops, interrupted with <code>\xintBreakFor</code> and <code>\xintBreakForAndDo</code>.</p></li> -<li><p>new <code>\xintifForFirst</code>, <code>\xintifForLast</code> for the <code>\xintFor</code> and <code>\xintFor*</code> loops,</p></li> +<li><p>(<strong>xint</strong>) <code>\xintintegers</code>, <code>\xintdimensions</code>, <code>\xintrationals</code> for infinite <code>\xintFor</code> loops, interrupted with <code>\xintBreakFor</code> and <code>\xintBreakForAndDo</code>.</p></li> +<li><p><code>\xintifForFirst</code>, <code>\xintifForLast</code> for the <code>\xintFor</code> and <code>\xintFor*</code> loops,</p></li> <li><p>the <code>\xintFor</code> and <code>xintFor*</code> loops are now <code>\long</code>, the replacement text and the items may contain explicit <code>\par</code>'s.</p></li> -<li><p>new conditionals <code>\xintifCmp</code>, <code>\xintifInt</code>, <code>\xintifOdd</code>.</p></li> +<li><p>conditionals <code>\xintifCmp</code>, <code>\xintifInt</code>, <code>\xintifOdd</code>.</p></li> <li><p>bug fix (<strong>xint</strong>): the <code>\xintFor</code> loop (not <code>\xintFor*</code>) did not correctly detect an empty list.</p></li> <li><p>bug fix (<strong>xint</strong>): <code>\xintiSqrt {0}</code> crashed. <code>:-((</code></p></li> <li><p>the documentation has been enriched with various additional examples, such as the <em>the quick sort algorithm illustrated</em> or the various ways of <em>computing prime numbers</em>.</p></li> @@ -285,7 +349,7 @@ License: LPPL 1.3c</code></pre> <li><p>(<strong>xint</strong>) <code>\xintFor</code> is a new type of loop, whose replacement text inserts the comma separated values or list items via macro parameters, rather than encapsulated in macros; the loops are nestable up to four levels (nine levels since <code>1.09f</code>) and their replacement texts are allowed to close groups as happens with the tabulation in alignments,</p></li> <li><p><code>\xintForpair</code>, <code>\xintForthree</code>, <code>\xintForfour</code> are experimental variants of <code>\xintFor</code>,</p></li> <li><p><code>\xintApplyInline</code> has been enhanced in order to be usable for generating rows (partially or completely) in an alignment,</p></li> -<li><p>new command <code>\xintSeq</code> to generate (expandably) arithmetic sequences of (short) integers,</p></li> +<li><p>command <code>\xintSeq</code> to generate (expandably) arithmetic sequences of (short) integers,</p></li> <li><p>again various improvements and changes in the documentation.</p></li> </ul> <h2 id="b-20131003"><code>1.09b (2013/10/03)</code></h2> @@ -294,7 +358,7 @@ License: LPPL 1.3c</code></pre> <li><p>more economical catcode management and re-loading handling,</p></li> <li><p>removal of all those <code>[0]</code>'s previously forcefully added at the end of fractions by various macros of <strong>xintcfrac</strong>,</p></li> <li><p><code>\xintNthElt</code> with a negative index returns from the tail of the list,</p></li> -<li><p>new macro <code>\xintPRaw</code> to have something like what <code>\xintFrac</code> does in math mode; i.e. a <code>\xintRaw</code> which does not print the denominator if it is one.</p></li> +<li><p>macro <code>\xintPRaw</code> to have something like what <code>\xintFrac</code> does in math mode; i.e. a <code>\xintRaw</code> which does not print the denominator if it is one.</p></li> </ul> <h2 id="a-20130924"><code>1.09a (2013/09/24)</code></h2> <ul> @@ -308,7 +372,7 @@ License: LPPL 1.3c</code></pre> <li><p><code>\xintnumexpr .. \relax</code> (now renamed <code>\xintiexpr</code>) is <code>\xintexpr round( .. ) \relax</code>.</p></li> <li><p><code>\xintNewExpr</code> now works with the standard macro parameter character <code>#</code>.</p></li> <li><p>both regular <code>\xintexpr</code>-essions and commands defined by <code>\xintNewExpr</code> will work with comma separated lists of expressions,</p></li> -<li><p>new commands <code>\xintFloor</code>, <code>\xintCeil</code>, <code>\xintMaxof</code>, <code>\xintMinof</code> (package <strong>xintfrac</strong>), <code>\xintGCDof</code>, <code>\xintLCM</code>, <code>\xintLCMof</code> (package <strong>xintgcd</strong>), <code>\xintifLt</code>, <code>\xintifGt</code>, <code>\xintifSgn</code>, <code>\xintANDof</code>, ...</p></li> +<li><p>commands <code>\xintFloor</code>, <code>\xintCeil</code>, <code>\xintMaxof</code>, <code>\xintMinof</code> (package <strong>xintfrac</strong>), <code>\xintGCDof</code>, <code>\xintLCM</code>, <code>\xintLCMof</code> (package <strong>xintgcd</strong>), <code>\xintifLt</code>, <code>\xintifGt</code>, <code>\xintifSgn</code>, <code>\xintANDof</code>, ...</p></li> <li><p>The arithmetic macros from package <strong>xint</strong> now filter their operands via <code>\xintNum</code> which means that they may use directly count registers and <code>\numexpr</code>-essions without having to prefix them by <code>\the</code>. This is thus similar to the situation holding previously already when <strong>xintfrac</strong> was loaded.</p></li> <li><p>a bug (<strong>xintfrac</strong>) introduced in <code>1.08b</code> made <code>\xintCmp</code> crash when one of its arguments was zero. <code>:-((</code></p></li> </ul> @@ -316,7 +380,7 @@ License: LPPL 1.3c</code></pre> <ul> <li><p>(<strong>xintexpr</strong>) Correction of a problem with spaces inside <code>\xintexpr</code>-essions.</p></li> <li><p>(<strong>xintfrac</strong>) Additional improvements to the handling of floating point numbers.</p></li> -<li><p>new section <em>Use of count registers</em> documenting how count registers may be directly used in arguments to the macros of <strong>xintfrac</strong>.</p></li> +<li><p>section <em>Use of count registers</em> documenting how count registers may be directly used in arguments to the macros of <strong>xintfrac</strong>.</p></li> </ul> <h2 id="a-20130611"><code>1.08a (2013/06/11)</code></h2> <ul> @@ -327,7 +391,7 @@ License: LPPL 1.3c</code></pre> <h2 id="section-2"><code>1.08 (2013/06/07)</code></h2> <ul> <li><p>(<strong>xint</strong> and <strong>xintfrac</strong>) Macros for extraction of square roots, for floating point numbers (<code>\xintFloatSqrt</code>), and integers (<code>\xintiSqrt</code>).</p></li> -<li><p>New package <strong>xintbinhex</strong> providing <em>conversion routines</em> to and from binary and hexadecimal bases.</p></li> +<li><p>new package <strong>xintbinhex</strong> providing <em>conversion routines</em> to and from binary and hexadecimal bases.</p></li> </ul> <h2 id="section-3"><code>1.07 (2013/05/25)</code></h2> <ul> @@ -335,7 +399,7 @@ License: LPPL 1.3c</code></pre> <pre><code>\xintexpr . . . \relax,</code></pre> <p>and its variant</p> <pre><code>\xintfloatexpr . . . \relax</code></pre> -<p>allowing on input formulas using the infix operators <code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>, and <code>^</code>, and arbitrary levels of parenthesizing. Within a float expression the operations are executed according to the current value of <code>\xintDigits</code>. Within an <code>\xintexpr</code>-ession the binary operators are computed exactly.</p> +<p>allowing on input formulas using the infix operators <code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>, and <code>^</code>, and arbitrary levels of parenthesizing. Within a float expression the operations are executed according to the current value set by <code>\xintDigits</code>. Within an <code>\xintexpr</code>-ession the binary operators are computed exactly.</p> <p>To write the <code>\xintexpr</code> parser I benefited from the commented source of the <code>l3fp</code> parser; the <code>\xintexpr</code> parser has its own features and peculiarities. <em>See its documentation</em>.</p></li> <li><p>The floating point precision <code>D</code> is set (this is a local assignment to a <code>\mathchar</code> variable) with <code>\xintDigits := D;</code> and queried with <code>\xinttheDigits</code>. It may be set to anything up to <code>32767</code>.<a href="#fn1" class="footnoteRef" id="fnref1"><sup>1</sup></a> The macro incarnations of the binary operations admit an optional argument which will replace pointwise <code>D</code>; this argument may exceed the <code>32767</code> bound.</p></li> <li><p>The <strong>xintfrac</strong> macros now accept numbers written in scientific notation, the <code>\xintFloat</code> command serves to output its argument with a given number <code>D</code> of significant figures. The value of <code>D</code> is either given as optional argument to <code>\xintFloat</code> or set with <code>\xintDigits := D;</code>. The default value is <code>16</code>.</p></li> diff --git a/Master/texmf-dist/doc/generic/xint/CHANGES.pdf b/Master/texmf-dist/doc/generic/xint/CHANGES.pdf Binary files differindex b6cfb59370a..d4ad85a9f9a 100644 --- a/Master/texmf-dist/doc/generic/xint/CHANGES.pdf +++ b/Master/texmf-dist/doc/generic/xint/CHANGES.pdf diff --git a/Master/texmf-dist/doc/generic/xint/README b/Master/texmf-dist/doc/generic/xint/README index 3ff98807f83..b3ad2a4b5e3 100644 --- a/Master/texmf-dist/doc/generic/xint/README +++ b/Master/texmf-dist/doc/generic/xint/README @@ -1,4 +1,4 @@ - Source: xint.dtx v1.2e 2015/11/22 (doc 2015/11/22) + Source: xint.dtx 1.2f 2016/03/12 (doc 2016/03/12) Author: Jean-Francois Burnol Info: Expandable operations on big integers, decimals, fractions License: LPPL 1.3c @@ -35,7 +35,7 @@ xintexpr loads all of them and provides expandable parsers allowing computations such as the above (and more). A more light-weight package bnumexpr (LaTeX only) loads only xintcore and provides a parser which handles only big integers, the four operations, the power operation and -the factorial (v1.2). +the factorial (1.2). @@ -180,7 +180,7 @@ filename database. LICENSE -Copyright (C) 2013-2015 by Jean-Francois Burnol +Copyright (C) 2013-2016 by Jean-Francois Burnol This Work may be distributed and/or modified under the conditions of the LaTeX Project Public License version 1.3c. This version of this license diff --git a/Master/texmf-dist/doc/generic/xint/README.html b/Master/texmf-dist/doc/generic/xint/README.html index fe6879e565c..3cb30ba8d53 100644 --- a/Master/texmf-dist/doc/generic/xint/README.html +++ b/Master/texmf-dist/doc/generic/xint/README.html @@ -4,7 +4,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <meta name="generator" content="pandoc" /> - <meta name="author" content="xint v1.2e" /> + <meta name="author" content="xint 1.2f" /> <title>README</title> <style type="text/css">code{white-space: pre;}</style> <style type="text/css"> @@ -17,8 +17,8 @@ <body> <div id="header"> <h1 class="title">README</h1> -<h2 class="author">xint v1.2e</h2> -<h3 class="date">2015/11/22</h3> +<h2 class="author">xint 1.2f</h2> +<h3 class="date">2016/03/12</h3> </div> <div id="TOC"> <ul> @@ -36,7 +36,7 @@ <li><a href="#license">License</a></li> </ul> </div> -<pre><code>Source: xint.dtx v1.2e 2015/11/22 (doc 2015/11/22) +<pre><code>Source: xint.dtx 1.2f 2016/03/12 (doc 2016/03/12) Author: Jean-Francois Burnol Info: Expandable operations on big integers, decimals, fractions License: LPPL 1.3c</code></pre> @@ -50,7 +50,7 @@ License: LPPL 1.3c</code></pre> <pre><code>\xinttheexpr mul(add(x(x+1)(x+2), x=y..y+15), y=171286,98762,9296)\relax</code></pre> <p>evaluates to <code>15979066346135829902328007959448563667099190784</code>.</p> <p>It is possible to use the package with Plain as well as with LaTeX.</p> -<p>Sub-units <code>xintcore</code>, <code>xint</code> and <code>xintfrac</code> provide the underlying macros, and <code>xintexpr</code> loads all of them and provides expandable parsers allowing computations such as the above (and more). A more light-weight package <a href="http://www.ctan.org/pkg/bnumexpr">bnumexpr</a> (LaTeX only) loads only <code>xintcore</code> and provides a parser which handles only big integers, the four operations, the power operation and the factorial (v1.2).</p> +<p>Sub-units <code>xintcore</code>, <code>xint</code> and <code>xintfrac</code> provide the underlying macros, and <code>xintexpr</code> loads all of them and provides expandable parsers allowing computations such as the above (and more). A more light-weight package <a href="http://www.ctan.org/pkg/bnumexpr">bnumexpr</a> (LaTeX only) loads only <code>xintcore</code> and provides a parser which handles only big integers, the four operations, the power operation and the factorial (1.2).</p> <h1 id="usage">Usage</h1> <h2 id="with-latex">With LaTeX</h2> <pre><code>\usepackage{xint} % expandable arithmetic with big integers @@ -122,7 +122,7 @@ sudo texhash /usr/local/texlive/texmf-local</code></pre></li> <p>Depending on the destination, it may then be necessary to refresh a filename database.</p> <h1 id="license">License</h1> <div class="mono"> -<p>Copyright (C) 2013-2015 by Jean-Francois Burnol</p> +<p>Copyright (C) 2013-2016 by Jean-Francois Burnol</p> <p>This Work may be distributed and/or modified under the conditions of the LaTeX Project Public License version 1.3c. This version of this license is in</p> <blockquote> <p><a href="http://www.latex-project.org/lppl/lppl-1-3c.txt" class="uri">http://www.latex-project.org/lppl/lppl-1-3c.txt</a></p> diff --git a/Master/texmf-dist/doc/generic/xint/README.pdf b/Master/texmf-dist/doc/generic/xint/README.pdf Binary files differindex b00a76e38c0..f5d338fc252 100644 --- a/Master/texmf-dist/doc/generic/xint/README.pdf +++ b/Master/texmf-dist/doc/generic/xint/README.pdf diff --git a/Master/texmf-dist/doc/generic/xint/sourcexint.pdf b/Master/texmf-dist/doc/generic/xint/sourcexint.pdf Binary files differindex cfdd9c00bb4..5552ceb954c 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 957babeb300..b2ffd8533d6 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 f2eebc0f906..74bc80a0d62 100644 --- a/Master/texmf-dist/source/generic/xint/xint.dtx +++ b/Master/texmf-dist/source/generic/xint/xint.dtx @@ -1,34 +1,30 @@ -% -*- coding: iso-latin-1; time-stamp-format: "%02d-%02m-%:y at %02H:%02M:%02S %Z" -*- -% N.B.: this dtx file does NOT use \DocInput, only docstrip. The user manual -% latex source is NOT prefixed with percent characters. +% -*- coding: utf-8; time-stamp-format: "%02d-%02m-%:y at %02H:%02M:%02S %Z" -*- +% This file: xint.dtx. Proudly produced by xint-dtxbuild.sh. +% Extract all files via "etex xint.dtx" and do "make help" +% or follow instructions from extracted README.md. %<*dtx> -\def\xintdtxtimestamp {Time-stamp: <22-11-2015 à 23:03:12 CET>} +\def\xintdtxtimestamp {Time-stamp: <12-03-2016 at 21:52:32 CET>} %</dtx> %<*drv> %% --------------------------------------------------------------- -\def\xintdocdate {2015/11/22} -\def\xintbndldate{2015/11/22} -\def\xintbndlversion {1.2e} +\def\xintdocdate {2016/03/12} +\def\xintbndldate{2016/03/12} +\def\xintbndlversion {1.2f} %</drv> -%<*dtx> -\iffalse % meta-comment -%</dtx> %<readme>% README %<changes>% CHANGE LOG -%<readme|changes>% xint v1.2e -%<readme|changes>% 2015/11/22 -%<*readme|changes> - - Source: xint.dtx v1.2e 2015/11/22 (doc 2015/11/22) - Author: Jean-Francois Burnol - Info: Expandable operations on big integers, decimals, fractions - License: LPPL 1.3c - -%</readme|changes> +%<readme|changes>% xint 1.2f +%<readme|changes>% 2016/03/12 +%<readme|changes> +%<readme|changes> Source: xint.dtx 1.2f 2016/03/12 (doc 2016/03/12) +%<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&!dopdfsh&!makefile> %% --------------------------------------------------------------- -%% The xint bundle v1.2e 2015/11/22 -%% Copyright (C) 2013-2015 by Jean-Francois Burnol +%% The xint bundle 1.2f 2016/03/12 +%% Copyright (C) 2013-2016 by Jean-Francois Burnol %<xintkernel>%% xintkernel: Paraphernalia for the xint packages %<xinttools>%% xinttools: Expandable and non-expandable utilities %<xintcore>%% xintcore: Expandable arithmetic on big integers @@ -41,7 +37,10 @@ %<xintcfrac>%% xintcfrac: Expandable continued fractions with xint package %% --------------------------------------------------------------- %</!readme&!changes&!dohtmlsh&!dopdfsh&!makefile> -%<*readme> +%<*dtx> +\bgroup\catcode2 0 \catcode`\\ 12 ^^Biffalse +%</dtx> +%<*readme>-------------------------------------------------------- This `README` is also available as `README.pdf` and `README.html`. Change log is to be found in `CHANGES.pdf` or `CHANGES.html`. @@ -49,19 +48,18 @@ Change log is to be found in `CHANGES.pdf` or `CHANGES.html`. The user manual is `xint.pdf`, and the commented source code is available as `sourcexint.pdf`. - Aim === The basic aim is provide *expandable* computations on big integers, and also big fractions. For example - + \xinttheexpr reduce(37189719/183618963+11390170/17310720)^17\relax will evaluate exactly the fraction (the result has 462 characters including the fraction slash). One can also work with dummy variables. For example - + \xinttheexpr mul(add(x(x+1)(x+2), x=y..y+15), y=171286,98762,9296)\relax evaluates to `15979066346135829902328007959448563667099190784`. @@ -74,8 +72,7 @@ parsers allowing computations such as the above (and more). A more light-weight package [bnumexpr](http://www.ctan.org/pkg/bnumexpr) (LaTeX only) loads only `xintcore` and provides a parser which handles only big integers, the four operations, the power operation -and the factorial (v1.2). - +and the factorial (1.2). Usage ===== @@ -108,7 +105,6 @@ be loaded in any catcode context such that letters, digits, `\` and which has the catcode handler and package identifier and defines a few utilities such as `\oodef`, `\fdef`, or `\xint_dothis/\xint_orthat`. - Installation ============ @@ -153,7 +149,7 @@ files as well as `xint.tds.zip`. It is for GNU/Linux-like (inc. Mac OS X) systems, with a teTeX like installation such as TeXLive. Furthermore the [Pandoc](http://johnmacfarlane.net/pandoc/) software is required. -1. obtain `xint.dtx` and `Makefile` from +1. obtain `xint.dtx` and `Makefile` from <http://mirror.ctan.org/macros/generic/xint>. 2. put them in an otherwise empty working repertory, run `make` or @@ -208,12 +204,11 @@ Finishing the installation in a TDS hierarchy: Depending on the destination, it may then be necessary to refresh a filename database. - License ======= <div class="mono"> -Copyright (C) 2013-2015 by Jean-Francois Burnol +Copyright (C) 2013-2016 by Jean-Francois Burnol This Work may be distributed and/or modified under the conditions of the LaTeX Project Public License version 1.3c. @@ -237,35 +232,110 @@ pandoctpl.latex, doHTMLs.sh, doPDFs.sh, xint.dvi, xint.pdf, Makefile.mk.</div> %</readme>-------------------------------------------------------- %<*changes>------------------------------------------------------- +`1.2f (2016/03/12)` +---- + +### Incompatible changes + + - no more `\xintFac` macro but `\xintiFac/\xintiiFac/\xintFloatFac`. + +### Bug fixes + + - squaring macro `\xintSqr` from **xintfrac.sty** was broken due to a + misspelled sub-macro name. Dates back to `1.1` release of `2014/10/28` + `:-((`. + + - `1.2c`'s fix to the subtraction bug from `1.2` introduced another bug, + which in some cases could create leading zeroes in the output, or even + worse. This could invalidate other routines using subtractions, like + `\xintiiSquareRoot`. + + - the comparison operators were not recognized by `\xintNewIIExpr` and + `\xintdefiifunc` constructs. + +### Improvements and new features + + - functions `binomial`, `pfactorial` and `factorial` in both integer + and float versions. + + - macros `\xintiiBinomial`, `\xintiiPFactorial` + (**xint.sty**) and `\xintFloatBinomial`, `\xintFloatPFactorial` + (**xintfrac.sty**). Improvements to `\xintFloatFac`. + + - faster implementation and increased accuracy of float power macros. + Half-integer exponents are now accepted inside float expressions. + + - faster implementation of both integral and float square root macros. + + - the float square root achieves + *correct* (aka *exact*) rounding in arbitrary precision. + + - modified behaviour for the `\xintPFloat` macro, used by + `\xintthefloatexpr` to prettify its output. It now opts for decimal + notation if and only if scientific notation would use an exponent between + `-5` and `5` inclusive. The zero value is printed `0.` with a dot. + + - the float macros for addition, subtraction, multiplication, division now + first round their two operands to P, not P+2, significant places before + doing the actual computation (P being the target precision). The same + applies to the power macros and to the square root macro. + + - the documentation offers a more precise (and accurate) discussion of + floating point issues. + + - various under-the-hood code improvements; the floatexpr operations are + chained in a faster way, from skipping some unneeded parsing on results of + earlier computations. The absence of a real inner data structure for floats + (incorporating their precisions, for one) is however still a bit hair + rising: currently the lengths of the mantissas of the operands are computed + again by each float macro or expression operation. + + - (TeXperts only) the macros defined (internally) from `\xintdeffunc` et al. + constructs do not incorporate an initial `\romannumeral` anymore. + + - renewed desperate efforts at improving the documentation by random + shuffling of sections and well thought additions; cuts were considered and + even performed. + + `1.2e (2015/11/22)` ---- - - bugfix in **xintfrac**: the `\xintFloatFac` from release `1.2` parsed - its argument only through `\numexpr` but it should have used `\xintNum`. +### Bug fixes - - bugfix in **xintexpr**: release `1.2d` had broken the recognition of - sub-expressions immediately after variable names (with tacit multiplication). + - in **xintfrac**: the `\xintFloatFac` from release `1.2` parsed its + argument only through `\numexpr` but it should have used `\xintNum`. - - new macro `\xintunassignvar`. + - in **xintexpr**: release `1.2d` had broken the recognition of + sub-expressions immediately after variable names (with tacit + multiplication). + + - in **xintexpr**: contrarily to what `1.2d` documentation said, tacit + multiplication was not yet always done with enhanced precedence. Now + yes. + +### Improvements and new features + + - macro `\xintunassignvar`. - slight modifications of the logged messages in case of `\xintverbosetrue`. - - - a space in `\xintdeffunc f(x)<space>:= expression ;` is now accepted. - - contrarily to what `1.2d` documentation said, tacit multiplication - was not yet always done with enhanced precedence. Now yes. + - a space in `\xintdeffunc f(x)<space>:= expression ;` is now accepted. - documentation enhancements: the _Quick Sort_ section with its included code samples has been entirely re-written; the _Commands of the xintexpr package_ section has been extended and reviewed entirely. - `1.2d (2015/11/18)` ---- - - bugfix in **xintcore**: release `1.2c` had inadvertently broken - the `\xintiiDivRound` macro. - +### Bug fixes + + - in **xintcore**: release `1.2c` had inadvertently broken the + `\xintiiDivRound` macro. + +### Improvements and new features + - the function definitions done by `\xintdeffunc` et al., as well as the macro declarations by `\xintNewExpr` et al. now have only local scope. @@ -277,37 +347,44 @@ Makefile.mk.</div> - some documentation enhancements, particularly in the chapter on xintexpr.sty, and also in the code source comments. - `1.2c (2015/11/16)` ---- - - bugfix in **xintcore**: recent release `1.2` introduced a bug in the +### Bug fixes + + - in **xintcore**: recent release `1.2` introduced a bug in the subtraction (happened when 00000001 was found under certain circumstances at certain mod 8 locations). - - - new macros `\xintdeffunc`, `\xintdefiifunc`, `\xintdeffloatfunc` and + +### Improvements and new features + + - macros `\xintdeffunc`, `\xintdefiifunc`, `\xintdeffloatfunc` and boolean `\ifxintverbose`. - on-going code improvements and documentation enhancements, but stopped in order to issue this bugfix release. - `1.2b (2015/10/29)` ---- - - bugfix in **xintcore**: recent release `1.2` introduced a bug in - the division macros, causing a crash when the divisor started - with 99999999 (it was attempted to use with 1+99999999 a - subroutine expecting only 8-digits numbers). +### Bug fixes + - in **xintcore**: recent release `1.2` introduced a bug in the division + macros, causing a crash when the divisor started with 99999999 (it was + attempted to use with 1+99999999 a subroutine expecting only 8-digits + numbers). `1.2a (2015/10/19)` ---- - - bugfix in **xintexpr**: recent release `1.2` introduced a bad bug - in the parsing of decimal numbers and as a result `\xinttheexpr +### Bug fixes + + - in **xintexpr**: recent release `1.2` introduced a bad bug in the + parsing of decimal numbers and as a result `\xinttheexpr 0.01\relax` expanded to `0` ! (sigh...) +### Improvements and new features + - added `\xintKeepUnbraced`, `\xintTrimUnbraced` (**xinttools**) and fixed documentation of `\xintKeep` and `\xintTrim` regarding brace stripping. @@ -317,10 +394,11 @@ Makefile.mk.</div> by the quicker ``\romannumeral`&&@`` (`^` being used as letter, had to find another character usable with catcode 7). - `1.2 (2015/10/10)` ---- +### Improvements and new features + - the basic arithmetic implemented in **xintcore** has been entirely rewritten. The mathematics remains the elementary school one, but the `TeX` implementation achieves higher speed (except, regarding @@ -338,7 +416,7 @@ Makefile.mk.</div> in one-go, as an exception to its normal mode of operation which expands token by token. - - new `\xintFloatFac` macro for computing the factorials of integers as + - `\xintFloatFac` macro for computing the factorials of integers as floating point numbers to a given precision. The `!` postfix operator inside `\xintfloatexpr` maps to this new macro rather than to the exact factorial as used by `\xintexpr` and `\xintiiexpr`. @@ -369,7 +447,6 @@ Makefile.mk.</div> - an effort at randomly shuffling around various pieces of the documentation has been done. - `1.1c (2015/09/12)` ---- @@ -381,26 +458,24 @@ Makefile.mk.</div> regarding the source code formatting in `sourcexint.pdf`, and minor issues in `Makefile.mk`. - `1.1b (2015/08/31)` ---- - - bugfix: some macros needed by the integer division routine from + - bugfix: some macros needed by the integer division routine from **xintcore** had been left in **xint.sty** since release `1.1`. This for example broke the `\xintGCD` from **xintgcd** if package **xint** was not loaded. - - Slight enhancements to the documentation, particularly in the + - Slight enhancements to the documentation, particularly in the `Read this first` section. - `1.1a (2014/11/07)` ---- - fixed a bug which prevented `\xintNewExpr` from producing correctly working macros from a comma separated replacement text. - - new `\xintiiSqrtR` for rounded integer square root; former `\xintiiSqrt` + - `\xintiiSqrtR` for rounded integer square root; former `\xintiiSqrt` already produced truncated integer square root; corresponding function `sqrtr` added to `\xintiiexpr..\relax` syntax. @@ -413,13 +488,13 @@ Makefile.mk.</div> - for the same reason, added `\xintiiGCD` and `\xintiiLCM`. - - added the previously mentioned `ii` macros, and some others from `v1.1`, to + - added the previously mentioned `ii` macros, and some others from `1.1`, to the user manual. But their main usage is internal to `\xintiiexpr`, to skip unnecessary overheads. - various typographical fixes throughout the documentation, and a bit of clean up of the code comments. Improved `\Factors` example of nested - `subs`, `rseq`, `iter` in `\xintiiexpr`. + `subs`, `rseq`, `iter` in `\xintiiexpr`. `1.1 (2014/10/28)` ---- @@ -428,7 +503,7 @@ bug fixes : - `\xintZapFirstSpaces` hence also `\xintZapSpaces` from package **xinttools** were buggy when used with an argument either empty or containing only - space tokens. + space tokens. - `\xintiiexpr` did not strip leading zeroes, hence `\xinttheiiexpr 001+1\relax` did not obtain the expected result ... @@ -439,13 +514,13 @@ bug fixes - the catcode of `;` was not set at package launching time. - the `\XINTinFloatPrd:csv` macro name had a typo, hence `prd` was - non-functional in `\xintfloatexpr`. + non-functional in `\xintfloatexpr`. breaking changes : - in `\xintiiexpr`, `/` does _rounded_ division, rather than the Euclidean division (for positive arguments, this is truncated division). - The new `//` operator does truncated division, + The `//` operator does truncated division, - the `:` operator for three-way branching is gone, replaced with `??`, @@ -460,14 +535,14 @@ breaking changes number scanner, `a/b[N]` notation can be used without use of braces (the `N` will end up as is in a `\numexpr`, it is not parsed by the `\xintexpr`-ession scanner), - + - although `&` and `|` are still available as Boolean operators the use of `&&` and `||` is strongly recommended. The single letter operators might be assigned some other meaning in later releases (bitwise operations, perhaps). Do not use them. - in earlier releases, place holders for `\xintNewExpr` could either - be denoted `#1`, `#2`, ... or also `$1`, `$2`, ... + be denoted `#1`, `#2`, ... or also `$1`, `$2`, ... Only the usual `#` form is now accepted and the special cases previously treated via the second form are now managed via a `protect(...)` function. @@ -478,7 +553,7 @@ breaking changes * neither **xint** nor **xintfrac** load **xinttools**. Only **xintexpr** does, - + * whenever some portion of code has been revised, often use has been made of the `\xint_dothis` and `\xint_orthat` pair of macros for expandably branching, @@ -502,14 +577,14 @@ breaking changes * this naturally will be also the case for the `+` and `-` operations in `\xintexpr`, - * new macros `\xintiiDivRound`, `\xintiiDivTrunc` and `\xintiiMod` for + * macros `\xintiiDivRound`, `\xintiiDivTrunc` and `\xintiiMod` for rounded and truncated division of big integers (now in **xintcore**), alongside the earlier `\xintiiQuo` and `\xintiiRem`, * with **xintfrac** loaded, the `\xintNum` macro does `\xintTTrunc` (which is truncation to an integer, same as `\xintiTrunc {0}`), - * new macro `\xintMod` in **xintfrac** for modulo operation with + * macro `\xintMod` in **xintfrac** for modulo operation with fractional numbers, * `\xintiexpr`, `\xinttheiexpr` admit an optional argument within brackets @@ -534,7 +609,7 @@ breaking changes * multi-letter infix binary words `'and'`, `'or'`, `'xor'`, `'mod'` (straight quotes mandatory), - * functions `even`, `odd`, + * functions `even`, `odd`, * `\xintdefvar A3:=3.1415;` for variable definitions (non expandable, naturally), usable in subsequent expressions; variable names may contain @@ -658,7 +733,7 @@ breaking changes * some various other small improvements, particularly in the power routines. - * (**xintfrac**) a new macro `\xintXTrunc` is designed to produce + * (**xintfrac**) a macro `\xintXTrunc` is designed to produce thousands or even tens of thousands of digits of the decimal expansion of a fraction. Although completely expandable it has its use limited to inside an `\edef`, `\write`, `\message`, \dots. It @@ -709,8 +784,8 @@ breaking changes dimensions and `\number`, see the further discussion in *Dimensions*. - * (**xintfrac**) new conditional `\xintifOne`; `\xintifTrueFalse` - renamed to `\xintifTrueAelseB`; new macros `\xintTFrac` + * (**xintfrac**) conditional `\xintifOne`; `\xintifTrueFalse` + renamed to `\xintifTrueAelseB`; macros `\xintTFrac` (`fractional part`, mapped to function `frac` in `\xintexpr`-essions), `\xintFloatE`. @@ -781,7 +856,7 @@ breaking changes as `\xintFor`, `\xintApplyUnbraced`, and `\xintiloop` available without the **xint** overhead. - * new expandable nestable loops `\xintloop` and `\xintiloop`. + * expandable nestable loops `\xintloop` and `\xintiloop`. * bugfix: `\xintFor` and `\xintFor*` do not modify anymore the value of `\count 255`. @@ -789,7 +864,7 @@ breaking changes `1.09f (2013/11/04)` ---- - * (**xint**) new `\xintZapFirstSpaces`, `\xintZapLastSpaces`, + * (**xint**) `\xintZapFirstSpaces`, `\xintZapLastSpaces`, `\xintZapSpaces`, `\xintZapSpacesB`, for expandably stripping away leading and/or ending spaces. @@ -818,17 +893,17 @@ breaking changes `1.09e (2013/10/29)` ---- - * (**xint**) new `\xintintegers`, `\xintdimensions`, `\xintrationals` + * (**xint**) `\xintintegers`, `\xintdimensions`, `\xintrationals` for infinite `\xintFor` loops, interrupted with `\xintBreakFor` and `\xintBreakForAndDo`. - * new `\xintifForFirst`, `\xintifForLast` for the `\xintFor` and + * `\xintifForFirst`, `\xintifForLast` for the `\xintFor` and `\xintFor*` loops, * the `\xintFor` and `xintFor*` loops are now `\long`, the replacement text and the items may contain explicit `\par`'s. - * new conditionals `\xintifCmp`, `\xintifInt`, `\xintifOdd`. + * conditionals `\xintifCmp`, `\xintifInt`, `\xintifOdd`. * bug fix (**xint**): the `\xintFor` loop (not `\xintFor*`) did not correctly detect an empty list. @@ -881,7 +956,7 @@ breaking changes * `\xintApplyInline` has been enhanced in order to be usable for generating rows (partially or completely) in an alignment, - * new command `\xintSeq` to generate (expandably) arithmetic sequences + * command `\xintSeq` to generate (expandably) arithmetic sequences of (short) integers, * again various improvements and changes in the documentation. @@ -899,7 +974,7 @@ breaking changes * `\xintNthElt` with a negative index returns from the tail of the list, - * new macro `\xintPRaw` to have something like what `\xintFrac` does in + * macro `\xintPRaw` to have something like what `\xintFrac` does in math mode; i.e. a `\xintRaw` which does not print the denominator if it is one. @@ -934,7 +1009,7 @@ breaking changes `\xintNewExpr` will work with comma separated lists of expressions, - * new commands `\xintFloor`, `\xintCeil`, `\xintMaxof`, `\xintMinof` + * commands `\xintFloor`, `\xintCeil`, `\xintMaxof`, `\xintMinof` (package **xintfrac**), `\xintGCDof`, `\xintLCM`, `\xintLCMof` (package **xintgcd**), `\xintifLt`, `\xintifGt`, `\xintifSgn`, `\xintANDof`, ... @@ -957,7 +1032,7 @@ breaking changes * (**xintfrac**) Additional improvements to the handling of floating point numbers. - * new section *Use of count registers* documenting how count + * section *Use of count registers* documenting how count registers may be directly used in arguments to the macros of **xintfrac**. @@ -982,7 +1057,7 @@ breaking changes for floating point numbers (`\xintFloatSqrt`), and integers (`\xintiSqrt`). - * New package **xintbinhex** providing *conversion routines* to and from + * new package **xintbinhex** providing *conversion routines* to and from binary and hexadecimal bases. `1.07 (2013/05/25)` @@ -1001,7 +1076,7 @@ breaking changes allowing on input formulas using the infix operators `+`, `-`, `*`, `/`, and `^`, and arbitrary levels of parenthesizing. Within a float expression the operations are executed according to the - current value of `\xintDigits`. Within an `\xintexpr`-ession the + current value set by `\xintDigits`. Within an `\xintexpr`-ession the binary operators are computed exactly. To write the `\xintexpr` parser I benefited from the commented @@ -1094,11 +1169,7 @@ Initial announcement: > The packages may be used with Plain and with LaTeX. -%</changes>------------------------------------------------------- -%<*dtx> -\fi -\catcode`+ 0 \catcode`\\ 12 +iffalse -%</dtx> +%</changes>------------------------------------------------------ %<*makefile>------------------------------------------------------ # This file: Makefile.mk (generated from xint.dtx) # Tested on Mac OS X Mavericks with GNU Make 3.81, @@ -1214,7 +1285,7 @@ helpless: @printf '$(subst $(newline),\n,$(helptext))' | less # RM = rm -f -JF_tmpdir := $(shell mktemp -d jfbu_XXX) +JF_tmpdir := $(shell mktemp -d TEMP_XINT_XXX) TEXMF_local = $(shell kpsewhich -var-value TEXMFLOCAL) TEXMF_home = $(shell kpsewhich -var-value TEXMFHOME) packages = xintkernel.sty xintcore.sty xint.sty xintfrac.sty xintexpr.sty\ @@ -1331,7 +1402,7 @@ clean: cleanall: clean rm -f $(extracted) $(doc_pdf) $(doc_html)\ README xint.pdf sourcexint.pdf xint.tds.zip -%</makefile>$------------------------------------------------------ +%</makefile>$----------------------------------------------------- %<*pandoctpl>----------------------------------------------------- $if(dvipdfmx)$ {\csname @for\endcsname\x:=hyperref,graphicx,color,xcolor\do @@ -1357,14 +1428,14 @@ $endif$ \catcode`\`\active \@firstofone {\endgroup \def\dostraightquotesandstar{% textcomp package is loaded by newtxtext - \let`\textasciigrave + \let`\textasciigrave \let'\textquotesingle \edef*{\noexpand\raisebox{-.25\noexpand\height}{\string*}}% \catcode39\active % ' \catcode96\active % ` \catcode42\active }% * }% for \texttt, let's just forget about math and italic correction things -\DeclareRobustCommand\texttt {\bgroup +\DeclareRobustCommand\texttt {\bgroup \dostraightquotesandstar\afterassignment\ttfamily\let\next=} $if(geometry)$ @@ -1443,7 +1514,7 @@ $endfor$ pandoc -o README.html -s --toc -V highlighting-css=' body{margin-left : 10%; margin-right : 15%; margin-top: 4ex; font-size: 14pt;} pre {white-space: pre-wrap; } - code {white-space: pre-wrap; } + code {white-space: pre-wrap; } .mono {font-family: monospace;}' README.md pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin-left : 10%; margin-right : 15%; margin-top: 4ex; font-size: 14pt;} @@ -1464,7 +1535,7 @@ latex -interaction=nonstopmode README latex -interaction=nonstopmode README dvipdfmx README.dvi -pandoc -o CHANGES.tex --template=pandoctpl --toc -V papersize=a4paper -V fontsize=11pt -V dvipdfmx --variable=geometry:footskip=1cm,left=2.5cm,right=2.5cm,top=2cm,bottom=3cm -V etoc=2 CHANGES.md +pandoc -o CHANGES.tex --template=pandoctpl --toc -V 'toc-depth'=2 -V papersize=a4paper -V fontsize=11pt -V dvipdfmx --variable=geometry:footskip=1cm,left=2.5cm,right=2.5cm,top=2cm,bottom=3cm -V etoc=2 CHANGES.md rm -f CHANGES.aux CHANGES.toc CHANGES.out latex -interaction=nonstopmode CHANGES latex -interaction=nonstopmode CHANGES @@ -1479,15 +1550,15 @@ dvipdfmx CHANGES.dvi %% \NeedsTeXFormat{LaTeX2e} \ProvidesFile{xint.tex}% -[\xintbndldate\space v\xintbndlversion\space driver file for xint documentation (jfB)]% +[\xintbndldate\space v\xintbndlversion\space driver file for xint documentation (JFB)]% \PassOptionsToClass{a4paper,fontsize=10pt}{scrdoc} \chardef\NoSourceCode 1 % set it to 0 if source code inclusion desired \input xint.dtx %%% Local Variables: %%% mode: latex %%% End: -%</drv>---------------------------------------------------------------------- -%<*ins>------------------------------------------------------------------------- +%</drv>----------------------------------------------------------- +%<*ins>----------------------------------------------------------- %% %% tex xint.ins extracts all package files from xint.dtx, as well as %% xint.tex, README.md, CHANGES.md, doPDFs.sh, doHTMLs.sh. @@ -1545,10 +1616,9 @@ dvipdfmx CHANGES.dvi \Msg{*} \Msg{************************************************************************} \endbatchfile -%</ins>------------------------------------------------------------------------- -%<*dtx> -+fi % end of \iffalse block -+catcode`\ 0 \catcode`\+ 12 +%</ins>----------------------------------------------------------- +%<*dtx>----------------------------------------------------------- +^^Bfi^^Begroup \chardef\noetex 0 \ifx\numexpr\undefined\chardef\noetex 1 \fi \ifnum\noetex=1 \chardef\extractfiles 0 % extract files, then stop @@ -1636,39 +1706,41 @@ dvipdfmx CHANGES.dvi % From this point on, run is necessarily with e-TeX. % Check if \MessageDeFin got defined, if yes put it at end of run. \ifdefined\MessageDeFin\AtEndDocument{\MessageDeFin}\fi -%------------------------------------------------------------------------------- -\documentclass {scrdoc} -\ifdefined\dosourcexint % this toggle is set by a Makefile rule +%----------------------------------------------------------------- +% -*- coding: utf-8; mode: latex -*- +% +\ifdefined\dosourcexint % this toggle is set from make sourcexint.pdf rule \chardef\NoSourceCode 0 \else \chardef\dosourcexint 0 \fi -\ifnum\NoSourceCode=1 \OnlyDescription\fi -% if latex, force output for dvipdfmx -\chardef\Withdvipdfmx 1 +% default is to assume latex + dvipdfmx +\chardef\Withdvipdfmx 1 -\usepackage{ifpdf} -\ifpdf\chardef\Withdvipdfmx 0 \fi +\RequirePackage{ifpdf} +\RequirePackage{ifxetex} -\usepackage{ifxetex} +\ifpdf \chardef\Withdvipdfmx 0 \fi \ifxetex\chardef\Withdvipdfmx 0 \fi -\makeatletter \ifnum\Withdvipdfmx=1 - \@for\@tempa:=hyperref,bookmark,graphicx,xcolor,pict2e\do - {\PassOptionsToPackage{dvipdfmx}\@tempa} - % - \PassOptionsToPackage{dvipdfm}{geometry} - \PassOptionsToPackage{bookmarks=true}{hyperref} - \PassOptionsToPackage{dvipdfmx-outline-open}{hyperref} - \PassOptionsToPackage{dvipdfmx-outline-open}{bookmark} - % - \def\pgfsysdriver{pgfsys-dvipdfm.def} +\def\pgfsysdriver{pgfsys-dvipdfm.def} +\documentclass [dvipdfm, dvipdfmx, dvipdfmx-outline-open]{scrdoc} \else - \PassOptionsToPackage{bookmarks=true}{hyperref} +\documentclass {scrdoc} \fi -\makeatother + + + + + + + +\PassOptionsToPackage{bookmarks=true}{hyperref} + +\ifnum\NoSourceCode=1 \OnlyDescription\fi + \pagestyle{headings} \makeatletter @@ -1683,18 +1755,24 @@ dvipdfmx CHANGES.dvi \makeatother \ifxetex - % à noter cependant qu'il y a des diacritiques dans mes commentaires - % de code, donc xelatex xint.dtx nécessiterait d'abord une conversion - % en utf-8. Mais pour xelatex xint.tex sans le code source, ok. \else \usepackage[T1]{fontenc} - \usepackage[latin1]{inputenc} + \usepackage[utf8]{inputenc} +% 2016-02-28 +% This is for use in pre-CTAN version of the dtx. Not needed for CTAN +% xint.dtx. Again an annoying preamble-only restriction whose rationale +% escape me. (The obelus serves to clean up the private sources from comments +% of the type as this one before uploading to CTAN). +% TS1 declarations loaded by newtxtt. +% \DeclareUnicodeCharacter{00F7}{\textdiv} + \def\PrivateObelus{\textdiv }% + \AtBeginDocument{\DeclareUnicodeCharacter {00F7}{\PrivateObelus}}% + \DeclareUnicodeCharacter {03B4}{\ensuremath{\delta}}% \fi \usepackage{multicol} \usepackage{geometry} -% 11 octobre 2014 \AtBeginDocument {\ttzfamily \newgeometry{textwidth=\dimexpr92\fontcharwd\font`X\relax, vscale=0.75}} @@ -1711,24 +1789,15 @@ dvipdfmx CHANGES.dvi \usepackage{xinttools} -\usepackage{enumitem}% à partir d'octobre 2014 +\usepackage{enumitem} \usepackage{varioref} -%\vrefwarning \usepackage{etoolbox} -% Est-ce que je l'utilise vraiment? oui, \ifnumequal dans un \IsPrime -\usepackage{tocloft}% pour la TOC de la section locale du code pour -% xintexpr, il vaut mieux un look standard, mais je dois customiser la -% "numwidth", trop petite. +\usepackage{tocloft} - -% 16 septembre 2015: j'ai oublié complètement pourquoi le | doit être -% actif ici ... -\catcode`| \active \usepackage{etoc}[2013/10/16] % I need \etocdepthtag.toc -\catcode`| 12 %---- USE OF ETOC FOR THE TABLES OF CONTENTS @@ -1740,13 +1809,9 @@ dvipdfmx CHANGES.dvi \fi \def\sectioncouleur{{cyan}} -\def\MARGEPAGENO {1.5em}% changera pour la partie implémentation +\def\MARGEPAGENO {1.5em}% changera pour la partie implémentation -% 1er avril 2014, je fais un vrai style, un peu grossier cependant, -% alors qu'avant j'utilisais savedsectionline, par paresse. -% 12 octobre 2014, emploi \llap, \leftmargini et aussi de \MARGEPAGENO ici aussi -% \leftmargini \dimexpr4\fontcharwd\font`X\relax \etocsetstyle{section}{} {\normalfont} {\kern\bigskipamount @@ -1760,17 +1825,10 @@ dvipdfmx CHANGES.dvi \strut\etocname \mdseries\nobreak\leaders\etoctoclineleaders\hfill\nobreak\strut \makebox[\MARGEPAGENO][r]{\etocpage}\par -% pour les sous-sections (1 avril 2014) \let\ETOCsectionnumber\etocthenumber }% {}% -% Octobre 2014: emploi de \leftmargini et ajout de \parskip\z@skip. -% \leftmargini \dimexpr4\fontcharwd\font`X\relax -% \leftmarginii\dimexpr3\fontcharwd\font`X\relax -% Samedi 07 novembre 2015 -% suite fusion, j'ai des numéros de sous-sections plus longs. -% j'en profite aussi pour intervenir sur le filet central etc... \newdimen\margegauchetoc \AtBeginDocument{\margegauchetoc \dimexpr 5\fontcharwd\font`X\relax} \makeatletter @@ -1779,20 +1837,16 @@ dvipdfmx CHANGES.dvi \setlength{\premulticols}{0pt}% \setlength{\multicolsep}{0pt}% \setlength{\columnsep}{\leftmarginii}% - \setlength{\columnseprule}{.4pt}% n'influence pas séparation colonnes - % Octobre 2014 mes problèmes d'alors étaient liés à la glue dans \parskip + \setlength{\columnseprule}{.4pt}% n'influence pas séparation colonnes \parskip\z@skip - % j'avais seulement ceci avant, je laisse les deux \raggedcolumns \addvspace{\smallskipamount}% \begin{multicols}{2} \leftskip \margegauchetoc % 12 octobre 2014 -% \rightskip \MARGEPAGENO plus 2em minus 1em % 18 octobre 2013 -% finalement Samedi 07 novembre 2015 \ifindescription \rightskip \MARGEPAGENO \else - \rightskip \MARGEPAGENO plus 2em minus 1em + \rightskip \MARGEPAGENO plus 2em minus 1em \fi \parfillskip -\MARGEPAGENO\relax } @@ -1808,14 +1862,6 @@ dvipdfmx CHANGES.dvi \strut\makebox[\MARGEPAGENO][r]{\small\etocpage}\endgraf } {\end{multicols}\endgroup\addvspace{\smallskipamount}}% -% Septembre 2015, -% je rajoute un style de subsubsection pour la local toc dans sourcexint.pdf -% pour xintcore. -% -% Dans le manuel pas de sous-sous-section dans les TOCs, et dans -% sourcexint.pdf il y avait déjà celle de xintexpr, mais avec le style -% standard customisé par tocloft. -% \etocsetstyle{subsubsection} {\begingroup\normalfont\small \leftskip \dimexpr\leftmargini+1em\relax } @@ -1835,16 +1881,11 @@ dvipdfmx CHANGES.dvi \addtocontents{toc}{\protect\hypersetup{hidelinks}} \usepackage[zerostyle=a,straightquotes,scaled=0.95]{newtxtt} -% j'ai essayé zerostyle=e, finalement je reviens à =a \usepackage{newtxmath} \makeatletter -% I need also the font with a slashed zero, for verbatim code. -% Mardi 18 novembre 2014 à 09:06:44 -% Test de newtxtt 1.05, 'q' pour uprightquotes -% (maintenant: straightquotes) \DeclareFontFamily{T1}{newtxttb}{\hyphenchar\font\m@ne} @@ -1864,30 +1905,83 @@ dvipdfmx CHANGES.dvi <-> ssub * newtxttb/m/sl }{} +% Ajouté le 9 mars 2016 + +\DeclareFontShape{T1}{newtxttb}{m}{sc}{ %cap & small cap + <-> s*[\newtxtt@scale]newtxttscbq +}{} +\DeclareFontShape{T1}{newtxttb}{b}{sc}{ %bold cap & small cap + <-> s*[\newtxtt@scale]newtxbttscbq +}{} +\DeclareFontShape{T1}{newtxttb}{b}{sl}{ %bold slanted + <-> s*[\newtxtt@scale]newtxbttslbq +}{} +\DeclareFontShape{T1}{newtxttb}{b}{it}{ %bold italic + <-> ssub * newtxttb/b/sl% +}{} +\DeclareFontShape{T1}{newtxttb}{bx}{sc}{ %bold extended cap & small cap + <-> ssub * newtxttb/b/sc% +}{} +\DeclareFontShape{T1}{newtxttb}{bx}{sl}{ %bold extended slanted + <-> ssub * newtxttb/b/sl% +}{} +\DeclareFontShape{T1}{newtxttb}{bx}{it}{ %bold extended italic + <-> ssub * newtxttb/b/sl% +}{} + +% Ajouté le 9 mars 2016 +\DeclareEncodingSubset{TS1}{newtxttb}{0} +\DeclareFontFamily{TS1}{newtxttb}{\hyphenchar\font\m@ne} + +\DeclareFontShape{TS1}{newtxttb}{m}{n}{ %medium + <-> s*[\newtxtt@scale]tcxtt% +}{} +\DeclareFontShape{TS1}{newtxttb}{m}{sc}{ %cap & small cap + <->ssub * newtxttb/m/n% +}{} +\DeclareFontShape{TS1}{newtxttb}{m}{sl}{ %slanted + <-> s*[\newtxtt@scale]tcxttsl% +}{} +\DeclareFontShape{TS1}{newtxttb}{m}{it}{ %italic + <->ssub * newtxttb/m/sl% +}{} +\DeclareFontShape{TS1}{newtxttb}{b}{n}{ %bold + <-> s*[\newtxtt@scale]tcxbtt% +}{} +\DeclareFontShape{TS1}{newtxttb}{b}{sc}{ %bold cap & small cap + <->ssub * newtxttb/b/n% +}{} +\DeclareFontShape{TS1}{newtxttb}{b}{sl}{ %bold slanted + <-> s*[\newtxtt@scale]tcxbttsl% +}{} +\DeclareFontShape{TS1}{newtxttb}{b}{it}{ %bold italic + <->ssub * newtxttb/b/sl% +}{} +\DeclareFontShape{TS1}{newtxttb}{bx}{n}{ %bold extended + <->ssub * newtxttb/b/n% +}{} +\DeclareFontShape{TS1}{newtxttb}{bx}{sc}{ %bold extended cap & small cap + <->ssub * newtxttb/b/sc% +}{} +\DeclareFontShape{TS1}{newtxttb}{bx}{sl}{ %bold extended slanted + <->ssub * newtxttb/b/sl% +}{} +\DeclareFontShape{TS1}{newtxttb}{bx}{it}{ %bold extended italic + <->ssub * newtxttb/b/it% +}{} + + \makeatother -% this is with a slashed 0 like the original txtt. \newcommand\ttbfamily {\fontfamily{newtxttb}\selectfont } -% I will leave this old markup here for the time being, in case there -% is later some use to it. -% 11 octobre, j'essaie couleur, YellowOrange, CadetBlue -% \def\digitstt {\bgroup \color[named]{OrangeRed}\let\next=} - -% Mardi 18 novembre 2014 à 09:07:30 -% test des old style figures par \textsc -% ATTENTION à cause emploi d'argument pouvant contenir des tokens comme \if -% (cf lignes environ 5319) -% Finalement pour release doc du 7 mars 2015, je n'utilise pas old style -%\def\digitstt #1{\begingroup\color[named]{OrangeRed}% -% \unless\ifmmode\scshape\fi #1\endgroup} + \def\digitstt #1{\begingroup\color[named]{OrangeRed}#1\endgroup} \let\dtt\digitstt \ifnum\dosourcexint=1 \else -% Septembre 2014 emploi de mathastext \renewcommand\familydefault\ttdefault \usepackage[noendash]{mathastext}% pas de endahs dans newtxtt \fi @@ -1898,11 +1992,8 @@ dvipdfmx CHANGES.dvi \usepackage[dvipsnames]{xcolor} \usepackage{framed} -% 14 octobre 2014 -% copié de snugshade de framed.sty \makeatletter \newenvironment{snugframed}{% -% transféré ici 17 octobre \fboxsep \dimexpr2\fontcharwd\font`X\relax \advance\linewidth-2\fboxsep \advance\csname @totalleftmargin\endcsname \fboxsep @@ -1942,54 +2033,51 @@ pdfkeywords={Expansion, arithmetic, TeX},% pdfstartview=FitH,% pdfpagemode=UseOutlines} -\ifnum\dosourcexint=1 +\ifnum\dosourcexint=1 \hypersetup{pdftitle={The xint bundle source code}} \fi \usepackage{bookmark} -\usepackage{picture} % permet d'utiliser des unités dans les dimensions de la +\usepackage{picture} % permet d'utiliser des unités dans les dimensions de la % picture et dans \put \usepackage{graphicx} \usepackage{eso-pic} %---- \MyMarginNote: a simple macro for some margin notes with no fuss -% je m'aperçois que je peux l'utiliser dans les footnotes... \makeatletter \def\MyMarginNote {\@ifnextchar[\@MyMarginNote{\@MyMarginNote[]}}% -% 18 janvier 2014, j'ai besoin d'un raccourci. \let\inmarg\MyMarginNote -\def\@MyMarginNote [#1]#2{% +\def\@MyMarginNote [#1]#2{\@bsphack \vadjust{\vskip-\dp\strutbox \smash{\hbox to 0pt {\color[named]{PineGreen}\normalfont\small \hsize 1.6cm\rightskip.5cm minus.5cm - \hss\vtop{\offinterlineskip #2}\ $\to$#1\ }}% - \vskip\dp\strutbox }\strut{}} -\def\MyMarginNoteWithBrace #1{% + \hss\vtop{#2}\ $\to$#1\ }}% + \vskip\dp\strutbox }\strut\@esphack} +\def\MyMarginNoteWithBrace #1{\@bsphack \vadjust{\vskip-\dp\strutbox \smash{\hbox to 0pt {\color[named]{PineGreen}%\normalfont\small \hss #1\ $\bigg\{$\ }}% - \vskip\dp\strutbox }\strut{}} -\def\IMPORTANT {\MyMarginNoteWithBrace + \vskip\dp\strutbox }\strut\@esphack} +\def\IMPORTANT {\MyMarginNoteWithBrace {\raisebox{-.5\height}{\resizebox{2\width}{!}{\ding{43}}}}} -% 26 novembre 2013: -\def\etype #1{% +\def\etype #1{\@bsphack \vadjust{\vskip-\dp\strutbox \smash{\hbox to 0pt {\hss\color[named]{PineGreen}% \itshape \xintListWithSep{\,}{#1}\ $\star$\quad }}% - \vskip\dp\strutbox }\strut{}} -\def\retype #1{% + \vskip\dp\strutbox }\strut\@esphack} +\def\retype #1{\@bsphack \vadjust{\vskip-\dp\strutbox \smash{\hbox to 0pt {\hss\color[named]{PineGreen}% \itshape \xintListWithSep{\,}{#1}\ \ding{73}\quad }}% - \vskip\dp\strutbox }\strut{}} -\def\ntype #1{% + \vskip\dp\strutbox }\strut\@esphack} +\def\ntype #1{\@bsphack \vadjust{\vskip-\dp\strutbox \smash{\hbox to 0pt {\hss\color[named]{PineGreen}% \itshape \xintListWithSep{\,}{#1}\quad }}% - \vskip\dp\strutbox }\strut{}} + \vskip\dp\strutbox }\strut\@esphack} %------------------------------------------------------------------------------- \def\Numf {{\vbox{\halign{\hfil##\hfil\cr \footnotesize \upshape Num\cr @@ -2004,14 +2092,21 @@ pdfpagemode=UseOutlines} \noalign{\hrule height 0pt \vskip1pt\relax} \itshape x\cr}}}} %------------------------------------------------------------------------------- -% 24 février 2014. J'ai besoin de me débarasser du \to -\def\NewWith #1{% +\def\NewWith #1{\@bsphack \vadjust{\vskip-\dp\strutbox \smash{\hbox to 0pt {\hss\color[named]{PineGreen}% \normalfont\small \hsize 1.5cm\rightskip.5cm minus.5cm \vtop{\noindent New with #1}\ }}% - \vskip\dp\strutbox }\strut{}} + \vskip\dp\strutbox }\strut\@esphack} + +\def\CHANGED #1{\@bsphack + \vadjust{\vskip-\dp\strutbox + \smash{\hbox to 0pt {\hss\color[named]{PineGreen}% + \normalfont\small + \hsize 1.5cm\rightskip.5cm minus.5cm + \vtop{\noindent Changed (#1)}\ }}% + \vskip\dp\strutbox }\strut\@esphack} \makeatother @@ -2028,7 +2123,7 @@ pdfpagemode=UseOutlines} % Actually my \centeredline works nicely in list environments. -% \ignorespaces ajouté le 9 juin 2013. +% \ignorespaces ajouté le 9 juin 2013. % Note: \centeredline creates a group @@ -2044,14 +2139,6 @@ pdfpagemode=UseOutlines} \def\@centeredline {\hbox to \linewidth \bgroup \hss \bgroup \aftergroup\centeredline@ } -% 12 octobre 2014 -% --------------- -% -% \centeredline-->\leftedline. -% And I add colored background. I have more sophisticated approaches, but the -% mark-up was essentially already there, thus I just wanted to exploit the -% manual from 1.09n for the transition to 1.1. -% \newif\ifinlefted @@ -2066,14 +2153,14 @@ pdfpagemode=UseOutlines} \def\@leftedline {\hbox to \linewidth \bgroup \inleftedtrue \everbatimeverypar - \bgroup + \bgroup \aftergroup\leftedline@ } \makeatother % verbatim environments % ===================== -% +% % June 2013, then October 2014. % ----------------------------- % @@ -2097,20 +2184,8 @@ pdfpagemode=UseOutlines} \def\makestarlowast {\let*\lowast\catcode`\*\active}% \catcode`* 12 -%--- straight quotes, added (finally...) Nov 2, 2014 -%--- obsolete with use of newtxtt 1.05, late 2014 - -% \begingroup\makeatletter -% \catcode`\'\active -% \catcode`\`\active -% \@firstofone {\endgroup -% \def\makequotesstraight{% assumes textcomp package -% \let`\textasciigrave -% \let'\textquotesingle -% \catcode39\active -% \catcode96\active }% -% } - + + %--- for soft-wrapping. I will use discretionaries. \DeclareFontFamily{U}{MdSymbolC}{} @@ -2120,19 +2195,18 @@ pdfpagemode=UseOutlines} \colorlet {softwrapicon}{blue} \def\SetSoftWrapIcon{% - \setbox\SoftWrapIcon\hb@xt@\z@ + \setbox\SoftWrapIcon\hb@xt@\z@ {\hb@xt@\fontdimen2\font {\hss{\color{softwrapicon}\usefont{U}{MdSymbolC}{m}{n}\char"97}\hss}% \hss}% } -\AtBeginDocument {\SetSoftWrapIcon }% ttzfamily déjà fait +\AtBeginDocument {\SetSoftWrapIcon }% ttzfamily déjà fait %--- \MacroFont, and a \MicroFont -% +% % Ne PAS mettre de changement de taille de police dans \MacroFont. -% 17/10/2014, essai avec CadetBlue après Purple. Puis Blue \def\restoreMicroFont {\def\MicroFont {\ttbfamily\makestarlowast \ifinlefted\else\ifineverb\else\color[named]{Blue}\fi\fi}} @@ -2203,12 +2277,11 @@ pdfpagemode=UseOutlines} \relax \ifmmode\else\leavevmode\null\fi \bgroup \let\do\@makeother \dospecials - %\makequotesstraight % belatedly added for 1.1a release \MicroFont % change font, color, catcode hooks, ... \catcode 32 10 \endlinechar 32 - \@@jfverb -}% + \@@jfverb +}% % Note (Oct 12, 2014): in the improbable situation a newlinechar is % found in the ##1, \scantokens will convert this to an end of line in % its "write" phase, which will be then ignored in its "read" phase due @@ -2233,16 +2306,16 @@ pdfpagemode=UseOutlines} \egroup \else % \penalty\z@, or rather (Oct 11, 2014) but I then adjust the textwidth -% precisely: +% precisely: \discretionary{\copy\SoftWrapIcon}{}{}% - #1\expandafter\@@jfverb_b\fi + #1\expandafter\@@jfverb_b\fi } \catcode`_ 8 \makeatother % --- \lverb -% Définition de \lverb +% Définition de \lverb \makeatletter \long\def\lverb {% \relax\par\smallskip\noindent\null @@ -2251,7 +2324,7 @@ pdfpagemode=UseOutlines} \aftergroup\@@par \aftergroup\endgroup \aftergroup\medskip \let\do\do@noligs \verbatim@nolig@list \let\do\@makeother \dospecials - %\makequotesstraight % belatedly added for 1.1a release + \def\PrivateObelus{\par\noindent\textdiv}% \catcode32 10 \catcode`\% 9 \catcode`\& 14 \catcode`\$ 0 \MicroFont % sera donc en couleur. \@lverb @@ -2263,7 +2336,7 @@ pdfpagemode=UseOutlines} %--- everbatim environment % October 13-14, 2014 % Verbatim with an \everypar hook, mainly to have background color, followed by -% execution of the code +% execution of the code \makeatletter \catcode`_ 11 @@ -2298,7 +2371,7 @@ pdfpagemode=UseOutlines} \parskip \z@skip \lineskip \z@skip \let\do\@makeother \dospecials - \let\do\do@noligs \verbatim@nolig@list + \let\do\do@noligs \verbatim@nolig@list \makestarlowast \everbatimhook \trivlist\item\relax @@ -2308,12 +2381,12 @@ pdfpagemode=UseOutlines} \parfillskip\@flushglue \parskip \z@skip \@@par - \def\par{\leavevmode\null\@@par\pagebreak[1]}% + \def\par{\leavevmode\null\@@par\pagebreak[1]}% \everypar\expandafter{\the\everypar \unpenalty - \everbatimeverypar + \everbatimeverypar \everypar \expandafter{\the\everypar\everbatimeverypar}% }% - \obeylines \@vobeyspaces + \obeylines \@vobeyspaces } \begingroup @@ -2331,38 +2404,20 @@ pdfpagemode=UseOutlines} |def|@everbatimx #1#2X#3\end{everbatimY}]% {#3\end{everbatim*}% \everbatimbottom - % No group here: this allows executed code to make macro - % definitions which may reused in later uses of everbatim. - % But the problem is with colors... j'ai visiblement un problème - % avec le color stack pour dvipdfmx avec les \colorlet/\color \newlinechar 13 - % Indentation of next paragraph produced from execution of #3 is - % suppressed, if #3 by itself or \everbatimbottom does no \par, - % from \@endparenv done by \endtrivlist \everbatimxprehook - \scantokens {#3}% there will typically be an EOL space after this if one - % continues after \end{everbatim} on same line, which - % is allowed. - \newlinechar #1\relax % restores \newlinechar to previous value. + \scantokens {#3}% + \newlinechar #1\relax \everbatimxposthook }% -% L'espace venant du endofline final mis par \scantokens sera inhibé si #3 se -% termine par un % ou un \x, etc... +% L'espace venant du endofline final mis par \scantokens sera inhibé si #3 se +% termine par un % ou un \x, etc... -% Mercredi 16 septembre 2015 à 19:40:28 -% ENFIN! compris et résolu mes problèmes de color stack overflow !!! -% Je ne pouvais pas créer de groupes car je fais des définitions dans les -% everbatim*. Et je n'allais pas re-parcourir le source pour identifier -% tous les everbatim* faisant des définitions ... \def\everbatimxprehook {\colorlet{everbsavedcolor}{.}\color[named]{OrangeRed}} \def\everbatimxposthook {\color{everbsavedcolor}} \ifpdf -% 17 septembre, je fais un essai, pour voir, cf pdftex.def/color.sty -% Pour déterminer la spécification, j'ai fait un -% \typeout{\meaning\current@color} dans un run de test -% ça marche - \def\everbatimxprehook + \def\everbatimxprehook {\pdfcolorstack\@pdfcolorstack push{0 1 0.5 0 k 0 1 0.5 0 K}\relax} \def\everbatimxposthook {\pdfcolorstack\@pdfcolorstack pop\relax} @@ -2371,29 +2426,19 @@ pdfpagemode=UseOutlines} \def\everbatimxprehook {\special{color push cmyk 0 1 0.5 0}} \def\everbatimxposthook {\special{color pop}} \else -\ifnum\Withdvipdfmx=1 % enfin problème résolu pour dvipdfmx !!! - % et donc après idem pour xelatex (et même pdf) +\ifnum\Withdvipdfmx=1 \def\everbatimxprehook {\special{pdf:bcolor OrangeRed}} \def\everbatimxposthook {\special{pdf:ecolor}} \fi\fi\fi -% MAIS ATTENTION: \normalcolor dans les everbatim du Quick Sort provoquait -% un terrible color leak pour dvipdfmx et AUSSI pour xelatex; pour ce dernier -% le color leak avec les \special plus haut était terriblissime... -% >>> Mercredi 16 septembre 2015 à 20:51:49 <<< -% >>> MAIS MAINTENANT J'AI DONC LA SOLUTION COMPLÈTE <<< -% J'ai aussi vérifié que supprimer les deux \normalcolor ne résolvait pas en -% soi le problème, il faut aussi les \special ci-dessus, sinon le color leak -% apparaissait certes plus loin mais il était là. Il y a quelques autres -% \normalcolor dans les everbatim* j'ai pas essayé en les supprimant tous. % --- \everb % Original was called \dverb and I did it in June 2013. % Then after doing everbatim, I transformed \dverb, now called \everb % for itself being as compatible as standard verbatim with list making % surrounding environments. -% Supposed to be used as +% Supposed to be used as % \everb|@ this will be ignored % stuff % escape character: " @@ -2401,7 +2446,7 @@ pdfpagemode=UseOutlines} % I chose @ as comment character, mainly for pretty-formatting of the % source, this can be changed by \everbhook. -% " comme caractère d'échappement. Par exemple pour colorier des parties. +% " comme caractère d'échappement. Par exemple pour colorier des parties. \def\restoreeverbhook{\def\everbhook{% \def\"{\begingroup\catcode123 1 \catcode 125 2 \everbescape }% \catcode`\" 0 \catcode`\@ 14 @@ -2419,7 +2464,7 @@ pdfpagemode=UseOutlines} \def\@everb #1{\catcode`#1\active \lccode`\~`#1% \lowercase{\def~{\if@newlist \leavevmode\fi - \endtrivlist + \endtrivlist \egroup \@doendpe \everbatimbottom }}% @@ -2434,10 +2479,6 @@ pdfpagemode=UseOutlines} % The mark-up being in place, I only have to use it here. \DeclareRobustCommand\csa [1] -% attention que le \expandafter est nécessaire ici, sinon \scantokens n'agit -% pas sur ce que produit \detokenize. Par ailleurs \MicroFont fait -% \makestarlowast (et c'est seulement à cause de * que je fais \scantokens) -% Attention cependant aux _ maintenant dans les noms de macros {{\MicroFont\char92\endlinechar-1 \catcode`_ 11 \scantokens\expandafter{\detokenize{#1}}}} @@ -2454,21 +2495,10 @@ pdfpagemode=UseOutlines} \newcommand\csbh[1] {\texorpdfstring{\csbnolk{#1}}{\textbackslash\detokenize{#1}}} -% --- \xintname, \xintnameimp etc... +% --- \xintname, \xintnameimp etc... -% 7 mars 2015, je résous (non!) un problème de color stack overflow avec -% dvipdfmx qui venait au final des page headers, et à cause d'un brace -% stripping qui enlevait la protection de mes \color ci-dessous. Il a suffi de -% rajouter un \empty pour me débarrasser finalement du problème. -% -% Bon c'est bizarre, en fait le problème n'est pas résolu. Après avoir -% supprimé fichiers auxiliaires et recompilé, il revient. -% Problème finalement résolu le 16 septembre 2015 -% cf \everbatimxprehook -% à noter que \hyperref fait un color, donc le color{joli} en fait un -% supplémentaire, difficile d'éviter. Alourdit le dvi, mais bref. \xintForpair #1#2 in {(xintkernel,kernel), @@ -2492,25 +2522,18 @@ pdfpagemode=UseOutlines} }% %--- \printnumber -% Nouvelle version 11 octobre 2014. -% Nouvelle version 21 novembre 2015. -% je le modifie pour qu'il respecte des (unique) space tokens. -% De plus je n'utilise plus \relax comme terminateur (même si \printnumber -% n'est utilisé dans xint.dtx qu'avec des \meaning ou des nombres). \catcode`_ 11 \makeatletter \catcode`& 3 \def\allowsplits_a {\futurelet\printnumber_token\allowsplits_b }% \def\allowsplits_b{\ifx\printnumber_token\@sptoken\space\fi\allowsplits_c } \def\allowsplits_c #1{\ifx \xint_dothis\xint_gobble_i\fi -% je retire l'espace dans cette branche car géré par allowsplits_a maintenant \if ,#1\xint_dothis {\discretionary{\rlap,}{}{,}}\fi \xint_orthat{\discretionary {\copy\SoftWrapIcon}% {}% {}#1}\allowsplits_a }% -% avant je prenais le premier token pour éviter un discretionary en premier \def\printnumber #1{\expandafter\allowsplits_a \romannumeral-`0#1&}% \hyphenpenalty \z@ @@ -2538,7 +2561,6 @@ pdfpagemode=UseOutlines} \colorlet {codeboxframe}{black!30} \colorlet {execboxfringe}{black!10} -% 12 octobre 2014 \AtBeginDocument{% \leftmargini \dimexpr4\fontcharwd\font`X\relax \leftmarginii\dimexpr3\fontcharwd\font`X\relax @@ -2546,9 +2568,6 @@ pdfpagemode=UseOutlines} \leftmarginiv \leftmarginii \parindent\dimexpr2\fontcharwd\font`X\relax \leftmargin\leftmargini % pourquoi pas 0? -% attention à un deuxième relax! -%\advance\linewidth\dimexpr-\everbatimindent-\everbatimindent\relax -% était alors bogué! \edef\everbatimindent{\the\dimexpr\leftmargini\relax\space }% \cftsubsecnumwidth 2\leftmarginii \cftsubsubsecnumwidth 2\leftmargini @@ -2561,14 +2580,8 @@ pdfpagemode=UseOutlines} % Septembre 2015 \def\liiibigint{\href{http://latex-project.org/svnroot/experimental/trunk/l3trial/l3bigint}{l3bigint}} -% % pour accéder à l'historique des commits: -% % https://github.com/latex3/latex3/tree/master/l3trial/l3bigint -% 20 octobre 2015 hier j'ai un peu rapidement remplacé les \romannumeral-`0 -% dans le code par de mystérieux \romannumeral`<character0catcode12>, en T1, -% newtxtt donne un ` pour le slot 0, les quelques occurrences de \meaning -% après \xintNewExpr dans la doc donne donc un bien mystérieux `` en output. \makeatletter \def\fixmeaning {\expandafter\fix@meaning\meaning} @@ -2577,9 +2590,9 @@ pdfpagemode=UseOutlines} {#1\string\romannumeral`\string^\string^@} \makeatother -% 2015/11/18: \xintverbosetrue + \begin{document}\thispagestyle{empty}% \ttzfamily already done \pdfbookmark[1]{Title page}{TOP} % \makeatletter % @ n'est plus actif dans dtx 1.1, ouf! @@ -2605,7 +2618,7 @@ pdfpagemode=UseOutlines} \bigskip -% Mercredi 08 octobre 2014 à 22:03:19 +% Mercredi 08 octobre 2014 à 22:03:19 % Skips safely. \ifnum\dosourcexint=1 \catcode`+ 0 \catcode0 9 % n'importe quoi sauf 15 (car ^^@) @@ -2613,20 +2626,62 @@ pdfpagemode=UseOutlines} +expandafter+iffalse+fi \fi -% ---- +\etocsetlevel{toctobookmark}{6} % 9 octobre 2013, je fais des petits tricks. + + +\etocsettocdepth {subsection} + +\renewcommand*{\etocbelowtocskip}{0pt} +\renewcommand*{\etocinnertopsep}{0pt} +\renewcommand*{\etoctoclineleaders} + {\hbox{\normalfont\normalsize\hbox to 1ex {\hss.\hss}}} +\etocmulticolstyle [1]{% + \phantomsection\section* {Contents} + \etoctoccontentsline*{toctobookmark}{Contents}{1}% +} + \etocsettagdepth {description}{subsection} + \etocsettagdepth {commands} {none} + \etocsettagdepth {implementation}{none} +\tableofcontents +\renewcommand*\etocabovetocskip{\bigskipamount} +\makeatletter +\etocmulticolstyle [2]{\parskip\z@skip\raggedcolumns + \setlength{\columnsep}{\leftmarginii}% + \setlength{\columnseprule}{0pt}% +}% +\makeatother + \etocsettagdepth {description}{none} + \etocsettagdepth {commands} {section} +\ifnum\NoSourceCode=1 + \etocsettagdepth {implementation}{none} +\else + \etocsettagdepth {implementation}{section} +\fi +\tableofcontents + +\etocignoredepthtags +\etocmulticolstyle [1]{% + \phantomsection% \section* {Contents} + \etoctoccontentsline*{toctobookmark}{Contents}{2}% +} + + +\clearpage + +% ---- % Fibonacci code % December 7, 2013. Expandably computing a big Fibonacci number -% with the help of TeX+\numexpr+\xintexpr, (c) Jean-François Burnol +% with the help of TeX+\numexpr+\xintexpr, (c) Jean-François Burnol \catcode`_ 11 % -% ajouté 7 janvier 2014 au xint.dtx pour 1.07j. +% ajouté 7 janvier 2014 au xint.dtx pour 1.07j. % -% Le 17 janvier je me décide de simplifier l'algorithme car l'original ne tenait -% pas compte de la relation toujours vraie A=B+C dans les matrices symétriques -% utilisées en sous-main [[A,B],[B,C]]. +% Le 17 janvier je me décide de simplifier l'algorithme car l'original ne tenait +% pas compte de la relation toujours vraie A=B+C dans les matrices symétriques +% utilisées en sous-main [[A,B],[B,C]]. % % la version ici est celle avec les * omis: car multiplication tacite devant les -% sous-expressions depuis 1.09j, et aussi devant les parenthèses depuis 1.09k. +% sous-expressions depuis 1.09j, et aussi devant les parenthèses depuis 1.09k. % (pour tester) \def\Fibonacci #1{% \expandafter\Fibonacci_a\expandafter @@ -2668,13 +2723,7 @@ pdfpagemode=UseOutlines} \def\Fibo #1.{\Fibonacci {#1}} % nice background added for 1.09j release, January 7, 2014. -% superbe, non? moi très content! -% bon je peaufine ce background le 17 janvier, c'est hard-coded mais je ne veux -% pas y passer plus de temps (ce qui est amusant c'est que j'ai constaté a -% posteriori qu'il y a 17 chiffres par lignes donc 1 chiffre avec son padding = -% 1cm... -% *\message{\xinttheexpr round(\dimexpr 8cm\relax/17,3)\relax} -% 877496.353 +% superbe, non? moi très content! \def\specialprintone #1% {% \ifx #1\relax \else \makebox[877496sp]{#1}\hskip 0pt plus 2sp\relax @@ -2694,12 +2743,10 @@ pdfpagemode=UseOutlines} }% } -% Samedi 27 septembre 2014 à 16:04:52 + +% Samedi 27 septembre 2014 à 16:04:52 \pdfbookmark[1]{Dependency graph}{DependencyGraph} -% modifié le Mercredi 16 septembre 2015 à 10:24:57 -% car j'avais oublié la dépendance partielle de xintfrac sur xinttools, -% pour \xintXTrunc. \tikzstyle{block} = [rectangle, draw, fill=codeboxbg, @@ -2709,7 +2756,7 @@ pdfpagemode=UseOutlines} text width=6em, text centered, rounded corners, minimum height=4em] \tikzstyle{line} = [draw, line width=1pt, color=codeboxframe] -\vspace{2\baselineskip} +\vspace*{\stretch{0.3333}} \begin{figure}[ht!] \phantomsection\label{dependencygraph} @@ -2767,151 +2814,27 @@ pdfpagemode=UseOutlines} \clearpage -\etocsetlevel{toctobookmark}{6} % 9 octobre 2013, je fais des petits tricks. - -% 18 novembre 2013, je n'inclus plus la TOC détaillée de xintexpr. Je -% reconfigure la TOC. - -\etocsettocdepth {subsection} - -\renewcommand*{\etocbelowtocskip}{0pt} -\renewcommand*{\etocinnertopsep}{0pt} -\renewcommand*{\etoctoclineleaders} - {\hbox{\normalfont\normalsize\hbox to 1ex {\hss.\hss}}} -\etocmulticolstyle [1]{% - \phantomsection\section* {Contents} - \etoctoccontentsline*{toctobookmark}{Contents}{1}% -} - \etocsettagdepth {description}{subsection} - \etocsettagdepth {commands} {none} - \etocsettagdepth {implementation}{none} -\tableofcontents -\renewcommand*\etocabovetocskip{\bigskipamount} -\makeatletter -% modifié Samedi 07 novembre 2015 -% y'en a un peu marre du style olé olé de la doc de multicols -% bon bref \columnsep donne la séparation indépendamment du filet vertical -% (logique, j'admets) -\etocmulticolstyle [2]{\parskip\z@skip\raggedcolumns - \setlength{\columnsep}{\leftmarginii}% - \setlength{\columnseprule}{0pt}% -}% -\makeatother - \etocsettagdepth {description}{none} - \etocsettagdepth {commands} {section} -\ifnum\NoSourceCode=1 - \etocsettagdepth {implementation}{none} -\else - \etocsettagdepth {implementation}{section} -\fi -\tableofcontents - -% pour la suite: [voir aussi juste avant la section Commandes de xint] -% 12 octobre 2014, je supprime tous les "Contents", maintenant que les -% TOC sont déplacées vers immédiatement après le titre de la section. -\etocignoredepthtags -\etocmulticolstyle [1]{% - \phantomsection% \section* {Contents} - \etoctoccontentsline*{toctobookmark}{Contents}{2}% -} - \etocdepthtag.toc {description} \section{Read this first}\label{sec:quickintro} This section provides recommended reading on first discovering the package. -% local TOC supprimée 12 octobre 2014 -% finalement non, car LaTeX laisse un énorme vide au bas de la page à la -% place!!! Bon, je ne le mets que s'il y a la place. - -\ifnum\NoSourceCode=1 -{\etocdefaultlines\etocsettocstyle{}{}\localtableofcontents} -\fi - -\subsection{The packages of the \xintname bundle} - -\begin{framed} - The \xintcorename and \xintname packages provide macros dedicated to - \emph{expandable} computations on numbers exceeding the \TeX{} (and \eTeX{}) - limit of \dtt{\number"7FFFFFFF} (\emph{i.e.} on numbers of $10$ digits or - more.) - -\medskip - - With package \xintfracname also decimal numbers (with a dot \dtt{.} as - decimal mark), numbers in scientific notation (with a lowercase \dtt{e}), - and even fractions (with a forward slash \dtt{/}) are acceptable inputs. -\medskip - - Package \xintexprname handles expressions - written with the standard infix notations, thus providing a more convenient - interface. -\begin{everbatim*} -\xinttheexpr (2981.279/.2662176e2-3.17127e2/3.129791)^3\relax -\end{everbatim*}\newline -(the |A/B[n]| notation on output means $(A/B)\times 10^n$), or also: -\begin{everbatim*} -\xintthefloatexpr 1.23456789123456789^123456789\relax -\end{everbatim*} (<- notice the size of this exponent). - -\smallskip - - Furthermore \xintexprname is also able since release |1.1| of |2014/10/28| to - do computations with dummy variables, as in this example: -\begin{everbatim*} -\xinttheexpr seq(1+reduce(add(mul((x-i+1)/i,i=1..j),j=1..floor(x/2))), - x=10..20, 31, 51)\relax -\end{everbatim*} -\smallskip - - The reasonable range of use of the package arithmetics is with numbers of - less than \emph{one hundred or perhaps two hundred digits.} Release |1.2| - has significantly improved the speed of the basic operations for numbers - with more than $50$ digits, the speed gains getting better for bigger - numbers. Although numbers up to about \dtt{19950} digits are acceptable - inputs, the package is not at his peak efficiency when confronted with such - really big numbers having thousands of digits.\footnotemark -\end{framed} - -\footnotetext{The maximal handled size for inputs to multiplication is - \dtt{19959} digits. This limit is observed with the current default values - of some parameters of the tex executable (input save stack size at 5000, - maximal expansion depth at 10000). Nesting of macros will reduce it and it - is best to restrain numbers to at most \dtt{19900} digits. The output, as - naturally is the case with multiplication, may exceed the bound.} - -The \eTeX{} extensions (dating back to 1999) must be enabled; this is the case -by default in modern distributions, except for the |tex| executable itself -which has to be the pure \textsc{D.~Knuth} software with no additions. The -name for the extended binary is |etex|. In |TL2014| for example |etex| is a -symbolic link to the |pdftex| executable which will then run in |DVI| output -mode, the \eTeX{} extensions being automatically active. - -All components may be loaded with \LaTeX{} |\usepackage| or -|\RequirePackage| or, for any other format based on \TeX{}, directly via -\string\input{}, e.g. |\input xint.sty\relax|. There are no package -options. -Each package automatically loads those not already loaded it depends on (but -in a few rare cases there are some extra dependencies, for example the |gcd| -function in \xintexprname expressions requires explicit loading of package -\xintgcdname for its activation).\smallskip - -%% \pdfbookmark[1]{Abstract}{ABSTRACT} - -\begin{addmargin}{1cm}\small - % \begin{center} \bfseries\large Description of the packages\par\smallskip - % \end{center}\medskip +\begin{addmargin}{1cm} \makeatletter \renewenvironment{description} - {\list{}{\topsep\z@\partopsep\z@ + {\list{}{\topsep\baselineskip\partopsep\z@skip \parsep\z@ \labelwidth\z@ \itemindent-\leftmargin \let\makelabel\descriptionlabel}} {\endlist} \makeatother + +%\noindent\null\par\kern-\baselineskip +\leavevmode + \begin{description} \item[\xinttoolsname] provides utilities of independent interest such as expandable and non-expandable loops. It is \fbox{not} @@ -2925,11 +2848,12 @@ function in \xintexprname expressions requires explicit loading of package in its default configuration). \item[\xintname] extends \xintcorename with additional operations on big - integers. + integers. Loads automatically \xintcorename. \item[\xintfracname] extends the scope of \xintname to decimal numbers, to numbers in scientific notation and also to fractions with arbitrarily - long such numerators and denominators separated by a forward slash. + long such numerators and denominators separated by a forward slash. Loads + automatically \xintname. \item[\xintexprname] extends \xintfracname with expandable parsers doing algebra (exact, float, or limited to integers) on comma separated @@ -2939,8 +2863,11 @@ function in \xintexprname expressions requires explicit loading of package one or many arguments, user-definable variables, user-definable functions, nestable use of dummy variables for evaluation of sub-expressions, with iterations admitting omit, abort, and break instructions. + Automatically loads \xinttoolsname and \xintfracname (hence \xintname and + \xintcorename too). \end{description} + Further modules: \begin{description} @@ -2957,7 +2884,110 @@ Further modules: \end{description} \end{addmargin} -\subsection{Quick first overview (expressions with \xintexprname)} +\begin{framed} +All macros from the \xintname packages doing computations are +\emph{expandable}, and naturally also the parsers provided by \xintexprname. + + The reasonable range of use of the package arithmetics is with numbers of + \emph{up to a few hundred digits.} +% Release |1.2| +% has significantly improved the speed of the basic operations for numbers +% with more than $50$ digits, the speed gains getting better for bigger +% numbers. + Although numbers up to about \dtt{19950} digits are acceptable + inputs, the package is not at his peak efficiency when confronted with such + really big numbers having thousands of digits.\footnotemark +\end{framed} + +\footnotetext{The maximal handled size for inputs to multiplication is + \dtt{19959} digits. This limit is observed with the current default values + of some parameters of the tex executable (input save stack size at 5000, + maximal expansion depth at 10000). Nesting of macros will reduce it and it + is best to restrain numbers to at most \dtt{19900} digits. The output, as + naturally is the case with multiplication, may exceed the bound.} + + + +\subsection{First examples} + +With |\usepackage{xintexpr}| if using \LaTeX, or |\input xintexpr.sty\relax| +for other formats, you can do computations such as the following. +\begin{description} +\item[with floats:]\leavevmode\par +\begin{everbatim*} +\xintthefloatexpr 3.25^100/3.2^100, 2^1000000, sqrt(1000!), 10^-3.5\relax +\end{everbatim*} +\item[with fractions:]\leavevmode\par +\begin{everbatim*} +\xinttheexpr reduce(add((-1)^(i-1)/i**2, i=1..25))\relax +\end{everbatim*} +\item[with integers:]\leavevmode\par +\begin{everbatim*} +\xinttheiiexpr 3^159+2^234\relax +\end{everbatim*} +\end{description} + +Float computations are done by default with \dtt{16} digits of precision. +This can be changed by a prior assignment to |\xintDigits|: +\begin{everbatim*} +% use braces (or a LaTeX environment) to limit the scope of the \xintDigits assignment +{\xintDigits := 88;\xintthefloatexpr 3.25^100-3.2^100\relax}\par +\end{everbatim*} + +We can even try daring things:\footnote{The \cs{printnumber} is not part of + the package, see \autoref{ssec:printnumber}.} +\begin{everbatim*} +{\xintDigits:=500;\printnumber{\xintthefloatexpr sqrt(2)\relax}} +\end{everbatim*} + +\medskip + +This is release |1.2f|. +\begin{enumerate} +\item |exp|, |cos|, |sin|, etc... are \emph{yet to be implemented}, +\item |NaN|, |+Infty|, |-Infty|, etc... are \emph{yet to be implemented}, +\item powers work currently only with integral \emph{or also + half-integral\NewWith{1.2f}} exponents (but the latter only for float + expressions), +\item \xintname can handle numbers with thousands of digits, but execution + times limit the practical range to a few hundreds (if many such computations + are needed), +\item computations in |\xinttheexpr| and |\xinttheiiexpr| are exact (except if + using |sqrt|, naturally), +\item fractions are not systematically reduced to smallest terms, use + |reduce| function, +\item for producing fixed point numbers with |d| digits after decimal mark, + use (note the extra `|i|' in the parser name!) |\xinttheiexpr [d] + ...\relax|. This is actually essentially synonymous with |\xinttheexpr + round(..,d)\relax| (for |d=0|, |\xinttheiexpr [0]| is the same as + |\xinttheiexpr| without optional argument, and is like |\xinttheexpr + round(..)\relax|). If truncation rather than rounding is needed use thus + |\xinttheexpr trunc(..,d)\relax| (and |\xinttheexpr trunc(..)\relax| for + truncation to integers), +\item all three parsers allow some constructs with dummy variables as seen + above; it is possible to define new functions or to declare variables for + use in upcoming computations, +\item |\xinttheiiexpr| is slightly faster than |\xinttheexpr|, but usually one + can use the latter with no significant time penalty also for integer-only + computations. +\end{enumerate} + +All operations executed by the parsers are based on underlying macros from +packages \xintfracname and \xintname which are loaded automatically by +\xintexprname. With extra packages \xintbinhexname and \xintgcdname the +parsers can handle hexadecimal notation on input (even fractional) and compute +|gcd|'s or |lcm|'s of integers. + +All macros doing computations ultimately rely on (and reduce to) the +|\numexpr| primitive from \eTeX{}. These \eTeX{} extensions date back to 1999 +and are by default incorporated into the |pdftex| etc... executables from +major modern \TeX{} installations since more than ten years now. Only the +|tex| binary does not benefit from them, as it has to remain the original +\textsc{D.~Knuth}'s software, but one can then use |etex| on the command line. +PDF\TeX\ (in pdf or dvi output mode), Lua\TeX, Xe\TeX\ all include the \eTeX\ +extensions. + +\subsection{Quick overview (expressions with \xintexprname)} This section gives a first few examples of using the expression parsers which are provided by package \xintexprname. Loading \xintexprname automatically also @@ -2976,24 +3006,33 @@ separated list of results. integers.} The forward slash \dtt{/} does the rounded integer division (\dtt{//} does truncated division, and \dtt{/:} is the associated modulo). There are two square root extractors \dtt{sqrt} and \dtt{sqrtr} for - truncated and rounded square roots. + truncated and rounded square roots. Scientific notation |6.02e23| is + \emph{not} accepted on input, one needs to wrap it as |num(6.02e23)| which + will convert to an integer notation \dtt{\printnumber{\xinttheiiexpr + num(6.02e23)\relax}}. \item \csbxint{thefloatexpr}| ... \relax| does computations with a given - precision \dtt{P}, as specified via a prior assignment |\xintDigits:=P;|. The - default is \dtt{P=16} digits. An optional argument controls the precision on - \emph{output} (this is not the precision of the computations themselves). - The four basic operations realize \emph{correct rounding.} + precision \dtt{P}, as specified via a prior assignment |\xintDigits:=P;|. + The default is \dtt{P=16} digits. An optional argument controls the + precision for \emph{formatting the output} (this is not the precision of the + computations themselves). The four basic operations and the square root + realize \emph{correct rounding.}\footnote{when the inputs are already + floating point numbers with at most |P|-digits mantissas.} \item \csbxint{theexpr}| ... \relax| handles integers, decimal numbers, numbers in scientific notation and fractions. The algebraic computations are - done \emph{exactly.} + done \emph{exactly.} The |sqrt| function is available and works + according to the |\xintDigits| precision or according to its second optional + argument. \end{itemize} \begin{framed} Currently, the sole available non-algebraic function is the square root extraction \dtt{sqrt}. It is allowed in |\xintexpr..\relax| but naturally can't return an \emph{exact} value, hence computes as if it was in - |\xintfloatexpr..\relax|. The power operator |^| (equivalently |**|) only - works with integral powers (half-integers are not accepted, despite square - root extraction having been implemented). + |\xintfloatexpr..\relax|. The power operator |^| (equivalently |**|) works + with integral exponents only in \csbxint{iiexpr} (non-negative) and + \csbxint{expr} (negative exponents allowed, of course) and also with + half-integral exponents in \csbxint{floatexpr} (it proceeds via an integral + power followed by a square-root extraction). \end{framed} Two derived parsers: @@ -3014,7 +3053,7 @@ Here is a (partial) list of the recognized symbols: \item the comma (to separate distinct computations or arguments to a function), \item parentheses, -\item infix operators |+|, |-|, |*|, |/|, |^| (or |**|), +\item infix operators |+|, |-|, |*|, |/|, |^| (or |**|), % \item |//| and |/:| only in \csbxint{iiexpr}|..\relax|, \item branching operators |(x)?{x non zero}{x zero}|, |(x)??{x<0}{x=0}{x>0}|, \item boolean operators |!|, |&&| or |'and'|, \verb+||+ or |'or'|, @@ -3026,13 +3065,13 @@ Here is a (partial) list of the recognized symbols: \item functions \xintFor #1 in {num, reduce, abs, sgn, frac, floor, ceil, sqr, sqrt, sqrtr, float, round, trunc, mod, quo, rem, gcd, lcm, max, min, |`+`|, |`*`|, not, all, any, xor, if, ifsgn, even, odd, first, - last, reversed, bool, togl}\do {\dtt{#1}, } + last, reversed, bool, togl, factorial, binomial, pfactorial}\do {\dtt{#1}, } \item functions with dummy variables \xintFor #1 in {add, mul, seq, subs, rseq, rrseq, iter}\do {\dtt{#1}\xintifForLast{.}{, }} \end{itemize} See \autoref{ssec:syntax} for the complete syntax, as well as \autoref{ssec:dummy} which contains examples illustrating further some -features which were added at the time of release |v1.1 2014/10/28|. +features which were added at the time of release |1.1 2014/10/28|. The normal mode of operation of the parsers is to unveil the parsed material token by token. This means that all elements may arise from expansion of @@ -3050,13 +3089,13 @@ fraction, or float, skipping the token by token expansion. \medskip Here is an example of a computation: \begin{everbatim*} -\xinttheexpr (31.567^2 - 21.56*52)^3/13.52^5\relax -\end{everbatim*} -\newline The result is a bit frightening but illustrates that +\xinttheexpr (31.567^2 - 21.56*52)^3/13.52^5\relax +\end{everbatim*}\newline +This illustrates that |\xinttheexpr..\relax| does its computations \emph{exactly}. The same example as a floating point evaluation: \begin{everbatim*} -\xintthefloatexpr (31.567^2 - 21.56*52)^3/13.52^5\relax +\xintthefloatexpr (31.567^2 - 21.56*52)^3/13.52^5\relax \end{everbatim*} Again, all computations done by |\xinttheexpr..\relax| are completely exact. @@ -3090,195 +3129,12 @@ not have been obtained in reduced terms: automatic manner by reduction to smallest terms: |A/B| multiplied by |C/D| returns |AC/BD|, |A/B| added to |C/D| returns |(AD+BC)/BD| except if either |B| divides |D| or |D| divides |B|. -% y réfléchir -% The command |\xintfracsetup{reduceall}| \end{framed} Make sure to read \autoref{ssec:userinterface}, \autoref{ssec:syntax} and the rest of \autoref{sec:expr}. -\subsection {Changes} - -The initial \xintname (|2013/03/28|) was followed by \xintfracname -(|2013/04/14|) which handled exactly fractions and decimal numbers. Later came -\xintexprname (|2013/05/25|) and at the same time \xintfracname got extended -to handle floating point numbers. Later, \xinttoolsname was detached -(|2013/11/22|). The main focus of development during late 2013 and early 2014 -was kept on \xintexprname. One year later it got a significant upgrade with -|1.1| of |2014/10/28|. The core integer routines remained essentially -unmodified during all this time (apart from a slight improvement of division -early 2014) until their complete rewrite with release -|1.2| from |2015/10/10|. - -\begin{description} -\item [|1.2a (2015/10/19) to 1.2e (2015/11/22):|] release |1.2| had at least - four bad bugs which these releases were supposed to fix; but sometimes they - themselves introduced new bugs which had to get fixed in the next one. We - managed to add some new features: - \begin{enumerate}[noitemsep] - \item new \csbxint{deffunc}, \csbxint{defiifunc}, \csbxint{deffloatfunc} - macros whose purpose is to define functions recognized as such by the - \xintexprname parsers. - \item new \csbxint{unassignvar}, new \csbxint{verbosetrue}. - \item local scope for the function declarations and for the macro - definitions done by \csbxint{NewExpr}. - \item extended \hyperref[ssec:tacit multiplication]{tacit multiplication}, - and it now always ``ties more'' than the regular division and - multiplication. - \item slightly more precise discussion of floating point issues in - \autoref{ssec:floatingpoint}, but the coverage by \xintfracname of - floating point operations is yet to be substantially extended. - \item extensive re-write of the ``Commands of \xintexprname'' \autoref{sec:expr}. - \item complete re-write of the \hyperref[ssec:quicksort]{Quick Sort - algorithm} section. - \end{enumerate} -\item [|1.2 (2015/10/10):|] complete rewrite of the core arithmetic routines. - The efficiency for numbers with less than $20$ or $30$ digits is slightly - compromised (for addition/subtraction) but it is increased for bigger - numbers. For multiplication and division the gains are there for almost all - sizes, and become quite noticeable for numbers with hundreds of digits. The - allowable inputs are constrained to have less than about $19950$ digits - ($19968$ for addition, $19959$ for multiplication). -\item [|1.1 (2014/10/28):|] many extensions to package \xintexprname, such as - the evaluation of expressions with dummy variables, possibly iteratively, - with allowed nesting. See \autoref{ssec:syntax} and \autoref{ssec:dummy} for - a description of these new functionalities. Also worthy of attention: -\begin{enumerate} -\item |\xintiiexpr...\relax| associates |/| with the \emph{rounded} - division (the |//| operator being provided for the \emph{truncated} - division) to be in synchrony with the habits of |\numexpr|, -\item the \xintfracname macro \csbxint{Add} (corresponding to |+| in - expressions) does not anymore blindly multiply denominators but first checks - if one is a multiple of the other. However doing systematic reduction to - smallest terms, or systematically computing the |LCM| of the denominators - would be too costly (I think). -\end{enumerate} -\xintname does not load \xinttoolsname -anymore (only \xintexprname does) and the core arithmetic macros are -moved to a new package \xintcorename (loaded automatically by -\xintname, itself loaded by \xintfracname, itself loaded by \xintexprname). - -Package \href{http://www.ctan.org/pkg/bnumexpr}{bnumexpr} (which is \LaTeX{} -only) now also loads only \xintcorename. -\end{description} - -There is a file |CHANGES.html| (also |CHANGES.pdf|) which provides the -detailed cumulative change log since the initial release. To access it, issue -on the command line |texdoc --list xint| (this works |TeXLive| and there is -probably an equivalent in |MikTeX|). - -It is also available on \href{http://ctan.org}{CTAN} via -\href{http://mirrors.ctan.org/macros/generic/xint/CHANGES.html}{this link}. -Or, running |etex xint.dtx| in a working repertory will extract a |CHANGES.md| -file with Markdown syntax. - -\subsection{Origins of the package} - -|2013/03/28.| Package |bigintcalc| by \textsc{Heiko Oberdiek} already -provides expandable arithmetic operations on ``big integers'', -exceeding the \TeX{} limits (of $2^{31}-1$), so why another% -% -\footnote{this section was written before the \xintfracname package; the - author is not aware of another package allowing expandable - computations with arbitrarily big fractions.} -% -one? - -I got started on this in early March 2013, via a thread on the -|c.t.tex| usenet group, where \textsc{Ulrich D\,i\,e\,z} used the -previously cited package together with a macro (|\ReverseOrder|) -which I had contributed to another thread.% -% -\footnote{the \csa{ReverseOrder} could be avoided in that circumstance, - but it does play a crucial r\^ole here.} -% -What I had learned in this -other thread thanks to interaction with \textsc{Ulrich D\,i\,e\,z} and -\textsc{GL} on expandable manipulations of tokens motivated me to -try my hands at addition and multiplication. - -I wrote macros \csa{bigMul} and \csa{bigAdd} which I posted to the -newsgroup; they appeared to work comparatively fast. These first -versions did not use the \eTeX{} \csa{numexpr} primitive, they worked -one digit at a time, having previously stored carry-arithmetic in -1200 macros. - -I noticed that the |bigintcalc| package used \csa{numexpr} -if available, but (as far as I could tell) not -to do computations many digits at a time. Using \csa{numexpr} for -one digit at a time for \csa{bigAdd} and \csa{bigMul} slowed them -a tiny bit but avoided cluttering \TeX{} memory with the 1200 -macros storing pre-computed digit arithmetic. I wondered if some speed -could be gained by using \csa{numexpr} to do four digits at a time -for elementary multiplications (as the maximal admissible number -for \csa{numexpr} has ten digits). - -The present package is the result of this initial questioning. - -\noindent|2015/10/10.| \xintname 1.2 also got its impulse from a fast -``reversing'' macro, which I wrote after my interest got awakened again as a -result of correspondance with Bruno \textsc{Le Floch} during September 2015: -this new reverse uses a \TeX nique which \emph{requires} the tokens to be -digits. I wrote a routine which works (expandably) in quasi-linear time, but a -less fancy |O(N^2)| variant which I developed concurrently proved to be faster -all the way up to perhaps $7000$ digits, thus I dropped the quasi-linear one. -The less fancy variant has the advantage that \xintname can handle numbers -with more than $19900$ digits (but not much more than $19950$). This is with -the current common values of the input save stack and maximal expansion depth: -$5000$ and $10000$ respectively. - -\subsection{Installation instructions} -\label{ssec:install} - -\xintname is made available under the -\href{http://www.latex-project.org/lppl/lppl-1-3c.txt}{LaTeX Project Public - License 1.3c}. It is included in the major \TeX\ distributions, thus there -is probably no need for a custom install: just use the package manager to -update if necessary \xintname to the latest version available. - -After installation, issuing in terminal |texdoc --list xint|, on installations -with a |"texdoc"| or similar utility, will offer the choice to display one of -the documentation files: |xint.pdf| (this file), |sourcexint.pdf| (source -code), |README|, |README.pdf|, |README.html|, |CHANGES.pdf|, and -|CHANGES.html|. - -For manual installation, follow the instructions from the |README| file which -is to be found on \href{http://www.ctan.org/pkg/xint}{CTAN}; it is also -available there in PDF and HTML formats. The simplest method proposed is to -use the archive file \href{http://www.ctan.org/pkg/xint}{xint.tds.zip}, -downloadable from the same location. - -The next simplest one is to make use of the |Makefile|, which is also -downloadable from -\href{http://mirror.ctan.org/macros/generic/xint}{CTAN}. This is -for GNU/Linux systems and Mac OS X, and necessitates use of the command -line. If for some reason you have |xint.dtx| but no internet access, -you can recreate |Makefile| as a file with this name and the following -contents: - -{\def\everbatimindent {0pt }% -\begin{everbatim} -include Makefile.mk -Makefile.mk: xint.dtx ; etex xint.dtx -\end{everbatim}} - -Then run |make| in a working repertory where there is |xint.dtx| and the file -named |Makefile| and having only the two lines above. The |make| will extract -the package files from |xint.dtx| and display some further instructions. - -If you have |xint.dtx|, no internet access and can not use the Makefile -method: |etex xint.dtx| extracts all files and among them the |README| as a -file with name |README.md|. Further help and options will be found therein. - - -\section{Introduction via examples} -\label{sec:examples} - -The main goal is to allow expandable computations with integers and -fractions of arbitrary sizes. - \subsection{Printing big numbers on the page}\label{ssec:printnumber} - When producing very long numbers there is the question of printing them on the page, without going beyond the page limits. In this document, I have most of the time made use of these macros (not provided by the package:) @@ -3307,7 +3163,7 @@ in text mode could not get it to break numbers accross lines). Recently I became aware of the \href{http://ctan.org/pkg/seqsplit}{seqsplit} package% % -\footnote{\url{http://ctan.org/pkg/seqsplit}} +\footnote{\url{http://ctan.org/pkg/seqsplit}} % which can be used to achieve this splitting accross lines, and does work in inline math mode (however it doesn't allow to separate digits by @@ -3330,7 +3186,7 @@ described in the previous section, or sometimes the |\np| command from the \begin{itemize} \item {$123456^{99}$: }\\ -|\xintiiPow {123456}{99}|: +|\xintiiPow {123456}{99}|: \dtt{\printnumber{\xintiiPow {123456}{99}}} \item {1234/56789 with 1500 digits after the decimal point: }\\ @@ -3356,7 +3212,7 @@ described in the previous section, or sometimes the |\np| command from the \leftedline{|\xintDigits:=20; \np{\xintthefloatexpr .7123045678952^-243\relax}|}% % -\leftedline{\xintDigits:=20;\dtt{\np{\xintthefloatexpr .7123045678952^-243\relax }}} +\leftedline{\xintDigits:=20;\dtt{\np{\xintthefloatexpr .7123045678952^-243\relax }}} % \xintDigits:=16;% % @@ -3364,7 +3220,7 @@ Side note: the exponent |-243| didn't have to be put inside parentheses, contrarily to what happens with some professional computational software. |;-)| % 6.342,022,117,488,416,127,3 10^35 -% maple n'aime pas ^-243 il veut les parenthèses, bon et il donne, en Digits +% maple n'aime pas ^-243 il veut les parenthèses, bon et il donne, en Digits % = 24: 0.634202211748841612732270 10^36 \end{snugframed} @@ -3373,7 +3229,7 @@ software. |;-)| \dtt{\printnumber{\xinttheiiexpr 200!\relax}} \item {$2000!$ as a float. As \xintexprname does not handle |exp/log| so far, - the computation is done internally without the Stirling formula, + the computation is done internally without the Stirling formula, by repeated multiplications truncated suitably:}\\ |\xintDigits:=50;|\newline |\xintthefloatexpr 2000!\relax|: {\xintDigits:=50;\dtt{\printnumber{\xintthefloatexpr 2000!\relax}}} @@ -3416,7 +3272,6 @@ $\U\times(7^{200}-3^{200})+\xintiOpp\V\times(2^{200}-1)=\D$ {\printnumber\U$\times(7^{200}-3^{200})+{}$% \printnumber{\xintiOpp\V}$\times(2^{200}-1)={}$\printnumber\D} -% 11 octobre 2014, je modifie juste d'une unité le deuxième... plus joli. \item The Euclide algorithm applied to \np{22206980239027589097} and \np{8169486210102119257}: (with \xintgcdname)% % @@ -3426,7 +3281,7 @@ $\U\times(7^{200}-3^{200})+\xintiOpp\V\times(2^{200}-1)=\D$ \noindent\begingroup\parskip0pt\relax |\xintTypesetEuclideAlgorithm {22206980239027589097}{8169486210102119257}|\par \dtt -{\xintTypesetEuclideAlgorithm {22206980239027589097}{8169486210102119257}} +{\xintTypesetEuclideAlgorithm {22206980239027589097}{8169486210102119257}} \endgroup \smallskip @@ -3517,9 +3372,6 @@ digits is |\xintLen{\xintiiQuo{\xintiiPow{2}{1000}}{\xintiFac{100}}}| which expands (in two steps) and tells us that $[2^{1000}/100!]$ has \dtt{\y} digits. This is not so many, let us print them here: \dtt{\printnumber\x}.% -% -% \footnote{See \autoref{ssec:printnumber} and \hyperref[fn:np]{a previous -% footnote}.} \end{itemize} @@ -3549,14 +3401,14 @@ digits. This is not so many, let us print them here: \item The computations of \hyperref[ssec:Machin]{ $\pi$ and $\log 2$} (\autoref{ssec:Machin}) using \xintname and the computation of the \hyperref[ssec:e-convergents]{convergents of $e$} with the further help of - the \xintcfracname package are among further examples. + the \xintcfracname package are among further examples. \item There is also an example of an \hyperref[xintXTrunc]{interactive session}, where results are output to the log or to a file. \item The functionalities of \xintexprname are illustrated with various - examples in \autoref{ssec:syntax} and + examples, in places such as in \autoref{xintdeffunc} and \autoref{ssec:dummy}. \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 @@ -3566,19 +3418,18 @@ run.% \footnote{The CPU of my computer hates me for all those re-compilations after changing a single letter in the \LaTeX{} source, which require each time to do all the zillions of evaluations contained in this document\dots} -% -% on examples which were selected to not impact too much the compilation time of -% this documentation. -% Nevertheless, there are so many computations done that compilation time -% is significantly increased compared to a \LaTeX\ run on a typical -% document of about the same size. + + +%\section{Introduction via examples} +%\label{sec:examples} + +% The main goal is to allow expandable computations with integers and +% fractions of arbitrary sizes. \section{The \xintname bundle} -% \section{User interface} -% {\etocdefaultlines\etocsettocstyle{}{}\localtableofcontents} \subsection{Characteristics} @@ -3597,8 +3448,7 @@ run.% \end{enumerate} `Arbitrarily big' currently means with less than about \dtt{19950} digits: the - maximal% - \MyMarginNote[\kern\dimexpr\FrameSep+\FrameRule\relax]{Changed!} + maximal number of digits for addition is at \dtt{19968} digits, and it is \dtt{19959} for multiplication. \end{framed} @@ -3624,7 +3474,7 @@ requires the \eTeX{} extensions) for higher speed, and also on fractions, not only integers. Arbitrary precision floating points operations are a derivative, and not the initial design goal.% % -\footnote{currently (|v1.08|), the only non-elementary operation +\footnote{currently (|1.08|), the only non-elementary operation implemented for floating point numbers is the square-root extraction; no signed infinities, signed zeroes, |NaN|'s, error traps\dots, have been implemented, only the notion of `scientific notation with a given @@ -3669,14 +3519,13 @@ available in September 2015, on one hand, and on the other hand \item \csbxint{iiexpr}'s multiplication appears slightly faster (about |1.5x| or |2x| to give an average order of magnitude) up to about $900$ digits, -\item at $1000$ digits, \liiibigint{} runs between |15%| and |20%| faster, +\item at $1000$ digits, \liiibigint{} runs between |15%| and |25%| faster, \item then its sub-quadratic growth shows up, and at $8000$ digits I observed - it to be about |7.6x| faster (I tried on two computers and on my laptop the - ratio was more like |8.5x--9x|). Its computation time increased from $1000$ - digits to $8000$ digits by a factor smaller than |30|, whereas for + it to be about |7.5x--9x| faster (I got quite varying results depending on + which computer the trial was conducted). Its computation time increased from + $1000$ digits to $8000$ digits by a factor smaller than |30|, whereas for \csbxint{iiexpr} it was a factor only slightly inferior to |200| (|225| on - my laptop) ... - Karatsuba multiplication brilliantly pays off ! + my laptop) ... Karatsuba multiplication brilliantly pays off ! \item One observes the transition at the powers of two for the \liiibigint{} algorithm, for example I observed \liiibigint{} to be |3.5x--4x| faster at $4000$ digits but only |3x--3.5x| faster at $5000$ digits. @@ -3718,128 +3567,48 @@ the complete expandability.% \subsection{Floating point evaluations} \label{ssec:floatingpoint} -\emph{This documentation is currently undergoing revision and is provided here - in some transient intermediate state.} - - Floating point macros are provided by package \xintfracname to work with a given arbitrary precision |P|. The default value is $P=16$ meaning that the -significands for non-zero numbers have $16$ decimal digits, the first one non -zero. The syntax to set the -precision to |P| is \centeredline{|\xintDigits:=P;|} To query the current -value use \csbxint{theDigits}. -\begin{everbatim*} -The current precision for floating point evaluations is \xinttheDigits. -{\xintDigits:=32;% -The current precision for floating point evaluations is \xinttheDigits.} -The current precision for floating point evaluations is \xinttheDigits. -\end{everbatim*} - -It is also possible to pass |P| as an optional argument within brackets to the -floating point macros such as \csbxint{FloatAdd}, \csbxint{FloatMul}, ... - -\csbxint{thefloatexpr}|...\relax| also admits an optional argument |Q| within -brackets, but it has no influence on the precision |P| for the computations, -its use is only to specify a rounding precision on output, typically to clean -up the computation result from cumulated errors resulting from iterated -operations, which unavoidably make possibly invalid the last digits (compared -to an exact theoretical evaluation; I say \emph{theoretical} because no -computer has ever nor ever will compute exactly $\sqrt 2$ in base $10$.) - +significands of the produced (non-zero) numbers have $16$ decimal +digits.\footnote{Currently in the cases when the rounding to nearest goes to + the next power of ten, the result is |10.0....0eN| with |P-1| zeroes after + decimal mark, hence a total of |P+1|, not |P|, digits.} The syntax to set +the precision to |P| is +% +\centeredline{|\xintDigits:=P;|} +% +The value is local to the group or environment (if using \LaTeX). To query the +current value use \csbxint{theDigits}. + +Most floating point macros accept an optional first argument |[P]| which then +sets the target precision and replaces the |\xintDigits| assigned +value.\footnote{the |[P]| must be repeated for the macro arguments, if + the latter are also \xintfracname macros with arguments of their own.} + +\csbxint{floatexpr}|...\relax| also admits an optional argument |[Q]| but it +has an altogether different meaning: the computations are always done with the +prevailing |\xinttheDigits| precision and the optional argument says to round +the final result to |Q| digits of precision. This makes sense only if +|Q<\xinttheDigits| and is intended to clean up the result from dubious last +digits. + +{\footnotesize The maximal allowed value for |P| in a |\xintDigits:=P;| assignment is -\dtt{32767}. It was possible earlier to use even bigger |P|'s as optional +\dtt{32767}. It was even possible earlier to use bigger |P|'s as optional argument to \csbxint{Float} for a one-short conversion\MyMarginNote{Changed with 1.2} to a gigantic float. However since release |1.2| this can't work -in complete generality: a fractional input will trigger the division macro -which can't handle inputs with more than about \dtt{19900} digits. For example -(tested 2015/11/07 with |v1.2b|) |\message{\xintFloat [19942]{1/7}}| works but -not |\message{\xintFloat [19943]{1/7}}|. On the other hand |\xintFloat -[50000]{1}| does work (slowly..), but there isn't much one can do afterwards -with it... +in complete generality: a fractional input will trigger internally the +division macro which can't handle arguments of more than about \dtt{19900} +digits. For example (tested 2015/11/07 with |1.2b|) |\message{\xintFloat + [19942]{1/7}}| works but not |\message{\xintFloat [19943]{1/7}}|. On the +other hand |\xintFloat [50000]{1}| does work (slowly..), but there isn't much +one can do afterwards with it...\par} More reasonably, working with significands of $24$, $32$, $48$, $64$, or even $80$ digits is well within the reach of the package. -%\begin{framed} -Currently, the only non-elementary operation is the square root -(\csbxint{FloatSqrt}). The elementary transcendantal functions are not yet -implemented. The power function (\csbxint{FloatPow}, \csbxint{FloatPower}) -accept only (positive or negative) integer exponents. -%\end{framed} - -\begin{framed} - Future releases of \xintname will have more extensive coverage of floating - point operations, and document better what exactly is the achieved - precision. Regarding the four basic operations, they always have achieved - \emph{correct rounding}. -\end{framed} -The maximal theoretically allowed exponent is currently set at -\dtt{\number"7FFFFFFF} (the minimal exponent is its opposite) which is the -maximal number handled by \TeX. - -% We refer here to the exponent |e| in a -% representation -% \leftedline{$x=\pm \underbrace{ddd\dots ddd}_{P\ \mathrm{digits}}\times 10^e$} -% where the \dtt{P} digits are the significand. This means that the maximal -% theoretical exactly representable number should be: -% \dtt{$9.9\dots 9\times 10^{\number"7FFFFFFF+(P-1)}$}. However, with for -% example the default \dtt{P=16} value for the precision, -% \begin{everbatim} -% \xintFloat {9.999999999999999e2147483662} -% \end{everbatim} -% raises an error, because the \eTeX{} primitive |\numexpr| suffers an -% arithmetic overflow if used for example as |\numexpr -1+2147483648\relax|, -% hence it understandably can't handle the |2147483662|. Sadly, already -% \begin{everbatim} -% \xintFloat {9.999999999999999e2147483647} -% \end{everbatim}% -% also raises an error, due to some arithmetic overflow originating in -% \csbxint{Float} parsing. There is no error with: -% \begin{everbatim*} -% \xintRaw {9.999999999999999e2147483647} -% \end{everbatim*}% -% but some extra manipulations done by |\xintFloat| (to go -% again from the |\xintRaw| format to the float format) create the -% problem. The maximal exactly represented and acceptable input to |\xintFloat| -% is observed to be: -% \begin{everbatim*} -% \xintFloat {9.999999999999999e2147483632} -% \end{everbatim*} -% With more |9|'s the number is still parsed but the output -% and the minimal one is \dtt{$10^{\number"7FFFFFFF}$} - -Perhaps in the future this will be -reduced, for example to \dtt{2147400000}. It could even be envisioned that the -maximal |e|${}_{\mathrm{max}}$ and minimal |e|${}_{\mathrm{min}}$ exponents -would be user-specified. - -% Suppose that the precision \dtt{P} has its default value \dtt{16}. Currently, attempting to subtract \dtt{1.0e-\the\numexpr\number"7FFFFFFF-15} from -% \dtt{1.1e-\the\numexpr\number"7FFFFFFF-15} by necessity leads to a low-level \eTeX{} error, -% because the result \dtt{1e-\xintiiPow2{31}} has a too big exponent in absolute -% value, thus necessarily somewhere an arithmetic overflow will occur. Actually, -% this overflow happens immediately during the parsing of -% \dtt{1.1e-\number"7FFFFFFF} because the very first parsing by \xintfracname -% will initially attempt to store the number as \dtt{11[-\xintiiPow2{31}]} and the -% arithmetic overflow will happen already at this stage. - -% reasonable value), and also would make easier the implementation of denormal - -Currently \xintfracname has no notion of |NaN|s or signed infinities or signed -zeroes. These notions are part of the -\href{https://en.wikipedia.org/wiki/IEEE_floating_point}{\texttt{IEEE - 754-2008}} standard for Floating-Point arithmetic (which initially regards -hardware floating point processing units but also has implications on -software)\footnote{The |IEEE 754-1985| was a binary standard with a specific - value for the precision ($24$ for single precision, $53$ for double - precision). The newer - \href{https://en.wikipedia.org/wiki/IEEE_floating_point}{\texttt{IEEE - 754-2008}} normalizes five basic formats, three binaries and two - decimals ($16$ and $34$ decimal digits) and discusses extended formats with - higher precision.} and, together with signed infinities, signed zeroes, -exception handling are not implemented currently by the \xintfracname macros -dealing with ``floating-point numbers''. \begin{framed} % Floating point multiplication of two numbers with |P| digits of precision @@ -3848,105 +3617,188 @@ dealing with ``floating-point numbers''. % large. But \xintname is initially an exact algebraic operator, not a % floating point one with a fixed maximal size for operands, and the author % hasn't yet had the opportunity to re-examine that point. - The |IEEE 754| requirement of \emph{correct rounding} for addition, - subtraction, multiplication and division is achieved by \xintfracname and - the \csbxint{thefloatexpr}|...\relax| parser: this means that for two - operands of |P| digits the output coincides exactly with the rounding of an - exact evaluation. - - The rounding mode is ``round to nearest, ties away from zero'', which is - based on the rounding to integers which maps $(-0.5,0.5)$ to $0$, - $[0.5, 1.5)$ to $1$, etc... and $(-1.5,-0.5]$ to $-1$ etc... It is not - customizable. + The |IEEE 754|\footnotemark\ requirement of \emph{correct rounding} for + addition, subtraction, multiplication, division and square root is achieved + (in arbitrary precision) by the macros of \xintfracname hence also by the + infix operations of the \csbxint{floatexpr}|...\relax| expressions: this + means that for operands given with at most |P| significant digits (and + arbitrary exponents) the output coincides exactly with the rounding of an + exact evaluation (baring overflow or underflow). + + The rounding mode is ``round to nearest, ties away from zero''. + It is not customizable. + + Currently \xintfracname has no notion of |NaN|s or signed infinities or signed + zeroes, but this is intended for the future. \end{framed} +\footnotetext{The |IEEE 754-1985| standard was for hardware implementations of + binary floating-point arithmetic with a specific value for the precision + ($24$ bits for single precision, $53$ bits for double precision). The newer + {\texttt{IEEE 754-2008}} + (\url{https://en.wikipedia.org/wiki/IEEE_floating_point}) normalizes five + basic formats, three binaries and two decimals ($16$ and $34$ decimal + digits) and discusses extended formats with higher precision. These + standards are only indirectly relevant to libraries like \xintname dealing + with arbitrary precision.} + + +Currently, the only non-elementary operation is the square root. The +elementary transcendantal functions are not yet implemented. The power +function accepts integer and half-integer exponents.\footnote{Half-integer + exponents work only inside \csbxint{floatexpr}|...\relax| expressions, not + directly via the \csbxint{FloatPower} macro.} + + +The maximal theoretically allowed exponent is currently set at +\dtt{\number"7FFFFFFF} (the minimal exponent is its opposite) which is the +maximal number handled by \TeX. But this means that overflow or underflow are +detected only via low-level |\numexpr| arithmetic overflows which are +basically un-recoverable. Besides there are some border effects as the +routines need to add or subtract lengths of numbers from exponents, possibly +triggering the low-level overflows. In the future not only the Precision but +also the maximal and minimal exponents |Emin| and |Emax| will be specifiable +by the user. + +\xintfracname is confronted with the problem that its float macros have to +handle inputs which not only may have much more digits than the target float +precision, but may even be fractions (which in a way means infinite +precision). As fractions should be handled as first class citizens, the float +macros should give the same result independently of whether an +argument is given as |A/B| or as |C/D| as long as |A/B=C/D| as rational numbers. +This was briefly the case when \xintfracname was first released, but very +shortly thereafter the fraction-to-float parsing (via \csbxint{Float}) was +modified for speed and as a result, currently this is not the case.% +% +\IMPORTANT{}\footnote{The author + had forgotten that the initial situation had been quickly modified, and for + some time this documentation wrongly asserted that the \xintfracname basic + floating point operations produced a value depending solely on the inputs as + abstract fractions.} +% + +Next major release of \xintname packages will adopt a definitive model for +floats, and it will have the property above of handling fractions +intrinsically. Most probably this will go via first correctly rounding the +inputs (inclusive of arbitrary fractions) to the target precision. + +The current situation is that for a fraction $A/B\cdot 10^N$ its numerator and +denominator are each first \emph{truncated} (not rounded, but that would not +change the issue) to |P+2| digits of precision if |P| is the asked-for +precision. Imagine that the original fraction was close to a boundary value +between rounding up or rounding down to a |P|-float. Changing even a tiny bit +the numerator and denominator moves the fraction, and as a result the rounding +to a |P|-float may be altered. + +If $B=1$ there is no issue because +truncating to |P+2| digits then rounding to nearest |P|-float is like rounding +directly to nearest |P|-float (that would not have applied if we had first +rounded, not truncated, to a |P+2|-float). For $A=1$ on the contrary +the issue is already there. Here is an illustration of the problem: + + +\begin{everbatim*} +Precision: \xinttheDigits\par +\xintFloat {1/1858798855725191} ("reduced" fraction)\par +\xintFloat {5379818246175219/10000000000000000980336298241829} ("big" fraction)\par +We check that the fractions are identical:\par +\xinttheexpr 1/1858798855725191 - 5379818246175219/10000000000000000980336298241829\relax\par +And we also examine more digits of the decimal expansion:\par +\xinttheexpr trunc(1/1858798855725191, 48)\relax\dots\par +But truncating the denominator of the "big" fraction to 18 digits leads to:\par +\xinttheexpr trunc(5379818246175219/10000000000000000900000000000000, 48)\relax\dots\par +The two values rounded to 16 significant places differ.\par +\end{everbatim*} + + + + + + +Here is a summary of the situation regarding floats which was prevailing from +release |1.08a| to release |1.2e|. Next, we will explain the new situation +with |1.2f|. + +\begin{itemize} +\item As explained above the |\xintFloat| macro which converts an input to a + P-float does the following in case of fraction $A/B[N]$: it truncates both + $A$ and $B$ to P+2 digits say $A'$ and $B'$ then computed the correct + rounding of $A'/B'$ to P digits. (not changed in |1.2f|) +\item The |\xintFloatAdd|, |\xintFloatSub|, |\xintFloatMul|, |\xintFloatDiv| + routines each first rounded their inputs to P+2 digits (thus + applying the previous item, but with P replaced by P+2). +\item The |\xintFloatPow| and |\xintFloatPower| routines rounded their inputs + to Q > P+2 digits, with Q a temporary increased precision for intermediate + computations, then they rounded the end result to the asked-for P digits (in + the case of a negative exponent the final rounding was applied to something + of the |1/C| shape, up to powers of ten naturally). +\item The multiplication and division produced the correctly rounded value + from the (P+2)-rounded inputs. Thus, not only did these + routines produce the correctly rounded result for P-digits inputs, they + actually achieved it for (P+2)-digits inputs (again, for fractional inputs, + the initial rounding viciates any hope of having the final result be the + correctly rounded exact one). +\item For addition and subtraction having now to deal with $A.10^M\pm B.10^N$, + with $A$ and $B$ having (P+2) digits, the rule was that if $M-N\geqslant + P+4$, then $B$ was dropped altogether, if $N-M\geqslant P+4$ then $A$ was + dropped, else the operation was done exactly then rounded to P digits. But + in those cases where one of the summands was dropped, correct rounding was not + guaranteed, because say $A$ having P+2 digits could be close or at a + mid-point between two P-floats, thus neglecting $B$ (however small it may + be) could viciate the final rounding. Also, when adding $B=0$ to $A$, as $A$ + is already the P+2 rounded original input, the final P-digit value could + end up not being the correct rounding of the original input (rounding to + nearest is not transitive; this is independent of the issues of handling + fractions as mentioned above). +\end{itemize} + +For |1.2f| I have decided that the two digits added on input to the +asked-for precision by the +four basic operations do not make much sense after all.\IMPORTANT{} Especially +as since |1.2| the basic core operations are handled by blocks of eight +digits, this procedure was adding a systematic overhead for inputs already of +the default 16-digits precision, forcing computations as if for 24 digits. +Besides, when used in \cs{xintfloatexpr}, most of the time the inputs will +already be results of earlier computations hence have P digits. It appears +wasteful to extend them by two zeros prior to each operation. + +Thus, |1.2f| adopts (provisorily perhaps) the policy that the inputs will +always be rounded first to P-floats, not (P+2)-floats.\CHANGED{1.2f} This does +not change the behaviour for inputs being already P-floats. All four +operations then and now produce the correctly rounded value. For coherence +also the square root and the power macros now first round their argument +to a P-float.% +% +\footnote{The power macros do not aim at correct rounding, currently. But the + change fixes the issue that there was a possible difference between the + evaluation of |x*x| and |x^2| or |1/x| vs |x^-1| in the \csbxint{floatexpr} + parser due to the fact that in the latter cases |x| was initially rounded + to P+3 digits but in the former cases only to P+2 digits.} +% +Also,\NewWith {1.2f} |1.2f| has implemented \emph{correct rounding} (in +arbitrary precision) for the square root extraction. + +What is yet lacking from |1.2f| is the improved handling via \csbxint{Float} +of fractions to achieve independence from the chosen representatives (which +currently only applies if numerators and denominators are of lengths at most +the target precision plus two -- the exponent is arbitrary). + +Next major release will decide if this initial rounding of the inputs is kept; +the more ambitious model would be for the basic operations to compute the +correct rounding of the value corresponding to the original inputs, whatever +their original lengths\footnote{The |MPFR| library + \url{http://www.mpfr.org/} implements this ...}, or nature\footnote{... but it + does not know fractions!}. This is definitely feasible as \xintfracname +knows how to compute exactly, but the question is how efficiently though. I +don't think that this will be the choice made. + + + + + + + -\medskip -\emph{Also the square root will provide correct rounding.} - -% http://www.cse.msu.edu/~cse320/Documents/FloatingPoint.pdf -% https://en.wikipedia.org/wiki/IEEE_floating_point -% je n'ai pas cherché beaucoup mais je n'ai pas vu de lien gratuit -% pour récupérer IEEE 754-2008. Mais je l'avais peut-être déjà récupéré il y a -% quelques mois. - - -The other float operations produce a value from which the exact result differs -by at most \dtt{0.6} ``units in the last place'' (of the significand of the -returned value). Thus the last digit may be wrong by at most one unit -(compared to the exact rounding of the exact theoretical value), but if it is -$0$ or $9$ also with it the next to last digit, etc... some macros may achieve -higher precision, check their documentations. Notice in particular that the -routines will return a zero value only if the theoretical exact evaluation -would have produced also zero (but as mentioned above a computation leading to -a floating point underflow or floating point overflow will at some point -inevitably raise a low-level \eTeX{} arithmetic overflow error). - -What happens for inputs having more than \dtt{P} digits ? it is not the same -to correctly round a theoretical exact value obtained from the exact inputs or -correctly round the theoretical exact result obtained from rounded inputs. Up -to release |v1.2b| (\emph{|1.2e| hasn't changed anything yet.}), the four -basic operations first rounded the inputs to \dtt{P+2} digits of precision. -The power operation |A^B| first rounded |A| to a number of digits equal to the -precision \dtt{P} plus a certain quantity depending on the exponent |B|, for -example for squaring this gave a first rounding to \dtt{P+3} digits of -precision. But this meant that in some rare cases |x*x| or |x^2| could produce -slightly different values. - -For example consider \leftedline{\dtt{x=1.772453850905516665}} which has 19 -digits. We want its square correctly rounded to 16 digits. The exact value is -\leftedline{1.772453850905516665\string^2=3.141592653589795499056780930592722225} -whose rounding to 16 -digits is \dtt{3.141592653589795}. But if we first round |x| to 18 digits, and -square, this gives -\leftedline{1.77245385090551667\string^2=3.1415926535897955167813194396478889} whose -rounding to 16 digits is \dtt{3.141592653589796}. - -Another example of a similar type (such examples are the exception rather than -the rule, but are not especially hard to find, if one understands where to -look): with \leftedline{\dtt{x=18587988557251906450}} which has 20 digits, we -compute |1/x| correctly rounded to 16 digits of precision, but after rounding -first |x| to either 20 (no alteration), 18, or 16 digits (and trailing -zeroes). We obtain: -\begin{everbatim} -(1/x) rounded to 16 digits=5.379818246175220e-20 % original x - =5.379818246175219e-20 % x was rounded to 18 digits - =5.379818246175218e-20 % x was rounded to 16 digits -\end{everbatim} -We got three distinct results. - -These examples are connected with the \emph{table-maker dilemma}: rounding to -\dtt{P} digits a value rounded to \dtt{Q} digits is not necessarily the same -as rounding directly to \dtt{P} digits. - -This impacted also how \xintfracname implemented the handling by macros of -fractional inputs |A/B|. If we were to first round |A| and |B| to some -precision \dtt{Q}, and then correctly round the fraction to precision \dtt{P}, -the process could give different results for inputs |A/B| and |A'/B'| -representing the same rational number. As \xintfracname treats exactly -fractions, this would create a very disquieting situation. Consider for -example the fraction: -\leftedline{1/1858798855725191=5379818246175218/\xintiiMul{1858798855725191}{5379818246175218}} -We mentioned already that the exact rounding to 16 digits is -\dtt{5.379818246175218e-16}. If however we treat the right hand side by first -rounding numerator and denominator to 16 digits, we are evaluating -\leftedline{5379818246175218/9999999999999999e15=\xintTrunc{24}{5379818246175218/9999999999999999}\dots - e-15} and the result rounded to 16 digits is \dtt{5.379818246175219e-16}. - -Thus, the float macros of \xintfracname have always treated fractional inputs -|A/B| \emph{exactly}, not doing any a priori rounding of numerator and -denominator, but rounding the \emph{exact} fraction before further treatment -(as stated above the basic operations up to now (|v1.2e|) have always done this -initial rounding of the inputs with \dtt{P+2} digits of kept precision). The -possible alternative could have been to systematically first reduce |A/B| to -smallest terms, then round numerator and denominator, but this was not the -choice made, as it raises issues of efficiency and accuracy. - -In an \emph{expression} however \dtt{/} is an operator and if the parser sees -|A/B|, the arguments |A| and |B| will be treated as separate inputs and be -rounded separately first, before division; to avoid that one may -code |\xintexpr A/B\relax| inside the \csbxint{thefloatexpr}|...\relax|, or, -since |v1.2|, use the |qfloat(A/B)| syntax. \subsection{Expansion matters} @@ -4007,10 +3859,10 @@ which are \emph{not} expandable.% % For example, something like \begin{everbatim} -\setcounter{Foo}{\count0=\Bar\relax \multiply\count0 by 2 +\setcounter{Foo}{\count0=\Bar\relax \multiply\count0 by 2 \advance\count0 by 15 \the\count0 } \end{everbatim} -although not creating errors produces only non-sense. +although not creating errors produces only non-sense. Since 1999, \eTeX{} has extended \TeX{} with expandable arithmetic. Thus nowadays% @@ -4069,7 +3921,7 @@ conventions this will be signaled by a% % \ntype{{\setbox0 \hbox{\Ff}\hbox to \wd0 {\hss f\hss}}} % -margin annotation next to the description of the arguments. +margin annotation next to the description of the arguments. \subsubsection{Summary of important expandability aspects} @@ -4079,7 +3931,7 @@ margin annotation next to the description of the arguments. un-expandable such as a\strut{} digit or a brace is hit against. This example % - \leftedline{|\def\x{98765}\def\y{43210}| |\xintiiAdd {\x}{\x\y}|} + \leftedline{|\def\x{98765}\def\y{43210}| |\xintiiAdd {\x}{\x\y}|} % is \emph{not} a legal construct, as the |\y| will remain untouched by expansion and not get converted into the digits which are expected by the @@ -4136,7 +3988,7 @@ margin annotation next to the description of the arguments. \def\x {12}% \def\AplusBC #1#2#3{\xintAdd {#1}{\xintMul {#2}{#3}}}% -\item \label{item:xpxp} With the definition +\item \label{item:xpxp} With the definition % \leftedline{|\def\AplusBC #1#2#3{\xintAdd {#1}{\xintMul {#2}{#3}}}|} % @@ -4156,7 +4008,7 @@ one obtains an \leftedline {|\def\AplusBC #1#2#3{\romannumeral-`0\xintAdd {#1}{\xintMul {#2}{#3}}}|} % -or use the \emph{lowercase} form of \csa{xintAdd}: +or use the \emph{lowercase} form of \csa{xintAdd}: % \smallskip % @@ -4174,7 +4026,7 @@ arbitrarily the package macros, and the new ones will be completely expandable and usable one within the other. Since release |1.07| the \csbxint{NewExpr} command automatizes the creation of -such expandable macros: +such expandable macros: % \leftedline{|\xintNewExpr\AplusBC[3]{#1+#2*#3}|} % @@ -4228,7 +4080,6 @@ variants: \subsection{User interface} \label{ssec:userinterface} -%{\etocdefaultlines\etocsettocstyle{}{}\localtableofcontents} The next sections will explain the various inputs which are recognized by the package macros and the format for their outputs. Inputs have mainly five @@ -4265,7 +4116,6 @@ Outputs are mostly of the following types: \subsection{No declaration of variables for macros} -%\begin{framed} There is no notion of a \emph{declaration of a variable}, which would be needed to use the arithmetic macros.% @@ -4277,7 +4127,7 @@ Outputs are mostly of the following types: \def\x{1729728} \def\y{352827927} \edef\z{\xintiiMul {\x}{\y}} \meaning\z \end{everbatim*} - + As an alternative to |\edef| the package provides |\oodef| which expands exactly twice the replacement text, and |\fdef| which applies \fexpan sion to the replacement text during the definition. @@ -4290,7 +4140,6 @@ In practice |\oodef| is slower than |\edef|, except for computations ending in very big final replacement texts (thousands of digits). On the other hand |\fdef|\IMPORTANT{} appears to be slightly faster than |\edef| already in the case of expansions leading to only a few dozen digits. -%\end{framed} \xintexprname does provide an interface to declare and assign values to identifiers which can then be used in expressions: \autoref{xintdefvar}. @@ -4370,8 +4219,8 @@ the allowed input formats for `long numbers' and `fractions' are: each of |A|, |B|, |N| (but then not |/| or |[|) may arise from \fexpan sion, |A| (after expansion) \emph{must} have a unique optional minus sign and no leading zeroes, |B| (after expansion) if present \emph{must} be a - positive integer with no signs and no leading zeroes, |N| (which may be - empty) will be given to |\numexpr|. This format is parsed with smaller + positive integer with no signs and no leading zeroes, |[N]| if present + will be given to |\numexpr|. This format is parsed with smaller overhead than the general one, thus allowing more efficient nesting of macros as it is the one used on output (except for the floating macros). Any deviation from the rules above will result in errors.\footnote{With @@ -4380,7 +4229,7 @@ the allowed input formats for `long numbers' and `fractions' are: |\numexpr|.} \end{description} Notice that |*|, |+| and |-| contrarily to the |/| (which is treated simply - as a kind of delimiter) are not acceptable within arguments of this + as a kind of delimiter) are not acceptable within arguments of this type\ntype{\Ff} (see however \autoref{sec:useofcount} for some exceptions). @@ -4389,8 +4238,8 @@ the allowed input formats for `long numbers' and `fractions' are: expansion, recognizes decimal and scientific numbers, and is described in \autoref{ssec:syntax}.% % -\footnote{The isolated dot |"."| is not legal anymore\MyMarginNote{Changed!} in expressions with - release |1.2|: there must be digits either before or after.} + \footnote{Starting with release |1.2|, the isolated dot |"."| is not legal + anymore in expressions: there must be digits either before or after.} \end{enumerate} Generally speaking, there should be no spaces among the digits in the inputs @@ -4398,10 +4247,10 @@ Generally speaking, there should be no spaces among the digits in the inputs macros, there are some cases where spaces could break havoc.% \footnote{The \csbxint{Num} macro does not remove spaces between digits beyond the first non zero ones; however this should not really alter the subsequent - functioning of the arithmetic macros, and besides, since \xintcorename v1.2 + functioning of the arithmetic macros, and besides, since \xintcorename 1.2 there is an initial parsing of the entire number, during which spaces will be gobbled. However I have not done a complete review of the legacy code to - be certain of all possibilities after |v1.2| release. One thing to be aware + be certain of all possibilities after |1.2| release. One thing to be aware of is that \csa{numexpr} stops on spaces between digits (although it provokes an expansion to see if an infix operator follows); the exponent for \csbxint{iiPow} or the argument of the factorial \csbxint{iFac} are only @@ -4417,10 +4266,6 @@ macros, there are some cases where spaces could break havoc.% \csa{numexpr}. Thus in conclusion, damages due to spaces are unlikely if only explicit digits are involved in the inputs, or arguments are single macros with no preceding space.} -% -% j'avais oublié que mon |...| savait gérer les \ dans les footnote pas besoin -% de \char92 ou autre! -% So the best is to avoid them entirely. This is entirely otherwise inside an |\xintexpr|-ession, where spaces are @@ -4498,7 +4343,7 @@ The output will be an integer. |(A/B)|$\times$|10^n|) where |A| and |B| are integers, with |B| positive, and |n| is a ``short'' integer (\emph{i.e} less in absolute value than \dtt{\number"7FFFFFFF}.) - + The output fraction is not reduced to smallest terms. The |A| and |B| may end in zeroes (\emph{i.e}, |n| does not represent all powers of ten). The denominator |B| is always strictly positive. There is no |+| sign on output @@ -4546,7 +4391,6 @@ $\xintIrr{273.3734e5/3395.7200e-2}$ \end{itemize} -%\subsection{Multiple outputs}\label{sec:multout} Some macros return a token list of two or more numbers or fractions; they are then each enclosed in braces. Examples are \csbxint{iiDivision} which gives @@ -4564,9 +4408,7 @@ Another type of multiple number output is when using commas inside This returns a comma separated list, with a space after each comma. -% \section{Use of \TeX{} registers and variables} -% {\etocdefaultlines\etocsettocstyle{}{}\localtableofcontents} \subsection{Use of count registers}\label{sec:useofcount} @@ -4603,7 +4445,7 @@ to have as argument an algebraic expression as would be acceptable by a in the input it will not get expanded, and braces around the name will be removed and chaos\IMPORTANT{} will ensue inside a \csa{numexpr}. One should enclose the whole input in \csa{the}\csa{numexpr}|...|\csa{relax} in such - cases.} + cases.} % The slash for rounded division in a |\numexpr| should be written with braces |{/}| to not be confused with the \xintfracname delimiter between @@ -4614,7 +4456,7 @@ maximal allowed number of tokens (the braced slash counts for only one). % \leftedline{|\cnta 10 \cntb 35 \xintRaw {\cnta+\cntb{/}17/1+\cnta*\cntb}|\dtt{->\cnta 10 \cntb 35 \xintRaw - {\cnta+\cntb{/}17/1+\cnta*\cntb}}} + {\cnta+\cntb{/}17/1+\cnta*\cntb}}} % For longer algebraic expressions using count registers, there are two possibilities: @@ -4672,8 +4514,6 @@ For example a millimeter exact value in terms of |sp| units is thus appears that \TeX{} truncates to get an integral multiple of the |sp| unit). -% impossible avec le \ignorespaces mis par LaTeX de faire \number\dimexpr -% idem à la fin avec \unskip, si je veux xinttheexpr \begin{figure*}[ht!] \phantomsection\label{tableofdimensions} \begingroup\let\ignorespaces\empty @@ -4765,11 +4605,11 @@ integral number of |sp|'s. Let us now use |\xintexpr| to compute the value of the Didot point in millimeters, if -the above rule is exactly verified: +the above rule is exactly verified: % \leftedline{|\xinttheexpr trunc(1238/1157*25.4/72.27,12)\relax|% - \dtt{=\xinttheexpr trunc(1238/1157*25.4/72.27,12)\relax}|...mm|} + \dtt{=\xinttheexpr trunc(1238/1157*25.4/72.27,12)\relax}|...mm|} % This fits very well with the possible values of the Didot point as listed in the @@ -4784,7 +4624,7 @@ The actual value in millimeters of exactly one Didot point as implemented in \TeX{} is % \leftedline {|\xinttheexpr trunc(\dimexpr - 1dd\relax/65536/72.27*25.4,12)\relax|} + 1dd\relax/65536/72.27*25.4,12)\relax|} % \leftedline{\dtt{=\xinttheexpr trunc(\dimexpr 1dd\relax/65536/72.27*25.4,12)\relax}|...mm|} @@ -4803,26 +4643,7 @@ and the centered convergents of this fraction are \xintFor* #1 in {\xintFtoCCv{543564351/508000000}}\do {\dtt{\printnumber{#1}}\xintifForLast{.}{, }} We do recover the $1238/1157$ therein! -% As a final comment on the \hyperref[tableofdimensions]{table of dimensions}, we -% conclude that the ``Relative Error'' column is misleading as these relative -% errors by necessity decrease for integer multiples of the given dimension units. -% This was already indicated by the \textbf{72bp} row. -% To conclude our comments on the -% \hyperref[tableofdimensions]{table of dimensions}, the big point, now known as -% \emph{Desktop Publishing Point} is less accurately implemented in \TeX{} than -% other units. Let us test for example the relation $1$\,|in|$=72$\,|bp|, the difference is -% % -% \centeredline{|\number\numexpr\dimexpr1in\relax-72*\dimexpr1bp\relax\relax|% -% \dtt{=\number\numexpr\dimexpr1in\relax-72*\dimexpr1bp\relax\relax}\,|sp|} -% \centeredline{|\number\dimexpr1in-72bp\relax|% -% \dtt{=\number\dimexpr1in-72bp\relax}\,|sp|} -% on the other hand -% \centeredline{|\xinttheexpr reduce(\dimexpr1in\relax-72.27*\dimexpr1pt\relax)\relax|} -% \centeredline -% \dtt{=\xinttheexpr reduce(\dimexpr1in\relax-72.27*\dimexpr1pt\relax)\relax}\,|sp|=$-0.72$\,|sp|} -% \centeredline -% {\dtt{=\number\dimexpr1in-72.27pt\relax}\,|sp|=$-0.72$\,|sp|} \subsection{\csh{ifcase}, \csh{ifnum}, ... constructs}\label{sec:ifcase} @@ -4872,7 +4693,7 @@ do with |\numexpr| to compute multiple things at once. See \autoref{ssec:fibonacci} for an example devoted to Fibonacci numbers (this section provides the code which was used on the title page for the \dtt{$F(1250)$} evaluation.) Notice that the $47$th Fibonacci number is -\dtt{\Fibonacci {47}} thus already too big for \TeX{} and \eTeX{}. +\dtt{\Fibonacci {47}} thus already too big for \TeX{} and \eTeX{}. The |\Fibonacci| macro found in \autoref{ssec:fibonacci} is completely expandable, (it is even \fexpan dable in the sense previously explained) hence @@ -4902,7 +4723,7 @@ which outputs: The |\Fibonacci| macro expanded its |\xintiiGCD{1859}{1573}| argument via the services of |\numexpr|: this step allows only things obeying the \TeX{} bound, -naturally! (but \dtt{F(\xintiiPow2{31}}) would be rather big anyhow...). +naturally! (but \dtt{F(\xintiiPow2{31}}) would be rather big anyhow...). In practice, whenever one typesets things, one has left the expansion only contexts; hence there is no objection to, on the contrary it is recommended, @@ -4957,15 +4778,6 @@ others are more annoying as they may pass through unsignaled. restriction, the two inputs |1.5/-3.5e-2| and |-1.5e2/3.5| are equivalent: |\xintRaw{1.5/-3.5e-2}|\dtt{=\xintRaw{1.5/-3.5e-2}}, |\xintRaw{-1.5e2/3.5}|\dtt{=\xintRaw{-1.5e2/3.5}}. -% \item specifying numerators and -% denominators with macros producing fractions when \xintfracname is loaded: -% |\edef\x{|\allowbreak|\xintMul {3}{5}/\xintMul{7}{9}}|. This expands to -% \texttt{\x} which is -% invalid on input. Using this |\x| in a fraction macro will most certainly -% cause a compilation error, with its usual arcane and undecipherable -% accompanying message. The fix here would be to use |\xintiMul|. The simpler -% alternative with package \xintexprname: -% |\xinttheexpr 3*5/(7*9)\relax|. \item generally speaking, using in a context expecting an integer (possibly restricted to the \TeX{} bound) a macro or expression which returns a fraction: |\xinttheexpr 4/2\relax| outputs \dtt{\xinttheexpr 4/2\relax}, @@ -4973,9 +4785,6 @@ others are more annoying as they may pass through unsignaled. (which rounds the result to the nearest integer, here, the result is already an integer) or |\xinttheiiexpr 4/2\relax|. Or, divide in your head |4| by |2| and insert the result directly in the \TeX{} source. -% trop technique -% \item use of square brackets |[|, |]| in |\xintexpr...\name| has some traps, see -% \autoref{sec:expr}. \end{itemize} \subsection{Error messages} @@ -4990,21 +4799,18 @@ token stream, after completion of the operation. Generally the problematic operation will output a zero. Possible such error message control sequences: -% \the\parskip\par % attention 0pt plus 1pt \begin{multicols}{2}\parskip0pt\relax \begin{everbatim} \xintError:ArrayIndexIsNegative \xintError:ArrayIndexBeyondLimit -\xintError:FactorialOfNegativeNumber -\xintError:FactorialOfTooBigNumber +\xintError:FactorialOfNegative +\xintError:TooBigFactorial \xintError:DivisionByZero \xintError:NaN \xintError:FractionRoundedToZero \xintError:NotAnInteger \xintError:ExponentTooBig -\xintError:TooBigDecimalShift -\xintError:TooBigDecimalSplit \xintError:RootOfNegative \xintError:NoBezoutForZeros \xintError:ignored @@ -5015,16 +4821,7 @@ sequences: \xintError:missing_xintthe! \end{everbatim} \end{multicols} -% NOTES 12 octobre 2014 -% J'ai voulu faire avec verbatim, mais bizarrement il met dans la -% colonne de gauche 10 et 8 dans celle de droite. Je n'ai pas réussi à -% reproduire le problème sur un MWE, en tout cas un exemple naïf ne -% reproduit pas le problème. Ensuite avec \everb c'est beaucoup mieux -% mais j'ai dû mettre \raggedcolumns. J'ai essayé avec \strut. Ah, mais -% le problème c'est \parskip. -% par ailleurs il y a trop d'espace vertical avant le multicols, mais -% bon. There are now a few more if for example one attempts to use |\xintAdd| without having loaded \xintfracname (with only \xintname loaded, only |\xintiAdd| and @@ -5052,7 +4849,7 @@ having loaded \xintfracname (with only \xintname loaded, only |\xintiAdd| and Don't forget to set |\errorcontextlines| to at least |2| to get from \LaTeX\ more meaningful error messages. Errors occuring during the parsing of |\xintexpr-essions| try to provide helpful information about the offending -token. +token. Release |1.1| employs in some situations delimited macros and there is the possibility in case of an ill-formed expression to end up beyond the @@ -5063,7 +4860,6 @@ daring experienced \TeX/\LaTeX\ user. \subsection{Package namespace, catcodes} -% note: v1.2 définit \m@ne si ce count n'existe pas. The bundle packages needs that the \csa{space} and \csa{empty} control sequences are pre-defined with the identical meanings as in Plain \TeX{} or @@ -5087,7 +4883,7 @@ For the good functioning of the macros, standard catcodes are assumed for the minus sign, the forward slash, the square brackets, the letter `e'. These requirements are dropped inside an |\xintexpr|-ession: spaces are gobbled, catcodes mostly do not matter, the |e| of scientific notation may be |E| (on -input) \dots{} +input) \dots{} If a character used in the |\xintexpr| syntax is made active, this will surely cause problems; prefixing it with |\string| is one option. @@ -5103,6 +4899,185 @@ un-expandable action). other and letters have category code letter. Nothing else is assumed. \end{framed} + +\subsection{Origins of the package} + +|2013/03/28.| Package |bigintcalc| by \textsc{Heiko Oberdiek} already +provides expandable arithmetic operations on ``big integers'', +exceeding the \TeX{} limits (of $2^{31}-1$), so why another% +% +\footnote{this section was written before the \xintfracname package; the + author is not aware of another package allowing expandable + computations with arbitrarily big fractions.} +% +one? + +I got started on this in early March 2013, via a thread on the +|c.t.tex| usenet group, where \textsc{Ulrich D\,i\,e\,z} used the +previously cited package together with a macro (|\ReverseOrder|) +which I had contributed to another thread.% +% +\footnote{the \csa{ReverseOrder} could be avoided in that circumstance, + but it does play a crucial r\^ole here.} +% +What I had learned in this +other thread thanks to interaction with \textsc{Ulrich D\,i\,e\,z} and +\textsc{GL} on expandable manipulations of tokens motivated me to +try my hands at addition and multiplication. + +I wrote macros \csa{bigMul} and \csa{bigAdd} which I posted to the +newsgroup; they appeared to work comparatively fast. These first +versions did not use the \eTeX{} \csa{numexpr} primitive, they worked +one digit at a time, having previously stored carry-arithmetic in +1200 macros. + +I noticed that the |bigintcalc| package used \csa{numexpr} +if available, but (as far as I could tell) not +to do computations many digits at a time. Using \csa{numexpr} for +one digit at a time for \csa{bigAdd} and \csa{bigMul} slowed them +a tiny bit but avoided cluttering \TeX{} memory with the 1200 +macros storing pre-computed digit arithmetic. I wondered if some speed +could be gained by using \csa{numexpr} to do four digits at a time +for elementary multiplications (as the maximal admissible number +for \csa{numexpr} has ten digits). + +|2013/04/14|. This initial \xintname was followed by \xintfracname which +handled exactly fractions and decimal numbers. + +|2013/05/25|. Later came \xintexprname and at the same time \xintfracname got +extended to handle floating point numbers. + +|2013/11/22|. Later, \xinttoolsname was detached. + +|2014/10/28|. Release |1.1| significantly extended the \xintexprname parsers. + +|2015/10/10|. Release |1.2| rewrote the core integer routines which had +remained essentially unmodified, apart from a slight improvement of division +early 2014. + +This |1.2| release also got its impulse from a fast +``reversing'' macro, which I wrote after my interest got awakened again as a +result of correspondance with Bruno \textsc{Le Floch} during September 2015: +this new reverse uses a \TeX nique which \emph{requires} the tokens to be +digits. I wrote a routine which works (expandably) in quasi-linear time, but a +less fancy |O(N^2)| variant which I developed concurrently proved to be faster +all the way up to perhaps $7000$ digits, thus I dropped the quasi-linear one. +The less fancy variant has the advantage that \xintname can handle numbers +with more than $19900$ digits (but not much more than $19950$). This is with +the current common values of the input save stack and maximal expansion depth: +$5000$ and $10000$ respectively. + + +\subsection{Installation instructions} +\label{ssec:install} + +\xintname is made available under the +\href{http://www.latex-project.org/lppl/lppl-1-3c.txt}{LaTeX Project Public + License 1.3c}. It is included in the major \TeX\ distributions, thus there +is probably no need for a custom install: just use the package manager to +update if necessary \xintname to the latest version available. + +After installation, issuing in terminal |texdoc --list xint|, on installations +with a |"texdoc"| or similar utility, will offer the choice to display one of +the documentation files: |xint.pdf| (this file), |sourcexint.pdf| (source +code), |README|, |README.pdf|, |README.html|, |CHANGES.pdf|, and +|CHANGES.html|. + +For manual installation, follow the instructions from the |README| file which +is to be found on \href{http://www.ctan.org/pkg/xint}{CTAN}; it is also +available there in PDF and HTML formats. The simplest method proposed is to +use the archive file \href{http://www.ctan.org/pkg/xint}{xint.tds.zip}, +downloadable from the same location. + +The next simplest one is to make use of the |Makefile|, which is also +downloadable from +\href{http://mirror.ctan.org/macros/generic/xint}{CTAN}. This is +for GNU/Linux systems and Mac OS X, and necessitates use of the command +line. If for some reason you have |xint.dtx| but no internet access, +you can recreate |Makefile| as a file with this name and the following +contents: + +{\def\everbatimindent {0pt }% +\begin{everbatim} +include Makefile.mk +Makefile.mk: xint.dtx ; etex xint.dtx +\end{everbatim}} + +Then run |make| in a working repertory where there is |xint.dtx| and the file +named |Makefile| and having only the two lines above. The |make| will extract +the package files from |xint.dtx| and display some further instructions. + +If you have |xint.dtx|, no internet access and can not use the Makefile +method: |etex xint.dtx| extracts all files and among them the |README| as a +file with name |README.md|. Further help and options will be found therein. + + +\subsection {Changes} + +The detailed cumulative change log since the initial release is in files +|CHANGES.html| (also available on \href{http://ctan.org}{CTAN} via +\href{http://mirrors.ctan.org/macros/generic/xint/CHANGES.html}{this link}) +and |CHANGES.pdf|. + +In a command line console, issue |texdoc --list xint| to access them. Or, run +|etex xint.dtx| in a working repertory which will extract a |CHANGES.md| file +with Markdown syntax. On a unix-like system you can then run |make -f +Makefile.mk CHANGES.html| to get the |html| version (requires |pandoc|). + +The last major release is |1.2 (2015/10/10)|. It came with a complete rewrite +of the core arithmetic routines. The efficiency for numbers with less than +$20$ or $30$ digits was slightly compromised (for addition/subtraction) but it +got increased for bigger numbers. For multiplication and division the gains were +there for almost all sizes, and became quite noticeable for numbers with +hundreds of digits. The allowable inputs are constrained to have less than +about $19950$ digits ($19968$ for addition, $19959$ for multiplication). + +|1.2a (2015/10/19)| to |1.2f (2016/03/12)|: unfortunately, release |1.2| had +at least four bad bugs. Subsequent releases were supposed to fix them but +sometimes they themselves introduced new bugs which had to get fixed in a +later one. For example |1.2f| fixes a bug in subtraction which was introduced +by |1.2c|'s fix of |1.2|'s subtraction. + +We managed to add some new features: + + \begin{enumerate}[noitemsep] + \item faster \csbxint{iiSquareRoot} (and allied square root macros) and + \csbxint{FloatSqrt}. The latter achieves \emph{correct rounding} in + arbitrary precision.\CHANGED{1.2f} + \item faster \csbxint{FloatPow} and + \csbxint{FloatPower}. The |^| in \csbxint{thefloatexpr}|...\relax| admits + an half-integer exponent. + \item functions |factorial|, |binomial|, |pfactorial|\NewWith{1.2f} and + associated macros \csbxint{iiBinomial}, \csbxint{FloatBinomial}, + \csbxint{iiPFactorial}, \csbxint{FloatPFactorial}. + \item \csbxint{deffunc}, \csbxint{defiifunc}, \csbxint{deffloatfunc} + macros to define functions recognized as such by the \xintexprname parsers. + \item new \csbxint{unassignvar}, new \csbxint{verbosetrue}. + \item declarations as per \csbxint{deffunc} \emph{et al.} and + macro definitions as per \csbxint{NewExpr} \emph{et al.} now with only + local scope. + \item \hyperref[ssec:tacit multiplication]{tacit multiplication} extended to + more cases and now always ``ties more'' than the regular division and + multiplication. + \item \csbxint{TrimUnbraced} and \csbxint{KeepUnbraced}. + \item more precise discussion of floating point issues in + \autoref{ssec:floatingpoint},\NewWith {1.2f} but the coverage by + \xintfracname of floating point operations is yet to be substantially + extended. + \item the float macros for addition, subtraction, multiplication, division + now first round their two operands to P significant places\CHANGED{1.2f} + (not P+2 as earlier) before doing the actual computation (P is the asked + for precision or \csbxint{theDigits}). The same applies to the float power + and square root operations. + \item extensive update to ``Commands of the \xintexprname package'' + (\autoref{sec:expr}.) + \item complete re-write of the \hyperref[ssec:quicksort]{Quick Sort + algorithm} section. + \item documentation fixes (including random shuffling around of various + sections), and more code comments, particularly in the |xintcore.sty| + section of |sourcexint.pdf|. Trimming of irrelevant old comments. + \end{enumerate} + \section{Some utilities from the \xinttoolsname package} This is a first overview. Many examples combining these utilities with the @@ -5115,14 +5090,14 @@ arithmetic macros of \xintname are to be found in \autoref{sec:tools}. It might not be necessary to maintain at all times complete expandability. A devoted syntax is provided to make these things more efficient, for example when using the \csbxint{iDivision} macro which computes both quotient and remainder -at +at the same time: % \leftedline{\csbxint{Assign} - |\xintiiDivision{\xintiiPow {2}{1000}}{\xintFac{100}}|\csbnolk{to}|\A\B|} + |\xintiiDivision{\xintiiPow {2}{1000}}{\xintiiFac{100}}|\csbnolk{to}|\A\B|} % give: -\xintAssign\xintiiDivision{\xintiPow {2}{1000}}{\xintFac{100}}\to\A\B +\xintAssign\xintiiDivision{\xintiPow {2}{1000}}{\xintiiFac{100}}\to\A\B |\meaning\A|\dtt{: \printnumber{\meaning\A}\relax} and |\meaning\B|\dtt{: \printnumber{\meaning\B}\relax}. % @@ -5130,7 +5105,7 @@ Another example (which uses \csbxint{Bezout} from the \xintgcdname package): % \leftedline{\csbxint{Assign} % - |\xintBezout{357}{323}|\csbnolk{to}|\A\B\U\V\D|} + |\xintBezout{357}{323}|\csbnolk{to}|\A\B\U\V\D|} % is equivalent to setting |\A| to \dtt{\tmpA}, |\B| to \dtt{\tmpB}, |\U| to \dtt{\tmpU}, |\V| to \dtt{\tmpV}, and |\D| to \dtt{\tmpD}. And indeed @@ -5242,21 +5217,6 @@ access to an iteration index, without using count registers which would break expandability. Check it out (\autoref{xintiloop}). -% Lundi 06 octobre 2014 à 22:02:44 -% je décide de ne plus inclure le README verbatim -% \begingroup -% \makeatletter\def\x{\baselineskip10pt -% \ttfamily -% %\settowidth\dimen@{X}% -% %\parindent \dimexpr.5\linewidth-33\dimen@\relax -% \parindent\z@ -% \let\do\do@noligs\verbatim@nolig@list -% \let\do\@makeother\dospecials -% \def\par{\leavevmode \null\@@par\penalty\interlinepenalty}% -% \makestarlowast -% \@vobeyspaces\obeylines -% \noindent\kern\parindent\input README.md -% \endgroup }\x \etocdepthtag.toc {commands} \indescriptionfalse @@ -5264,7 +5224,7 @@ expandability. Check it out (\autoref{xintiloop}). \renewcommand{\etocaftertochook}{\addvspace{\bigskipamount}} - +\clearpage \section{Commands of the \xintkernelname package} \label{sec:kernel} @@ -5310,12 +5270,6 @@ them). There is a similar macro |\odef| with only one expansion of the replacement text |<stuff>|, and |\fdef| which expands fully |<stuff>| using |\romannumeral-`0|. -% These tools are provided as it is sometimes wasteful (from the point of view -% of running time) to do an |\edef| when one knows that the contents expand in -% only two steps for example, as is the case with all (except \csbxint{loop} -% and \csbxint{iloop}) the expandable macros of the \xintname packages. Each -% will be defined only if \xintkernelname finds them currently undefined. - They can be prefixed with |\global|. It appears than |\fdef| is generally a bit faster than |\edef| when expanding macros from the \xintname bundle, when the result has a few dozens of digits. |\oodef| needs thousands of digits it seems @@ -5350,6 +5304,7 @@ variant which first \fexpan ds its argument. \leftedline{${}\neq{}$|\xintLen {\xintiPow {2}{100}}|\dtt{=\xintLen {\xintiPow{2}{100}}}} +\clearpage \section{Commands of the \xinttoolsname package} \label{sec:tools} @@ -5400,7 +5355,7 @@ thus be macros one does not want to expand. % \leftedline{|\edef\y{\xintRevWithBraces\x}|} % -\leftedline{|\meaning\y:|\dtt{\meaning\y}} +\leftedline{|\meaning\y:|\dtt{\meaning\y}} % The examples above could be defined with |\edef|'s because the braced material did not contain macros. Alternatively: @@ -5409,7 +5364,7 @@ did not contain macros. Alternatively: % \leftedline{|{\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}}|} % -\leftedline{|\meaning\w:|\dtt{\meaning\w}} +\leftedline{|\meaning\w:|\dtt{\meaning\w}} % The macro \csa{xintReverseWithBracesNoExpand}\etype{n} does the same job without the initial expansion of its argument. @@ -5461,7 +5416,7 @@ its argument, nor brace removal of any sort, nor does it alter \meta{stuff} in anyway apart from stripping away all \emph{ending} spaces. The same remarks as for \csbxint{ZapFirstSpaces} apply. -% ATTENTION à l'\ignorespaces fait par \color! +% ATTENTION à l'\ignorespaces fait par \color! \begingroup \def\x { \a { \X } { \b \Y } } % @@ -5515,8 +5470,6 @@ all leading and all ending spaces and possibly removing one level of braces if \label{xintCSVtoList} \label{xintCSVtoListNoExpand} -% {\small New with release |1.06|. Starting with |1.09f|, \fbox{\emph{removes -% spaces around commas}!}\par} \csa{xintCSVtoList}|{a,b,c...,z}|\etype{f} returns |{a}{b}{c}...{z}|. A \emph{list} is by @@ -5527,7 +5480,7 @@ as for \LaTeX{} and command arguments [they are the same things]). The word `list' in `comma separated list of items' has its usual linguistic meaning, and then an ``item'' is what is delimited by commas. -So \csa{xintCSVtoList} takes on input a `comma separated list of items' and +So \csa{xintCSVtoList} takes on input a `comma separated list of items' and converts it into a `\TeX{} list of braced items'. The argument to |\xintCSVtoList| may be a macro: it will first be \hyperref[ssec:expansions]{\fexpan ded}. Hence the item before the first comma, @@ -5625,7 +5578,7 @@ the input). \leftedline{|\def\y{ \a,\b,\c,\d,\e} \xintCSVtoList\y->|% {\makeatletter\dtt{\expandafter\strip@prefix\meaning\Y}}} % -\leftedline{|\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} +\leftedline{|\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} % \leftedline {|\xintCSVtoList\t->|\makeatletter\dtt{\expandafter\strip@prefix\meaning\T}} @@ -5644,8 +5597,6 @@ may have direct use: % \leftedline{|\xintCSVtoListNoExpand {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} % -% ATTENTION 18 novembre TEST DE newtxtt 1.05 PAS POSSIBLE \textsc DANS \dtt -% mais on peut avec \scshape. Finalement je n'utilise pas les old style figures. \leftedline{|->|\dtt{\expandafter\detokenize\expandafter {\romannumeral0\xintcsvtolistnoexpand {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}}}} @@ -5664,7 +5615,6 @@ without removal of spaces around the commas, there is \subsection{\csbh{xintNthElt}}\label{xintNthElt} -% {\small New in release |1.06|. With |1.09b| negative indices count from the tail.\par} \def\macro #1{\the\numexpr 9-#1\relax} @@ -5685,14 +5635,14 @@ itself may be a macro which is first \fexpan ded. \detokenize\expandafter\expandafter\expandafter {\xintNthElt {2}{{agh}\u{{zzz}}\v{Z}}}}} % -\leftedline{|\xintNthElt {37}{\xintFac {100}}|\dtt{=\xintNthElt - {37}{\xintFac {100}}} is the thirty-seventh digit of $100!$.} +\leftedline{|\xintNthElt {37}{\xintiiFac {100}}|\dtt{=\xintNthElt + {37}{\xintiiFac {100}}} is the thirty-seventh digit of $100!$.} % \leftedline{|\xintNthElt {10}{\xintFtoCv {566827/208524}}|\dtt{=\xintNthElt {10}{\xintFtoCv {566827/208524}}}} \leftedline{is the tenth convergent of $566827/208524$ (uses \xintcfracname - package).} + package).} % \leftedline{|\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% \dtt{=\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} @@ -5807,7 +5757,6 @@ argument. \subsection{\csbh{xintListWithSep}}\label{xintListWithSep} -%{\small New with release |1.04|.\par} \def\macro #1{\the\numexpr 9-#1\relax} @@ -5822,15 +5771,14 @@ is used starting with at least two elements. Using an empty separator has the net effect of unbracing the braced items constituting the \meta{list} (in such cases the new list may thus be longer than the original). % -\leftedline{|\xintListWithSep{:}{\xintFac - {20}}|\dtt{=\xintListWithSep{:}{\xintFac {20}}}} +\leftedline{|\xintListWithSep{:}{\xintiiFac + {20}}|\dtt{=\xintListWithSep{:}{\xintiiFac {20}}}} The macro \csa{xintListWithSepNoExpand}\etype{nn} does the same job without the initial expansion. \subsection{\csbh{xintApply}}\label{xintApply} -%{\small New with release |1.04|.\par} \def\macro #1{\the\numexpr 9-#1\relax} @@ -5861,8 +5809,8 @@ the result of applying |\macro| on it. % \leftedline{|\def\macro #1{\the\numexpr 9-#1\relax}|} % % -\leftedline{|\xintApply\macro{\xintFac - {20}}|\dtt{=\xintApply\macro{\xintFac {20}}}} +\leftedline{|\xintApply\macro{\xintiiFac + {20}}|\dtt{=\xintApply\macro{\xintiiFac {20}}}} The macro \csa{xintApplyNoExpand}\etype{fn} does the same job without the first initial expansion which gave the \meta{list} of braced tokens to which |\macro| @@ -5870,7 +5818,6 @@ is applied. \subsection{\csbh{xintApplyUnbraced}}\label{xintApplyUnbraced} -%{\small New in release |1.06b|.\par} \csa{xintApplyUnbraced}|{\macro}|\marg{list}\etype{ff} is like \csbxint{Apply}. The difference is that after having expanded its list argument, and applied @@ -5897,25 +5844,19 @@ the first initial expansion which gave the \meta{list} of braced tokens to which |\macro| is applied. \subsection{\csbh{xintSeq}}\label{xintSeq} -%{\small New with release |1.09c|.\par} \csa{xintSeq}|[d]{x}{y}|\etype{{{\upshape[\numx]}}\numx\numx} generates -expandably |{x}{x+d}...| up to and possibly including |{y}| if |d>0| or -down to and including |{y}| if |d<0|. Naturally |{y}| is omitted if -|y-x| is not a multiple of |d|. If |d=0| the macro returns |{x}|. If -|y-x| and |d| have opposite signs, the macro returns nothing. If the -optional argument |d| is omitted it is taken to be the sign of |y-x| -(beware that |\xintSeq {1}{0}| is thus not empty but |{1}{0}|, use -|\xintSeq [1]{1}{N}| if you want an empty sequence for |N| zero or -negative). - -The current implementation is only for (short) integers; possibly, a future -variant could allow big integers and fractions, although one already has -access to similar -functionality using \csbxint{Apply} to get any arithmetic sequence of long -integers. Currently thus, |x| and |y| are expanded inside a -|\numexpr| so they may be count registers or a \LaTeX{} |\value{countername}|, -or arithmetic with such things. +expandably |{x}{x+d}...| up to and possibly including |{y}| if |d>0| or down +to and including |{y}| if |d<0|. Naturally |{y}| is omitted if |y-x| is not a +multiple of |d|. If |d=0| the macro returns |{x}|. If |y-x| and |d| have +opposite signs, the macro returns nothing. If the optional argument |d| is +omitted it is taken to be the sign of |y-x|. Hence |\xintSeq {1}{0}| is not +empty but |{1}{0}|. But |\xintSeq [1]{1}{0}| is empty. + + +The arguments |x| and |y| are expanded inside a |\numexpr| so they may be +count registers or a \LaTeX{} |\value{countername}|, or arithmetic with such +things. % \begin{everbatim*} @@ -5926,27 +5867,13 @@ or arithmetic with such things. \xintiiSum{\xintSeq [3]{1}{1000}} \end{everbatim*} -\textbf{Important:} for reasons of efficiency, this macro, when not given the -optional argument |d|, works backwards, leaving in the token stream the already -constructed integers, from the tail down (or up). But this will provoke a -failure of \IMPORTANT{} the |tex| run if the number of such items exceeds the -input stack -limit; on my installation this limit is at $5000$. +When the macro is used without the optional argument |d|, it can only generate +up to about $5000$ numbers\IMPORTANT, the precise value depends upon some +\TeX{} memory parameter (input save stack). -However, when given the optional argument |d| (which may be $+1$ or -$-1$), the macro proceeds differently and does not put stress on the input stack -(but is significantly slower for sequences with thousands of integers, -especially if they are somewhat big). For -example: |\xintSeq [1]{0}{5000}| works and |\xintiiSum{\xintSeq [1]{0}{5000}}| -returns the correct value \dtt{\xintHalf{\xintiMul{5000}{5001}}}. +With the optional argument |d| the macro proceeds differently (but less +efficiently) and does not stress the input save stack. -The produced integers are with explicit litteral digits, so if used in |\ifnum| -or other tests they should be properly terminated% -% -\footnote{a \csa{space} will - stop the \TeX{} scanning of a number and be gobbled in the process, - maintaining expandability if this is required; the \csa{relax} stops the - scanning but is not gobbled and remains afterwards as a token.}. \subsection{Completely expandable prime test}\label{ssec:primesI} @@ -5979,7 +5906,6 @@ We used the \xintname provided expandable tests (on big integers or fractions) in oder for |\IsPrime| to be \fexpan dable. Our integers are short, but without |\expandafter|'s with -%\makeatletter|\@firstoftwo|\catcode`@ \active, |\@firstoftwo|, % @ n'est plus actif dans le dtx 1.1 ! or some other related techniques, direct use of |\ifnum..\fi| tests is dangerous. So to make the macro more @@ -6044,12 +5970,6 @@ breaking expandability. The \hyperref[ssec:primesII]{xintiloop variant} does not first evaluate the integer square root, the \hyperref[ssec:primesIII]{xintFor variant} still does. I did not compare their efficiencies. -% Hmm, if one really needs to compute primes fast, sure I do applaud using -% \xintname, but, well, there is some slight -% overhead\MyMarginNoteWithBrace{funny private joke} in using \TeX{} for these -% things (something like a factor $1000$? not tested\dots) compared to accessing -% to the |CPU| ressources via standard compiled code from a standard programming -% language\dots Let us construct with this expandable primality test a table of the prime numbers up to $1000$. We need to count how many we have in order to know how @@ -6147,8 +6067,6 @@ $168$). \label{xintbreakloop} \label{xintbreakloopanddo} \label{xintloopskiptonext} -% {\small New with release |1.09g|. Release |1.09h| -% makes them long macros.\par} |\xintloop|\meta{stuff}|\if<test>...\repeat|\retype{} is an expandable loop compatible with nesting. However to break out of the loop one almost always need @@ -6202,7 +6120,6 @@ illustrate use of the nesting capabilities of |\xintloop|.% November 11, 2013.} % -%\def\everbhook {\makeatother } \begin{everbatim*} \newcount\rowmax \newcount\colmax \newcount\summax @@ -6249,7 +6166,7 @@ illustrate use of the nesting capabilities of |\xintloop|.% \def\B@size #1#2]{\ifx I#24\else3\fi}% 4rows, 3columns \def\B@entry #1#2{\the\numexpr #1-#2\relax}% not pre-computed... \makeatother -\MatrixMultiplication\A\B\C \MatrixMultiplication\C\C\D +\MatrixMultiplication\A\B\C \MatrixMultiplication\C\C\D \MatrixMultiplication\C\D\E \MatrixMultiplication\C\E\F \begin{multicols}2 \[\begin{pmatrix} @@ -6300,7 +6217,6 @@ illustrate use of the nesting capabilities of |\xintloop|.% \end{multicols} \end{everbatim*} -% \restoreeverbhook \subsection{\csbh{xintiloop}, \csbh{xintiloopindex}, \csbh{xintouteriloopindex}, \csbh{xintbreakiloop}, \csbh{xintbreakiloopanddo}, \csbh{xintiloopskiptonext}, @@ -6312,7 +6228,6 @@ illustrate use of the nesting capabilities of |\xintloop|.% \label{xintiloopskipandredo} \label{xintiloopindex} \label{xintouteriloopindex} -%{\small New with release |1.09g|.\par} \csa{xintiloop}|[start+delta]|\meta{stuff}|\if<test> ... \repeat|\retype{} is a completely expandable nestable loop. complete expandability depends naturally on @@ -6411,7 +6326,7 @@ list of prime numbers: \ifnum \xintiloopindex < 10999 \repeat }% \meaning\z\endgroup \end{everbatim*}and we should have taken -some steps to not have a trailing comma, but +some steps to not have a trailing comma, but the point was to show that one can do that in an |\edef|\,! See also \autoref{ssec:primesII} which extracts from this code its way of testing primality. @@ -6599,9 +6514,6 @@ The reason for some strange looking expressions is to avoid arithmetic overflow. \subsection{\csbh{xintApplyInline}}\label{xintApplyInline} -% {\small |1.09a|, enhanced in |1.09c| to be usable within alignments, and -% corrected in |1.09d| for a problem related to spaces at the very end of the -% list parameter.\par} \csa{xintApplyInline}|{\macro}|\marg{list}\ntype{o{\lowast f}} works non expandably. It applies the one-parameter |\macro| to the first element of the @@ -6690,10 +6602,6 @@ this does not work:\par \noindent But see \csbxint{For}. \subsection{\csbh{xintFor}, \csbh{xintFor*}}\label{xintFor}\label{xintFor*} -% {\small New with |1.09c|. Extended in |1.09e| (\csbxint{BreakFor}, -% \csbxint{integers}, \dots). |1.09f| version handles all macro parameters up -% to -% |#9| and removes spaces around commas.\par} \csbxint{For}\ntype{on} is a new kind of for loop. Rather than using macros for encapsulating list items, its behavior is more like a macro with parameters: @@ -6708,7 +6616,7 @@ nested loops. Here is an example: $$#9\times#1\times#3\times#2=\xintiiPrd{{#1}{#2}{#3}{#9}}$$}}}} | \noindent This example illustrates that one does not have to use |#1| as the -first one: +first one: the order is arbitrary. But each level of nesting should have its specific macro parameter. Nine levels of nesting is presumably overkill, but I did not know where it was reasonable to stop. |\par| tokens are accepted in both the comma @@ -6785,14 +6693,7 @@ which encapsulate the item in a macro expanding to that item. \edef\@thefnmark {\thefootnote} \@footnotetext{braces around single token items are optional so this is the same as \texttt{\{123456\}}.} -% \stepcounter{footnote} -% \edef\@thefnmark {\thefootnote} -% \@footnotetext{the \csa{space} will stop the \TeX{} scanning of a number and be -% gobbled in the process; the \csa{relax} stops the scanning but is not -% gobbled. Or one may do \csa{numexpr}\texttt{\#1}\csa{relax}, and then the -% \csa{relax} is gobbled.} \endgroup -%\addtocounter{Hfootnote}{2} \addtocounter{Hfootnote}{1} The macro \csbxint{Seq} which generates arithmetic sequences may only be used @@ -6855,7 +6756,7 @@ For example: \expandafter\def\expandafter\z\expandafter {\z\sep (##1,##2)} }% }% }% -\T\def\sep {\def\sep{, }}\z +\T\def\sep {\def\sep{, }}\z \end{everbatim*} Similarly when the replacement text @@ -6890,7 +6791,6 @@ finds, gobbling spaces). \subsection{\csbh{xintifForFirst}, \csbh{xintifForLast}} \label{xintifForFirst}\label{xintifForLast} -% {\small New in |1.09e|.\par} \csbxint{ifForFirst}\,\texttt{\{YES branch\}\{NO branch\}}\etype{nn} and \csbxint{ifForLast}\,\texttt{\{YES @@ -6922,7 +6822,6 @@ replacement text of the loop to update it. \subsection{ \csbh{xintBreakFor}, \csbh{xintBreakForAndDo}} \label{xintBreakFor}\label{xintBreakForAndDo} -%{\small New in |1.09e|.\par} One may immediately terminate an \csbxint{For} or \csbxint{For*} loop with \csbxint{BreakFor}. As the criterion for breaking will be decided on a @@ -6954,7 +6853,6 @@ in the next section which is devoted to ``forever'' loops. \subsection{\csbh{xintintegers}, \csbh{xintdimensions}, \csbh{xintrationals}} \label{xintegers}\label{xintintegers} \label{xintdimensions}\label{xintrationals} -%{\small New in |1.09e|.\par} If the list argument to \csbxint{For} (or \csbxint{For*}, both are equivalent in this context) is \csbxint{integers} (equivalently \csbxint{egers}) or more @@ -6994,99 +6892,10 @@ one uses \fbox{\csa{the\#1}}. The chosen representation guarantees exact incrementation with no rounding errors accumulating from converting into points at each step. -% original definitions, a bit slow. -%\def\DimToNum #1{\number\dimexpr #1\relax } -% cube -%\xintNewIExpr \FA [2] {protect(\DimToNum {#2})^3/protect(\DimToNum{#1})^2} -% square root -%\xintNewIExpr \FB [2] {sqrt (protect(\DimToNum {#2})*protect(\DimToNum {#1}))} -%\xintNewExpr \Ratio [2] {trunc(protect(\DimToNum {#2})/protect(\DimToNum{#1}),3)} -% improved faster code (4 four times faster) -\def\DimToNum #1{\the\numexpr \dimexpr#1\relax/10000\relax } -\def\FA #1#2{\xintDSH{-4}{\xintiQuo {\xintiPow {\DimToNum {#2}}{3}}{\xintiSqr -{\DimToNum{#1}}}}} -\def\FB #1#2{\xintDSH {-4}{\xintiSqrt - {\xintiMul {\DimToNum {#2}}{\DimToNum{#1}}}}} -\def\Ratio #1#2{\xintTrunc {2}{\DimToNum {#2}/\DimToNum{#1}}} -% a further 2.5 gain is made through using .25pt as horizontal step. -\begin{figure*}[ht!] -\phantomsection\hypertarget{graphic}{}% -\centeredline{% -\raisebox{-1cm}{\xintFor #1 in {\xintdimensions [0pt+.25pt]} \do - {\ifdim #1>2cm \expandafter\xintBreakFor\fi - {\color [rgb]{\Ratio {2cm}{#1},0,0}% - \vrule width .25pt height \FB {2cm}{#1}sp depth -\FA {2cm}{#1}sp }% - }% end of For iterated text -}% -\hspace{.5cm}% -\scriptsize\baselineskip8pt\relax -\begin{minipage}{\dimexpr\linewidth-2.5cm-\parindent\relax}\def\everbatimindent{0pt }% -\begin{everbatim} -\def\DimToNum #1{\number\dimexpr #1\relax } -\xintNewIExpr \FA [2] {protect(\DimToNum {#2})^3/protect(\DimToNum{#1})^2} %cube -\xintNewIExpr \FB [2] {sqrt (protect(\DimToNum {#2})*protect(\DimToNum {#1}))} %sqrt -\xintNewExpr \Ratio [2] {trunc(protect(\DimToNum {#2})/protect(\DimToNum{#1}),3)} -\xintFor #1 in {\xintdimensions [0pt+.1pt]} \do - {\ifdim #1>2cm \expandafter\xintBreakFor\fi - {\color [rgb]{\Ratio {2cm}{#1},0,0}% - \vrule width .1pt height \FB {2cm}{#1}sp depth -\FA {2cm}{#1}sp }% - }% end of For iterated text -\end{everbatim} -\end{minipage}} -\end{figure*} -The\xintNewIExpr \FA [2] {protect(\DimToNum {#2})^3/protect(\DimToNum{#1})^2} -\hyperlink{graphic}{graphic}, with the code on its right% -% -\footnote{see \autoref{sssec:protect} for the significance of the |protect|'s: - they are needed because the expression has macro parameters inside macros, - and not only functions from the \csbxint{expr} syntax. The \csa{FA} turns - out to have meaning \texttt{\fixmeaning\FA}. The \csa{romannumeral} part is - only to ensure it expands in only two steps, and could be removed. The - \expandafter|\string\xintRound::csv| and - \expandafter|\string\xintSPRaw::csv| commands are used internally by - \csbxint{iexpr} to round and pretty print its result (or comma separated - results). See also the next footnote.}, -% -is for illustration only, not -only because of pdf rendering artefacts when displaying adjacent rules (which do -\emph{not} show in |dvi| output as rendered by |xdvi|, and depend from your -viewer), but because not using anything but rules it is quite inefficient and -must do lots of computations to not confer a too ragged look to the borders. -With a width of |.5pt| rather than |.1pt| for the rules, one speeds up the -drawing by a factor of five, but the boundary is then visibly ragged. -\newbox\codebox -\begingroup\makeatletter -\def\x{% - \parindent0pt - \def\par{\@@par\leavevmode\null}% - \let\do\do@noligs \verbatim@nolig@list - \let\do\@makeother \dospecials - \catcode`\@ 14 \makestarlowast - \ttfamily \scriptsize\baselineskip 8pt \obeylines \@vobeyspaces - \catcode`\|\active - \lccode`\~`\|\lowercase{\let~\egroup}}% -\global\setbox\codebox \vbox\bgroup\x -\def\DimToNum #1{\the\numexpr \dimexpr#1\relax/10000\relax } % no need to be more precise! -\def\FA #1#2{\xintDSH {-4}{\xintiQuo {\xintiPow {\DimToNum {#2}}{3}}{\xintiSqr {\DimToNum{#1}}}}} -\def\FB #1#2{\xintDSH {-4}{\xintiSqrt {\xintiMul {\DimToNum {#2}}{\DimToNum{#1}}}}} -\def\Ratio #1#2{\xintTrunc {2}{\DimToNum {#2}/\DimToNum{#1}}} -\xintFor #1 in {\xintdimensions [0pt+.25pt]} \do - {\ifdim #1>2cm \expandafter\xintBreakFor\fi - {\color [rgb]{\Ratio {2cm}{#1},0,0}% - \vrule width .25pt height \FB {2cm}{#1}sp depth -\FA {2cm}{#1}sp }% - }% end of For iterated text -|% -\endgroup -\footnote{to tell the whole truth we cheated and divided by |10| the - computation time through using the following definitions, together with a - horizontal step of |.25pt| rather than |.1pt|. The displayed original code - would make the slowest computation of all those done in this document using - the \xintname bundle macros!\par\smallskip - \noindent\box \codebox\par } If the list argument to \csbxint{For} (or \csbxint{For*}) is \csbxint{rationals} or more generally @@ -7195,8 +7004,6 @@ as they are able to deal with arbitrarily big integers. } | -%\newcounter{primecount} -%\newcounter{cellcount} As we used \csbxint{For} inside a macro we had to double the |#| in its |#1| parameter. Here is now the code which creates the prime table (the table has @@ -7308,11 +7115,6 @@ course!) the 1250th Fibonacci number: \catcode`_ 8 \end{everbatim*} -% ok -% \def\Fibo #1.{\xintthe\FibonacciN {#1}}% to use \xintiloopindex... -% \message{\xintiloop [0+1] -% \expandafter\Fibo\xintiloopindex., -% \ifnum\xintiloopindex<49 \repeat \xintthe\FibonacciN{50}.} I have modified the ending: we want not only one specific value |F(N)| but a pair of successive values which can serve as starting point of another routine @@ -7329,7 +7131,7 @@ numbers, it is only for validating \csa{FibonacciN}). % \begin{everbatim} \def\Fibo #1.{\xintthe\FibonacciN {#1}}% -\message{\xintiloop [0+1] \expandafter\Fibo\xintiloopindex., +\message{\xintiloop [0+1] \expandafter\Fibo\xintiloopindex., \ifnum\xintiloopindex<49 \repeat \xintthe\FibonacciN{50}.} \end{everbatim} \endgroup @@ -7503,10 +7305,6 @@ been put in a \hyperref[fibonacci]{float}, which appears readers the task to explain the visible patterns\dots |;-)|. \subsection{\csbh{xintForpair}, \csbh{xintForthree}, \csbh{xintForfour}}\label{xintForpair}\label{xintForthree}\label{xintForfour} -% {\small New in |1.09c|. The \csa{xintifForFirst} -% |1.09e| mechanism was missing and has been added for |1.09f|. The |1.09f| -% version handles better spaces and admits all (consecutive) macro -% parameters.\par} The syntax\ntype{on} is illustrated in this example. The notation is the usual one for |n|-uples, with parentheses and @@ -7530,13 +7328,8 @@ also \csa{xintForthree} (from |#1#2#3| to |#7#8#9|) and \csa{xintForfour} (from |#1#2#3#4| to |#6#7#8#9|). |\par| tokens are accepted in both the comma separated list and the replacement text. -% These three macros |\xintForpair|, |\xintForthree| and |\xintForfour| are to -% be considered in experimental status, and may be removed, replaced or -% substantially modified at some later stage. \subsection{\csbh{xintAssign}}\label{xintAssign} -%\small{ |1.09i| adds optional parameter. |1.09j| has default optional -% parameter |[]| rather than |[e]|\par} \csa{xintAssign}\meta{braced things}\csa{to}% \meta{as many cs as they are things} %\ntype{{(f$\to$\lowast [x)}{\lowast N}} @@ -7597,14 +7390,7 @@ of |\edef|. \par } -% This -% macro uses various \csa{edef}'s, thus is incompatible with expansion-only -% contexts. - \subsection{\csbh{xintAssignArray}}\label{xintAssignArray} -% {\small Changed in release |1.06| to let the defined macro pass its -% argument through a |\numexpr...\relax|. |1.09i| adds optional -% parameter. \par} \xintAssignArray \xintBezout {1000}{113}\to\Bez @@ -7771,6 +7557,8 @@ change this one will use internally lists of braced items (the initial conversion via \csbxint{CSVtoList} handles all potential spurious space problems). +\unless\ifxetex % pour tester compilation de xint.dtx avec xetex qui n'a pas + % \pdfuniformedeviate \begin{everbatim*} % QuickSort expandably on comma separated values with random choice of pivots % ====> Requires availability of \pdfuniformdeviate <==== @@ -7862,6 +7650,7 @@ problems). \noindent\ \ \ \scantokens\expandafter{\meaning\z}\par \endgroup \end{everbatim*} +\fi % fin de si pas xetex All these examples were with numbers which may have been handled via |\ifdim| tests rather than \csbxint{ifCmp} from \xintfracname ; naturally that would @@ -7897,7 +7686,7 @@ give a variant which picks up the last item as pivot. \definecolor{INERTpiv}{RGB}{237,237,237} \definecolor{PIVOT}{RGB}{109,8,57} % Start of macro defintions -\makeatletter +\makeatletter % \catcode`? 3 % a bit too paranoid. Normal ? will do. % % argument will never be empty @@ -7914,7 +7703,7 @@ give a variant which picks up the last item as pivot. \def\QS@sep@R@start\QS@sep@I {\noexpand\empty?\QSRr\QS@sep@R}% \def\QS@sep@R #1#2{\ifcase#1\or\or{#2}\else\expandafter\QS@sep@done\fi\QS@sep@R}% \def\QS@sep@done\QS@sep@R {\noexpand\empty?}% -% +% \def\QS@loop {% \xintloop % pivot phase @@ -7945,10 +7734,10 @@ give a variant which picks up the last item as pivot. \def\DecoPivot #1{\begingroup\color{PIVOT}\advance\fboxsep-\fboxrule\fbox{#1}\endgroup}% % \def\DecoLEFTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do + \xintFor* ##1 in {#1} \do {\xintifForFirst {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}}% \def\DecoINERTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do + \xintFor* ##1 in {#1} \do {\xintifForFirst {\colorbox{INERTpiv}{##1}}{\colorbox{INERT}{##1}}}}% \def\DecoRIGHTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% \xintFor* ##1 in {#1} \do @@ -7989,10 +7778,10 @@ Here is the variant which always picks the pivot as the rightmost element. {\romannumeral0\xintnthelt{-1}{#1}}#1??}% % \def\DecoLEFTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do + \xintFor* ##1 in {#1} \do {\xintifForLast {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}} \def\DecoINERTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do + \xintFor* ##1 in {#1} \do {\xintifForLast {\colorbox{INERTpiv}{##1}}{\colorbox{INERT}{##1}}}} \def\DecoRIGHTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% \xintFor* ##1 in {#1} \do @@ -8023,6 +7812,7 @@ particular the |\Deco..withPivot| macros need to know where the pivot is, and currently this is implemented by using either |\xintifForFirst| or |\xintifForLast|. +\clearpage \section{Commands of the \xintcorename package} \label{sec:core} @@ -8048,7 +7838,7 @@ automatically through \hyperref[xintiNum]{\string\xintNum}. This type of expansion applied to an argument is signaled by a \textcolor[named]{PineGreen}{\Numf} in the margin. The accepted input format is then a sequence of plus and minus signs, followed by some string of zeroes, -followed by digits. +followed by digits. If \xintfracname additionally to \xintcorename is loaded, \csbxint{Num} becomes a synonym to \csbxint{TTrunc}; this means that @@ -8085,13 +7875,6 @@ expression, in the arguments to the package macros, see the whether \xintfracname was loaded or not. They now have been \fbox{removed.} \MyMarginNote[\kern\dimexpr\FrameSep+\FrameRule\relax]{Changed} - % Due to this variability of the output format on whether the document uses - % only \xintname or loads additionally \xintfracname, code using these macros - % is fragile, because loading at some later date a package which itself loads - % \xintfracname or \xintexprname will modify their output format, and this is - % catastrophic for example in locations expanded by |\ifnum|, or even in - % arguments to those other macros of \xintname with |ii| in their names. - The macros \csbxint{iAdd}, \csbxint{iMul}, \dots, or \csbxint{iiAdd}, \csbxint{iiMul}, \dots which come with \xintcorename are guaranteed to always output an integer without a trailing |/B[n]|. The latter have the @@ -8099,9 +7882,6 @@ expression, in the arguments to the package macros, see the even if used with true fractions, as they will then truncate their arguments to integers. But their output format remains unmodified: integers with no fraction slash nor |[N]| thingy. - % It was an error for the \xintname package (now \xintcorename) to provide - % macros |\xintAdd|, |\xintMul|, |\xintSub| \dots. They should be used only - % with \xintfracname loaded. \end{framed} The {\color[named]{PineGreen}$\star$}'s in the margin are there to remind of @@ -8115,7 +7895,7 @@ in \autoref{ssec:expansions}. zeroes. % % \leftedline{|\xintNum{+---++----+--000000000367941789479}|\dtt - {=\xintNum{+---++----+--000000000367941789479}}} + {=\xintNum{+---++----+--000000000367941789479}}} All \xintname macros with a single |i| in their names, such as \csbxint{iAdd}, \csbxint{iMul} apply \csbxint{Num} to their arguments. @@ -8149,7 +7929,7 @@ skips the \csbxint{Num} overhead.\etype{f} |\xintiiFDg|\n\etype{f} returns the first digit (most significant) of the decimal expansion. It skips the overhead of parsing via \csbxint{Num}. The variant \csa{xintFDg}\etype{\Numf} uses |\xintNum| and gets extended by -\xintfracname. +\xintfracname. \subsection{\csbh{xintiiLDg}}\label{xintLDg}\label{xintiiLDg} @@ -8161,7 +7941,6 @@ ten. It skips the overhead of parsing via \csbxint{Num}. The variant \subsection{\csbh{xintDouble}, \csbh{xintHalf}} \label{xintDouble} \label{xintHalf} -%{\small New with |1.08|.\par} |\xintDouble|\n\etype{f} returns |2N| and |\xintHalf|\n is |N/2| rounded towards zero. These macros remain integer-only, even with \xintfracname loaded. @@ -8169,7 +7948,6 @@ towards zero. These macros remain integer-only, even with \xintfracname loaded. \subsection{\csbh{xintInc}, \csbh{xintDec}} \label{xintInc} \label{xintDec} -%{\small New with |1.08|.\par} |\xintInc|\n\etype{f} is |N+1| and |\xintDec|\n{} is |N-1|. These macros remain integer-only, even with \xintfracname loaded. They skip the overhead @@ -8186,7 +7964,6 @@ of parsing via \csbxint{Num}. \csa{xintiiSub} skips the \csbxint{Num} overhead.\etype{ff} \subsection{\csbh{xintiMul}, \csbh{xintiiMul}}\label{xintiMul}\label{xintiiMul} -%{\small Modified in release |1.03|.\par} |\xintiMul|\n\m\etype{\Numf\Numf} returns the product of the two numbers. \csa{xintiiMul} skips the \csbxint{Num} overhead.\etype{ff} @@ -8222,31 +7999,50 @@ before finally making the reasoning above. Indeed, each such computation with that I can hardly go on working on it! And it takes about 12 minutes for each |\xintiiPow2{N}| with such |N|'s of the order of $130000$ (a.t.t.o.w.). -\csa{xintiiPow} is an integer only variant skipping the \csbxint{Num} -overhead\etype{f\numx}, it produces the same result as \csa{xintiPow} with -stricter assumptions on the inputs, and is thus a tiny bit faster. +When \xintfracname is loaded the type of the second argument to \csa{xintiPow} +becomes \Numf: fractional input is accepted but will be truncated to an +integer; it still must be non-negative else the macro would produce fractions. +For the version accepting negative (but still integer) exponents see +\csbxint{Pow}. + +\csa{xintiiPow} is the variant which skips the \csbxint{Num} +overhead\etype{f\numx} for the first argument. + + +\subsection{\csbh{xintiFac}, \csbh{xintiiFac}} +\label{xintiiFac} + +|\xintiiFac|\x\etype{\numx} computes the factorial. -\xintfracname also provides the floating variants \csbxint{FloatPow} (for -which the exponent must still obey the \TeX{} bound) and \csbxint{FloatPower} -(which has no restriction at all on the size of the exponent). Negative -exponents do not then raise errors anymore. The float version is able to deal -with things such as |2^999999999| without any problem. +\begin{framed} + The (theoretically) allowable range is $0\leqslant x\leqslant10000$. + + However the maximal possible computation depends on the values of some memory + parameters of the |tex| executable: with the current default settings of + TeXLive 2015, the maximal computable factorial (a.t.t.o.w. 2015/10/06) turns + out to be $5971!$ which has $19956$ digits.%\footnotemark +\end{framed} + + + +|\xintiFac| is originally a synonym. With \xintfracname loaded it applies +|\xintNum| to its argument and thus accepts a fractional input but truncates +it to an integer. + +The |factorial| function, or equivalently |!| as post-fix operator is +available in \csbxint{iiexpr}, \csbxint{expr}: \begin{everbatim*} -$\xintFloatPow[32]{2}{50000}<\xintFloatPow[32]{2}{999999999}$ -\end{everbatim*}% -and both are computed swiftly! -% je ne sais plus ce qu'était cette note de bas de page -%\footnote{see however \autoref{fn:floatpow}.} +\printnumber{\xinttheiiexpr 200!\relax}\par +\end{everbatim*} +See also \csbxint{FloatFac} from package \xintfracname for the float variant, +used in \csbxint{floatexpr}. + + -Within an \csbxint{iiexpr}|..\relax| the infix operator |^| is mapped to -\csa{xintiiPow}; within an \csbxint{expr}-ession it is mapped to \csbxint{Pow} -(as extended by \xintfracname); in \csbxint{floatexpr}, it is mapped to -\csbxint{FloatPower}. \subsection{\csbh{xintiDivision}, \csbh{xintiiDivision}}\label{xintiDivision}\label{xintiiDivision} -% 17 octobre 2014: je supprime \xintDivision, seulement \xintiDivision. |\xintiiDivision|\n\m\etype{ff} returns |{quotient Q}{remainder R}|. This is euclidean division: |N = QM + R|, |0|${}\leq{}$\verb+R < |M|+. So the @@ -8263,7 +8059,7 @@ which divides one fraction by another. \subsection{\csbh{xintiQuo}, \csbh{xintiiQuo}}\label{xintiQuo}\label{xintiiQuo} |\xintiiQuo|\n\m\etype{ff} returns the quotient from the euclidean division. -It skips the overhead of parsing via \csbxint{Num}. +It skips the overhead of parsing via \csbxint{Num}. |\xintiQuo|\etype{\Numf\Numf} submits its arguments to \csbxint{Num} and is extended by \xintfracname to accept fractions on input, which it truncates @@ -8291,9 +8087,6 @@ Note: |\xintRem| is the former name of |\xintiRem|. Its use is deprecated. quotient $N/M$ of two big integers. The rounding of half integers is towards the nearest integer of bigger absolute value. The macro skips the overhead of parsing via \csbxint{Num}. The rounding is away from zero. -% si seulement j'avais mis ceci j'aurais évité l'incident stupide avec 1.2c -% qui avait cassé \xintiiDivRound. Pas le temps maintenant de rajouter des -% exemples à toutes les macros. \begin{everbatim*} \xintiiDivRound {100}{3}, \xintiiDivRound {101}{3} \end{everbatim*} @@ -8321,21 +8114,28 @@ $\xintiiQuo {1000}{-57}, \xintiiDivRound {1000}{-57}, \xintiiDivTrunc {1000}{-57 algebraic quotient truncated towards zero . The macro skips the overhead of parsing the operands with \csbxint{Num}. For $M>0$ it is the same as \csbxint{iiRem}. \begin{everbatim*} -$\xintiiRem {1000}{-57}, \xintiiMod {1000}{-57}, +$\xintiiRem {1000}{-57}, \xintiiMod {1000}{-57}, \xintiiRem {-1000}{57}, \xintiiMod {-1000}{57}$ \end{everbatim*} |\xintiMod|\etype{\Numf\Numf} submits first its arguments to \csbxint{Num}. +\clearpage \section{Commands of the \xintname package} \label{sec:xint} +\begin{framed} + This package loads automatically \xintcorename (and \xintkernelname) hence + all macros described in \autoref{sec:core} are still available. Notice + though that it does \emph{not} load package \xinttoolsname. +\end{framed} + \localtableofcontents Version |1.0| was released |2013/03/28|. This is \texttt{\xintbndlversion} of \texttt{\xintbndldate}. The core arithmetic macros have been moved to separate package \xintcorename, which is -automatically loaded by \xintname. +automatically loaded by \xintname. See the documentation of \xintcorename or \autoref{ssec:expansions} for the significance of the \textcolor[named]{PineGreen}{\Numf}, @@ -8361,7 +8161,7 @@ of related routines explains to some extent the higher speed of release |1.2|. \begin{everbatim*} \fdef\x{\xintReverseDigits {-98765432109876543210987654321098765432109876543210}}\meaning\x\par -\noindent\fdef\x{\xintReverseDigits {\xintReverseDigits +\noindent\fdef\x{\xintReverseDigits {\xintReverseDigits {-98765432109876543210987654321098765432109876543210}}}\meaning\x\par \end{everbatim*} \endgroup @@ -8403,7 +8203,6 @@ naturally still being either |1|, |0|, or |-1|). \csa{xintiiCmp} skips the \csbxint{Num} overhead.\etype{ff} \subsection{\csbh{xintEq}, \csbh{xintiiEq}}\label{xintEq} -%{\small New with release |1.09a|.\par} |\xintEq|\n\m\etype{\Numf\Numf} returns 1 if |N=M|, 0 otherwise. Extended by \xintfracname to fractions. @@ -8411,7 +8210,6 @@ by \xintfracname to fractions. \csa{xintiiEq} skips the \csbxint{Num} overhead.\etype{ff} \subsection{\csbh{xintNeq}, \csbh{xintiiNeq}} -%{\small New with release |1.09a|.\par} |\xintNeq|\n\m\etype{\Numf\Numf} returns 0 if |N=M|, 1 otherwise. Extended by \xintfracname to fractions. @@ -8419,7 +8217,6 @@ by \xintfracname to fractions. \csa{xintiiNeq} skips the \csbxint{Num} overhead.\etype{ff} \subsection{\csbh{xintGt}, \csbh{xintiiGt}}\label{xintGt} -%{\small New with release |1.09a|.\par} |\xintGt|\n\m\etype{\Numf\Numf} returns 1 if |N|$>$|M|, 0 otherwise. Extended by \xintfracname to fractions. @@ -8427,7 +8224,6 @@ Extended by \xintfracname to fractions. \csa{xintiiGt} skips the \csbxint{Num} overhead.\etype{ff} \subsection{\csbh{xintLt}, \csbh{xintiiLt}}\label{xintLt} -%{\small New with release |1.09a|.\par} |\xintLt|\n\m\etype{\Numf\Numf} returns 1 if |N|$<$|M|, 0 otherwise. Extended by \xintfracname to fractions. @@ -8449,7 +8245,6 @@ Extended by \xintfracname to fractions. \csa{xintiiGtorEq} skips the \csbxint{Num} overhead.\etype{ff} \subsection{\csbh{xintIsZero}, \csbh{xintiiIsZero}}\label{xintIsZero} -%{\small New with release |1.09a|.\par} |\xintIsZero|\n\etype{\Numf} returns 1 if |N=0|, 0 otherwise. Extended by \xintfracname to fractions. @@ -8457,12 +8252,10 @@ Extended by \xintfracname to fractions. \csa{xintiiIsZero} skips the \csbxint{Num} overhead.\etype{f} \subsection{\csbh{xintNot}}\label{xintNot} -%{\small New with release |1.09c|.\par} \csa{xintNot}\etype{\Numf} is a synonym for \csa{xintIsZero}. \subsection{\csbh{xintIsNotZero}, \csbh{xintiiIsNotZero}}\label{xintIsNotZero} -%{\small New with release |1.09a|.\par} |\xintIsNotZero|\n\etype{\Numf} returns 1 if |N<>0|, 0 otherwise. Extended by \xintfracname to fractions. @@ -8470,8 +8263,7 @@ Extended by \xintfracname to fractions. \csa{xintiiIsNotZero} skips the \csbxint{Num} overhead.\etype{f} \subsection{\csbh{xintIsOne}, - \csbh{xintiiIsOne}}\label{xintIsOne}\label{xintiiIsOne} -%{\small New with release |1.09a|.\par} + \csbh{xintiiIsOne}}\label{xintIsOne}\label{xintiiIsOne} |\xintIsOne|\n\etype{\Numf} returns 1 if |N=1|, 0 otherwise. Extended by \xintfracname to fractions. @@ -8479,25 +8271,21 @@ Extended by \xintfracname to fractions. \csa{xintiiIsOne} skips the \csbxint{Num} overhead.\etype{f} \subsection{\csbh{xintAND}}\label{xintAND} -%{\small New with release |1.09a|.\par} |\xintAND|\n\m\etype{\Numf\Numf} returns 1 if |N<>0| and |M<>0| and zero otherwise. Extended by \xintfracname to fractions. \subsection{\csbh{xintOR}}\label{xintOR} -%{\small New with release |1.09a|.\par} |\xintOR|\n\m\etype{\Numf\Numf} returns 1 if |N<>0| or |M<>0| and zero otherwise. Extended by \xintfracname to fractions. \subsection{\csbh{xintXOR}}\label{xintXOR} -%{\small New with release |1.09a|.\par} |\xintXOR|\n\m\etype{\Numf\Numf} returns 1 if exactly one of |N| or |M| is true (i.e. non-zero). Extended by \xintfracname to fractions. \subsection{\csbh{xintANDof}}\label{xintANDof} -%{\small New with release |1.09a|.\par} \csa{xintANDof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast\Numf} returns 1 if all are true (i.e. non zero) and zero otherwise. The list argument may be a macro, @@ -8505,14 +8293,12 @@ it (or rather its first token) is \fexpan ded first (each item also is \fexpan ded). Extended by \xintfracname to fractions. \subsection{\csbh{xintORof}}\label{xintORof} -%{\small New with release |1.09a|.\par} \csa{xintORof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast\Numf} returns 1 if at least one is true (i.e. does not vanish). The list argument may be a macro, it is \fexpan ded first. Extended by \xintfracname to fractions. \subsection{\csbh{xintXORof}}\label{xintXORof} -%{\small New with release |1.09a|.\par} \csa{xintXORof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast\Numf} returns 1 if an odd number of them are true (i.e. does not vanish). The list argument may be a @@ -8547,7 +8333,6 @@ The |\xintiiMin| macro skips the overhead of parsing the operands with \csbxint{Num}.\etype{ff} \subsection{\csbh{xintiMaxof}, \csbh{xintiiMaxof}}\label{xintiMaxof}\label{xintiiMaxof} -%{\small New with release |1.09a|.\par} \csa{xintiMaxof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast\Numf} returns the maximum. The list argument may be a macro, it is \fexpan ded first. Each item @@ -8557,7 +8342,6 @@ is submitted to |\xintNum| normalization. items.\NewWith {1.2a} \subsection{\csbh{xintiMinof}, \csbh{xintiiMinof}}\label{xintiMinof}\label{xintiiMinof} -%{\small New with release |1.09a|.\par} \csa{xintiMinof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast\Numf} returns the minimum. The list argument may be a macro, it is \fexpan ded first. Each item @@ -8575,8 +8359,8 @@ Note: the summands are \emph{not} parsed by \csbxint{Num}. % \leftedline{% - \csa{xintiiSum}|{{123}{-98763450}{\xintFac{7}}{\xintiMul{3347}{591}}}|% - \dtt{=\xintiiSum{{123}{-98763450}{\xintFac{7}}{\xintiMul{3347}{591}}}}} + \csa{xintiiSum}|{{123}{-98763450}{\xintiiFac{7}}{\xintiMul{3347}{591}}}|% + \dtt{=\xintiiSum{{123}{-98763450}{\xintiiFac{7}}{\xintiMul{3347}{591}}}}} % \leftedline{\csa{xintiiSum}|{1234567890}|\dtt{=\xintiiSum{1234567890}}} An empty sum is no error and returns zero: |\xintiiSum @@ -8586,8 +8370,6 @@ Attention that |\xintiiSum {-1234}| is not legal input and will make the \TeX{} run fail. On the other hand |\xintiiSum {1234}|\dtt{=\xintiiSum{1234}}. -% retiré de la doc le 22 octobre 2013 -% \subsection{\csbh{xintSumExpr}}\label{xintiiSumExpr} \subsection{\csbh{xintiiPrd}}\label{xintiiPrd} @@ -8597,9 +8379,9 @@ single tokens). Each is expanded (with the usual meaning), and the product of all these numbers is returned. Note: the operands are \emph{not} parsed by \csbxint{Num}. % -\leftedline{\csa{xintiiPrd}|{{-9876}{\xintFac{7}}{\xintiMul{3347}{591}}}|% +\leftedline{\csa{xintiiPrd}|{{-9876}{\xintiiFac{7}}{\xintiMul{3347}{591}}}|% \dtt{=% - \xintiiPrd{{-9876}{\xintFac{7}}{\xintiMul{3347}{591}}}}} + \xintiiPrd{{-9876}{\xintiiFac{7}}{\xintiMul{3347}{591}}}}} % \leftedline{\csa{xintiiPrd}|{123456789123456789}|\dtt{=% \xintiiPrd{123456789123456789}}} An empty product is no error and returns 1: @@ -8619,11 +8401,9 @@ With \xintexprname, this would be easier: \leftedline {|\xinttheiiexpr 2^200*3^100*7^100\relax |} -% \subsection{\csbh{xintPrdExpr}}\label{xintiiPrdExpr} \subsection{\csbh{xintSgnFork}}\label{xintSgnFork} -%{\small New with release |1.07|. See also \csbxint{ifSgn}.\par} \csa{xintSgnFork}\verb+{-1|0|1}+\marg{A}\marg{B}\marg{C}\etype{xnnn} expandably chooses to execute either the \meta{A}, \meta{B} or \meta{C} code, @@ -8635,7 +8415,6 @@ macros choosing depending on a condition which one of the package macros to use, or which values to confer to their arguments. \subsection{\csbh{xintifSgn}, \csbh{xintiiifSgn}}\label{xintifSgn} -%{\small New with release |1.09a|.\par} Similar to \csa{xintSgnFork}\etype{\Numf nnn} except that the first argument may expand to a (big) integer (or a fraction if \xintfracname is loaded), and it is @@ -8645,7 +8424,6 @@ first argument may be a count register, with no |\the| or |\number| prefix. \csa{xintiiifSgn} skips the \csbxint{Num} overhead.\etype{f} \subsection{\csbh{xintifZero}, \csbh{xintiiifZero}}\label{xintifZero} -%{\small New with release |1.09a|.\par} \csa{xintifZero}\marg{N}\marg{IsZero}\marg{IsNotZero}\etype{\Numf nn} expandably checks if the first mandatory argument |N| (a number, possibly a fraction if @@ -8657,7 +8435,6 @@ must be present. \subsection{\csbh{xintifNotZero}, \csbh{xintiiifNotZero}}\label{xintifNotZero} -%{\small New with release |1.09a|.\par} \csa{xintifNotZero}\marg{N}\marg{IsNotZero}\marg{IsZero}\etype{\Numf nn} expandably checks if the first mandatory argument |N| (a number, possibly a @@ -8668,7 +8445,6 @@ that both branches must be present. \csa{xintiiifNotZero} skips the \csbxint{Num} overhead.\etype{f} \subsection{\csbh{xintifOne}, \csbh{xintiiifOne}}\label{xintifOne} -%{\small New with release |1.09i|.\par} \csa{xintifOne}\marg{N}\marg{IsOne}\marg{IsNotOne}\etype{\Numf nn} expandably checks if the first mandatory argument |N| (a number, possibly a fraction if @@ -8682,8 +8458,6 @@ must be present. \label{xintifTrueAelseB} \label{xintifFalseAelseB} -%\label{xintifFalseTrue} -%{\small New with release |1.09c|, renamed in |1.09e|.\par} \csa{xintifTrueAelseB}\marg{N}\marg{true branch}\marg{false branch}\etype{\Numf nn} is a synonym for \csbxint{ifNotZero}. @@ -8699,7 +8473,6 @@ must be present. nn} is a synonym for \csbxint{ifZero}. \subsection{\csbh{xintifCmp}, \csbh{xintiiifCmp}}\label{xintifCmp} -%{\small New with release |1.09e|.\par} \csa{xintifCmp}\marg{A}\marg{B}\marg{if A<B}\marg{if A=B}\marg{if A>B}\etype{\Numf\Numf nnn} compares @@ -8708,7 +8481,6 @@ its arguments and chooses accordingly the correct branch. \csa{xintiiifCmp} skips the \csbxint{Num} overhead.\etype{ff} \subsection{\csbh{xintifEq}, \csbh{xintiiifEq}}\label{xintifEq} -%{\small New with release |1.09a|.\par} \csa{xintifEq}\marg{A}\marg{B}\marg{YES}\marg{NO}\etype{\Numf\Numf nn} checks equality of its two first arguments (numbers, or fractions if @@ -8717,7 +8489,6 @@ checks equality of its two first arguments (numbers, or fractions if \csa{xintiiifEq} skips the \csbxint{Num} overhead.\etype{ff} \subsection{\csbh{xintifGt}, \csbh{xintiiifGt}}\label{xintifGt} -%{\small New with release |1.09a|.\par} \csa{xintifGt}\marg{A}\marg{B}\marg{YES}\marg{NO}\etype{\Numf\Numf nn} checks if $A>B$ and in that case executes the |YES| branch. Extended to fractions (in @@ -8726,7 +8497,6 @@ particular decimal numbers) by \xintfracname. \csa{xintiiifGt} skips the \csbxint{Num} overhead.\etype{ff} \subsection{\csbh{xintifLt}, \csbh{xintiiifLt}}\label{xintifLt} -%{\small New with release |1.09a|.\par} \csa{xintifLt}\marg{A}\marg{B}\marg{YES}\marg{NO}\etype{\Numf\Numf nn} checks if $A<B$ and in that case executes the |YES| branch. Extended to @@ -8735,7 +8505,6 @@ fractions (in particular decimal numbers) by \xintfracname. \csa{xintiiifLt} skips the \csbxint{Num} overhead.\etype{ff} \subsection{\csbh{xintifOdd}, \csbh{xintiiifOdd}}\label{xintifOdd} -%{\small New with release |1.09e|.\par} \csa{xintifOdd}\marg{A}\marg{YES}\marg{NO}\etype{\Numf nn} checks if $A$ is and odd integer and in that case executes the |YES| branch. @@ -8750,72 +8519,16 @@ odd integer and in that case executes the |YES| branch. integers (with no |/B[N]|). \end{framed} -\subsection{\csbh{xintiFac}}\label{xintiFac} - -|\xintiFac|\x\etype{\numx} returns the factorial. It is an error on input if -the argument is negative. - -\begin{framed} - The macro will limit the acceptable inputs to a maximum of $9999$. However - the maximal computation depends on the values of some memory parameters of - the |tex| executable: with the the current default settings of TeXLive 2015, - the maximal computable factorial (a.t.t.o.w. 2015/10/06) turns out to be - $5971!$ which has $19956$ digits.%\footnotemark -\end{framed} -% \footnotetext{The computation with \xintname 1.2 of $5971!$ takes of the order -% of 27 seconds on my laptop. And about half a second for the $2568$ digits of -% $1000!$.} - -Package \xintfracname provides \csbxint{FloatFac} which allows to evaluate -faster significant digits of big factorials and accepts (theoretically) inputs -up to $99999999$. See \autoref{sec:examples} for the example of $2000!$ with -$50$ significant digits. - -% avant 1.09j c'était 1000000. -% avant 1.2 c'était 100000. (n'importe quoi!) - -|\xintFac| is the variant applying |\xintNum| on his input and thus, when -\xintfracname is loaded, accepting a fraction on input (but it truncates it -first). - -% avec xint1.2: 1000!, 2000!, 3000! -% Mercredi 07 octobre 2015 à 14:34:20 -% (0.534s) -% 402387260077093773543702, 2568, 4.023872600770938e2567. -% (2.521s) -% 331627509245063324117539, 5736, 3.316275092450633e5735. -% (6.097s) -% 414935960343785408555686, 9131, 4.149359603437854e9130. - -% ATTENTION TOTALEMENT MAIS TOTALEMENT OBSOLETE -% JE CONSERVE UNIQUEMENT POUR ME SOUVENIR DU PASSÉ -% ---- obsolète, remonte au premier xint -% On my laptop $1000!$ (2568 digits) -% is computed in a little less than ten seconds, $2000!$ (5736 -% digits) is computed in a little less than one hundred seconds, and -% $3000!$ (which has 9131 digits) needs close to seven minutes\dots -% I have no idea how much time $10000!$ would need (do rather -% $9999!$ if you can, the algorithm has some overhead at the -% transition from $N=9999$ to $10000$ and higher; $10000!$ has 35660 -% digits). Not to mention $100000!$ which, from the Stirling formula, -% should have 456574 digits. -% ---- (je rêvais à l'époque avec 100000! ... -% -% Je me souviens qu'au tout début je ne m'attendais pas du tout à rencontrer -% de tels problèmes dès des nombres de quelques milliers de chiffres, car je -% n'étais pas imprégné de la pénalité liée à parcourir par des macros -% délimités de longues séquences de tokens \subsection{\csbh{xintiiMON}, \csbh{xintiiMMON}} \label{xintMON}\label{xintMMON}\label{xintiiMON}\label{xintiiMMON} -%{\small New in version |1.03|.\par} |\xintiiMON|\n\etype{f} returns |(-1)^N| and |\xintiiMMON|\n{} returns |(-1)^{N-1}|. They skip the overhead of parsing via \csbxint{Num}. % \leftedline{|\xintiiMON {-280914019374101929}|\dtt{=\xintiiMON {280914019374101929}}, |\xintiiMMON - {-280914019374101929}|\dtt{=\xintiiMMON {280914019374101929}}} + {-280914019374101929}|\dtt{=\xintiiMMON {280914019374101929}}} The variants \csa{xintMON}\etype{\Numf} and \csa{xintMMON} use |\xintNum| and get extended @@ -8836,7 +8549,6 @@ variant using |\xintNum| and extended to fractions by \xintfracname. \subsection{\csbh{xintiSqrt}, \csbh{xintiiSqrt}, \csbh{xintiiSqrtR}, \csbh{xintiSquareRoot}, \csbh{xintiiSquareRoot}}\label{xintiSqrt}\label{xintiiSqrt}\label{xintiiSqrtR} \label{xintiSquareRoot}\label{xintiiSquareRoot} -%{\small New with |1.08|.\par} \noindent|\xintiSqrt|\n\etype{\Numf} returns the largest integer whose square is at most equal to |N|. |\xintiiSqrt| is the variant skipping the |\xintNum| @@ -8851,7 +8563,7 @@ returns the rounded, not truncated, square root.\etype{f} \end{everbatim*} |\xintiSquareRoot|\n\etype{\Numf} returns |{M}{d}| with |d>0|, |M^2-d=N| and -|M| smallest (hence |=1+\xintiSqrt{N}|). +|M| smallest (hence |=1+\xintiSqrt{N}|). |\xintiiSquareRoot|\etype{f} is the variant skipping the |\xintNum| overhead. @@ -8867,6 +8579,116 @@ then |M=k+1| and this gives |k+1/(2k+2)|, not |k|). Package \xintfracname has \csbxint{FloatSqrt} for square roots of floating point numbers. +\subsection{\csbh{xintiFac}, \csbh{xintiiFac}} + +Defined in \xintcorename, see \autoref{xintiiFac} for more info. + +\subsection{\csbh{xintiBinomial}, \csbh{xintiiBinomial}} +\label{xintiiBinomial} + +|\xintiiBinomial{x}{y}|\etype{\numx\numx} computes binomial coefficients. + +|\xintiBinomial| is originally a synonym.\NewWith{1.2f} +With \xintfracname loaded it applies +|\xintNum| to its arguments and thus accepts fractional inputs but truncates +them to an integer. + +\begin{framed} + The (theoretically) allowable range is $0\leqslant y \leqslant x\leqslant99999999$. +\end{framed} + % Thus the maximal computable value is ${9999 \choose 5000}$ which turns out + % to have \dtt{3008} digits. + This theoretical range includes binomial coefficients with more than the + roughly 19950 digits that the arithmetics of \xintname can handle. In such + cases, the computation will end up in a low-level \TeX{} error after a + long time. + +% +It turns out that ${65000 \choose 32500}$ has \dtt{19565} digits and +${64000 \choose 32000}$ has \dtt{19264} digits. The latter can be evaluated +(this takes a long long time) but presumably not the former (I didn't try). +Reasonable feasible evaluations are with binomial coefficients not exceeding +about one thousand digits. + + +% +The |binomial| function is available in the \xintexprname parsers. +\begin{everbatim*} +\xinttheiiexpr seq(binomial(100,i), i=47..53)\relax +\end{everbatim*} + +See \csbxint{FloatBinomial} from package \xintfracname for the float variant, +used in \csbxint{floatexpr}. + + + +In order to +evaluate binomial coefficients ${x \choose y}$ with $x>99999999$, or even +$x\geqslant 2^{31}$, but $y$ is not too large, one may use an ad hoc function +definition such as: +\begin{everbatim*} +\xintdeffunc mybigbinomial(x,y):=`*`(x-y+1..[1]..x)//y!;% +% without [1], x would have been limited to < 2^31 +\printnumber{\xinttheexpr mybigbinomial(98765432109876543210,10)\relax} +\end{everbatim*} + + +To get this functionality in macro form, one can do: +\begin{everbatim*} +\xintNewIIExpr\MyBigBinomial [2]{`*`(#1-#2+1..[1]..#1)//#2!} +\printnumber{\MyBigBinomial {98765432109876543210}{10}} +\end{everbatim*} + +As we used \csa{xintNewIIExpr}, this macro will only accept strict integers. +Had we used \csa{xintNewExpr} the |\MyBigBinomial| would have accepted general +fractions or decimal numbers, and computed the product at the numerator +without truncating them to integers; but the factorial at the denominator +would truncate its argument. + +\subsection{\csbh{xintiPFactorial}, \csbh{xintiiPFactorial}} +\label{xintiiPFactorial} + +|\xintiiPFactorial{a}{b}|\etype{\numx\numx} computes the partial factorial +|(a+1)(a+2)...b|. + +|\xintiPFactorial| is originally a synonym.\NewWith{1.2f} +With \xintfracname loaded it applies +|\xintNum| to its arguments and thus accepts fractional inputs but truncates +them to an integer. + +\begin{framed} + The (theoretically) allowable range is $0\leqslant a \leqslant + b\leqslant99999999$. If |a=b| the value is |1|. + +\begin{everbatim*} +\xintiiPFactorial {100}{130} +\end{everbatim*} +\end{framed} + + This theoretical range includes values with more than the + roughly 19950 digits that the arithmetics of \xintname can handle. In such + cases, the computation will end up in a low-level \TeX{} error after a + long time. + +% +The |pfactorial| function is available in the \xintexprname parsers. +\begin{everbatim*} +\xinttheiiexpr pfactorial(100,130)\relax +\end{everbatim*} + +See \csbxint{FloatPFactorial} from package \xintfracname for the float +variant, used in \csbxint{floatexpr}. + + +In case values are needed with $b>99999999$, or even $b\geqslant 2^{31}$, but +$b-a$ is not too large, one may use an ad hoc function definition such as: +\begin{everbatim*} +\xintdeffunc mybigpfac(a,b):=`*`(a+1..[1]..b);% +% without [1], b would have been limited to < 2^31 +\printnumber{\xinttheexpr mybigpfac(98765432100,98765432120)\relax} +\end{everbatim*} + + \begin{framed} The macros described next are strictly for integer-only arguments. These arguments are \emph{not} filtered via \csbxint{Num}. The macros are not @@ -8893,7 +8715,6 @@ multiplication by $10^{-x}$). When |x| positive, it is like iterating thus the same as the quotient from the euclidean division by |10^x|. \subsection{\csbh{xintDSHr}, \csbh{xintDSx}}\label{xintDSHr}\label{xintDSx} -%{\small New in release |1.01|.\par} |\xintDSHr|\x\n\etype{\numx f} expects |x| to be zero or positive and it returns then a value |R| which is correlated to the value |Q| returned by @@ -8949,7 +8770,6 @@ simultaneously. \subsection{\csbh{xintDecSplit}}\label{xintDecSplit} -%{\small This has been modified in release |1.01|.\par} |\xintDecSplit|\x\n\etype{\numx f} cuts the number into two pieces (each one within a pair of enclosing braces). First the sign if present is \emph{removed}. @@ -9007,9 +8827,18 @@ of \csa{xintDecSplit}. %\pagebreak +\clearpage \section{Commands of the \xintfracname package} \label{sec:frac} +\begin{framed} + This package loads automatically \xintname and \xintcorename, hence all + macros described in \autoref{sec:xint} and \autoref{sec:core} are + available; but some among them will only accept integers on input, not + fractions or numbers in scientific notation. This is the case + particularly for all those having |ii| in their names. +\end{framed} + \localtableofcontents \def\x{|{x}|} @@ -9051,8 +8880,8 @@ whereas |\xintPRaw {\xintIrr {\xintAdd {2/5}{3/5}}}}. As we knew the result was an integer we could have used |\xintNum {\xintAdd {2/5}{3/5}}=|\xintNum {\xintAdd {2/5}{3/5}}. -Some macros (such as \csbxint{iTrunc}, -\csbxint{iRound}, and \csbxint{Fac}) always produce directly integers on output. +Some macros (such as \csbxint{iTrunc}, \csbxint{iRound}, and \csbxint{iFac}) +always produce integers on output. The macro \csbxint{XTrunc} uses \csbxint{iloop} from package \xinttoolsname, hence there is a partial dependency of \xintfracname on @@ -9079,7 +8908,6 @@ as the macro will according to its definition add all the needed zeroes to produce an explicit integer in strict format. \subsection{\csbh{xintifInt}}\label{xintifInt} -%{\small New with release |1.09e|.\par} \csa{xintifInt}|{f}{YES branch}{NO branch}|\etype{\Ff nn} expandably chooses the |YES| branch if |f| reveals itself after expansion and simplification to @@ -9097,8 +8925,6 @@ The original macro\etype{\Ff} is extended to accept a fraction on input. \dtt{=\xintLen {1234}}} \subsection{\csbh{xintRaw}}\label{xintRaw} -%{\small New with release |1.04|.\par} -%{\small \color{red}MODIFIED IN |1.07|.\par} This macro `prints' the\etype{\Ff} fraction |f| as it is received by the package after its parsing and @@ -9113,18 +8939,17 @@ printed even if it has value |1|. 571*987\relax.123e-10/\the\numexpr -201+59\relax e-7}}} \subsection{\csbh{xintPRaw}}\label{xintPRaw} -%{\small New in |1.09b|.\par} |PRaw|\etype{\Ff} stands for ``pretty raw''. It does \emph{not} show the |[n]| -if |n=0| and does \emph{not} show the |B| if |B=1|. +if |n=0| and does \emph{not} show the |B| if |B=1|. % % % \leftedline{|\xintPRaw {123e10/321e10}=|\dtt{\xintPRaw {123e10/321e10}}, % -|\xintPRaw {123e9/321e10}=|\dtt{\xintPRaw {123e9/321e10}}} +|\xintPRaw {123e9/321e10}=|\dtt{\xintPRaw {123e9/321e10}}} % % % -\leftedline{|\xintPRaw {\xintIrr{861/123}}=|\dtt{\xintPRaw{\xintIrr{861/123}}}\ vz.\ - |\xintIrr{861/123}=|\dtt{\xintIrr{861/123}}} +\leftedline{|\xintPRaw {\xintIrr{861/123}}=|\dtt{\xintPRaw{\xintIrr{861/123}}}\ vz.\ + |\xintIrr{861/123}=|\dtt{\xintIrr{861/123}}} % % See also \csbxint{Frac} (or \csbxint{FwOver}) for math mode. As is examplified above the \csbxint{Irr} macro which puts the fraction into irreducible form @@ -9158,7 +8983,7 @@ This returns\etype{\Ff} the denominator corresponding to the internal representation of the fraction:% % \footnote{recall that the |[]| construct excludes - presence of a decimal point.} + presence of a decimal point.} % \leftedline{|\xintDenominator {178000/25600000[17]}|\dtt{=\xintDenominator {178000/25600000[17]}}} @@ -9177,7 +9002,6 @@ through the removal of the decimal point. For a result uniquely associated to the value of the fraction first apply \csa{xintIrr}. \subsection{\csbh{xintRawWithZeros}}\label{xintRawWithZeros} -%{\small New name in |1.07| (former name |\xintRaw|).\par} This macro `prints'\etype{\Ff} the fraction |f| (after its parsing and expansion) in |A/B| form, with |A| @@ -9211,8 +9035,8 @@ denominator is omitted when it has value one, the number being separated from the power of ten by a |\cdot|. |$\xintFrac {178.000/25600000}$| gives $\xintFrac {178.000/25600000}$, |$\xintFrac {178.000/1}$| gives $\xintFrac {178.000/1}$, |$\xintFrac {3.5/5.7}$| gives $\xintFrac {3.5/5.7}$, and |$\xintFrac {\xintNum - {\xintFac{10}/|\allowbreak|\xintiSqr{\xintFac {5}}}}$| gives $\xintFrac -{\xintNum {\xintFac{10}/\xintiSqr{\xintFac {5}}}}$. As shown by the examples, + {\xintiiFac{10}/|\allowbreak|\xintiSqr{\xintiiFac {5}}}}$| gives $\xintFrac +{\xintNum {\xintiiFac{10}/\xintiSqr{\xintiiFac {5}}}}$. As shown by the examples, simplification of the input (apart from removing the decimal points and moving the minus sign to the numerator) is not done automatically and must be the result of macros such as |\xintIrr|, |\xintREZ|, or |\xintNum| (for fractions @@ -9220,7 +9044,6 @@ being in fact integers.) \subsection{\csbh{xintSignedFrac}}\label{xintSignedFrac} -%{\small New with release |1.04|.\par} This is as \csbxint{Frac}\etype{\Ff} except that a negative fraction has the sign put in front, not in the numerator. % @@ -9236,13 +9059,12 @@ primitive is used for the fraction (in case the denominator is not one; and a pair of braces contains the |A\over B| part). |$\xintFwOver {178.000/25600000}$| gives $\xintFwOver {178.000/25600000}$, |$\xintFwOver {178.000/1}$| gives $\xintFwOver {178.000/1}$, |$\xintFwOver {3.5/5.7}$| gives $\xintFwOver -{3.5/5.7}$, and |$\xintFwOver {\xintNum {\xintFac{10}/\xintiSqr{\xintFac - {5}}}}$| gives $\xintFwOver {\xintNum {\xintFac{10}/\xintiSqr{\xintFac +{3.5/5.7}$, and |$\xintFwOver {\xintNum {\xintiiFac{10}/\xintiSqr{\xintiiFac + {5}}}}$| gives $\xintFwOver {\xintNum {\xintiiFac{10}/\xintiSqr{\xintiiFac {5}}}}$. \subsection{\csbh{xintSignedFwOver}}\label{xintSignedFwOver} -%{\small New with release |1.04|.\par} This is as \csbxint{FwOver}\etype{\Ff} except that a negative fraction has the sign put in front, not in the numerator. % @@ -9280,10 +9102,10 @@ This also puts the fraction\etype{\Ff} into its unique irreducible form: % This is faster than \csa{xintIrr} for fractions having some big common factor in the numerator and the denominator.\par -{\centering |\xintJrr {\xintiPow{\xintFac {15}}{3}/\xintiiPrdExpr -{\xintFac{10}}{\xintFac{30}}{\xintFac{5}}\relax }|\dtt{=% - \xintJrr {\xintiPow{\xintFac {15}}{3}/\xintiiPrdExpr -{\xintFac{10}}{\xintFac{30}}{\xintFac{5}}\relax }}\par} But to notice the +{\centering |\xintJrr {\xintiPow{\xintiiFac {15}}{3}/\xintiiPrdExpr +{\xintiiFac{10}}{\xintiiFac{30}}{\xintiiFac{5}}\relax }|\dtt{=% + \xintJrr {\xintiPow{\xintiiFac {15}}{3}/\xintiiPrdExpr +{\xintiiFac{10}}{\xintiiFac{30}}{\xintiiFac{5}}\relax }}\par} But to notice the difference one would need computations with much bigger numbers than in this example. Starting with release |1.08|, \csa{xintJrr} does not remove the trailing |/1| @@ -9317,14 +9139,6 @@ give $-0.000...$. {12}{\xintAdd {-1/3}{3/9}}}} The digits printed are exact up to and including the last one. -% The identity |\xintTrunc {x}{-f}=-\xintTrunc {x}{f}| -% holds.% -% -% \footnote{Recall that |-\string\macro| is not valid as argument to any -% package macro, one must use |\string\xintOpp\string{\string\macro\string}| or -% |\string\xintiOpp\string{\string\macro\string}|, except inside -% |\string\xinttheexpr...\string\relax|.} - \subsection{\csbh{xintiTrunc}}\label{xintiTrunc} \csa{xintiTrunc}|{x}{f}|\etype{\numx\Ff} returns the integer equal to |10^x| @@ -9352,7 +9166,6 @@ zero). This is the same as |\xintiTrunc {0}{f}| and as \csbxint{Num}. \subsection{\csbh{xintXTrunc}}\label{xintXTrunc} -%{\small New with release |1.09j|.\par} \csa{xintXTrunc}|{x}{f}|\retype{\numx\Ff} is completely expandable but not \fexpan dable, as is indicated by the hollow star in the margin. It can not be @@ -9429,14 +9242,10 @@ YES! *\bye No pages of output. Transcript written on worksheet-66049.log. -xxx:_xint $ +xxx:_xint $ | \endgroup -% \emph{Outdated note: Using |\xintTrunc| rather than |\xintXTrunc| would be -% hopeless on such long outputs (and even |\xintXTrunc| needed of the order of -% seconds to complete here). But it is not worth it to use |\xintXTrunc| for -% less than hundreds of digits.} \begin{framed} The |\xintiiMul {\ZA}{66049}| above can sadly \emph{not} be executed with @@ -9457,7 +9266,7 @@ reasons lead to the use of some tricks.% \footnote{Technical note: I do not provide an |\xintXFloat| because this would almost certainly mean having to clone the entire core division routines into a ``long division'' variant. But this - could have given another approach to the implementation of + could have given another approach to the implementation of |\xintXTrunc|, especially for the case of a negative |N|. Doing these things with \TeX{} is an effort. Besides an |\xintXFloat| would be interesting only if also for example the square root routine @@ -9471,7 +9280,6 @@ Also, the first argument must be at least $1$. \subsection{\csbh{xintRound}}\label{xintRound} -%{\small New with release |1.04|.\par} \csa{xintRound}|{x}{f}|\etype{\numx\Ff} returns the start of the decimal expansion of the fraction |f|, rounded to |x| digits precision after the decimal @@ -9500,7 +9308,6 @@ zero. % \subsection{\csbh{xintiRound}}\label{xintiRound} -%{\small New with release |1.04|.\par} \csa{xintiRound}|{x}{f}|\etype{\numx\Ff} returns the integer equal to |10^x| times what \csa{xintRound}|{x}{f}| would return. % @@ -9518,7 +9325,6 @@ zeroes.) \subsection{\csbh{xintFloor}, \csbh{xintiFloor}} \label{xintFloor}\label{xintiFloor} -%{\small New with release |1.09a|.\par} |\xintFloor {f}|\etype{\Ff} returns the largest relative integer |N| with |N|${}\leqslant{}$|f|. % @@ -9530,7 +9336,7 @@ zeroes.) } |\xintiFloor {f}|\etype{\Ff} does the same but without adding the -|/1[0]|. +|/1[0]|. % \leftedline{|\xintiFloor {-2.13}|\dtt{=\xintiFloor {-2.13}}, |\xintiFloor {-2}|\dtt{=\xintiFloor {-2}}, |\xintiFloor @@ -9538,7 +9344,6 @@ zeroes.) \subsection{\csbh{xintCeil}, \csbh{xintiCeil}} \label{xintCeil}\label{xintiCeil} -%{\small New with release |1.09a|.\par} |\xintCeil {f}|\etype{\Ff} returns the smallest relative integer |N| with |N|${}>{}$|f|. % @@ -9588,7 +9393,6 @@ conversion to a floating point number with the precision as set by |\xintDigits| \dtt{=\xintTFrac {1.122435727e5}}} \subsection{\csbh{xintE}}\label{xintE} -%{\small New with |1.07|.} |\xintE {f}{x}|\etype{\Ff\numx} multiplies the fraction |f| by $10^x$. The \emph{second} argument |x| must obey the \TeX{} bounds. Example: @@ -9634,46 +9438,65 @@ an integer format on output use \csbxint{iSqr}. \subsection{\csbh{xintDiv}}\label{xintDiv} -Computes the algebraic quotient \etype{\Ff\Ff} of two fractions. +Computes the quotient \etype{\Ff\Ff} of two fractions. (|\xintDiv{F}{G}| computes |F/G|). To keep for integers the integer format on output use \csbxint{iMul}. No reduction attempted. -\subsection{\csbh{xintFac}}\label{xintFac} -%{\small Modified in |1.08b| (to allow fractions on input).\par} +\subsection{\csbh{xintDivTrunc}, \csbh{xintDivRound}} +\label{xintDivTrunc} +\label{xintDivRound} + +Computes the quotient \etype{\Ff\Ff} of the two arguments then either +truncates or rounds to an integer. + +\subsection{\csbh{xintiFac}}\label{xintiFac} + + +With \xintfracname loaded |\xintiFac|\etype{\Numf} is extended to allow a +fraction |f| as input, it will be truncated first to an integer |n| before the +evaluation of the factorial. The output is an integer in strict format, +without a trailing |/1[0]|. See the \hyperref[xintiiFac]{\csa{xintiiFac} doc} +for more info. -The original\etype{\Numf} is extended to allow a fraction |f| which will be -truncated first to an integer |n|. See \csbxint{iFac} for a discussion of the -maximal allowed input. +\subsection{\csbh{xintiBinomial}}\label{xintiBinomial} -Output format is an integer without trailing |/1[0]|. +With \xintfracname loaded |\xintiBinomial|\etype{\Numf\Numf} is extended to +allow fractional inputs which will be truncated to integers before the +evaluation of the binomial. The output is an integer in strict format, without +a trailing |/1[0]|. See the +\hyperref[xintiiBinomial]{\csa{xintiiBinomial} doc} for the current allowable +range. -The original macro\etype{\numx} (which parses its input via |\numexpr|) is -still available as \csbxint{iFac}. +\subsection{\csbh{xintiPFactorial}}\label{xintiPFactorial} +% fait 2015/11/29 pour 1.2f. + +With \xintfracname loaded |\xintiPFactorial|\etype{\Numf\Numf} is extended to +allow fractional inputs which will be truncated to integers before the +evaluation of the partial factorial. The output is an integer in strict +format, without a trailing |/1[0]|. See the +\hyperref[xintiiPFactorial]{\csa{xintiiPFactorial} doc} for more info. \subsection{\csbh{xintPow}}\label{xintPow} -\csa{xintPow}{|{f}{g}|}:\etype{\Ff\Numf} computes |f^g| with |f| a fraction -and |g| possibly also, but |g| will first get truncated to an integer. +\csa{xintPow}{|{f}{x}|}:\etype{\Ff\Numf} computes |f^x| with |f| a fraction and +|x| possibly also, but |x| will first get truncated to a (positive or negative) +integer. The output will now always be in the form |A/B[n]| (even when the exponent vanishes: |\xintPow {2/3}{0}|\dtt{=\xintPow{2/3}{0}}). -The original -is available as \csbxint{iPow}. +The macro handling only integers is available as \csbxint{iPow}. Only +\csa{xintPow} accepts negative exponent, as this produces fractions. -%%%%% OBSOLETE -% The exponent (after truncation to an integer) will be checked to not exceed -% |100000|. Indeed |2^50000| already has \dtt{\xintLen {\xintFloatPow -% [1]{2}{50000}}} digits, and squaring such a number would take hours (I -% think) with the expandable routine of \xintname. -\subsection{\csbh{xintSum}}\label{xintSum}\label{xintSumExpr} +Within an \csbxint{iiexpr}|..\relax| the infix operator |^| is mapped to +\csa{xintiiPow}; within an \csbxint{expr}-ession it is mapped to +\csa{xintPow}. + -% The original commands are extended to accept fractions on input and produce -% fractions on output. Their outputs will now always be in the form |A/B[n]|. The -% originals are available as \csa{xintiiSum} and \csa{xintiiSumExpr}. +\subsection{\csbh{xintSum}}\label{xintSum}\label{xintSumExpr} This\etype{f{$\to$}{\lowast\Ff}} computes the sum of fractions. The output will now always be in the form |A/B[n]|. The original, for big integers only @@ -9683,9 +9506,7 @@ will now always be in the form |A/B[n]|. The original, for big integers only \xintSum {{1282/2196921}{-281710/291927}{4028/28612}} \end{everbatim*} -No simplification attempted. - -% \subsection{\csbh{xintPrd}, \csbh{xintPrdExpr}}\label{xintPrd}\label{xintPrdExpr} +No simplification attempted. \subsection{\csbh{xintPrd}}\label{xintPrd}\label{xintPrdExpr} @@ -9697,22 +9518,15 @@ will now always be in the form |A/B[n]|. The original, for big integers only \xintPrd {{1282/2196921}{-281710/291927}{4028/28612}} \end{everbatim*} -No simplification attempted. +No simplification attempted. \subsection{\csbh{xintCmp}}\label{xintCmp} -%{\small Rewritten in |1.08a|.\par} -This\etype{\Ff\Ff} compares two fractions |F| and |G| and produces +This\etype{\Ff\Ff} compares two fractions |F| and |G| and produces |-1|, |0|, or |1| according to |F<G|, |F=G|, |F>G|. -For choosing branches according to the result of comparing |f| and |g|, the -following syntax is recommended: |\xintSgnFork{\xintCmp{f}{g}}{code for - f<g}{code for f=g}{code for f>g}|. - -% Note that since release |1.08a| using this macro on inputs with large powers of -% tens does not take a quasi-infinite time, contrarily to the earlier, somewhat -% dumb version (the earlier version indirectly led to the creation of giant chains -% of zeroes in certain circumstances, causing a serious efficiency impact). +For choosing branches according to the result of comparing |f| and |g|, see +\csbxint{ifCmp}. \subsection{\csbh{xintIsOne}} @@ -9723,7 +9537,6 @@ This\etype{\Ff} returns |1| if the fraction is |1| and |0| if not. \end{everbatim*} \subsection{\csbh{xintGeq}}\label{xintGeq} -%{\small Rewritten in |1.08a|.\par} This\etype{\Ff\Ff} compares the \emph{absolute values} of two fractions.|\xintGeq{f}{g}| returns |1| if {\catcode`| 12 $|f|\geqslant|g|$} and |0| @@ -9734,7 +9547,6 @@ May be used for expandably branching as: |f|+$\geqslant$\verb+|g|}+ \subsection{\csbh{xintMax}}\label{xintMax} -%{\small Rewritten in |1.08a|.\par} The maximum of two fractions.\etype{\Ff\Ff} But now |\xintMax {2}{3}| returns \dtt{\xintMax {2}{3}}. The original, for use with (possibly big) @@ -9749,7 +9561,6 @@ first truncates them to integers. \end{everbatim*} \subsection{\csbh{xintMin}}\label{xintMin} -%{\small Rewritten in |1.08a|.\par} The maximum of two fractions.\etype{\Ff\Ff} The original, for use with (possibly big) integers only with no need of normalization, is available as \csbxint{iiMin}: @@ -9787,17 +9598,17 @@ whereas |\xintiAbs {-2}|\dtt{=\xintiAbs {-2}}. \subsection{\csbh{xintSgn}}\label{xintSgn} -The sign of a fraction.\etype{\Ff} +The sign of a fraction.\etype{\Ff} \subsection{\csbh{xintOpp}}\label{xintOpp} -The opposite of a fraction. Note that |\xintOpp {3}| now outputs \dtt{\xintOpp +The opposite of a fraction.\etype{\Ff} +Note that |\xintOpp {3}| now outputs \dtt{\xintOpp {3}} whereas |\xintiOpp {3}| returns \dtt{\xintiOpp {3}}. \subsection{\csbh{xintDigits}, \csbh{xinttheDigits}} \label{xintDigits} \label{xinttheDigits} -%{\small New with release |1.07|.\par} The syntax |\xintDigits := D;| (where spaces do not matter) assigns the value of |D| to the number of digits to be used by floating point @@ -9806,10 +9617,9 @@ operations. The default is |16|. The maximal value is |32767|. The macro \subsection{\csbh{xintFloat}}\label{xintFloat} -%{\small New with release |1.07|.\par} The macro |\xintFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} has an optional argument |P| which replaces -the current value of |\xintDigits|. The (rounded truncation of the) fraction +the current value of |\xinttheDigits|. The (rounded truncation of the) fraction |f| is then printed in scientific form, with |P| digits, a lowercase |e| and an exponent |N|. The first digit is from |1| to |9|, it is preceded by an optional minus sign and @@ -9823,12 +9633,9 @@ equality with zero). % \leftedline{|\xintFloat[32]{1234567/7654321}|% \dtt{=\xintFloat[32]{1234567/7654321}}} -% \pdfresettimer % -\leftedline{|\xintFloat[32]{1/\xintFac{100}}|% - \dtt{=\xintFloat[32]{1/\xintFac{100}}}} -% \the\pdfelapsedtime -% 992: plus rapide que ce que j'aurais cru.. +\leftedline{|\xintFloat[32]{1/\xintiiFac{100}}|% + \dtt{=\xintFloat[32]{1/\xintiiFac{100}}}} The argument to \csa{xintFloat} may be an |\xinttheexpr|-ession, like the other macros; only its final evaluation is submitted to \csa{xintFloat}: the @@ -9838,116 +9645,229 @@ mode. For this one must use |\xintthefloatexpr|. \subsection{\csbh{xintPFloat}}\label{xintPFloat} The macro |\xintPFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} is like -\csbxint{Float} but ``pretty-prints'' the output, in the sense of dropping the -scientific notation if possible. Here are the rules: -\begin{enumerate} -\item if it is possible to drop the scientific part and express the number as - a decimal number with the same number of digits as in the significand and a - decimal mark, it is done so, -\item if the number is less than one and at most four zeros need be inserted - after the decimal mark to express it without scientific part, it is done - so, -\item if the number is zero it is printed as \dtt{\xintPFloat{0}}. All other - cases have either a decimal mark or a scientific part or both. -\item trailing zeros are not trimmed. -\end{enumerate} +\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.\footnote{In the exceptional case of an input + rounded up towards next power of ten, the exponent referred-to here is the + integer |N| in |10.0..0eN| with a total number of zeroes equal to the + precision.} + +If the input vanishes the output will be \dtt{\xintPFloat{0}} with a a decimal +mark\CHANGED{1.2f} (the original version printed \dtt{0} with no decimal +mark).\footnote{Currently there are no subnormal numbers, and no underflow + because the exponent is only limited by the maximal \TeX\ number; thus + underflow situations would manifest themselves via low-level arithmetic + overflow errors.} + +\csbxint{thefloatexpr} applies this macro to its output (or each of +its outputs, if comma separated). + +Currently trailing zeros are not trimmed. + \begin{everbatim*} -\begin{itemize}[noitemsep] -\item \xintPFloat {0} -\item \xintPFloat {123} -\item \xintPFloat {0.00004567} -\item \xintPFloat {0.000004567} -\item \xintPFloat {12345678e-12} -\item \xintPFloat {12345678e-13} -\item \xintPFloat {12345678.12345678} -\item \xintPFloat {123456789.123456789} -\item \xintPFloat {123456789123456789} -\item \xintPFloat {1234567891234567} +\begingroup\def\test #1{#1${}\to{}$\xintPFloat{#1}}% +\string\xintDigits\ at \xinttheDigits +\begin{itemize}[nosep] +\item \test {0} +\item \test {1.23456789e-7} +\item \test {1.23456789e-6} +\item \test {1.23456789e-5} +\item \test {1.23456789e-4} +\item \test {1.23456789e-3} +\item \test {1.23456789e-2} +\item \test {1.23456789e-1} +\item \test {1.23456789e0} +\item \test {1.23456789e1} +\item \test {1.23456789e2} +\item \test {1.23456789e3} +\item \test {1.23456789e4} +\item \test {1.23456789e5} +\item \test {1.23456789e6} +\item \test {1.23456789e7} \end{itemize} +\endgroup \end{everbatim*} + \subsection{\csbh{xintFloatE}}\label{xintFloatE} -%{\small New with |1.097|.} |\xintFloatE [P]{f}{x}|\etype{{\upshape[\numx]}\Ff\numx} multiplies the input |f| by $10^x$, and converts it to float format according to the optional first argument or current -value of |\xintDigits|. +value of |\xinttheDigits|. % \leftedline{|\xintFloatE {1.23e37}{53}|\dtt{=\xintFloatE {1.23e37}{53}}} \subsection{\csbh{xintFloatAdd}}\label{xintFloatAdd} -%{\small New with release |1.07|.\par} -|\xintFloatAdd [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| and -|g| with their float approximations, with 2 safety digits. It then adds exactly -and outputs in float format with precision |P| (which is optional) or -|\xintDigits| if |P| was absent, the result of this computation. +|\xintFloatAdd [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| +and |g| with their float approximations |f'| and |g'| to |P| significant +places or to the precision from |\xintDigits|.\CHANGED{1.2f} It then produces +the sum |f'+g'|, correctly rounded to nearest with the same number of +significant places. + +As for \csbxint{Float}, in case of rounding up to next power of ten, the value +may exceptionally come out as |10.0...0eN| with a total of |P+1| digits. + +See \autoref{ssec:floatingpoint} for more. + \subsection{\csbh{xintFloatSub}}\label{xintFloatSub} -%{\small New with release |1.07|.\par} -|\xintFloatSub [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| and -|g| with their float approximations, with 2 safety digits. It then subtracts -exactly and outputs in float format with precision |P| (which is optional), or -|\xintDigits| if |P| was absent, the result of this computation. +|\xintFloatSub [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| +and |g| with their float approximations |f'| and |g'| to |P| significant +places or to the precision from |\xintDigits|.\CHANGED{1.2f} It then produces +the difference |f'-g'| correctly rounded to nearest |P|-float. + +As for \csbxint{Float}, in case of rounding up to next power of ten, the value +may exceptionally come out as |10.0...0eN| with a total of |P+1| digits. + +See \autoref{ssec:floatingpoint} for more. + \subsection{\csbh{xintFloatMul}}\label{xintFloatMul} -%{\small New with release |1.07|.\par} -|\xintFloatMul [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| and -|g| with their float approximations, with 2 safety digits. It then multiplies -exactly and outputs in float format with precision |P| (which is optional), or -|\xintDigits| if |P| was absent, the result of this computation. +|\xintFloatMul [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| +and |g| with their float approximations |f'| and |g'| to |P| (or +|\xinttheDigits|) significant places.\CHANGED{1.2f} It then correctly rounds +the product |f'*g'| to nearest |P|-float. + +See \autoref{ssec:floatingpoint} for more. \begin{framed} It is obviously much needed that the author improves its algorithms to avoid - going through the exact |2P| or |2P-1| digits (plus safety digits) before + going through the exact |2P| or |2P-1| digits before throwing to the waste-bin half of those digits ! - \xintname initially was purely an \emph{exact} arbitrary precision - arithmetic machine, and the introduction of floating point numbers was an - after-thought. I got it working in release |1.07 (2013/05/25)| and never had - time to come back to it. + % \xintname initially was purely an \emph{exact} arbitrary precision + % arithmetic machine, and the introduction of floating point numbers was an + % after-thought. I got it working in release |1.07 (2013/05/25)| and never had + % time to come back to it. \end{framed} \subsection{\csbh{xintFloatDiv}}\label{xintFloatDiv} -%{\small New with release |1.07|.\par} -|\xintFloatDiv [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| and -|g| with their float approximations, with 2 safety digits. It then divides -exactly and outputs in float format with precision |P| (which is optional), or -|\xintDigits| if |P| was absent, the result of this computation. +|\xintFloatDiv [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| +and |g| with their float approximations |f'| and |g'| to |P| (or +|\xinttheDigits|) significant places.\CHANGED{1.2f} It then correctly rounds +the fraction |f'/g'| to nearest |P|-float. + +See \autoref{ssec:floatingpoint} for more. + \subsection{\csbh{xintFloatFac}}\label{xintFloatFac} -\csa{xintFloatFac}|[P]{f}|\etype{{\upshape[\numx]}\Ff} returns the -factorial. +\csa{xintFloatFac}|[P]{f}|\etype{{\upshape[\numx]}\Numf} returns the +factorial with either \csa{xinttheDigits} or |P| digits of precision. + +% je devrais vérifier mais j'ai écrit cela fin novembre 2015 début décembre je +% suppose que je savais ce que je disais. + + +The exact theoretical value differs from the calculated one |Y| by an absolute +error strictly less than |0.6 ulp(Y)|.\NewWith{1.2} + \begin{everbatim*} $1000!\approx{}$\xintFloatFac [30]{1000} \end{everbatim*} -The computation\NewWith{1.2 !} proceeds via doing explicitely the product, as +The computation proceeds via doing explicitely the product, as the Stirling formula cannot be used for lack so far of |exp/log|. -% \footnote{The computation of $100000!$ with $16$ digits of precision takes -% about three or four seconds and for $1000000!$ it is about fifty seconds on -% my laptop (2015/10/06).} -% -There is no a priori limit set on the |P| optional argument, thus the Stirling -approach would become complicated if that freedom was to be obeyed. -The macro |\xintFloatFac| chooses dynamically an appropriate number of -digits for the intermediate computations, large enough to achieve the desired -accuracy (hopefully). +The maximal allowed argument is $99999999$, but already $100000!$ currently +takes, for \dtt{16} digits of precision, a few seconds on my laptop (it +returns \dtt{2.824229407960348e456573}). + +The |factorial| function is available in \csbxint{floatexpr}: +\begin{everbatim*} +\xintthefloatexpr factorial(1000)\relax % same as 1000! +\end{everbatim*} + +\subsection{\csbh{xintFloatBinomial}}\label{xintFloatBinomial} + +\csa{xintFloatBinomial}|[P]{x}{y}|\etype{{\upshape[\numx]}\Numf\Numf} computes +binomial coefficients with either \csa{xinttheDigits} or |P| digits of +precision.\NewWith{1.2f} + +The exact theoretical value differs from the calculated one |Y| by an absolute +error strictly less than |0.6 ulp(Y)|. + +\begin{everbatim*} +${3000\choose 1500}\approx{}$\xintFloatBinomial [24]{3000}{1500} +\end{everbatim*} + +% \begin{everbatim*} +% ${9999\choose 5000}\approx{}$\xintFloatBinomial [24]{9999}{5000} +% \end{everbatim*} + +% 2015/11/28 +% 7.95895131766219474168799e3007 +% aparté: (testé avec Maple 16, 2015/11/28) +% > binomial (9999.,5000.); +% 3008 +% 0.795895131768 10 +% +% > Digits:=32; +% Digits := 32 +% +% > binomial (9999.,5000.); +% 3008 +% 0.795895131768 10 +% apparemment le binomial de Maple ne sait pas calculer avec plus de +% précision! +% et son dernier chiffre est faux! Pourtant GAMMA(9999.) fonctionne. Sauf si +% je n'ai pas compris quelque chose il me semble donc que le binomial de Maple +% est bogué...binomial(100.,50.); marche lui et binomial(4999.,2000.); aussi, +% bon clairement on a un bug de Maple ! oui binomial(8999.,5000.); ainsi que +% binomial(10999.,5000.); fonctionnent avec Digits:=32 mais **pas** +% binomial(9999.,5000.)... binomial(10000.,5000.); et binomial(9998.,5000.); +% sont OK. Est-ce qu'on gagne quelque chose pour un bug report ? +% > binomial(9999.,5000.); +% 3008 +% 0.795895131768 10 +% > binomial(10000.,5000.); +% 3009 +% 0.1591790263532438948337597273641521 10 +% > binomial(9998.,5000.); +% 3008 +% 0.3979077671466477799149739359402922 10 +% en plus je lui demande 32 chiffres et il m'en sort 34. + +The |binomial| function is available in \csbxint{floatexpr}: +\begin{everbatim*} +\xintthefloatexpr binomial(3000,1500)\relax +\end{everbatim*} + +The computation is based on the formula |(x-y+1)...x/y!| (here one arranges +|y<=x-y| naturally). + + +\subsection{\csbh{xintFloatPFactorial}}\label{xintFloatPFactorial} + +\csa{xintFloatPFactorial}|[P]{x}{y}|\etype{{\upshape[\numx]}\Numf\Numf} +computes the product |(x+1)...y|. + +The inputs |x| and |y| must evaluate to non-negative integers less than +$10^8$.\NewWith{1.2f} + +% J'ai écrit ça début décembre 2015. Je suppose que je peux me faire confiance. +The exact theoretical value differs from the calculated one |Y| by an absolute +error strictly less than |0.6 ulp(Y)|. + +The |pfactorial| function is available in \csbxint{floatexpr}: +\begin{everbatim*} +\xintthefloatexpr pfactorial(2500,5000)\relax +\end{everbatim*} \subsection{\csbh{xintFloatPow}}\label{xintFloatPow} -%{\small New with |1.07|.\par} |\xintFloatPow [P]{f}{x}|\etype{{\upshape[\numx]}\Ff\numx} uses either the -optional argument |P| or the value of |\xintDigits|. It computes a floating +optional argument |P| or the value of |\xinttheDigits|. It computes a floating approximation to |f^x|. The precision |P| must be at least |1|, naturally. The exponent |x| will be fed to a |\numexpr|, hence count registers are accepted @@ -9957,16 +9877,15 @@ which allows the exponent to be a fraction simplifying to an integer and does not limit its size. This slightly slower routine is the one to which |^| is mapped inside |\xintthefloatexpr...\relax|. -The macro |\xintFloatPow| chooses dynamically an appropriate number of -digits for the intermediate computations, large enough to achieve the desired -accuracy (hopefully). +The argument |f| is first rounded to |P| significant places to give +|f'|.\CHANGED{1.2f} The output |Z| is such that the exact |f'^x| differs from +|Z| by an absolute error less than |0.52 ulp(Z)|. % \leftedline{|\xintFloatPow [8]{3.1415}{1234567890}|% \dtt{=\xintFloatPow [8]{3.1415}{1234567890}}} \subsection{\csbh{xintFloatPower}}\label{xintFloatPower} -%{\small New with |1.07|.\par} \csa{xintFloatPower}|[P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Numf} computes a floating point value |f^g| where the exponent |g| is not constrained to be at @@ -9974,9 +9893,18 @@ most the \TeX{} bound \texttt{\number "7FFFFFFF}. It may even be a fraction |A/B| but must simplify to a (possibly big) integer. The exponent of the \emph{output} however \emph{must} at any rate obey the \TeX{} \dtt{\number"7FFFFFFF} bound. + +The argument |f| is first rounded to |P| significant places to give +|f'|.\CHANGED{1.2f} The output |Z| is such that the exact |f'^g| differs from +|Z| by an absolute error less than |0.6 ulp(Z)| (actually |0.52 +ulp(Z)|).\footnote{For the |0.6 ulp(Z)| bound, earlier releases had + potentially a problem for negative exponents; the final reverse was done + with only two guard digits (due to the implementation of \csbxint{Float}), + and as a result the final error could conceivably exceed |0.6 ulp(Z)|, + although remaining smaller than |0.7 ulp(Z)|.} + + % -\leftedline{|\xintFloatPower [8]{1.000000000001}{1e12}|% - \dtt{=\xintFloatPower [8]{1.000000000001}{1e12}}} % \leftedline{|\xintFloatPower [8]{3.1415}{3e9}|% \dtt{=\xintFloatPower [8]{3.1415}{3e9}}} Notice that |3e9>2^31|. @@ -9997,8 +9925,13 @@ $2^{31}$ is not quite there yet.\footnote{The printing of the result was done package.} Inside an |\xintfloatexpr|-ession, \csa{xintFloatPower} is the function to -which |^| is mapped. Thus the same computation as above can be done via the -non-expandable assignment |\xintDigits:=48;| and +which |^| is mapped.\footnote{I am constantly hesitating about this. In my + testing, switching to \csbxint{FloatPow} would only bring from 5\% to + perhaps 20\% gain for computations with \dtt{16} digits of precision and + moderately sized exponent.}\footnote{Since |1.2f|, the \string^ operator + handles also half-integer exponents.\NewWith {1.2f}} Thus the same +computation as above can be done via the non-expandable assignment +|\xintDigits:=48;| and % \leftedline{|\xintthefloatexpr 1.1547^(2^35)\relax|} % @@ -10016,58 +9949,44 @@ There is an important difference between |\xintFloatPower [Q]{X}{Y}| and with |Q| digits or precision (but if |X| and |Y| themselves stand for some floating point macros with arguments, their respective evaluations obey the precision |\xinttheDigits| or as set optionally in the macro calls -themselves), whereas with \csbxint{thefloatexpr} the evaluation of the +themselves), whereas with \csbxint{thefloatexpr}|[Q]| the evaluation of the expression proceeds with |\xinttheDigits| digits of precision, and the final -output is rounded to |Q| digits: thus this makes real sense only if used with -|Q<\xinttheDigits|. +result is then rounded to |Q| digits: thus this makes real sense only if used +with |Q<\xinttheDigits|. + -The intermediate multiplications executed by |\xintFloatPower| are done with a -higher precision than |\xinttheDigits| or the optional |P| argument, in order -for the final result to have the desired accuracy. -% % -% \footnote{\label{fn:floatpow}% -% Release |1.2| did not change a single line of code to these macros because -% they don't access low-level entry points. There is some sure important -% efficiency gains to be obtained in maintaining internally the best inner -% format for the successive squarings and multiplications, but I decided to -% postpone that, as the more urgent issue is to improve \csbxint{FloatMul} to -% not compute exactly with all digits the product before keeping only the -% required digits.} -\emph{This means that the error, compared to rounding an exact evaluation, is - guaranteed to be strictly less than |0.6| floating point unit. The last - digit may thus be wrong, and if it is |0| or |9| with it the next to last, - etc... } -% ATTENTION A VERIFIER QUE JE FAIS BIEN CELA. \subsection{\csbh{xintFloatSqrt}}\label{xintFloatSqrt} -%{\small New with |1.08|.\par} \csa{xintFloatSqrt}|[P]{f}|\etype{{\upshape[\numx]}\Ff} computes a floating point approximation of $\sqrt{|f|}$, either using the optional precision |P| or -the value of |\xintDigits|. If the asked-for precision is for less than |17| -figures the computation proceeds nevertheless to achieve that precision and -the output is rounded to the smaller precision. -% -\leftedline{|\xintFloatSqrt [50]{12.3456789e12}|} -% -\leftedline{${}\approx{}$\dtt{\xintFloatSqrt [50]{12.3456789e12}}} -% -\leftedline{|\xintDigits:=50;\xintFloatSqrt {\xintFloatSqrt {2}}|} -% -\leftedline{${}\approx{}$\xintDigits:=50;\dtt{\xintFloatSqrt {\xintFloatSqrt - {2}}}} +the value of |\xinttheDigits|. + +More precisely the macro achieves so-called \emph{correct + rounding}:\IMPORTANT{} the produced value is the rounding to |P| significant +places of the abstract exact value, \emph{if the input has itself at most |P| + digits} (and an arbitrary exponent).\NewWith{1.2f} + +\begin{everbatim*} +\xintFloatSqrt [89]{10}\newline +\xintFloatSqrt [89]{100}\newline +\xintFloatSqrt [89]{123456789}\newline +And now some tests to check that correct rounding applies correctly (sic):\newline +(we observe in passing illustrations that rounding to nearest is not transitive)\newline +\xintFloatSqrt {5625000075000001}\newline +\xintFloatSqrt [24]{5625000075000001}\newline +\xintFloatSqrt [32]{5625000075000001}\newline +\xintFloatSqrt [48]{562500000000000000000000750000000000000000000001}\newline +\xintFloatSqrt [64]{562500000000000000000000750000000000000000000001}\newline +\xintFloatSqrt [80]{562500000000000000000000750000000000000000000001}\par +\end{everbatim*} + + -% maple: 0.351364182864446216166582311675807703715914271812431919843183 1O^7 -% 3.5136418286444621616658231167580770371591427181243e6 -% maple: 1.18920711500272106671749997056047591529297209246381741301900 -% 1.1892071150027210667174999705604759152929720924638e0 -\xintDigits:=16; -% removed from doc october 22 -% \subsection{\csbh{xintSum}, \csbh{xintSumExpr}}\label{xintSum} -% \label{xintSumExpr} +\xintDigits:=16; \subsection{\csbh{xintiDivision}, \csbh{xintiQuo}, \csbh{xintiRem}, \csbh{xintFDg}, \csbh{xintLDg}, \csbh{xintMON}, \csbh{xintMMON}, @@ -10089,6 +10008,7 @@ be used when one is dealing exclusively with (big) integers. %\etocdepthtag.toc {xintexpr} +\clearpage \section{Commands of the \xintexprname package}% \label{sec:expr} @@ -10119,13 +10039,6 @@ the only arithmetic package from the \xintname bundle which loads \end{everbatim*} \end{itemize} -% \begin{framed} -% Despite some enhancements this documentation still has repetitions, is -% a.t.t.o.w generally speaking not well structured, mixes old explanations -% dating back to the first release and some more recent ones. -% \end{framed} - - \subsection{The \csbh{xintexpr} expressions} \label{xintexpr} \label{xinttheexpr} @@ -10162,12 +10075,20 @@ As an alternative and equivalent syntax to \begin{everbatim} \xintexpr round(<expression>, D)\relax \end{everbatim} -there is +there is\footnote{For truncation rather than rounding, one uses +|\xintexpr trunc(<expression>, D)\relax|.} \begin{everbatim} \xintiexpr [D] <expression> \relax \end{everbatim} -The parameter |D| must be zero or positive. Perhaps some future version will -give a meaning to using a negative |D|.\footnote{Thanks to KT for this suggestion.} +The parameter |D| must be zero or positive.\footnote{Notice that |D=0| + corresponds to using |round(<expression>)| not |round(<expression>,0)| which + would leave a trailing dot. Same for |trunc|. There is also function |float| + for floating point rounding to \csbxint{theDigits} or the given number of + significant digits as second argument.} Perhaps some future version will +give a meaning to using a negative |D|.\footnote{Thanks to KT for this + suggestion. Sorry for the delay in implementing it... matter of formatting + the output and corresponding choice of user interface are still in need of + some additional thinking.} \begin{itemize} \item the expression may contain arbitrarily many levels of nested parenthesized @@ -10182,336 +10103,13 @@ give a meaning to using a negative |D|.\footnote{Thanks to KT for this suggestio |\xinttheexpr...\relax| or |\xintthe\xintexpr...\relax| forms. Similarly, printing the result itself must be done with these forms. \item one should not use |\xinttheexpr...\relax| as a sub-constituent of an - |\xintexpr...\relax| but\IMPORTANT{} only the + |\xintexpr...\relax| but\IMPORTANT{} only the |\xintexpr...\relax| form which is more efficient in this context. \item each \xintexprname{}ession, whether prefixed or not with |\xintthe|, is completely expandable and obtains its result in two expansion steps. \end{itemize} -\subsection{\csbh{xintdefvar}, \csbh{xintunassignvar}, \csbh{xintdeffunc}, \csbh{xintverbosetrue}} -\label{xintdefvar} -\label{xintdefiivar} -\label{xintdeffloatvar} -\label{xintdeffunc} -\label{xintdefiifunc} -\label{xintdeffloatfunc} -\label{xintunassignvar} -\label{xintverbosetrue} -\label{xintverbosefalse} -\label{ifxintverbose} - -Since release |1.1| it is possible to assign a variable name to let it be -known to the parsers of \xintexprname. -\begin{everbatim*} -\xintdefvar Pi:=3.141592653589793238462643; -\xintthefloatexpr Pi^100\relax -\xintdefvar x_1 := 10;\xintdefvar x_2 := 20;\xintdefvar y@3 := 30; -\quad $x_1\cdot x_2\cdot y@3+1=\xinttheiiexpr x_1*x_2*y@3+1\relax$. -\end{everbatim*} - -As |x_1x| is a licit variable name, as well as |x_1x_| and |x_1x_2| and -|x_1x_2y| etc... we could not count on tacit multiplication being applied to -something like |x_1x_2|; the parser goes not go to the effort of tracing back -its steps. Hence we had to insert explicit |*| infix operators (one often -falls into this trap when playing with variables and counting too much on the -divinatory talents of \xintexprname...). - -The variable definition is done with \csa{xintdefvar}, \csa{xintdefiivar}, or -with \csa{xintdeffloatvar}, the variable will be computed using respectively -\csbxint{expr}, \csbxint{iiexpr} or \csbxint{floatexpr}. The variable -once defined can be used in the other parsers, except naturally that in -\csa{xintiiexpr} only integers are accepted. - -When defining a variable with \csa{xintdeffloatvar}, it is important that -reduction to \csbxint{theDigits} digits of precision happens inside -\csbxint{floatexpr} only if an operation is executed. Thus, for a variable -declaration with no operations, the value is registered with all its digits. -\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 -\xintthefloatexpr - 2.718281828459045, 2.718281828459045^1000, 2.718281828459045^1000000\relax\newline -\xintdeffloatvar e:=2.7182818284590452353602874713526624977572470936999595749669676;% -\xintthefloatexpr e, e^1000, e^1000000\relax\par -\end{everbatim*} - -Legal variable names are composed with letters, digits, |@| and |_| signs. -They must start with a letter.\footnote{this is for obvious reasons for digits; - and names starting with |@| or |_| are reserved to the enjoyment of the - package author; currently |@|, |@1|, |@2|, |@3|, |@4|, |@@|, |@@@|, |@@@@| - have special meanings and the |@| and |_| are used internally; you will have - been warned.} Single letter names |a..z| and |A..Z| are pre-declared by the -package for use as special type of variables called ``dummy variables''. - - -Since release |1.2c| it is possible to also declare functions: -\begin{everbatim*} -\xintdeffunc - Rump(x,y):=1335 y^6/4 + x^2 (11 x^2 y^2 - y^6 - 121 y^4 - 2) + 11 y^8/2 + x/2y; -\end{everbatim*}(notice the numerous tacit multiplications in this expression; -and that |x/2y| is interpreted as |x/(2y)|.) - -\begin{framed} - The (dummy) variables used in the function declaration are necessarily single - letters (lowercase or uppercase) which have \emph{not} been re-declared via - |\xintdefvar| as assigned variables. The choice of the letters is entirely - up to the user and has nil influence on the actual function, naturally. - - A function can have at most nine variables. - - The names of the macros \csa{xintdeffunc}, \csa{xintdefiifunc}, - \csa{xintdeffloatfunc} (and those for variables) as well as their syntax - (with |:=| and an ending |;|) will be set definitely only in next release. - \footnotemark -\end{framed} -\footnotetext{with the current syntax, the |;| as used for |iter|, |rseq|, - |rrseq| must be hidden as |{;}| to not be confused with the |;| ending the - declaration.} - -Let's try the famous \textsc{Rump} test: -\begin{everbatim*} -\xinttheexpr Rump(77617,33096)\relax. -\end{everbatim*} -Nothing problematic for an \emph{exact} evaluation, naturally ! - -A function may be declared either via \csa{xintdeffunc}, \csa{xintdefiifunc}, -\csa{xintdeffloatfunc}. It will then be known \emph{only} to the parser which -was used for its definition. - -Thus to test the \textsc{Rump} polynomial (it is not quite a polynomial with -its |x/2y| final term) with floats, we \emph{must} also -declare |Rump| as a function to be used there: -\begin{everbatim*} -\xintdeffloatfunc - Rump(x,y):=333.75 y^6 + x^2 (11 x^2 y^2 - y^6 - 121 y^4 - 2) + 5.5 y^8 + x/2y; -\end{everbatim*} -(I used coefficients |333.75| and |5.5| rather than fractions only because this -is how I saw the polynomial defined in one computer class reference found on -internet; and for float operations this may matter on the rounding). - -The numbers are scanned with the current precision, hence as here it is -\dtt{16}, they are scanned exactly in this case. We can then vary the -precision for the evaluation. -\begin{everbatim*} -\def\CR{\cr} -\halign -{\tabskip1ex -\hfil\bfseries#&\xintDigits:=\xintiloopindex;\xintthefloatexpr Rump(77617,33096)#\cr -\xintiloop [8+1] -\xintiloopindex &\relax\CR -\ifnum\xintiloopindex<40 \repeat -} -\end{everbatim*} - -It is licit to overload a variable name (all Latin letters are predefined as -dummy variables) with a function name and vice versa. The parsers will decide -from the context if the function or variable interpretation must be used -(dropping various cases of tacit multiplication as normally applied). -\begin{everbatim*} -\xintdefiifunc f(x):=x^3; -\xinttheiiexpr add(f(f),f=100..120)\relax\newline -\xintdeffunc f(x,y):=x^2+y^2; -\xinttheexpr mul(f(f(f,f),f(f,f)),f=1..10)\relax -\end{everbatim*} - -The mechanism for functions is identical with the one underlying the -\csbxint{NewExpr} command. A function once declared is a first class citizen, -its expression is entirely parsed and converted into a big nested \fexpan -dable macro. When used its action is via this defined macro. For example -\begin{everbatim*} -\xintdeffunc - e(z):=(((((((((z/10+1)z/9+1)z/8+1)z/7+1)z/6+1)z/5+1)z/4+1)z/3+1)z/2+1)z+1; -\end{everbatim*} -creates a macro whose meaning one can find in the log file, after -|\xintverbosetrue|. Here it is: -\begin{everbatim} - Function e for \xintexpr parser associated to \XINT_expr_userfunc_e with me -aning macro:#1,->\romannumeral `^^@\xintAdd {\xintMul {\xintAdd {\xintDiv {\xin -tMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xi -ntDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\x -intAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {# -1}{10}}{1}}{#1}}{9}}{1}}{#1}}{8}}{1}}{#1}}{7}}{1}}{#1}}{6}}{1}}{#1}}{5}}{1}}{#1 -}}{4}}{1}}{#1}}{3}}{1}}{#1}}{2}}{1}}{#1}}{1} -\end{everbatim} - - -See \autoref{sssec:limitations} for some limitations of the syntax, shared -with those of the \csbxint{NewExpr} command. The main one is that dummy -variables may be used only over values not depending upon the arguments to the -function being declared. For example |\xintdeffunc f(x):=add(i^2,i=1..x);| is -currently illegal. As an Ersatz, one may in this case use the alternative -syntax allowed by list operations: -\begin{everbatim*} -\xintdeffunc f(x):=`+`([1..x]^2); -\xinttheexpr seq(f(x), x=1..20)\relax -\end{everbatim*}\newline -The two syntaxes here are anyhow roughly equivalent: both first generate -explicitely the list of integers from one to |x|. Side remark: as the -|seq(f(x), x=1..10)| does many times the same computations, an |rseq| here -would be more efficient:\footnote{see the next section for the explanation of - the syntax. Note that |omit| and |abort| are not usable in |add| or |mul| - (currently).} -\begin{everbatim*} -\xinttheexpr rseq(1; (x>20)?{abort}{@+x^2}, x=2++)\relax -\end{everbatim*} - -On the other hand a construct like the following has no issue, as the values -iterated over do not depend upon the function parameters: -\begin{everbatim*} -\xintdeffunc f(x):=iter(1{;} @*x/i+1, i=10..1);% one must hide the first semi-colon ! -\xinttheexpr e(1), f(1)\relax -\end{everbatim*} - -It is somewhat frustrating not to be able to use the whole \xintexprname -syntax in \csa{xintdeffunc} and \csa{xintNewExpr}. The explanation is simply -that the implementation of |seq|, |iter|, etc... relies on exhaustive -expansion inside |\csname ... \endcsname| whereas \csa{xintdeffunc} tries to -construct an \fexpan dable macro. Furthermore the |omit| and |abort| keywords -as well as the |break()| function are discovered ``dynamically'' when an -expression is parsed from left to right; if they were to be used with an -abstract value list, the information of their presence would have to be coded -especially. This could end up not being much different than storing the whole -|seq|, |iter|, etc.. thing ``as is'' into something not much different from a -macro definition: -\begin{everbatim} -\def\macro #1#2{\xinttheexpr iter(1{;} @*#2/i+1, i=#1..1)\relax} -\end{everbatim} -whic is very different from a function declaration (side remark: beware that -using it with |#2=1+1| will cause unexpected result, the macro definition -above should have employed |(#2)| rather than |#2|.) - -With |\xintverbosetrue| the values of the variables and the meanings of the -functions (or rather their associated macros) will be written to the log. For -example the first |Rump| declaration above generates this in the log file: -\begin{everbatim} - Function Rump for \xintexpr parser associated to \XINT_expr_userfunc_Rump w -ith meaning macro:#1,#2,->\romannumeral `^^@\xintAdd {\xintAdd {\xintAdd {\xint -Div {\xintMul {1335}{\xintPow {#2}{6}}}{4}}{\xintMul {\xintPow {#1}{2}}{\xintSu -b {\xintSub {\xintSub {\xintMul {\xintMul {11}{\xintPow {#1}{2}}}{\xintPow {#2} -{2}}}{\xintPow {#2}{6}}}{\xintMul {121}{\xintPow {#2}{4}}}}{2}}}}{\xintDiv {\xi -ntMul {11}{\xintPow {#2}{8}}}{2}}}{\xintDiv {#1}{\xintMul {2}{#2}}} -\end{everbatim} -and the declaration of function |f(x)| generates the following log: -\begin{everbatim} - Function f for \xintexpr parser associated to \XINT_expr_userfunc_f with me -aning macro:#1,->\romannumeral `^^@\xintAdd {\xintDiv {\xintMul {\xintAdd {\xin -tDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xi -ntAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\x -intMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\ -xintDiv {\xintMul {1}{#1}}{10/1[0]}}{1}}{#1}}{9/1[0]}}{1}}{#1}}{8/1[0]}}{1}}{#1 -}}{7/1[0]}}{1}}{#1}}{6/1[0]}}{1}}{#1}}{5/1[0]}}{1}}{#1}}{4/1[0]}}{1}}{#1}}{3/1[ -0]}}{1}}{#1}}{2/1[0]}}{1}}{#1}}{1/1[0]}}{1} -\end{everbatim} - -Starting with |1.2d| the definitions made by \csbxint{NewExpr} have local -scope, hence this is also the case with the definitions made by -\csbxint{deffunc}.\IMPORTANT{} One can not ``undeclare'' a function, but -naturally one can provide a new definition for it. - -Variable declarations also are local. One can not really ``unassign'' a -declared variable, but macro \csa{xintunassignvar} will let it insert a zero -and provoke a \TeX{} ``undefined macro'' error. Also, using -\csa{xintunassignvar}\IMPORTANT{} on a letter will let it recover fully its -original meaning as dummy variable. This may even be used for other -characters, if they are used in expressions with catcode 11. As most every -character in the ascii range already has some meaning for \xintexprname, this -is not really recommended, though. -\begin{everbatim*} -\xintFor #1 in {e_1, e_2, e_3, e_4, e} \do {\xintunassignvar {#1}} -\end{everbatim*} - -N.B.: we declared in this section |e| as a function. This can not be undone, -and if |e| is used as dummy variable tacit multiplication in front of -parentheses will not be applied, it is the function interpretation which -will prevail. Except naturally if the function declaration was done in a group -or a \LaTeX{} environment whose scope has ended. - - -\subsection{Tacit multiplication} -\label{ssec:tacit multiplication} - -Tacit multiplication (insertion of a |*|) applies when the parser is currently -either scanning the digits of a number (or its decimal part or scientific -part, or hexadecimal input), or is looking for an infix operator, and: -(1.)~\emph{encounters a count or dimen or skip register or variable or an - \eTeX{} expression}, or (2.)~\emph{encounters a sub-\csa{xintexpr}ession}, -or (3.)~\emph{encounters an opening parenthesis}, or (4.)~\emph{encounters a - letter (which is interpreted as signaling the start of either a variable or - a function name)}. - -% ATTENTION QUE SI JE RETIRE LE FRAME IL FAUDRA ``UNASSIGN''-ER x ET y -\begin{framed} - For example, if |x, y, z| are variables all three of |(x+y)z|, |x(y+z)|, - |(x+y)(x+z)| will create a tacit multiplication. - - Furthermore starting with release - |1.2e|,\MyMarginNote[\kern\dimexpr\FrameSep+\FrameRule\relax]{Changed} - whenever tacit multiplication is applied, in all cases it \emph{always} - ``ties'' more\IMPORTANT{} than normal multiplication or division, but - still less than power. Thus |x/2y| is interpreted as |x/(2y)| and - similarly for |x/2max(3,5)| but |x^2y| is still interpreted as |(x^2)*y| - and |2n!| as |2*n!|. - -\begin{everbatim*} -\xintdefvar x:=30;\xintdefvar y:=5;% -\xinttheexpr (x+y)x, x/2y, x^2y, x!, 2x!, x/2max(x,y)\relax -\end{everbatim*} - - The ``tye more'' rule applies to all cases of tacit multiplication. It - impacts only situations when a division was the last seen operator, as the - normal rule for the \xintexprname parsers is left-associativity in case of - equal precedence. -\begin{everbatim*} -\xinttheexpr (1+2)/(3+4)(5+6), 2/x(10), 2/10x, 3/y\xintiiexpr 5+6\relax, 1/x(y)\relax -\end{everbatim*} - - Note that |y\xinttheiiexpr 5+6\relax| would have tried to use a variable - with name |y11| rather than doing |y*11|: tacit multiplication works only - in front of sub-\csbxint{expr}essions, not in front of - \csbxint{theexpr}essions which are unlocked into explicit digits. - - These examples above redeclared the |x| and |y| which thus can not be used as - dummy variables anymore (but see \csbxint{unassignvar}); as this happened - inside a \LaTeX{} environment (for the frame), they will have - recovered their meanings after the frame. In the meantime we use letter - |z| for the next example. Here is an expression whose meaning is - completely modified by the ``tye more'' property of tacit multiplication:\IMPORTANT -\begin{everbatim} -\xintdeffunc e(z):=1+z(1+z/2(1+z/3(1+z/4))); -\end{everbatim} -will be parsed as |1+z*(1+z/(2*(1+z/(3*(1+z/4)))))| which is - not at all like the presumably hoped: -\begin{everbatim} -\xintdeffunc e(z):=1+z(1+z/2*(1+z/3*(1+z/4))); -\end{everbatim} -This form can also be used, alternatively: -\begin{everbatim} -\xintdeffunc e(z):=(((z/4+1)z/3+1)z/2+1)z+1; -\end{everbatim} - - Attention! tacit multiplication before an opening parenthesis applies - always, but tacit multiplication after a closing parenthesis \emph{does - not} apply in front of digits: |(1+1)5| is not legal. But - |subs((1+1)x,x=5)| is, because in that case a variable is following the - closing parenthesis. -\end{framed} - -\subsection{The syntax} +\subsection{Expression syntax overview} \label{ssec:syntax} An expression is enclosed between either \csbxint{expr}, or \csbxint{iexpr}, @@ -10557,10 +10155,11 @@ two |t|'s. of the previous \csa{xintexprSafeCatcodes}. \item The infix operators are |+|, |-|, |*|, |/|, |^| (or |**|) for exact or - floating point algebra (only integer exponents for power operations), |&&| + floating point algebra (currently, only integer and half-integer + exponents are allowed for float power operations), |&&| and \verb+||+ \footnote{with releases earlier than |1.1|, only single character operators |&| and \verb+|+ were available, because the parser - did not handle multi-character operators. Their usage in this rôle is now + did not handle multi-character operators. Their usage in this rôle is now deprecated,\IMPORTANT{} as they may be assigned some new meaning in the future.} for combining ``true'' (non zero) and ``false'' (zero) conditions, as can be formed for example with the |=| (or |==|), |<|, |>|, @@ -10573,106 +10172,19 @@ two |t|'s. \item The |?| may serve either as a function (the truth value) requiring an argument within parentheses, or as two-way post-fix branching operator - |(cond)?{YES}{NO}|. The false branch will \emph{not} be evaluated. + |(cond)?{YES}{NO}|. The false branch will \emph{not} be evaluated. \item There is also |??| which branches according to the scheme |(x)??{<0}{=0}{>0}|. \item Comma separated lists may be generated with |a..b| and |a..[d]..b| and - they may be manipulated to some extent once put into bracket. There is no - real concept of a list object, nor list operations, although itemwise - manipulation are made possible as shown below via the |[..]| constructor. - There is no notion of an ``nuple'' object. The variable |nil| is reserved, - it represents an empty list. - \begin{itemize} - \item |a..b| constructs the \textbf{small} integers from $\lceil a\rceil$ to - $\lfloor b\rfloor$ (possibly a decreasing sequence), -\begin{everbatim*} -\xinttheexpr 1.5..11.23\relax -\end{everbatim*} - - \item |a..[d]..b| allows big integers, or fractions, it proceeds by step of |d|. -\begin{everbatim*} -\xinttheexpr 1.5..[0.97]..11.23\relax -\end{everbatim*} - - \item |[list][n]| extracts the |n|th element, or give the number of items if - |n=0|. If |n<0| it extracts from the tail. -\begin{everbatim*} -\xinttheiexpr \empty[1..10][6], [1..10][0], [1..10][-1], [1..10][23*18-22*19]\relax\ -(and 23*18-22*19 has value \the\numexpr 23*18-22*19\relax). -\end{everbatim*} - -See the frame coming next for the |\empty| token. -As shown, it is perfectly legal to do operations in the index parameter, which -will be handled by the parser as everything else. The same remark applies to -the next items. - - \item |[list][:n]| extracts the first |n| elements if |n>0|, or suppresses - the last \verb+|n|+ elements if |n<0|. -\begin{everbatim*} -\xinttheiiexpr [1..10][:6]\relax\ and \xinttheiiexpr [1..10][:-6]\relax -\end{everbatim*} - \item |[list][n:]| suppresses the first |n| elements if |n>0|, or extracts - the last \verb+|n|+ elements if |n<0|. -\begin{everbatim*} -\xinttheiiexpr [1..10][6:]\relax\ and \xinttheiiexpr [1..10][-6:]\relax -\end{everbatim*} -\item More generally, |[list][a:b]| works according to the Python ``slicing'' - rules (inclusive of negative indices). Notice though that there is no - optional third argument for the step, which always defaults to |+1|. -\begin{everbatim*} -\xinttheiiexpr [1..20][6:13]\relax\ = \xinttheiiexpr [1..20][6-20:13-20]\relax -\end{everbatim*} -\item It is naturally possible to nest these things: -\begin{everbatim*} -\xinttheexpr [[1..50][13:37]][10:-10]\relax -\end{everbatim*} -\item itemwise operations either on the left or the right are possible: -\begin{everbatim*} -\xinttheiiexpr 123*[1..10]^2\relax -\end{everbatim*} - -\begin{snugframed} - As list operations are implemented using square brackets, it is - necessary in |\xintiexpr| and |\xintfloatexpr| to insert something before - the first bracket if it belongs to a list, to avoid confusion with the - bracket of an optional parameter. We need something expandable which does - not leave a trace: the |\empty| does the trick.\IMPORTANT{} + they may be manipulated to some extent once put into bracket. See + \autoref{ssec:lists}. There is no real concept of a list object, nor list + operations, although itemwise manipulation are possible. There is no notion + of an ``nuple'' object. The variable |nil| is reserved, it represents an + empty list. -\begin{everbatim*} -\xinttheiexpr \empty [1,3,6,99,100,200][2:4]\relax -\end{everbatim*} - - An alternative is to use parentheses -\begin{everbatim*} -\xinttheiexpr ([1,3,6,99,100,200][2:4])\relax -\end{everbatim*} - - Notice though that |([1,3,6,99,100,200])[2:4]| would not work. It is - mandatory for |][| and |][:| not to be interspersed with parentheses. On - the other hand spaces are perfectly legal: -\begin{everbatim*} -\xinttheiiexpr [1..10 ] [ : 7 ]\relax -\end{everbatim*} - -Similarly all the |+[|, |*[|, \dots and |]**|, |]/|, \dots operators admit -spaces but nothing else in-between their constituent characters. -\begin{everbatim*} -\xinttheiiexpr [ 1 . . 1 0 ] * * 1 1 \relax -\end{everbatim*} - - In an other vein, the parser will be confused by |1..[list][3]|, one must - write |1..([list][3])|. Also things such as |[100,300,500,700][2]//11| will - be confusing because the |]/| is an operator with higher priority than the - |][|, and then there will a dangling |/11| which does not make sense. In - fact even |[100,300,500,700][2]/11| is a syntax error: one must write - |([100,300,500,700][2])//11|. -\end{snugframed} - -\end{itemize} - -\item count registers and |\numexpr|-essions are accepted (LaTeX{}'s counters +\item Count registers and |\numexpr|-essions are accepted (LaTeX{}'s counters can be inserted using |\value|) natively without |\the| or |\number| as prefix. Also dimen registers and control sequences, skip registers and control sequences (\LaTeX{}'s lengths), |\dimexpr|-essions, @@ -10683,10 +10195,10 @@ spaces but nothing else in-between their constituent characters. (|\numexpr| or |\dimexpr| or |\glueexpr|) expression is immediately prefixed by a (decimal) number. -\item see \autoref{ssec:tacit multiplication} for the complete rules +\item See \autoref{ssec:tacit multiplication} for the complete rules of tacit multiplication.\IMPORTANT -\item with a macro |\x| defined like this: +\item With a macro |\x| defined like this: % \leftedline{|\def\x {\xintexpr \a + \b \relax}| or |\edef\x {\xintexpr \a+\b\relax}|} @@ -10695,21 +10207,19 @@ spaces but nothing else in-between their constituent characters. to use it in some other macros expanding their arguments. The |\edef| does the computation immediately but keeps it in an internal private format. Naturally, the |\edef| is only possible if |\a| and |\b| are already - defined. With both cases (the `yet-to-be computed' and the `already - computed') the |\x| can be inserted in other expressions, as for example + defined. With both approaches the |\x| can be inserted in other expressions, + as for example (assuming naturally as we use an |\edef| that in the + `yet-to-be computed' case the |\a| and |\b| now have some suitable meaning): % \leftedline {|\edef\y {\xintexpr \x^3\relax}|} -\item there is also \csbxint{boolexpr}| ... \relax| and +\item There is also \csbxint{boolexpr}| ... \relax| and \csbxint{theboolexpr}| ... \relax|. Same as |\xintexpr| with the final result converted to $1$ if it is not zero. See also \csbxint{ifboolexpr} (\autoref{xintifboolexpr}) and the \hyperlink{item:bool}{discussion} of the |bool| and |togl| functions in \autoref{sec:expr}. Here is an example: -\catcode`| 12 % \xintNewBoolExpr le fait mais ça sera trop tard - % après le \scantokens qui aura redonné à | son - % caractère actif... avant j'utilisais ici \everb - % avec délimiteur ! +\catcode`| 12 % \begin{everbatim*} \xintNewBoolExpr \AssertionA[3]{ #1 && (#2|#3) } \xintNewBoolExpr \AssertionB[3]{ #1 || (#2) } @@ -10723,14 +10233,14 @@ spaces but nothing else in-between their constituent characters. \end{everbatim*}\catcode`| 13 This example used for efficiency \csbxint{NewBoolExpr}. See also the - \autoref{xintNewExpr}. + \autoref{xintNewExpr}. -\item there is \csbxint{floatexpr}| ... \relax| where the algebra is done +\item There is \csbxint{floatexpr}| ... \relax| where the algebra is done in floating point approximation (also for each intermediate result). Use the syntax |\xintDigits:=N;| to set the precision. Default: $16$ digits. % \leftedline{|\xintthefloatexpr 2^100000\relax:| \dtt{\xintthefloatexpr - 2^100000\relax }} + 2^100000\relax }} % The square-root operation can be used in |\xintexpr|, it is computed as a float with the precision set by |\xintDigits| or by the optional @@ -10739,20 +10249,20 @@ spaces but nothing else in-between their constituent characters. \begin{everbatim*} \xinttheexpr sqrt(2,60)\relax -Here the [60] is to avoid truncation to |\xintDigits| of precision on output. +Here the [60] is to avoid truncation to |\xinttheDigits| of precision on output. \printnumber{\xintthefloatexpr [60] sqrt(2,60)\relax} \end{everbatim*} - -\item - Floats are quickly indispensable when using the power function (which - can only have an integer exponent), as exact results will easily have - hundreds, if not thousands, of digits. + + Floats are quickly indispensable when using the power function , as exact + results will easily have hundreds, if not thousands, of digits. % \begin{everbatim*} \xintDigits:=48;\xintthefloatexpr 2^100000\relax \end{everbatim*} -\item hexadecimal \TeX{} number denotations (\emph{i.e.}, with a |"| prefix) +Only integer and half-integer exponents are allowed. + +\item Hexadecimal \TeX{} number denotations (\emph{i.e.}, with a |"| prefix) are recognized by the |\xintexpr| parser and its variants. \fbox{This requires \xintbinhexname}. Except in |\xintiiexpr|, a (possibly empty) fractional part with the dot |.| as ``hexadecimal'' mark is allowed. @@ -10766,59 +10276,231 @@ Here the [60] is to avoid truncation to |\xintDigits| of precision on output. % Letters must be uppercased, as with standard \TeX{} hexadecimal denotations. -\end{itemize} - -Note that |2^-10| is perfectly accepted input, no need for parentheses; and -that operators of power |^|, division |/|, and subtraction |-| are all -left-associative: |2^4^8| is evaluated as |(2^4)^8|. The minus sign as prefix -has various precedence levels: |\xintexpr -3-4*-5^-7\relax| evaluates as -|(-3)-(4*(-(5^(-7))))| and |-3^-4*-5-7| as |(-((3^(-4))*(-5)))-7|. +\item |2^-10| is perfectly accepted input, no need for parentheses; and + operators of power |^|, division |/|, and subtraction |-| are all + left-associative: |2^4^8| is evaluated as |(2^4)^8|. The minus sign as + prefix has various precedence levels: |\xintexpr -3-4*-5^-7\relax| evaluates + as |(-3)-(4*(-(5^(-7))))| and |-3^-4*-5-7| as |(-((3^(-4))*(-5)))-7|. -An exception to left associativity is applied in case of tacit -multiplication|x/2y| is interpreted as |x/(2y)|, not as |(x/2)*y| and -|(1+2)/(3+4)(5+6)| is computed as |(1+2)/((3+4)*(5+6))|. See -\autoref{ssec:tacit multiplication}. + An exception to left associativity is applied in case of tacit + multiplication |x/2y| is interpreted as |x/(2y)| and + |(1+2)/(3+4)(5+6)| is computed as |(1+2)/((3+4)*(5+6))|. See + \autoref{ssec:tacit multiplication}. -If one uses \emph{macros} within |\xintexpr..\relax| one should obviously take -into account that the parser will \emph{not} see the macro arguments. This -applies also to macros defined via \csbxint{NewExpr}. Functions declared with -\csbxint{deffunc} on the other hand behave exactly like the native functions -of the package. +\item if one uses \emph{macros} within |\xintexpr..\relax| one should + obviously take into account that the parser will \emph{not} see the macro + arguments. This applies also to macros defined via \csbxint{NewExpr}. + Functions declared with \csbxint{deffunc} on the other hand behave exactly + like the native functions of the package. -Here is, listed from the highest priority to the lowest, the complete list of -operators and functions. +\end{itemize} +\subsection{Infix and other operators and their precedence levels} % \ctexttt is a remnant of 1.09n manual, don't have time to get rid of it now. - \newcommand\ctexttt [1]{\begingroup\color[named]{DarkOrchid}%\bfseries #1\endgroup} + +We go through the various syntax elements from highest to lowest precedence. + \begin{itemize}[parsep=0pt, labelwidth=\leftmarginii, itemindent=0pt, listparindent=\leftmarginiii, leftmargin=\leftmarginii] -\item +\item Functions share the highest precedence. + + +\item \def\MicroFont{\color[named]{DarkOrchid}\ttfamily}The + |.| as decimal mark; the number scanner treats it as an inherent, + optional and unique component of a being formed number. One can do + things such as + % + \leftedline{\restoreMicroFont|\xinttheexpr 0.^2+2^.0\relax|} + % + which is |0^2+2^0| and produces \dtt{\xinttheexpr 0.^2+2^.0\relax}. + + However a single dot |"."| as in |\xinttheexpr .^2\relax| is now illegal + input.\IMPORTANT + +\item The |e| and |E| for scientific notation. They are parsed + like the decimal mark is. +\begingroup +\restoreMicroFont |1e3^2| is \dtt{\xinttheexpr 1e3^2\relax} +\endgroup + +\item The |"| for hexadecimal numbers: it is treated with highest + priority, allowed only at locations where the parser expects to start + forming a numeric operand, once encountered it triggers the + hexadecimal scanner which looks for successive hexadecimal digits (as + usual skipping spaces and expanding forward everything; letters |A|, ..., |F|, + but not |a|, ..., |f|) possibly a + unique optional dot (allowed directly in front) and then an optional + (possibly empty) fractional part. The dot and fractional part are not + allowed in {\restoreMicroFont|\xintiiexpr..\relax|}. The |"| + functionality \fbox{requires package \xintbinhexname} (there is + no warning, but an ``undefined control sequence'' error will + naturally results if the package has not been loaded). +\begingroup + \restoreMicroFont |"A*"A^"A| is \dtt{\xinttheexpr "A*"A^"A\relax}. +\endgroup + +\item The postfix operators \ctexttt{!} and the branching conditionals \ctexttt{?, ??}. + \begin{description} + \item[{\color[named]{DarkOrchid}!}] computes the factorial of an integer. + + \item[{\color[named]{DarkOrchid}?}] is used as |(cond)?{yes}{no}|. It + evaluates the (numerical) condition (any non-zero value counts as + |true|, zero counts as |false|). It then acts as a macro with two + mandatory arguments within braces (hence this escapes from the + parser scope, the braces can not be hidden in a macro), chooses the + correct branch \emph{without evaluating the wrong one}. Once the + braces are removed, the parser scans and expands the uncovered + material so for example + % + \leftedline{|\xinttheiexpr (3>2)?{5+6}{7-1}2^3\relax|} + % + is legal and computes + |5+62^3=|\dtt{\xinttheiexpr(3>2)?{5+(6}{7-(1}2^3)\relax}. Note + though that it would be better practice to include here the |2^3| + inside the branches. The contents of the branches may be arbitrary + as long as once glued to what is next the syntax is respected: + {|\xintexpr (3>2)?{5+(6}{7-(1}2^3)\relax| also works.} Differs thus + from the |if| conditional in two ways: the false branch is not at + all computed, and the number scanner is still active on exit, more + digits may follow. + + \item[{\color[named]{DarkOrchid}??}] is used as |(cond)??{<0}{=0}{>0}|. + |cond| is anything, its sign is evaluated and depending on the sign the + correct branch is un-braced, the two others are swallowed. The un-braced + branch will then be parsed as usual. Differs from the |ifsgn| conditional + as the two false branches are not evaluated and furthermore the number + scanner is still active on exit. + % + \leftedline{|\def\x{0.33}\def\y{1/3}|} + % + \leftedline{|\xinttheexpr (\x-\y)??{sqrt}{0}{1/}(\y-\x)\relax|% + \dtt{=\def\x{0.33}\def\y{1/3}% + \xinttheexpr (\x-\y)??{sqrt}{0}{1/}(\y-\x)\relax }} + % + \end{description} + +\item The minus sign |-| as prefix unary operator inherits the precedence of + the infix operator it follows. With things such as |5+------2*3|, the + \xintexprname parsers don't try to be efficient: once |2*3| is evaluated the + opposite function will be applied the necessary number of times. On the other + hand the plus sign |+| as prefix unary operator as in, for example + |5-++++++2*3|, is immediately gobbled. + +\item The power operator |^|, or |**|. It is left associative: + {\restoreMicroFont|\xinttheiexpr 2^2^3\relax|} evaluates to \xinttheiexpr + 2^2^3\relax, not \xinttheiexpr 2^(2^3)\relax. Note that if the float + precision is too low, iterated powers within |\xintfloatexpr..\relax| may + fail: for example with the default setting |(1+1e-8)^(12^16)| will be + computed with |12^16| approximated from its $16$ most significant digits + but it has $18$ digits (\dtt{={\xintiiPow{12}{16}}}), hence the result is + wrong: + \begingroup + % + \leftedline{$\np{\xintthefloatexpr (1+1e-8)^(12^16)\relax }$} + % + One should code + % + \leftedline{\restoreMicroFont|\xintthe\xintfloatexpr (1+1e-8)^\xintiiexpr 12^16\relax + \relax|} + % + to obtain the correct floating point evaluation + % + \leftedline{$\np{1.00000001}^{12^{16}}\approx\np{\xintthefloatexpr + (1+1e-8)^\xintiiexpr 12^16\relax\relax }$} + % + \endgroup + +\item Multiplication and division \raisebox{-.3\height}{|*|}, |/|. The + division is left associative, too: + % + \begingroup\restoreMicroFont + % + |\xinttheiexpr 100/50/2\relax| evaluates to \xinttheiexpr 100/50/2\relax, + not \xinttheiexpr 100/(50/2)\relax. + % + \endgroup + Inside \csbxint{iiexpr}, |/| does \emph{rounded} division. + +\item Truncated division |//| and modulo |/:| (equivalently |'mod'|, quotes + mandatory) are at the same level of priority than multiplication and + division, thus left-associative with them. Apply parentheses for + disambiguation. +\begin{everbatim*} +\xinttheexpr 100000//13, 100000/:13, 100000 'mod' 13, trunc(100000/13,10), + trunc(100000/:13/13,10)\relax +\end{everbatim*} + +\item The list itemwise operators |*[|, |/[|, |^[|, |**[|, |]*|, |]/|, |]^|, + |]**| are at the same precedence level as, respectively, |*| and |/| or |^| + and |**|. + +\item Addition and subtraction |+|, |-|. Again, |-| is left + associative: + % + \begingroup\restoreMicroFont + % + |\xinttheiexpr 100-50-2\relax| evaluates to \xinttheiexpr 100-50-2\relax, + not \xinttheiexpr 100-(50-2)\relax. + % + \endgroup + +\item The list itemwise operators |+[|, |-[|, |]+|, |]-|, are at + the same precedence level as |+| and |-|, + +\item Comparison operators |<|, |>|, |=| (same as |==|), |<=|, |>=|, |!=| all + at the same level of precedence, use parentheses for disambiguation. + +\item Conjunction (logical and): |&&| or equivalently + |'and'| (quotes mandatory). + +\item Inclusive disjunction (logical or): \verb+||+ + and equivalently |'or'| (quotes mandatory). + +\item XOR: |'xor'| with mandatory quotes is at the same level of precedence + as \verb+||+. + +\item The list generation operators |..|, |..[|, |]..| are at the same + (low) precedence level as the \verb+||+ operator of logical disjunction. + +\item The comma: +\restoreMicroFont with |\xinttheexpr 2^3,3^4,5^6\relax| +one obtains as output \xinttheexpr 2^3,3^4,5^6\relax{}. + +\item The parentheses. The list outer brackets |[|, |]| share the same + functional precedence as parentheses. The semi-colon |;| in an |iter| or + |rseq| has the same precedence as a closing parenthesis. +\end{itemize} + +\subsection{Available functions} + Functions are at the same top level of priority. All functions even |?| and |!| (as prefix) require parentheses around their arguments. \begin{snugframed} - \xintFor #1 in {num, qint, qfrac, qfloat, reduce, abs, sgn, frac, floor, ceil, - sqr, sqrt, sqrtr, float, round, trunc, mod, quo, rem, gcd, lcm, max, - min, `+`, `*`, ?, !, not, all, any, xor, if, ifsgn, even, odd, first, - last, reversed, bool, togl, add, mul, seq, subs, rseq, rrseq, iter} - \do {\ctexttt{#1}\xintifForLast{}{, }} - - |quo|, |rem|, |even|, |odd|, |gcd| and |lcm| will first truncate their - arguments to integers; the latter two require package \xintgcdname; - |togl| requires the |etoolbox| package; |all|, |any|, |xor|, |`+`|, - |`*`|, |max| and |min| are functions with arbitrarily many comma - separated arguments. + \xintFor #1 in {num, qint, qfrac, qfloat, reduce, abs, sgn, frac, floor, + ceil, sqr, sqrt, sqrtr, factorial, binomial, pfactorial, float, round, + trunc, mod, quo, rem, gcd, lcm, max, min, `+`, `*`, ?, !, not, all, + any, xor, if, ifsgn, even, odd, first, last, reversed, bool, togl, + add, mul, seq, subs, rseq, rrseq, iter} \do + {\ctexttt{#1}\xintifForLast{}{, }} + + |factorial|, |binomial|, |pfactorial|, |quo|, |rem|, |even|, |odd|, + |gcd| and |lcm| will first truncate their arguments to integers; the + latter two require package \xintgcdname; |togl| requires the |etoolbox| + package; |all|, |any|, |xor|, |`+`|, |`*`|, |max|, |min|, |first|, + |last|, |reversed| are functions with arbitrarily many comma separated + arguments. |bool|, |togl| use delimited macros to fetch their argument and the closing parenthesis which thus must be explicit, not arising from expansion. - The same holds for |qint|, |qfrac|, |qfloat|.\NewWith{1.2} + The same holds for |qint|, |qfrac|, |qfloat|.\NewWith{1.2} Similarly |add|, |mul|, |subs|, |seq|, |rseq|, |rrseq|, |iter| use some delimited macros to fetch the |,<letter>| part, checking the correct @@ -10846,7 +10528,7 @@ operators and functions. \begin{description}[parsep=0pt, labelwidth=\leftmarginii, itemindent=0pt, listparindent=\leftmarginiii, leftmargin=\leftmarginii] - \item[functions with a single (numeric) argument] + \item[functions with a single (numeric) argument] \noindent\par \begin{description} \item[num] truncates to the nearest integer (truncation towards zero). @@ -10890,22 +10572,25 @@ Recall that this is NOT done automatically, for example when adding fractions. \xinttheexpr frac(-355/113), frac(-1129.218921791279)\relax \end{everbatim*} - \item[floor] floor function - \item[ceil] ceil function - \item[sqr] square + \item[floor] floor function. + \item[ceil] ceil function. + \item[sqr] square. \item[sqrt] in |\xintiiexpr|, truncated square root; in |\xintexpr| or |\xintfloatexpr| this is the floating point square root, and there is an - optional second argument for the precision. + optional second argument for the precision. \item[sqrtr] in |\xintiiexpr| only, rounded square root. + \item[factorial] factorial function,\NewWith {1.2f} same as previously + available post-fix |!| operator. When used in |\xintexpr| or + |\xintfloatexpr| there is an optional second argument. See discussion later. \item[?] |?(x)| is the truth value, $1$ if non zero, $0$ if zero. Must use parentheses. \item[!] |!(x)| is logical not, $0$ if non zero, $1$ if zero. Must use parentheses. - \item[not] logical not - \item[even] evenness of the truncation + \item[not] logical not. + \item[even] evenness of the truncation. \begin{everbatim*} \xinttheexpr seq((x,even(x)), x=-5/2..[1/3]..+5/2)\relax \end{everbatim*} - \item[odd] oddness of the truncation + \item[odd] oddness of the truncation. \begin{everbatim*} \xinttheexpr seq((x,odd(x)), x=-5/2..[1/3]..+5/2)\relax \end{everbatim*} @@ -10987,32 +10672,55 @@ Recall that this is NOT done automatically, for example when adding fractions. \noindent\par \begin{description} \item[round] For example - |round(-2^9/3^5,12)=|\dtt{\xinttheexpr round(-2^9/3^5,12)\relax.} + |round(-2^9/3^5,12)=|\dtt{\xinttheexpr round(-2^9/3^5,12)\relax.} \item[trunc] For example - |trunc(-2^9/3^5,12)=|\dtt{\xinttheexpr trunc(-2^9/3^5,12)\relax.} + |trunc(-2^9/3^5,12)=|\dtt{\xinttheexpr trunc(-2^9/3^5,12)\relax.} \item[float] For example - |float(-20^9/3^5,12)=|\dtt{\xinttheexpr float(-20^9/3^5,12)\relax.} - \item [sqrt] in \csbxint{expr} and \csbxint{floatexpr}, uses the float evaluation - with the precision given by the optional second argument. + |float(-2^9/3^5,12)=|\dtt{\xinttheexpr float(-2^9/3^5,12)\relax.} + \item [sqrt] in \csa{xintexpr}|...\relax| and \csa{xintfloatexpr}|...\relax| + it achieves the precision given by the optional second argument. \begin{everbatim*} \xinttheexpr sqrt(2,31)\relax\ and \xinttheiiexpr sqrt(num(2e60))\relax \end{everbatim*} + \item[factorial] when the second optional argument\NewWith {1.2f} is made + use of inside \csa{xintexpr}|...\relax|, this switches to the use of the + float version, rather than the exact one. +\begin{everbatim*} +\xinttheexpr factorial (100,32)\relax, {\xintDigits:=32;\xintthefloatexpr + factorial (100)\relax}\newline +\xinttheexpr factorial (50)\relax\newline +\xinttheexpr factorial (50, 32)\relax +\end{everbatim*} \end{description} - \item[functions with two arguments] + \item[functions with two arguments] \noindent\par \begin{description} \item[quo] first truncates the arguments then computes the Euclidean quotient. \item[rem] first truncates the arguments then computes the Euclidean remainder. \item[mod] computes the modulo associated to the truncated division, same as - |/:| infix operator + |/:| infix operator. \begin{everbatim*} \xinttheexpr mod(11/7,1/13), reduce(((11/7)//(1/13))*1/13+mod(11/7,1/13)), mod(11/7,1/13)- (11/7)/:(1/13), (11/7)//(1/13)\relax \end{everbatim*} + \item[binomial] computes binomial coefficients.\NewWith {1.2f} +\begin{everbatim*} +\xinttheexpr seq(binomial(20, i), i=0..20)\relax +\end{everbatim*} +\begin{everbatim*} +\xintthefloatexpr seq(binomial(100, 50+i), i=-5..+5)\relax +\end{everbatim*} +The arguments must be (expand to) short integers. + \item[pfactorial] computes partial factorials.\NewWith {1.2f} +\begin{everbatim*} +\xinttheexpr seq(pfactorial(20, i), i=20..30)\relax +\end{everbatim*} +The arguments must be (expand to) short integers. + \end{description} - \item[the if conditional (twofold way)] + \item[the if conditional (twofold way)] \noindent\par \ctexttt{if}|(cond,yes,no)| checks if |cond| is true or false and takes the corresponding @@ -11081,12 +10789,18 @@ The usable dummy variables are all lowercase and uppercase Latin letters. Attention that |xz| generates an error, one must use explicitely |x*z|, else the parser expects a variable with name |xz|. +This is useful for example when defining macros for which some argument |#1| +will be used more than once but may itself be a complicated expression or +macro, and should be evaluated only once, for matters of efficiency. + The substituted variable may be a comma separated list (this is impossible with |seq| which will always pick one item after the other from a list). \begin{everbatim*} \xinttheexpr subs([x]^2,x=-123,17,32)\relax \end{everbatim*} +See the examples related to the |3x3| determinant in the +\autoref{xintNewExpr} for an illustration of list substitution. \item[add] addition \begin{everbatim*} @@ -11150,7 +10864,7 @@ previous items, but decided to drop it as the package was becoming big. \item[iter] same as |rrseq| but does not print any value until the last |K|. \begin{everbatim*} -\xinttheiiexpr iter(0,1; @1+@2, i=2..5, 6..10)\relax +\xinttheiiexpr iter(0,1; @1+@2, i=2..5, 6..10)\relax % the iterated over list is allowed to have disjoint defining parts. \end{everbatim*} \end{description} @@ -11169,182 +10883,485 @@ With |seq|, |rseq|, |rrseq|, |iter|, \textbf{but not} with |subs|, |add|, in conjunction with an |abort| or |break| is often more efficient, because in other cases the list to iterate over is first completely constructed. \begin{everbatim*} -\xinttheiiexpr iter(1;(@>10^40)?{break(@)}{2@},i=1++)\relax +\xinttheiiexpr iter(1;(@>10^40)?{break(@)}{2@},i=1++)\relax \end{everbatim*} Note that |n++| can not work in the format |i=10,17,30++|, only |n++| - nothing before. + nothing before. \begin{everbatim*} First Fibonacci number at least |2^31| and its index \xinttheiiexpr iter(0,1; (@1>=2^31)?{break(i)}{@2+@1}, i=1++)\relax \end{everbatim*} \end{description} -Some additional examples are to be found at the end of this section. +Some additional examples are to be found in \autoref{ssec:dummy} \end{description} -\item The postfix operators \ctexttt{!} and the branching conditionals \ctexttt{?, ??}. - \begin{description} - \item[{\color[named]{DarkOrchid}!}] computes the factorial of an integer. - \item[{\color[named]{DarkOrchid}?}] is used as |(cond)?{yes}{no}|. It - evaluates the (numerical) condition (any non-zero value counts as - |true|, zero counts as |false|). It then acts as a macro with two - mandatory arguments within braces (hence this escapes from the - parser scope, the braces can not be hidden in a macro), chooses the - correct branch \emph{without evaluating the wrong one}. Once the - braces are removed, the parser scans and expands the uncovered - material so for example - % - \leftedline{|\xinttheiexpr (3>2)?{5+6}{7-1}2^3\relax|} - % - is legal and computes - |5+62^3=|\dtt{\xinttheiexpr(3>2)?{5+(6}{7-(1}2^3)\relax}. Note - though that it would be better practice to include here the |2^3| - inside the branches. The contents of the branches may be arbitrary - as long as once glued to what is next the syntax is respected: - {|\xintexpr (3>2)?{5+(6}{7-(1}2^3)\relax| also works.} Differs thus - from the |if| conditional in two ways: the false branch is not at - all computed, and the number scanner is still active on exit, more - digits may follow. +\subsection{List operations} +\label{ssec:lists} - \item[{\color[named]{DarkOrchid}??}] is used as |(cond)??{<0}{=0}{>0}|. - |cond| is anything, its sign is evaluated and depending on the sign the - correct branch is un-braced, the two others are swallowed. The un-braced - branch will then be parsed as usual. Differs from the |ifsgn| conditional - as the two false branches are not evaluated and furthermore the number - scanner is still active on exit. - % - \leftedline{|\def\x{0.33}\def\y{1/3}|} - % - \leftedline{|\xinttheexpr (\x-\y)??{sqrt}{0}{1/}(\y-\x)\relax|% - \dtt{=\def\x{0.33}\def\y{1/3}% - \xinttheexpr (\x-\y)??{sqrt}{0}{1/}(\y-\x)\relax }} - % - \end{description} +A ``list'' simply refers to comma-separated numbers. There is no notion of +``list of lists'' nor is there an ``nuple'' type. Functions such as |gcd|, +|lcm|, |max|, |min|, |first|, |last|, |reversed| apply to lists as well as the +logical functions |all|, |any|, |xor|, and the |`+`|, |`*`| sum and product +operators. -\item \def\MicroFont{\color[named]{DarkOrchid}\ttfamily}The - |.| as decimal mark; the number scanner treats it as an inherent, - optional and unique component of a being formed number. One can do - things such as - % - \leftedline{\restoreMicroFont|\xinttheexpr 0.^2+2^.0\relax|} - % - which is |0^2+2^0| and produces \dtt{\xinttheexpr 0.^2+2^.0\relax}. +\xintexprname provides list constructors and list operators, inclusive of +Python-like slicing operators. - However a single dot |"."| as in |\xinttheexpr .^2\relax| is now illegal - input.\IMPORTANT +\begin{itemize} + \item |a..b| constructs the \textbf{small} integers from the ceil $\lceil + a\rceil$ to the floor + $\lfloor b\rfloor$ (possibly a decreasing sequence): one has to be careful + if using this for algorithms that |1..0| for example is not empty or |1| + but expands to |1, 0|. Again, |a..b| \emph{can not} be used with |a| and + |b| greater than $2^{31}-1$. Also, only about at most \dtt{5000} integers + can be generated (this depends upon some \TeX{} memory settings). + + The |..| has lower precedence than the arithmetic operations. +\begin{everbatim*} +\xinttheexpr 1.5+0.4..2.3+1.1\relax; \xinttheexpr 1.9..3.4\relax; \xinttheexpr 2..3\relax +\end{everbatim*} -\item The |e| and |E| for scientific notation. They are parsed - like the decimal mark is. -% Thus |1e(3+2)| is no legal syntax anymore, one -% must use |10^(3+2)| in such cases. -\begingroup -\restoreMicroFont |1e3^2| is \dtt{\xinttheexpr 1e3^2\relax} -\endgroup + \item |a..[d]..b| allows to generate big integers, or also fractions, it + proceeds with step (non necessarily integral nor positive) |d|. It does + \emph{not} replace |a| by its ceil, nor |b| by its floor. The generated + list is empty if |b-a| and |d| are of opposite signs; if |d=0| or if |a=b| + the list expands to single element |a|. +\begin{everbatim*} +\xinttheexpr 1.5..[1.01]..11.23\relax +\end{everbatim*} -\item The |"| for hexadecimal numbers: it is treated with highest - priority, allowed only at locations where the parser expects to start - forming a numeric operand, once encountered it triggers the - hexadecimal scanner which looks for successive hexadecimal digits (as - usual skipping spaces and expanding forward everything; letters |A|, ..., |F|, - but not |a|, ..., |f|) possibly a - unique optional dot (allowed directly in front) and then an optional - (possibly empty) fractional part. The dot and fractional part are not - allowed in {\restoreMicroFont|\xintiiexpr..\relax|}. The |"| - functionality \fbox{requires package \xintbinhexname} (there is - no warning, but an ``undefined control sequence'' error will - naturally results if the package has not been loaded). -\begingroup - \restoreMicroFont |"A*"A^"A| is \dtt{\xinttheexpr "A*"A^"A\relax}. -\endgroup + \item |[list][n]| extracts the |n|th element, or give the number of items if + |n=0|. If |n<0| it extracts from the tail. +\begin{everbatim*} +\xinttheiexpr \empty[1..10][6], [1..10][0], [1..10][-1], [1..10][23*18-22*19]\relax\ +(and 23*18-22*19 has value \the\numexpr 23*18-22*19\relax). +\end{everbatim*} +See the next frame for the reason of the presence of |\empty|. -\item The power operator |^|, or |**|. It is left associative: - {\restoreMicroFont|\xinttheiexpr 2^2^3\relax|} evaluates to \xinttheiexpr - 2^2^3\relax, not \xinttheiexpr 2^(2^3)\relax. Note that if the float - precision is too low, iterated powers within |\xintfloatexpr..\relax| may - fail: for example with the default setting |(1+1e-8)^(12^16)| will be - computed with |12^16| approximated from its $16$ most significant digits - but it has $18$ digits (\dtt{={\xintiiPow{12}{16}}}), hence the result is - wrong: - % REVOIR CECI - \begingroup - % - \leftedline{$\np{\xintthefloatexpr (1+1e-8)^(12^16)\relax }$} - % - One should code - % - \leftedline{\restoreMicroFont|\xintthe\xintfloatexpr (1+1e-8)^\xintiiexpr 12^16\relax - \relax|} - % - to obtain the correct floating point evaluation - % REVOIR CECI - % - \leftedline{$\np{1.00000001}^{12^{16}}\approx\np{\xintthefloatexpr - (1+1e-8)^\xintiiexpr 12^16\relax\relax }$} - % - \endgroup +As shown, it is perfectly legal to do operations in the index parameter, which +will be handled by the parser as everything else. The same remark applies to +the next items. -\item Multiplication and division \raisebox{-.3\height}{|*|}, |/|. The - division is left associative, too: - % - \begingroup\restoreMicroFont - % - |\xinttheiexpr 100/50/2\relax| evaluates to \xinttheiexpr 100/50/2\relax, - not \xinttheiexpr 100/(50/2)\relax. - % - \endgroup - Inside \csbxint{iiexpr}, |/| does \emph{rounded} division. + \item |[list][:n]| extracts the first |n| elements if |n>0|, or suppresses + the last \verb+|n|+ elements if |n<0|. +\begin{everbatim*} +\xinttheiiexpr [1..10][:6]\relax\ and \xinttheiiexpr [1..10][:-6]\relax +\end{everbatim*} + \item |[list][n:]| suppresses the first |n| elements if |n>0|, or extracts + the last \verb+|n|+ elements if |n<0|. +\begin{everbatim*} +\xinttheiiexpr [1..10][6:]\relax\ and \xinttheiiexpr [1..10][-6:]\relax +\end{everbatim*} +\item More generally, |[list][a:b]| works according to the Python ``slicing'' + rules (inclusive of negative indices). Notice though that there is no + optional third argument for the step, which always defaults to |+1|. +\begin{everbatim*} +\xinttheiiexpr [1..20][6:13]\relax\ = \xinttheiiexpr [1..20][6-20:13-20]\relax +\end{everbatim*} +\item It is naturally possible to nest these things: +\begin{everbatim*} +\xinttheexpr [[1..50][13:37]][10:-10]\relax +\end{everbatim*} +\item itemwise operations either on the left or the right are possible: +\begin{everbatim*} +\xinttheiiexpr 123*[1..10]^2\relax +\end{everbatim*} + +\begin{snugframed} + As list operations are implemented using square brackets, it is + necessary in |\xintiexpr| and |\xintfloatexpr| to insert something before + the first bracket if it belongs to a list, to avoid confusion with the + bracket of an optional parameter. We need something expandable which does + not leave a trace: the |\empty| does the trick.\IMPORTANT{} -\item Truncated division |//| and modulo |/:| (equivalently |'mod'|, quotes - mandatory) are at the same level of priority than multiplication and - division, thus left-associative with them. Apply parentheses for - disambiguation. \begin{everbatim*} -\xinttheexpr 100000//13, 100000/:13, 100000 'mod' 13, trunc(100000/13,10), - trunc(100000/:13/13,10)\relax +\xinttheiexpr \empty [1,3,6,99,100,200][2:4]\relax \end{everbatim*} -\item The list itemwise operators |*[|, |/[|, |^[|, |**[|, |]*|, |]/|, |]^|, - |]**| are at the same precedence level as, respectively, |*| and |/| or |^| - and |**|. + An alternative is to use parentheses +\begin{everbatim*} +\xinttheiexpr ([1,3,6,99,100,200][2:4])\relax +\end{everbatim*} -\item Addition and subtraction |+|, |-|. Again, |-| is left - associative: - % - \begingroup\restoreMicroFont - % - |\xinttheiexpr 100-50-2\relax| evaluates to \xinttheiexpr 100-50-2\relax, - not \xinttheiexpr 100-(50-2)\relax. - % - \endgroup + Notice though that |([1,3,6,99,100,200])[2:4]| would not work. It is + mandatory for |][| and |][:| not to be interspersed with parentheses. On + the other hand spaces are perfectly legal: +\begin{everbatim*} +\xinttheiiexpr [1..10 ] [ : 7 ]\relax +\end{everbatim*} -\item The list itemwise operators |+[|, |-[|, |]+|, |]-|, are at - the same precedence level as |+| and |-|, +Similarly all the |+[|, |*[|, \dots and |]**|, |]/|, \dots operators admit +spaces but nothing else in-between their constituent characters. +\begin{everbatim*} +\xinttheiiexpr [ 1 . . 1 0 ] * * 1 1 \relax +\end{everbatim*} -\item Comparison operators |<|, |>|, |=| (same as |==|), |<=|, |>=|, |!=| all - at the same level of precedence, use parentheses for disambiguation. + In an other vein, the parser will be confused by |1..[list][3]|, one must + write |1..([list][3])|. Also things such as |[100,300,500,700][2]//11| will + be confusing because the |]/| is an operator with higher priority than the + |][|, and then there will a dangling |/11| which does not make sense. In + fact even |[100,300,500,700][2]/11| is a syntax error: one must write + |([100,300,500,700][2])/11|. +\end{snugframed} -\item Conjunction (logical and): |&&| or equivalently - |'and'| (quotes mandatory). +\end{itemize} -\item Inclusive disjunction (logical or): \verb+||+ - and equivalently |'or'| (quotes mandatory). -\item XOR: |'xor'| with mandatory quotes is at the same level of precedence - as \verb+||+. +\subsection{Tacit multiplication} +\label{ssec:tacit multiplication} -\item The comma: -\restoreMicroFont With |\xinttheexpr 2^3,3^4,5^6\relax| -one obtains as output \xinttheexpr 2^3,3^4,5^6\relax{}. +Tacit multiplication (insertion of a |*|) applies when the parser is currently +either scanning the digits of a number (or its decimal part or scientific +part, or hexadecimal input), or is looking for an infix operator, and: +(1.)~\emph{encounters a count or dimen or skip register or variable or an + \eTeX{} expression}, or (2.)~\emph{encounters a sub-\csa{xintexpr}ession}, +or (3.)~\emph{encounters an opening parenthesis}, or (4.)~\emph{encounters a + letter (which is interpreted as signaling the start of either a variable or + a function name)}. -\item The parentheses. -\end{itemize} +\begin{framed} + For example, if |x, y, z| are variables all three of |(x+y)z|, |x(y+z)|, + |(x+y)(x+z)| will create a tacit multiplication. + + Furthermore starting with release + |1.2e|,\MyMarginNote[\kern\dimexpr\FrameSep+\FrameRule\relax]{Changed} + whenever tacit multiplication is applied, in all cases it \emph{always} + ``ties'' more\IMPORTANT{} than normal multiplication or division, but + still less than power. Thus |x/2y| is interpreted as |x/(2y)| and + similarly for |x/2max(3,5)| but |x^2y| is still interpreted as |(x^2)*y| + and |2n!| as |2*n!|. + +\begin{everbatim*} +\xintdefvar x:=30;\xintdefvar y:=5;% +\xinttheexpr (x+y)x, x/2y, x^2y, x!, 2x!, x/2max(x,y)\relax +\end{everbatim*} + + The ``tye more'' rule applies to all cases of tacit multiplication. It + impacts only situations when a division was the last seen operator, as the + normal rule for the \xintexprname parsers is left-associativity in case of + equal precedence. +\begin{everbatim*} +\xinttheexpr (1+2)/(3+4)(5+6), 2/x(10), 2/10x, 3/y\xintiiexpr 5+6\relax, 1/x(y)\relax +\end{everbatim*} -\subsection{Some further examples with dummy variables} + Note that |y\xinttheiiexpr 5+6\relax| would have tried to use a variable + with name |y11| rather than doing |y*11|: tacit multiplication works only + in front of sub-\csbxint{expr}essions, not in front of + \csbxint{theexpr}essions which are unlocked into explicit digits. + + These examples above redeclared the |x| and |y| which thus can not be used as + dummy variables anymore (but see \csbxint{unassignvar}); as this happened + inside a \LaTeX{} environment (for the frame), they will have + recovered their meanings after the frame. In the meantime we use letter + |z| for the next example. Here is an expression whose meaning is + completely modified by the ``tye more'' property of tacit multiplication:\IMPORTANT +\begin{everbatim} +\xintdeffunc e(z):=1+z(1+z/2(1+z/3(1+z/4))); +\end{everbatim} +will be parsed as |1+z*(1+z/(2*(1+z/(3*(1+z/4)))))| which is + not at all like the presumably hoped: +\begin{everbatim} +\xintdeffunc e(z):=1+z(1+z/2*(1+z/3*(1+z/4))); +\end{everbatim} +This form can also be used, alternatively: +\begin{everbatim} +\xintdeffunc e(z):=(((z/4+1)z/3+1)z/2+1)z+1; +\end{everbatim} + + Attention! tacit multiplication before an opening parenthesis applies + always, but tacit multiplication after a closing parenthesis \emph{does + not} apply in front of digits: |(1+1)5| is not legal. But + |subs((1+1)x,x=5)| is, because in that case a variable is following the + closing parenthesis. +\end{framed} + + +\subsection{User definable variables and functions} +\label{xintdefvar} +\label{xintdefiivar} +\label{xintdeffloatvar} +\label{xintdeffunc} +\label{xintdefiifunc} +\label{xintdeffloatfunc} +\label{xintunassignvar} +\label{xintverbosetrue} +\label{xintverbosefalse} +\label{ifxintverbose} + +Since release |1.1| it is possible to assign a variable name to let it be +known to the parsers of \xintexprname. +\begin{everbatim*} +\xintdefvar Pi:=3.141592653589793238462643; +\xintthefloatexpr Pi^100\relax +\xintdefvar x_1 := 10;\xintdefvar x_2 := 20;\xintdefvar y@3 := 30; +\quad $x_1\cdot x_2\cdot y@3+1=\xinttheiiexpr x_1*x_2*y@3+1\relax$. +\end{everbatim*} + +As |x_1x| is a licit variable name, as well as |x_1x_| and |x_1x_2| and +|x_1x_2y| etc... we could not count on tacit multiplication being applied to +something like |x_1x_2|; the parser goes not go to the effort of tracing back +its steps. Hence we had to insert explicit |*| infix operators (one often +falls into this trap when playing with variables and counting too much on the +divinatory talents of \xintexprname...). + +The variable definition is done with \csa{xintdefvar}, \csa{xintdefiivar}, or +with \csa{xintdeffloatvar}, the variable will be computed using respectively +\csbxint{expr}, \csbxint{iiexpr} or \csbxint{floatexpr}. The variable +once defined can be used in the other parsers, except naturally that in +\csa{xintiiexpr} only integers are accepted. + +When defining a variable with \csa{xintdeffloatvar}, it is important that +reduction to \csbxint{theDigits} digits of precision happens inside +\csa{xintfloatexpr} only if an operation is executed. Thus, for a variable +declaration with no operations, the value is registered with all its digits. +\begin{everbatim*} +\xintdeffloatvar e:=2.7182818284590452353602874713526624977572470936999595749669676;% +\xinttheexpr e\relax\newline % shows the recorded value +\xintthefloatexpr e\relax\newline % output rounds +\xintthefloatexpr 1+e\relax\newline % the rounding was done by addition (trust me...) +\xintdeffloatvar e:=float(2.7182818284590452353602874713526624977572470936999595749669676);% +\xinttheexpr e\relax\par % use of float forced immediate rounding +\end{everbatim*} + +In the next examples we examine the effect of cumulated float operations on +rounding errors: +\begin{everbatim*} +\xintdefvar e_1:=add(1/i!, i=0..10);% exact sum +\xintdeffloatvar e_2:=add(1/i!, i=0..10);% float sum +\xintthefloatexpr e_1, e_2\relax\newline +\xintdefvar e_3:=e_1+add(1/i!, i=11..20);% exact sum +\xintdeffloatvar e_4:=e_2+add(1/i!, i=11..20);% float sum +\xintthefloatexpr e_3, e_4\relax\newline +\xintdeffloatvar e:=2.7182818284590452353602874713526624977572470936999595749669676;% +\xintDigits:=24; +\xintthefloatexpr[16] e, e^1000, e^1000000\relax (e rounded to 24 digits first)\newline +\xintDigits:=16; +\xintthefloatexpr e, e^1000, e^1000000\relax (e rounded to 16 digits first)\par +\end{everbatim*} + +Legal variable names are composed of letters, digits, |@| and |_| signs. +They can not start with a digit. They may start with |@| or |_|. Currently +|@|, |@1|, |@2|, |@3|, and |@4| are reserved because they have special +meanings for use in iterations. The |@@|, |@@@|, |@@@@| are also reserved but +are technically functions, not variables. Thus a user may possibly use |@@| as +a variable name, but if it is followed by parentheses, the function +interpretation will be applied, rather than doing a tacit multiplication. + +Single letter names |a..z| and |A..Z| are pre-declared by the package for use +as special type of variables called ``dummy variables''. They can be assigned +values via |\xintdefvar| et al., and be later unassigned using +\csa{xintunassign} (see later in this section). + +Since release |1.2c| it is possible to also declare functions: +\begin{everbatim*} +\xintdeffunc + Rump(x,y):=1335 y^6/4 + x^2 (11 x^2 y^2 - y^6 - 121 y^4 - 2) + 11 y^8/2 + x/2y; +\end{everbatim*}(notice the numerous tacit multiplications in this expression; +and that |x/2y| is interpreted as |x/(2y)|.) + +\begin{framed} + The (dummy) variables used in the function declaration are necessarily single + letters (lowercase or uppercase) which have \emph{not} been re-declared via + |\xintdefvar| as assigned variables. The choice of the letters is entirely + up to the user and has nil influence on the actual function, naturally. + + A function can have at most nine variables. + + The names of the macros \csa{xintdeffunc}, \csa{xintdefiifunc}, + \csa{xintdeffloatfunc} (and those for variables) as well as their syntax + (with |:=| and an ending |;|) will be set definitely only in next release. + \footnotemark +\end{framed} +\footnotetext{with the current syntax, the |;| as used for |iter|, |rseq|, + |rrseq| must be hidden as |{;}| to not be confused with the |;| ending the + declaration.} + +Let's try the famous \textsc{Rump} test: +\begin{everbatim*} +\xinttheexpr Rump(77617,33096)\relax. +\end{everbatim*} +Nothing problematic for an \emph{exact} evaluation, naturally ! + +A function may be declared either via \csa{xintdeffunc}, \csa{xintdefiifunc}, +\csa{xintdeffloatfunc}. It will then be known \emph{only} to the parser which +was used for its definition. + +Thus to test the \textsc{Rump} polynomial (it is not quite a polynomial with +its |x/2y| final term) with floats, we \emph{must} also +declare |Rump| as a function to be used there: +\begin{everbatim*} +\xintdeffloatfunc + Rump(x,y):=333.75 y^6 + x^2 (11 x^2 y^2 - y^6 - 121 y^4 - 2) + 5.5 y^8 + x/2y; +\end{everbatim*} +(I used coefficients |333.75| and |5.5| rather than fractions only because this +is how I saw the polynomial defined in one computer class reference found on +internet; and for float operations this may matter on the rounding). + +The numbers are scanned with the current precision, hence as here it is +\dtt{16}, they are scanned exactly in this case. We can then vary the +precision for the evaluation. +\begin{everbatim*} +\def\CR{\cr} +\halign +{\tabskip1ex +\hfil\bfseries#&\xintDigits:=\xintiloopindex;\xintthefloatexpr Rump(77617,33096)#\cr +\xintiloop [8+1] +\xintiloopindex &\relax\CR +\ifnum\xintiloopindex<40 \repeat +} +\end{everbatim*} + +It is licit to overload a variable name (all Latin letters are predefined as +dummy variables) with a function name and vice versa. The parsers will decide +from the context if the function or variable interpretation must be used +(dropping various cases of tacit multiplication as normally applied). +\begin{everbatim*} +\xintdefiifunc f(x):=x^3; +\xinttheiiexpr add(f(f),f=100..120)\relax\newline +\xintdeffunc f(x,y):=x^2+y^2; +\xinttheexpr mul(f(f(f,f),f(f,f)),f=1..10)\relax +\end{everbatim*} + +The mechanism for functions is identical with the one underlying the +\csbxint{NewExpr} command. A function once declared is a first class citizen, +its expression is entirely parsed and converted into a big nested \fexpan +dable macro. When used its action is via this defined macro. For example +\begin{everbatim*} +\xintdeffunc + e(z):=(((((((((z/10+1)z/9+1)z/8+1)z/7+1)z/6+1)z/5+1)z/4+1)z/3+1)z/2+1)z+1; +\end{everbatim*} +creates a macro whose meaning one can find in the log file, after +|\xintverbosetrue|. Here it is: +\begin{everbatim} + Function e for \xintexpr parser associated to \XINT_expr_userfunc_e with me +aning macro:#1,->\xintAdd {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\x +intDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\ +xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv { +\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {#1}{10}}{1}}{#1}}{9 +}}{1}}{#1}}{8}}{1}}{#1}}{7}}{1}}{#1}}{6}}{1}}{#1}}{5}}{1}}{#1}}{4}}{1}}{#1}}{3} +}{1}}{#1}}{2}}{1}}{#1}}{1} +\end{everbatim} + + +See \autoref{sssec:limitations} for some limitations of the syntax, shared +with those of the \csbxint{NewExpr} command. Some constructs with dummy +variables will not work, when the iterated-over values depend upon the +function arguments. For example |\xintdeffunc f(x):=add(i^2,i=1..x);| leads to +an unusable |f|. But in this case one can use the alternative syntax with list +operations:\footnote{It turns out |`+`(seq(i^2, i=1..x))| would work here, but + this isn't always the case with |seq| constructs.} +\begin{everbatim*} +\xintdeffunc f(x):=`+`([1..x]^2);\xinttheexpr seq(f(x), x=1..20)\relax +\end{everbatim*} + +Side remark: as the |seq(f(x), x=1..10)| does many times the same +computations, an |rseq| here would be more efficient:\footnote{Note that + |omit| and |abort| are not usable in |add| or |mul| (currently).} +\begin{everbatim*} +\xinttheexpr rseq(1; (x>20)?{abort}{@+x^2}, x=2++)\relax +\end{everbatim*} + +On the other hand a construct like the following has no issue, as the values +iterated over do not depend upon the function parameters: +\begin{everbatim*} +\xintdeffunc f(x):=iter(1{;} @*x/i+1, i=10..1);% one must hide the first semi-colon ! +\xinttheexpr e(1), f(1)\relax +\end{everbatim*} + +It is somewhat frustrating not to be able to use the whole \xintexprname +syntax in \csa{xintdeffunc} and \csa{xintNewExpr}. The explanation is simply +that the implementation of |seq|, |iter|, etc... relies on exhaustive +expansion inside |\csname ... \endcsname| whereas \csa{xintdeffunc} tries to +construct an \fexpan dable macro. Furthermore the |omit| and |abort| keywords +as well as the |break()| function are discovered ``dynamically'' when an +expression is parsed from left to right; if they were to be used with an +abstract value list, the information of their presence would have to be coded +especially. This could end up being not that different from storing the whole +|seq|, |iter|, etc.. thing ``as is'' into a macro definition: +\begin{everbatim} +\def\macro #1#2{\xinttheexpr iter(1{;} @*#2/i+1, i=#1..1)\relax} +\end{everbatim} +which does not all achieve what a function declaration, if possible, would. +Side remark: beware that using it with |#2=1+1| will cause unexpected result, +the definition of \csa{macro} should have employed |(#2)| rather than |#2|. + +With |\xintverbosetrue| the values of the variables and the meanings of the +functions (or rather their associated macros) will be written to the log. For +example the first |Rump| declaration above generates this in the log file: +\begin{everbatim} + Function Rump for \xintexpr parser associated to \XINT_expr_userfunc_Rump w +ith meaning macro:#1,#2,->\xintAdd {\xintAdd {\xintAdd {\xintDiv {\xintMul {133 +5}{\xintPow {#2}{6}}}{4}}{\xintMul {\xintPow {#1}{2}}{\xintSub {\xintSub {\xint +Sub {\xintMul {11}{\xintMul {\xintPow {#1}{2}}{\xintPow {#2}{2}}}}{\xintPow {#2 +}{6}}}{\xintMul {121}{\xintPow {#2}{4}}}}{2}}}}{\xintDiv {\xintMul {11}{\xintPo +w {#2}{8}}}{2}}}{\xintDiv {#1}{\xintMul {2}{#2}}} +\end{everbatim} +and the declaration |\xintdeffunc f(x):=iter(1{;} @*x/i+1, i=10..1);| generates: +\begin{everbatim} + Function f for \xintexpr parser associated to \XINT_expr_userfunc_f with me +aning macro:#1,->\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\x +intAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\ +xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd { +\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul {\xintAdd {\xintDiv {\xintMul +{1}{#1}}{10/1[0]}}{1}}{#1}}{9/1[0]}}{1}}{#1}}{8/1[0]}}{1}}{#1}}{7/1[0]}}{1}}{#1 +}}{6/1[0]}}{1}}{#1}}{5/1[0]}}{1}}{#1}}{4/1[0]}}{1}}{#1}}{3/1[0]}}{1}}{#1}}{2/1[ +0]}}{1}}{#1}}{1/1[0]}}{1} +\end{everbatim} + +Starting with |1.2d| the definitions made by \csbxint{NewExpr} have local +scope, hence this is also the case with the definitions made by +\csbxint{deffunc}.\IMPORTANT{} One can not ``undeclare'' a function, but +naturally one can provide a new definition for it. + +Variable declarations also are local. One can not really ``unassign'' a +declared variable, but macro \csa{xintunassignvar} will let it insert a zero +and provoke a \TeX{} ``undefined macro'' error. Also, using +\csa{xintunassignvar}\IMPORTANT{} on a letter will let it recover fully its +original meaning as dummy variable. This may even be used for other +characters, if they are used in expressions with catcode 11. As most every +character in the ascii range already has some meaning for \xintexprname, this +is not really recommended, though. +\begin{everbatim*} +\xintFor #1 in {e_1, e_2, e_3, e_4, e} \do {\xintunassignvar {#1}} +\end{everbatim*} + +It is possible to define functions which expand to comma-separated values, for +example the declarations: +\begin{everbatim*} +\xintdeffunc f(x):= x, x^2, x^3, x^x; +\xintdeffunc g(x):= x^[0..x];% x^[1, 2, 3, x] would be like f above. +\end{everbatim*} +will generate +\begin{everbatim} + Function f for \xintexpr parser associated to \XINT_expr_userfunc_f with me +aning macro:#1,->#1,\xintPow {#1}{2},\xintPow {#1}{3},\xintPow {#1}{#1} + Function g for \xintexpr parser associated to \XINT_expr_userfunc_g with me +aning macro:#1,->\xintApply::csv {\xintPow {#1}}{\xintSeq::csv {0}{#1}} +\end{everbatim} +and we can check that they work: +\begin{everbatim*} +\xinttheexpr f(10)\relax; \xinttheexpr g(10)\relax +\end{everbatim*} + +N.B.: we declared in this section |e|, |f|, |g| as functions. Except naturally +if the function declarations are done in a group or a \LaTeX{} environment +whose scope has ended, they can not be completely undone, and if |e|, |f|, or +|g| are used as dummy variables the tacit multiplication in front of +parentheses will not be applied, it is their function interpretation which will +prevail. However, with an explicit |*| in front of the opening parenthesis, it +does work: +\begin{everbatim*} +\xinttheexpr add(f*(f+f), f= 1..10)\relax % f is used as variable, not function. +\end{everbatim*} + + +\subsection{More examples with dummy variables} \label{ssec:dummy} -These examples were first added to this manual at the time of the |v1.1| +These examples were first added to this manual at the time of the |1.1| release (|2014/10/29|). \begin{everbatim*} @@ -11418,7 +11435,7 @@ This might look a bit scary, I admit. \xintexprname has minimal tools and is obstinate about doing everything expandably! We are hampered by absence of a notion of ``nuple''. The algorithm divides |N| by |2| until no more possible, then by |3|, then by |4| (which is silly), then by |5|, then by |6| (silly -again), \dots. +again), \dots. The variable |L=rseq(#1;...)| expands, if one follows the steps, to a comma separated list starting with the initial (evaluated) |N=#1| and then @@ -11439,7 +11456,7 @@ allowing a non unit step). Notice that in |iter(([@][1])//p;| the |@| refers to the previous triplet (or in the first step to |N|), but the latter |@| showing up in |(@/:p)?| refers -to the previous value computed by |iter|. +to the previous value computed by |iter|. \begin{snugframed} Parentheses are essential in |..([y][0])| else the parser will see |..[| and @@ -11488,32 +11505,6 @@ argument. \makeatother \end{everbatim} -% 18 novembre 2015 -% le fichier testfactorize.tex est dans devtests. -% 12400 -% 87975 -% à comparer à ces résultats du 5 novembre 2014: -% % Résultat: 30 itérations -% % 12232 % \factorize par macros -% % 94307 % \factors par xintiiexpr 1.1a -% % 1815443 % l3bigint -% à propos l3bigint s'est amélioré depuis ! -% cependant je ne peux pas tester car \bigint_factor:n plus fonctionnel. -% Pour mémoire timing du fichier complet: -% en novembre 2014 -% 12308 -% 94591 -% 434095 -% macro:->2147483647, 2147483647, 1+++ -% 3443269 -% macro:->2147483647, 2147483647, 1+++ -% en novembre 2015 -% 12441 -% 87878 -% 210898 -% macro:->2147483647, 2147483647, 1+++ -% 2700184 -% macro:->2147483647, 2147483647, 1+++ The macro |\Factorize| puts a little stress on the input save stack in order not be bothered with previously gathered things. I timed it to be about seven @@ -11549,7 +11540,7 @@ expansion steps for any serious work in \TeX{} for dealing with tokens. \draw [blue] (-1.1,0)--(1,0); \draw [blue] (0,-1)--(0,+1); \draw [red] plot[smooth] coordinates {\xintthecoords - % converts into (x1, y1) (x2, y2)... format + % converts into (x1, y1) (x2, y2)... format \xintfloatexpr seq((x^2-1,mul(x-t,t=-1+[0..4]/2)),x=-1.2..[0.1]..+1.2) \relax }; \end{tikzpicture}\par } \end{everbatim*} @@ -11558,7 +11549,7 @@ expansion steps for any serious work in \TeX{} for dealing with tokens. % off the curve, not MY fault!!! \csbxint{thecoords} should be followed immediately by \csbxint{floatexpr} or -\csbxint{iexpr} or \csbxint{iiexpr}, but not |\xintthefloatexpr|, etc\dots +\csbxint{iexpr} or \csbxint{iiexpr}, but not |\xintthefloatexpr|, etc\dots Besides, as |TikZ| will not understand the |A/B[N]| format which is used on output by |\xintexpr|, |\xintexpr| is not really usable with |\xintthecoords| @@ -11575,10 +11566,9 @@ the page for examination with about correct line-breaks. \xintexprname} -Release |1.1| of |2014/10/29| had brought many changes to \xintexprname. The -numerous syntax extensions have now been incorporated to the general -description in \autoref{ssec:syntax}. Here we keep only a short list of the -then breaking changes, for the record. +Release |1.1| of |2014/10/29| brought many changes to \xintexprname whose +description has been incorporated to previous sections. Here we keep only a +short list of the then breaking changes, for the record. \begin{itemize}[parsep=0pt, labelwidth=\leftmarginii, itemindent=0pt, listparindent=\leftmarginiii, leftmargin=\leftmarginii] @@ -11665,14 +11655,13 @@ non-expandable step as it changes catcodes. \subsubsection{\csbh{xintexprSafeCatcodes}} \label{xintexprSafeCatcodes} -%{\small New with release |1.09a|.\par} This command sets the catcodes of the relevant characters to safe values. This is used internally by \csbxint{NewExpr} (restoring the catcodes on exit), hence \csa{xintNewExpr} does not have to be protected against active characters. -Attention however that if the whole +Attention however that if the whole \begin{everbatim} \xintNewExpr \foo [N] {<expression with #1,...>} \end{everbatim} @@ -11682,9 +11671,8 @@ the expression. \subsubsection{\csbh{xintexprRestoreCatcodes}} \label{xintexprRestoreCatcodes} -%{\small New with release |1.09a|.\par} -Restores the catcodes to the earlier state. +Restores the catcodes to the earlier state. \bigskip @@ -11773,7 +11761,7 @@ evaluations (for example |(#1+#2)*#3-#1*#3-#2*#3)|) each with number having \emph{hundreds} of digits. Typical error message can be: \begin{everbatim} ./testaleatoires.tex:243: TeX capacity exceeded, sorry [pool size=6134970]. -<argument> ...19140037877484848545931233090884903 +<argument> ...19140037877484848545931233090884903 \end{everbatim} There is a (partial) solution.% @@ -11805,7 +11793,8 @@ eliminated, but the computation it realizes will need only as many |\csname|'s as there are arguments to the function and will create only one more to store the result of the evaluation. -\subsection{The \csbh{xintNewExpr} command}\label{xintNewExpr} +\subsection{The \csbh{xintNewExpr} command} +\label{xintNewExpr} The command is used as: % @@ -11869,7 +11858,7 @@ Macros created by |\xintNewExpr| can thus be nested. Such a macro |\myformula|, if it was used tens of thousands of times with various big inputs would end up populating large parts of \TeX's memory. It would thus be better for such use cases to go for: - % + % \leftedline{|\xintNewExpr\myformula [1]{#1^3\relax}|} % Here naturally the situation is over-simplified and it would be even simpler @@ -11935,56 +11924,61 @@ will use |\meaning| which reveals the contents of a macro. \printnumber{\fixmeaning\DET} \end{everbatim*} +\unless\ifxetex Notice that since |1.2c| it is perhaps more natural to do: \begin{everbatim*} -% attention that «ad» would try to use non-existent variable "ad" +% attention that «ad» would try to use non-existent variable "ad" \xintdeffunc det2(a, b, c, d) := a*d - b*c ; -% This is impossible because we must use single letters : +% This is impossible because we must use single letters : % \xintdeffunc det3(x_11, x_12, x_13, x_21, x_22, x_23, x_31, x_32, x_33) := % x_11 * det2 (x_22, x_23, x_32, x_33) + x_21 * det2 (x_32, x_33, x_12, x_13) % + x_31 * det2 (x_12, x_13, x_22, x_23); \xintdeffunc det3 (a, b, c, u, v, w, x, y, z) := a*v*z + b*w*x + c*u*y - b*u*z - c*v*x - a*w*y ; \xinttheexpr det3 (1,1,1,1,2,4,1,3,9), det3 (1,10,100,1,100,10000,1,1000,1000000), 90*900*990, reduce(det3 (1,1/2,1/3,1/2,1/3,1/4,1/3,1/4,1/5))\relax\newline -\xintdeffunc det3bis (a, b, c, u, v, w, x, y, z) := +\xintdeffunc det3bis (a, b, c, u, v, w, x, y, z) := a*det2(v,w,y,z)-b*det2(u,w,x,z)+c*det2(u,v,x,y); \pdfsetrandomseed 123456789 % xint.pdf should be predictable from xint.dtx ! \xinttheexpr subs(subs(subs(subs(subs(subs(subs(subs(subs( -% we use one extra pair of parentheses to hide the commas from the subs - (a, b, c, u, v, w, x, y, z, det3 (a, b, c, u, v, w, x, y, z), +% we use one extra pair of parentheses to hide the commas from the subs + (a, b, c, u, v, w, x, y, z, det3 (a, b, c, u, v, w, x, y, z), det3bis (a, b, c, u, v, w, x, y, z)), z=\pdfuniformdeviate 1000), y=\pdfuniformdeviate 1000), x=\pdfuniformdeviate 1000), w=\pdfuniformdeviate 1000), v=\pdfuniformdeviate 1000), u=\pdfuniformdeviate 1000), c=\pdfuniformdeviate 1000), b=\pdfuniformdeviate 1000), a=\pdfuniformdeviate 1000)\relax \end{everbatim*} -% Note: \csa{pdfuniformdeviate} expands to a list -% of tokens, pas besoin de \the (qui donnerait une erreur j'imagine) ou -% \number -% \odef\z {\pdfuniformdeviate1000} fonctionne. + + +The last computation with its nine nested |subs| can be coded more +economically (and efficiently), exploiting the fact that a single dummy +variable can expand to a whole list: +\begin{everbatim*} +\pdfsetrandomseed 123456789 % xint.pdf should be predictable from xint.dtx ! +\xinttheexpr subs((L, det3(L), det3bis(L)), % parentheses used to hide the inner commas + L=\pdfuniformdeviate 1000, \pdfuniformdeviate 1000, \pdfuniformdeviate 1000, + \pdfuniformdeviate 1000, \pdfuniformdeviate 1000, \pdfuniformdeviate 1000, + \pdfuniformdeviate 1000, \pdfuniformdeviate 1000, \pdfuniformdeviate 1000)\relax +\end{everbatim*} +\fi % de pas de xetex With |\xintverbosetrue| we will find in the log: \begin{everbatim} Function det3 for \xintexpr parser associated to \XINT_expr_userfunc_det3 w -ith meaning macro:#1,#2,#3,#4,#5,#6,#7,#8,#9,->\romannumeral `^^@\xintSub {\xin -tSub {\xintSub {\xintAdd {\xintAdd {\xintMul {\xintMul {#1}{#5}}{#9}}{\xintMul -{\xintMul {#2}{#6}}{#7}}}{\xintMul {\xintMul {#3}{#4}}{#8}}}{\xintMul {\xintMul - {#2}{#4}}{#9}}}{\xintMul {\xintMul {#3}{#5}}{#7}}}{\xintMul {\xintMul {#1}{#6} -}{#8}} +ith meaning macro:#1,#2,#3,#4,#5,#6,#7,#8,#9,->\xintSub {\xintSub {\xintSub {\x +intAdd {\xintAdd {\xintMul {\xintMul {#1}{#5}}{#9}}{\xintMul {\xintMul {#2}{#6} +}{#7}}}{\xintMul {\xintMul {#3}{#4}}{#8}}}{\xintMul {\xintMul {#2}{#4}}{#9}}}{\ +xintMul {\xintMul {#3}{#5}}{#7}}}{\xintMul {\xintMul {#1}{#6}}{#8}} +Package xintexpr Info: (on line 11) Function det3bis for \xintexpr parser associated to \XINT_expr_userfunc_det -3bis with meaning macro:#1,#2,#3,#4,#5,#6,#7,#8,#9,->\romannumeral `^^@\xintAdd - {\xintSub {\xintMul {#1}{\xintSub {\xintMul {#5}{#9}}{\xintMul {#6}{#8}}}}{\xi -ntMul {#2}{\xintSub {\xintMul {#4}{#9}}{\xintMul {#6}{#7}}}}}{\xintMul {#3}{\xi -ntSub {\xintMul {#4}{#8}}{\xintMul {#5}{#7}}}} +3bis with meaning macro:#1,#2,#3,#4,#5,#6,#7,#8,#9,->\xintAdd {\xintSub {\xintM +ul {#1}{\xintSub {\xintMul {#5}{#9}}{\xintMul {#6}{#8}}}}{\xintMul {#2}{\xintSu +b {\xintMul {#4}{#9}}{\xintMul {#6}{#7}}}}}{\xintMul {#3}{\xintSub {\xintMul {# +4}{#8}}{\xintMul {#5}{#7}}}} \end{everbatim} -% \smallskip -% \begin{everbatim*} -% \xintNewExpr\FA[3]{ #1*#1+#2*#2+#3*#3-(#1*#2+#2*#3+#3*#1) } -% \printnumber{\fixmeaning\FA } -% \end{everbatim*} \medskip Lists, including Python-like selectors, are compatible with \csa{xintNewExpr}: @@ -12146,19 +12140,29 @@ isn't really one. \subsection{\csbh{xintiexpr}, \csbh{xinttheiexpr}} \label{xintiexpr}\label{xinttheiexpr} -Equivalent\etype{x} to doing |\xintexpr round(...)\relax| (if the expression -is comma separated, read |round(..), round(..), ...|). Thus, \emph{only} the -final result is rounded to an integer. Half integers are rounded towards -$+\infty$ for positive numbers and towards $-\infty$ for negative ones. Comma -separated lists of expressions are allowed. +Equivalent\etype{x} to doing |\xintexpr round(...)\relax| (more precisely, +|round| is applied to each one of the evaluated values, if the expression was +comma separated). Thus, only the \emph{final result value} is rounded to an +integer. Half integers are rounded towards $+\infty$ for positive numbers and +towards $-\infty$ for negative ones. -An optional positive parameter within brackets, immediately after |\xintiexpr| +An optional parameter |d>0| within brackets, immediately after |\xintiexpr| is allowed: it instructs the expression to do its final rounding to the nearest value with that many digits after the decimal mark, \emph{i.e.}, -|\xintiexpr [d] <expression>\relax| is equivalent to |\xintexpr -round(<expression>,d)\relax|. +|\xintiexpr [d] <expression>\relax| is equivalent (in case of a single +expression) to |\xintexpr round(<expression>, d)\relax|. -Perhaps in the future negative optional parameter will be given some meaning.\footnote{Thanks to KT for this suggestion.} +|\xintiexpr [0] ...| is the same as |\xintiexpr ...|.\footnote{Incidentally + using |round(...,0)| in place of |round(...)| in |\xintexpr| would leave a + trailing dot in the produced value.} + +If truncation rather than rounding is needed use (in case of a single +expression, naturally) |\xintexpr trunc(...)\relax| for truncation to an +integer or |\xintexpr trunc(...,d)\relax| for truncation to a decimal number +with |d>0| digits after the decimal mark. + +Perhaps in the future some meaning will be given to using negative value for +the optional parameter |d|.\footnote{Thanks to KT for this suggestion.} \subsection{\csbh{xintiiexpr}, \csbh{xinttheiiexpr}} \label{xintiiexpr}\label{xinttheiiexpr} @@ -12176,7 +12180,7 @@ integers. Comma separated lists of expressions are allowed. The \csbxint{iiexpr}-essions use the `ii' macros for addition, subtraction, multiplication, power, square, sums, products, euclidean quotient and -remainder. +remainder. The |round|, |trunc|, |floor|, |ceil| functions are still available, and are about the only places where fractions can be used, but |/| within, if not @@ -12229,7 +12233,7 @@ etc\dots on their output. \xinttheiiexpr round(\xintFloatSqrt [20]{2},19)+round(\xintFloatSqrt [20]{3},19)\relax -(the second argument of |round| and |trunc| tells how many digits from after the +(the second argument of |round| and |trunc| tells how many digits from after the decimal mark one should keep.) \end{everbatim*} @@ -12237,17 +12241,12 @@ The whole point of \csbxint{iiexpr} is to gain some speed in \emph{integer-only} algorithms, and the above explanations related to how to nevertheless use fractions therein are a bit peripheral. We observed (2013/12/18) of the order of $30$\% speed gain when dealing with numbers with -circa one hundred digits (v1.2: this info may be obsolete). +circa one hundred digits (1.2: this info may be obsolete). -% but this gain decreases the longer the manipulated -% numbers become and becomes negligible for numbers with thousand digits: the -% overhead from parsing fraction format is little compared to other expensive -% aspects of the expandable shuffling of tokens \subsection{\csbh{xintboolexpr}, \csbh{xinttheboolexpr}}\label{xintboolexpr}\label{xinttheboolexpr} -%{\small New in |1.09c|.\par} Equivalent\etype{x} to doing |\xintexpr ...\relax| and returning $1$ if the result does not vanish, and $0$ is the result is zero. As |\xintexpr|, this @@ -12258,101 +12257,93 @@ comma separated list of $0$'s and $1$'s. \csbh{xintthefloatexpr}}\label{xintfloatexpr}\label{xintthefloatexpr} \csbxint{floatexpr}|...\relax|\etype{x} is exactly like |\xintexpr...\relax| -but with the four binary operations and the power function mapped to +but with the four binary operations and the power function are mapped to \csa{xintFloatAdd}, \csa{xintFloatSub}, \csa{xintFloatMul}, \csa{xintFloatDiv} -and \csa{xintFloatPower}. The precision for the computation is from the +and \csa{xintFloatPower}, respectively.\footnote{Since |1.2f| the \string^ + handles half-integer exponents, contrarily to \csa{xintFloatPower}} + +The target precision for the computation is from the current setting of |\xintDigits|. Comma separated lists of expressions are -allowed. +allowed. An optional (positive) parameter within brackets is allowed: the final float will have that many digits of precision. This is provided to get rid of -non-relevant last digits. +possibly irrelevant last digits, thus makes sense only if this parameter is +less than the |\xinttheDigits| precision. + +Since |1.2f| all float operations first round their arguments; a parsed number +is not rounded prior to its use as operand to such a float operation. + + -\xintDigits:= 9; -Note that |1.000000001| and |(1+1e-9)| will not be equivalent for -|D=\xinttheDigits| set to nine or less. Indeed the addition implicit in |1+1e-9| -(and executed when the closing parenthesis is found) will provoke the rounding -to |1|. Whereas |1.000000001|, when found as operand of one of the four -elementary operations is kept with |D+2| digits, and even more for the power -function. \emph{This may be modified in the future, when floating point - support will have been extended and finalized.} -% REVOIR ceci -% -\leftedline{|\xintDigits:= 9; \xintthefloatexpr - (1+1e-9)-1\relax|\dtt{=\xintthefloatexpr (1+1e-9)-1\relax}} -% -\leftedline{|\xintDigits:= 9; \xintthefloatexpr - 1.000000001-1\relax|\dtt{=\xintthefloatexpr 1.000000001-1\relax}} -For the fun of it:\xintDigits:=20; |\xintDigits:=20;|% -% -\leftedline{|\xintthefloatexpr (1+1e-7)^1e7\relax|% - \dtt{=\xintthefloatexpr (1+1e-7)^1e7\relax}} |\xintDigits:=36;|\xintDigits:=36; % \leftedline{|\xintthefloatexpr - ((1/13+1/121)*(1/179-1/173))/(1/19-1/18)\relax|} + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax|} % \leftedline{\dtt{\xintthefloatexpr - ((1/13+1/121)*(1/179-1/173))/(1/19-1/18)\relax}} + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax}} +% 0.00564487459334466559166166079096852897 % -\leftedline{|\xintFloat{\xinttheexpr - ((1/13+1/121)*(1/179-1/173))/(1/19-1/18)\relax}|} +\leftedline{|\xintthefloatexpr\xintexpr + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax\relax|} % -\leftedline{\dtt{\xintFloat - {\xinttheexpr((1/13+1/121)*(1/179-1/173))/(1/19-1/18)\relax}}} +\leftedline{\dtt{\xintthefloatexpr\xintexpr + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax\relax}} \xintDigits := 16; The latter is the rounding of the exact result. The former one has -rounding errors coming from the various roundings done for each -sub-expression. It was a bit funny to discover that |maple|, configured with -|Digits:=36;| and with decimal dots everywhere to let it input the numbers as -floats, gives exactly the same result with the same rounding errors -as does |\xintthefloatexpr|! - -% commented out 2015/11/22 Je dois revoir ce paragraphe -% Using |\xintthefloatexpr| only pays off compared to using |\xinttheexpr| -% followed with |\xintFloat| if the computations turn out to involve hundreds of -% digits. For elementary calculations with hand written numbers (not using the -% scientific notation with exponents differing greatly) it will generally be more -% efficient to use |\xinttheexpr|. The situation is quickly otherwise if one -% starts using the Power function. Then, |\xintthefloat| is often useful; and -% sometimes indispensable to achieve the (approximate) computation in reasonable -% time. - -We can try some crazy things: \emph{please skip this paragraph} -% -\leftedline{|\xintDigits:=12;\xintthefloatexpr 1.000000000000001^1e15\relax|} -% -\leftedline{\xintDigits:=12;% - \dtt{\xintthefloatexpr 1.000000000000001^1e15\relax}} -% -Contrarily to some professional computing sofware which are our concurrents on -this market, the \dtt{1.000000000000001} wasn't rounded to |1| despite the -setting of \csa{xintDigits}; \emph{This may be modified in the - future,\IMPORTANT{} when floating point support will have been extended and - finalized.} It would have been if we had input it as |(1+1e-15)| because the -addition would have rounded to twelve digits of precision on output (and would -have kept the operands only with fourteen=twelve+two digits of precision). - -Anyway: the previous paragraph was written before \csa{xintfloatexpr} had been -added an optional argument and it is better not to rely on any internal -specifics of the floating point operations (which here explain why the \dtt{1} -in sixteenth position is not lost from the input although working with only -twelve digits of precision) and to code this now much more naturally as: -% -\leftedline{|\xintDigits:=16;\xintthefloatexpr [12] 1.000000000000001^1e15\relax|} -% -\leftedline{\xintDigits:=16;% - \dtt{\xintthefloatexpr [12] 1.000000000000001^1e15\relax}} - -\xintDigits := 16; % mais en fait \centeredline crée un groupe. +its last three digits wrong due to the cumulative effect of rounding errors +in the intermediate computations, as compared to exact evaluations. + + + + +I recall here from \autoref{ssec:floatingpoint} that with release |1.2f| the +float macros for addition, subtraction, multiplication and division round +their arguments first to |P| significant places with |P| the asked-for +precision of the output;\CHANGED{1.2f} and similarly the power macros and the +square root macro. This does not modify anything for computations with +arguments having at most |P| significant places already. + + + + + +\xintDigits := 16; % mais en fait \centeredline crée un groupe. + +\subsection{Using an expression parser within another one} + +This was already illustrated before. In the following: +\begin{everbatim*} +\xintthefloatexpr \xintexpr add(1/i, i=1234..1243)\relax ^100\relax +\end{everbatim*}, +the inner sum is computed exactly. Then it will be rounded to |\xinttheDigits| +significant digits, and then its power will be evaluated as a float operation. +One should avoid the "|\xintthe|" parsers in inner positions as this induces +digit by digit parsing of the inner computation result by the outer parser. +Here is the same computation done with floats all the way: +\begin{everbatim*} +\xintthefloatexpr add(1/i, i=1234..1243)^100\relax +\end{everbatim*} + +Not surprisingly this differs from the previous one which was exact until +raising to the |100|th power. + +The fact that the inner expression occurs inside a bigger one has nil +influence on its behaviour. There is the limitation though that the outputs +from \csbxint{expr} and \csbxint{floatexpr} can not be used directly in +\csbxint{theiiexpr} integer-only parser. But one can do: +\begin{everbatim*} +\xinttheiiexpr num(\xintfloatexpr 3.14^10\relax)\relax +\end{everbatim*} + \subsection{\csbh{xintifboolexpr}}\label{xintifboolexpr} -%{\small New in |1.09c|.\par} \csh{xintifboolexpr}|{<expr>}{YES}{NO}|\etype{xnn} does |\xinttheexpr <expr>\relax| and then executes the |YES| or the |NO| branch depending on @@ -12364,14 +12355,12 @@ whether the outcome of the computation vanishes or not. Will not work on an expression composed of comma separated sub-expressions. \subsection{\csbh{xintifboolfloatexpr}}\label{xintifboolfloatexpr} -%{\small New in |1.09c|.\par} \csh{xintifboolfloatexpr}|{<expr>}{YES}{NO}|\etype{xnn} does |\xintthefloatexpr <expr>\relax| and then executes the |YES| or the |NO| branch depending on whether the outcome was non zero or zero. \subsection{\csbh{xintifbooliiexpr}}\label{xintifbooliiexpr} -%{\small New in |1.09i|.\par} \csh{xintifbooliiexpr}|{<expr>}{YES}{NO}|\etype{xnn} does |\xinttheiiexpr <expr>\relax| and then executes the |YES| or the |NO| branch depending on @@ -12381,7 +12370,7 @@ whether the outcome was non zero or zero. This is exactly like \csbxint{NewExpr} except that the created formulas are set-up to use |\xintthefloatexpr|. The precision used for the computation will -be the one given by |\xintDigits| at the time of use of the created formulas. +be the one given by |\xinttheDigits| at the time of use of the created formulas. However, the numbers hard-wired in the original expression will have been evaluated with the then current setting for |\xintDigits|. @@ -12397,7 +12386,7 @@ evaluated with the then current setting for |\xintDigits|. {\xintDigits := 32;\f {2} (?? we thought we had a higher precision. Explanation next)} The sqrt(2) in the second formula was computed with only \xinttheDigits{} of -precision. Setting |\xintDigits| to a higher value at the time of definition will +precision. Setting |\xinttheDigits| to a higher value at the time of definition will confirm that the result above is from a mismatch of the precision for |sqrt(2)| at the time of its evaluation and the precision for the new |sqrt(2)| with |#1=2| at the time of use. @@ -12407,20 +12396,15 @@ the time of use. \end{everbatim*} \subsection{\csbh{xintNewIExpr}}\label{xintNewIExpr} -%{\small New in |1.09c|.\par } -Like \csbxint{NewExpr} but using |\xinttheiexpr|. +Like \csbxint{NewExpr} but using |\xinttheiexpr|. -%Former denomination was -%|\xintNewNumExpr| which is deprecated and should not be used. \subsection{\csbh{xintNewIIExpr}}\label{xintNewIIExpr} -%{\small New in |1.09i|.\par } Like \csbxint{NewExpr} but using |\xinttheiiexpr|. \subsection{\csbh{xintNewBoolExpr}}\label{xintNewBoolExpr} -%{\small New in |1.09c|.\par } Like \csbxint{NewExpr} but using |\xinttheboolexpr|. @@ -12449,8 +12433,6 @@ The format of the output of to |\numexpr| which is non-expandable, if not prefixed by |\the|, |\number|, or |\romannumeral| or in some other context where \TeX{} is building a number. See \autoref{ssec:fibonacci} for some illustration. -% pour mémoire: -% \MyMarginNote[\kern\dimexpr\FrameSep+\FrameRule\relax]{New with 1.09j!} \end{framed} I decided to put all intermediate results (from each evaluation of an infix @@ -12472,7 +12454,7 @@ his/her expansion control. Syntax errors in the input such as using a one-argument function with two arguments will generate low-level \TeX{} processing unrecoverable errors, with -cryptic accompanying message. +cryptic accompanying message. Some other problems will give rise to `error messages' macros giving some indication on the location and nature of the problem. Mainly, an attempt has @@ -12492,12 +12474,8 @@ may be hidden from \csa{xintdeffunc} as |{;}| for example. Again, this remark does \emph{not} apply to the comma |,| which precedes the |<letter>=| part. The comma will be fetched by delimited macros and must be there. Nesting is handled by checking (again using suitable delimited macros) that parentheses -are suitably balanced. It is not needed to use brace pairs. +are suitably balanced. -% When the scanner is looking for a number and finds something else not otherwise -% treated, it assumes it is the start of the function name and will expand forward -% in the hope of hitting an opening parenthesis; if none is found at least it -% should stop when encountering the |\relax| marking the end of the expressions. Note that |\relax| is \emph{mandatory} (contrarily to the situation for |\numexpr|). @@ -12511,8 +12489,8 @@ particular a text called ``roadmap'' which was helpful). Also the source of the |calc| package was instructive, despite the fact that here for |\xintexpr| the principles are necessarily different due to the aim of achieving expandability. -%\etocdepthtag.toc {commandsB} +\clearpage \section{Commands of the \xintbinhexname package} \label{sec:binhex} @@ -12586,6 +12564,7 @@ least one hundred hexadecimal digits. \string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent \dtt{->\printnumber{\xintCHexToBin{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}} +\clearpage \section{Commands of the \xintgcdname package} \label{sec:gcd} @@ -12618,14 +12597,12 @@ zero. \csa{xintiiGCD} skips the \csbxint{Num} overhead.\etype{ff} \subsection{\csbh{xintGCDof}}\label{xintGCDof} -%{\small New with release |1.09a|.\par} \csa{xintGCDof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast\Numf}} computes the greatest common divisor of all integers |a|, |b|, \dots{} The list argument may be a macro, it is \fexpan ded first and must contain at least one item. \subsection{\csbh{xintLCM}, \csbh{xintiiLCM}}\label{xintLCM}\label{xintiiLCM} -%{\small New with release |1.09a|.\par} |\xintGCD|\n\m\etype{\Numf\Numf} computes the least common multiple. It is |0| if one of the two integers vanishes. @@ -12633,7 +12610,6 @@ may be a macro, it is \fexpan ded first and must contain at least one item. \csa{xintiiLCM} skips the \csbxint{Num} overhead.\etype{ff} \subsection{\csbh{xintLCMof}}\label{xintLCMof} -%{\small New with release |1.09a|.\par} \csa{xintLCMof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast\Numf}} computes the least common multiple of all integers |a|, |b|, \dots{} The list argument may be a @@ -12746,6 +12722,7 @@ macro and modify it to what is needed. \leftedline{|\xintTypesetBezoutAlgorithm {10000}{1113}|} \xintTypesetBezoutAlgorithm {10000}{1113} +\clearpage \section{Commands of the \xintseriesname package} \label{sec:series} @@ -12807,7 +12784,7 @@ practice systematic reduction to lowest terms. A more efficient way to code |\coeff| is illustrated next. \begin{everbatim*} \def\coeff #1{\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}% -% The [0] in \coeff is a tiny optimization: in its presence the \xintfracname parser +% The [0] in \coeff is a tiny optimization: in its presence the \xintfracname parser % sees something which is already in internal format. \fdef\w {\xintSeries {0}{50}{\coeff}} \[\sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12}=\xintFrac\w\] @@ -12858,7 +12835,7 @@ factor of \dtt{\xintNum {\xintDenominator\w/\xintDenominator\z}}. | \[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx \xintTrunc -{40}{\xintiSeries {0}{50}{\coeff}[-40]}\] +{40}{\xintiSeries {0}{50}{\coeff}[-40]}\] We should have cut out at least the last two digits: truncating errors originating with the first @@ -12900,7 +12877,6 @@ and that the sum of rounded terms fared a bit better. \subsection{\csbh{xintRationalSeries}}\label{xintRationalSeries} -%{\small \hspace*{\parindent}New with release |1.04|.\par} \noindent \csa{xintRationalSeries}|{A}{B}{f}{\ratio}|\etype{\numx\numx\Ff\Ff} evaluates $\sum_{\text{|n=A|}}^{\text{|n=B|}}|F(n)|$, where |F(n)| is specified @@ -12911,7 +12887,7 @@ must be such that |\macro{n}| expands to |F(n)/F(n-1)|. The name indicates that a fraction. The macro |\ratio| must be an expandable-only compatible command and expand to its value after iterated full expansion of its first token. |A| and |B| are fed to a |\numexpr| hence may be count registers or arithmetic -expressions built with such; they must obey the \TeX{} bound. The initial term +expressions built with such; they must obey the \TeX{} bound. The initial term |f| may be a macro |\f|, it will be expanded to its value representing |F(A)|. \begin{everbatim*} @@ -12922,7 +12898,7 @@ expressions built with such; they must obey the \TeX{} bound. The initial term \noindent$\sum_{n=0}^{\the\cnta} \frac{2^n}{n!}= \xintTrunc{12}\z\dots= \xintFrac\z=\xintFrac{\xintIrr\z}$\vtop to 5pt{}\par -\ifnum\cnta<20 \advance\cnta 1 \repeat +\ifnum\cnta<20 \advance\cnta 1 \repeat \end{quote} \end{everbatim*} @@ -12981,7 +12957,7 @@ Here is a slightly more complicated evaluation: \loop \fdef\z {\xintRationalSeries {\cnta} {2*\cnta-1} - {\xintiPow {\the\cnta}{\cnta}/\xintFac{\cnta}} + {\xintiPow {\the\cnta}{\cnta}/\xintiiFac{\cnta}} {\ratioexp{\the\cnta}}}% \fdef\w {\xintRationalSeries {0}{2*\cnta-1}{1}{\ratioexp{\the\cnta}}}% \noindent @@ -12995,7 +12971,6 @@ $\sum_{n=\the\cnta}^{\the\numexpr 2*\cnta-1\relax} \frac{\the\cnta^n}{n!}/% \subsection{\csbh{xintRationalSeriesX}}\label{xintRationalSeriesX} -%{\small \hspace*{\parindent}New with release |1.04|.\par} \noindent\csa{xintRationalSeriesX}|{A}{B}{\first}{\ratio}{\g}|% \etype{\numx\numx\Ff\Ff f} is a parametrized version of \csa{xintRationalSeries} @@ -13093,9 +13068,6 @@ other test cases: \xintLen {\xintNumerator \z}; length of denominator: \xintLen {\xintDenominator \z}) -% \pdfresettimer -% \edef\w{\xintDenominator{\xintIrr{\z}}} -% \the\pdfelapsedtime Thus decimal numbers such as |0.123| (equivalently @@ -13112,7 +13084,7 @@ of series and hope that \xintname will joyfully do all at the speed of light! Hence, truncating the output (or better, rounding) is the only way to go if one needs a general calculus of special functions. This is why the package \xintseriesname provides, besides \csbxint{Series}, \csbxint{RationalSeries}, or -\csbxint{PowerSeries} which compute \emph{exact} sums, +\csbxint{PowerSeries} which compute \emph{exact} sums, \csbxint{FxPtPowerSeries} for fixed-point computations and a (tentative naive) \csbxint{FloatPowerSeries}. @@ -13249,7 +13221,7 @@ avoid having to compute the factorial from scratch at each coefficient, the same way \csa{xintFxPtPowerSeries} does not compute |f^n| from scratch at each |n|. Perhaps in the next package release. -\def\coeffexp #1{1/\xintFac {#1}[0]}% [0] for faster parsing +\def\coeffexp #1{1/\xintiiFac {#1}[0]}% [0] for faster parsing \def\f {-1/2[0]}% \newcount\cnta @@ -13265,19 +13237,15 @@ $\xintFxPtPowerSeries {0}{\cnta}{\coeffexp}{\f}{20}$\\ \repeat\par \end{multicols} \everb|@ -\def\coeffexp #1{1/\xintFac {#1}[0]}% 1/n! +\def\coeffexp #1{1/\xintiiFac {#1}[0]}% 1/n! \def\f {-1/2[0]}% [0] for faster input parsing \cnta 0 % previously declared \count register \noindent\loop $\xintFxPtPowerSeries {0}{\cnta}{\coeffexp}{\f}{20}$\\ \ifnum\cnta<19 \advance\cnta 1 \repeat\par -% One should **not** trust the final digits, as the potential truncation -% errors of up to 10^{-20} per term accumulate and never disappear! (the -% effect is attenuated by the alternating signs in the series). We can -% confirm that the last two digits (of our evaluation of the nineteenth -% partial sum) are wrong via the evaluation with more digits: | + % \leftedline{|\xintFxPtPowerSeries {0}{19}{\coeffexp}{\f}{25}=| \dtt{\xintFxPtPowerSeries {0}{19}{\coeffexp}{\f}{25}}} @@ -13302,7 +13270,6 @@ of digits possibly of dubious significance. \subsection{\csbh{xintFxPtPowerSeriesX}}\label{xintFxPtPowerSeriesX} -%{\small\hspace*{\parindent}New with release |1.04|.\par} \noindent\csa{xintFxPtPowerSeriesX}|{A}{B}{\coeff}{\f}{D}|% \ntype{\numx\numx} @@ -13313,10 +13280,6 @@ of the series being \emph{truncated} to |D| digits after the decimal point. The sole difference is that |\f| is first expanded and it is the result of this which is used in the computations. -% Let us illustrate this on the computation of |(1+y)^{5/3}| where -% |1+y=(1+x)^{3/5}| and each of the two binomial series is evaluated with ten -% terms, the results being computed with |8| digits after the decimal point, and -% $|f|<1/10$. Let us illustrate this on the numerical exploration of the identity % @@ -13381,7 +13344,6 @@ release. \subsection{\csbh{xintFloatPowerSeries}}\label{xintFloatPowerSeries} -%{\small\hspace*{\parindent}New with |1.08a|.\par} \noindent\csa{xintFloatPowerSeries}|[P]{A}{B}{\coeff}{f}|% \ntype{{\upshape[\numx]}\numx\numx} @@ -13414,7 +13376,6 @@ with |\coeff{n}|, and the sum is done adding one term at a time with \subsection{\csbh{xintFloatPowerSeriesX}}\label{xintFloatPowerSeriesX} -%{\small\hspace*{\parindent}New with |1.08a|.\par} \noindent\csa{xintFloatPowerSeriesX}|[P]{A}{B}{\coeff}{f}|% \ntype{{\upshape[\numx]}\numx\numx} @@ -13426,7 +13387,7 @@ efficient chaining of such series evaluations. \def\coefflog #1{\the\numexpr\ifodd#1 1\else-1\fi\relax/#1[0]}% \everb+@ -\def\coeffexp #1{1/\xintFac {#1}[0]}% 1/n! (exact, not float) +\def\coeffexp #1{1/\xintiiFac {#1}[0]}% 1/n! (exact, not float) \def\coefflog #1{\the\numexpr\ifodd#1 1\else-1\fi\relax/#1[0]}% \xintFloatPowerSeriesX [8]{0}{30}{\coeffexp} {\xintFloatPowerSeries [8]{1}{30}{\coefflog}{-1/2[0]}} @@ -13633,16 +13594,16 @@ You want more digits and have some time? compile this copy of the \odef\W {\the\pdfelapsedtime} \message{\Z} \message{computed in \xintRound {2}{\W/65536} seconds.} -\bye +\bye | This will log the first 1000 digits of $\pi$ after the decimal point. On my laptop (a 2012 model) this took about $5.6$ seconds last time I tried.% % -\footnote{With \texttt{v1.09i} and earlier \xintname, this used to be \dtt{42} - seconds; starting with \texttt{v1.09j}, and prior to \texttt{v1.2}, it was +\footnote{With \texttt{1.09i} and earlier \xintname, this used to be \dtt{42} + seconds; starting with \texttt{1.09j}, and prior to \texttt{1.2}, it was \dtt{16} seconds (this was probably due to a more efficient division with - denominators at most $9999$). The |v1.2| \xintcorename achieves a further + denominators at most $9999$). The |1.2| \xintcorename achieves a further gain.} % As mentioned in the @@ -13677,8 +13638,7 @@ decimal expansion, so we truncate and compute more terms until the earlier result gets validated. Finally if we do want the rounding we can always do it on a value computed with |D+1| truncation. -% \clearpage - +\clearpage \section{Commands of the \xintcfracname package} \label{sec:cfrac} @@ -13866,11 +13826,11 @@ convergents, return them as a list of braced items, with no separator (as does \csbxint {FtoC} for the partial quotients). Here is an example: \begin{everbatim*} -\[\xintFrac{915286/188421}\to +\[\xintFrac{915286/188421}\to \xintListWithSep{,}{\xintApply\xintFrac{\xintFtoCv{915286/188421}}}\] \end{everbatim*} \begin{everbatim*} -\[\xintFrac{915286/188421}\to +\[\xintFrac{915286/188421}\to \xintListWithSep{,}{\xintApply\xintFrac{\xintFtoCCv{915286/188421}}}\] \end{everbatim*} % @@ -13967,7 +13927,7 @@ will \fexpan d to it). It admits the same optional argument as \csa{xintCFrac}. Plain \TeX{} with |amstex| users, see \csbxint{GCtoGCx}. \begin{everbatim*} -\[\xintGCFrac {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintFac {6}}\] +\[\xintGCFrac {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}\] \end{everbatim*} This is mostly a typesetting macro, although it does provoke the expansion of the coefficients. See \csbxint{GCtoF} if you are impatient @@ -14163,12 +14123,12 @@ provoke the needed coefficient expansion.% ok \csa{xintGCtoF}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} computes the fraction defined by the inline generalized continued fraction. Coefficients may be fractions but must then be put within braces. They can be macros. The plus signs -are mandatory. +are mandatory. \begin{everbatim*} -\[\xintGCFrac {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintFac {6}} = -\xintFrac{\xintGCtoF {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintFac {6}}} = +\[\xintGCFrac {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}} = +\xintFrac{\xintGCtoF {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}} = \xintFrac{\xintIrr{\xintGCtoF - {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintFac {6}}}}\] + {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}}}\] \end{everbatim*} \begin{everbatim*} @@ -14272,7 +14232,7 @@ The |N| parameter is given to a |\numexpr|. \begin{everbatim*} \def\coeffA #1{\the\numexpr #1+4-3*((#1+2)/3)\relax }% \def\coeffB #1{\the\numexpr \ifodd #1 -\fi 1\relax }% (-1)^n -\[\xintGCFrac{\xintGCntoGC {6}{\coeffA}{\coeffB}} = +\[\xintGCFrac{\xintGCntoGC {6}{\coeffA}{\coeffB}} = \xintFrac{\xintGCntoF {6}{\coeffA}{\coeffB}}\] \end{everbatim*} There is also \csbxint{GCntoGC} to get the `inline format' continued @@ -14299,7 +14259,7 @@ of the corresponding coefficients, from |n=0| to |n=N|. The |N| is given to a The coefficients, after expansion, are, as shown, being enclosed in an added pair of braces, they may thus be fractions. \begin{everbatim*} -\def\macro #1{\the\numexpr\ifodd#1 -1-#1\else1+#1\fi\relax/\the\numexpr 1+#1*#1\relax} +\def\macro #1{\the\numexpr\ifodd#1 -1-#1\else1+#1\fi\relax/\the\numexpr 1+#1*#1\relax} \fdef\x{\xintCntoGC {5}{\macro}}\meaning\x \[\xintGCFrac{\xintCntoGC {5}{\macro}}\] \end{everbatim*} @@ -14347,7 +14307,7 @@ braces. % \begin{everbatim*} \fdef\x {\xintGCtoGC {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/% - \xintFac {6}+\xintCstoF {2,-7,-5}/16}} \meaning\x + \xintiiFac {6}+\xintCstoF {2,-7,-5}/16}} \meaning\x \end{everbatim*} To be honest I have forgotten for which purpose I wrote this macro in the first @@ -14388,10 +14348,6 @@ the convergents of Euler's number $e$. {\xintApply\mymacro{\xintiCstoCv{\xintCntoCs {35}{\cn}}}} \end{everbatim*} -% \def\testmacro #1{\xintTrunc {30}{\xintAdd {1[0]}{#1}}\xintAdd {1[0]}{#1}} -% \pdfresettimer -% \oodef\z{\xintApply\testmacro{\xintiCstoCv{\xintCntoCs {35}{\cn}}}} -% (\the\pdfelapsedtime) \smallskip @@ -14432,7 +14388,7 @@ $1$ or $-1$. \centeredline{|sourcexint.pdf|,} % which should be among the candidates proposed by |texdoc --list xint|. To - produce a single file including both the user documentation and the + produce a single file including both the user documentation and the source code, run |tex xint.dtx| to generate |xint.tex| (if not already available), then edit |xint.tex| to set the |\NoSourceCode| toggle to |0|, then run thrice |latex| on |xint.tex| and finally |dvipdfmx| on |xint.dvi|. @@ -14441,11 +14397,10 @@ $1$ or $-1$. \end{framed} \fi -% Mercredi 08 octobre 2014 à 22:09:54 \ifnum\dosourcexint=1 +fi +catcode`\ 0 -\catcode0 15 % retour à la normale, peu importe +\catcode0 15 % retour à la normale, peu importe \catcode`\+ 12 \etocignoredepthtags \etocsetnexttocdepth{section} @@ -14460,10 +14415,6 @@ $1$ or $-1$. \etocsettocstyle {}{} \else \clearpage -% \newgeometry{%hmarginratio=4:3, -% hscale=0.75,vscale=0.75}% ATTENTION \newgeometry fait -% % un reset de vscale si on ne le -% % précise pas ici !!! \fi \def\MARGEPAGENO{1.25em} @@ -14478,25 +14429,24 @@ $1$ or $-1$. \unexpanded\expandafter{\storedlinecounts}% {{#1}{\the\c@CodelineNo}}}\c@CodelineNo\z@ } -% Pour le code des macros -% On va redéfinir \macro@font -% Pas de couleur, et 0 slashed \def\macro@font {\ttbfamily } -% Pour \lverb \def\MicroFont {\ttzfamily\color[named]{Purple}\makestarlowast } \makeatother \MakePercentIgnore -% -% \catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11 -% \let</dtx>\relax -% \def<*xintkernel>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 } -%</dtx> -%<*xintkernel> +%\def\gardesactifs {^^A +%\catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11 } +%\def\gardesinactifs {^^A +%\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 } +%\gardesactifs +%\let</dtx>\relax +%\let<*xintkernel>\gardesinactifs +%</dtx>^^A-------------------------------------------------------- +%<*xintkernel>^^A------------------------------------------------- % % \bigskip % This is \expandafter|\xintbndlversion| of \expandafter|\xintbndldate|. @@ -14506,8 +14456,8 @@ $1$ or $-1$. % arithmetic routines in \xintcorenameimp. Many macros benefit indirectly % from the faster core routines. The new model is yet to be extended to % other portions of the code: for example the routines of \xintbinhexnameimp -% could be made faster for very big inputs if they adopted some of the style -% used now for the basic arithmetic routines. +% could be made faster for very big inputs if they adopted some techniques +% from the implementation of the basic arithmetic routines. % % The parser of \xintexprnameimp is also faster at gathering digits and does % not have a limit at |5000| digits per number anymore. @@ -14525,6 +14475,7 @@ $1$ or $-1$. % time I was learning my trade in expandable TeX macro programming. At some % point in the future, I will have to re-examine the older parts of the code. % +% \clearpage % \section {Package \xintkernelnameimp implementation} % \label{sec:kernelimp} % @@ -14535,7 +14486,7 @@ $1$ or $-1$. % more helper macros and all |\chardef|'s have been moved here. The package is % loaded by both |xintcore.sty| and |xinttools.sty| hence by all other % packages. -% +% % First appeared as a separate package with release |1.1|. % % \subsection{Catcodes, \protect\eTeX{} and reload detection} @@ -14592,21 +14543,6 @@ $1$ or $-1$. \fi \fi \ifx\z\relax\else\expandafter\z\fi% -% \end{macrocode} -% |1.2| corrects a long-standing somewhat subtle bug, of which the author -% became aware only on |15/09/13|: earlier releases had |\aftergroup\endinput| -% above, rather than |\def\z{\endgroup\endinput}| and the |\ifx| test. The -% |\endinput| token was indeed inserted after the |\endgroup| from -% |\PrepareCatcodes|, but all material and in particular |\XINT_setupcatcodes| -% from the macro now called |\PrepareCatcodes| was expanded before the -% |\endinput| had come into effect ! as a result the catcodes would be -% modified in unwanted ways, in Plain \TeX, if the source had for example -% |\input xint.sty| followed by |\input xintkernel.sty|: the catcode changes -% would be done before the second input of |xintkernel.sty| had been aborted. -% One didn't see the situation under \LaTeX{} (in normal circumstances), -% because a second |\usepackage{xintkernel}| would not do any input of -% |xintkernel.sty| to start with. -% \begin{macrocode} \def\PrepareCatcodes {% \endgroup @@ -14721,10 +14657,10 @@ $1$ or $-1$. \fi \XINT_providespackage \ProvidesPackage {xintkernel}% - [2015/11/22 v1.2e Paraphernalia for the xint packages (jfB)]% + [2016/03/12 1.2f Paraphernalia for the xint packages (JFB)]% % \end{macrocode} % \subsection{Constants} -% |v1.2| decides to move them to \xintkernelnameimp from \xintcorenameimp and +% |1.2| decides to move them to \xintkernelnameimp from \xintcorenameimp and % \xintnameimp. The |\count|'s are left in their respective packages. % \begin{macrocode} \chardef\xint_c_ 0 @@ -14752,7 +14688,7 @@ $1$ or $-1$. % \subsection{Token management utilities} % \begin{macrocode} \def\XINT_tmpa { }% -\ifx\XINT_tmpa\space\else +\ifx\XINT_tmpa\space\else \immediate\write-1{Package xintkernel Warning: ATTENTION!}% \immediate\write-1{\string\space\XINT_tmpa macro does not have its normal meaning.}% @@ -14829,7 +14765,7 @@ $1$ or $-1$. % \if..\xint_dothis{..}\fi <multiple times> followed by \xint_orthat{...}. To % be used with less probable things first.| % \begin{macrocode} -\long\def\xint_dothis #1#2\xint_orthat #3{\fi #1}% v1.1 +\long\def\xint_dothis #1#2\xint_orthat #3{\fi #1}% 1.1 \let\xint_orthat \xint_firstofone \long\def\xintdothis #1#2\xintorthat #3{\fi #1}% \let\xintorthat \xint_firstofone @@ -14870,7 +14806,7 @@ $1$ or $-1$. % % 1.2e adds \xint_zapspaces_o. Expansion of #1 should not gobble a space ! | % \begin{macrocode} -\def\xint_zapspaces #1 #2{#1#2\xint_zapspaces }% v1.1 +\def\xint_zapspaces #1 #2{#1#2\xint_zapspaces }% 1.1 \def\xint_zapspaces_o #1{\expandafter\xint_zapspaces#1 \xint_gobble_i}% % \end{macrocode} % \subsection{\csh{odef}, \csh{oodef}, \csh{fdef}} @@ -14958,14 +14894,15 @@ $1$ or $-1$. \newif\ifxintverbose \XINT_restorecatcodes_endinput% % \end{macrocode} -%\catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11 -%\let</xintkernel>\relax -%\def<*xinttools>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 } -%</xintkernel> -%<*xinttools> % % \StoreCodelineNo {xintkernel} % +%\gardesactifs +%\let</xintkernel>\relax +%\let<*xinttools>\gardesinactifs +%</xintkernel>^^A------------------------------------------------- +%<*xinttools>^^A-------------------------------------------------- +% \clearpage % \section{Package \xinttoolsnameimp implementation} % \label{sec:toolsimp} % @@ -15032,7 +14969,7 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xinttools}% - [2015/11/22 v1.2e Expandable and non-expandable utilities (jfB)]% + [2016/03/12 1.2f 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.| @@ -15105,7 +15042,7 @@ $1$ or $-1$. % \lverb|defined via an \edef in order to inject space tokens inside.| % \begin{macrocode} \long\edef\xintzapfirstspaces #1% - {\noexpand\XINT_zapbsp_a \space #1\xint_relax \space\space\xint_relax }% + {\noexpand\XINT_zapbsp_a \space #1\xint_relax \space\space\xint_relax }% \xint_firstofone {\long\edef\XINT_zapbsp_a #1 } %<- space token here {% % \end{macrocode} @@ -16211,7 +16148,7 @@ $1$ or $-1$. % \end{macrocode} % \subsection{\csh{xintForpair}, \csh{xintForthree}, \csh{xintForfour}} % \lverb|1.09c. -% +% % [2013/11/02] 1.09f \xintForpair delegate to \xintCSVtoList and its % \xintZapSpacesB the handling of spaces. Does not share code with \xintFor % anymore. @@ -16288,7 +16225,7 @@ $1$ or $-1$. % \end{macrocode} % \subsection{\csh{xintAssign}, \csh{xintAssignArray}, \csh{xintDigitsOf}} % \lverb|\xintAssign {a}{b}..{z}\to\A\B...\Z resp. \xintAssignArray -% {a}{b}..{z}\to\U. +% {a}{b}..{z}\to\U. % % \xintDigitsOf=\xintAssignArray. % @@ -16343,7 +16280,7 @@ $1$ or $-1$. \long\def\XINT_assign_d #1\to #2% {% \expandafter\XINT_assign_def\expandafter #2\expandafter{\xint_temp}% - \XINT_assign_c #1\to + \XINT_assign_c #1\to }% \def\XINT_assign_e #1\to {}% \def\xintRelaxArray #1% @@ -16431,22 +16368,22 @@ $1$ or $-1$. \let\XINT_tmpa\relax \let\XINT_tmpb\relax \let\XINT_tmpc\relax \XINT_restorecatcodes_endinput% % \end{macrocode} -%\catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11 -%\let</xinttools>\relax -%\def<*xintcore>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 } -%</xinttools> -%<*xintcore> % % \StoreCodelineNo {xinttools} % +%\gardesactifs +%\let</xinttools>\relax +%\let<*xintcore>\gardesinactifs +%</xinttools>^^A-------------------------------------------------- +%<*xintcore>^^A--------------------------------------------------- +% \clearpage % \section{Package \xintcorenameimp implementation} % \label{sec:coreimp} % % \localtableofcontents % -% Got split off from \xintnameimp with release |1.1|. Release |1.1| also added -% the new macro |\xintiiDivRound|. The package does not load -% \xinttoolsnameimp. +% Got split off from \xintnameimp with release |1.1|, which also added +% the new macro |\xintiiDivRound|. % % \begin{framed} % The core arithmetic routines have been entirely rewritten for release @@ -16458,10 +16395,10 @@ $1$ or $-1$. % all. % \end{framed} % -% Also, with |1.2|, |\xintAdd| etc... have been left undefined control -% sequences: only |\xintiAdd| and |\xintiiAdd| (etc...) are provided via -% \xintcorenameimp. It was announced a long time ago that |\xintAdd| etc... -% were to be removed from \xintnameimp and only defined by \xintfracnameimp. +% Also, starting with |1.2|, |\xintAdd| etc... are defined only via +% \xintfracnameimp. Only |\xintiAdd| and |\xintiiAdd| (etc...) are provided +% via \xintcorenameimp. +% % % \subsection{Catcodes, \protect\eTeX{} and reload detection} % @@ -16520,7 +16457,7 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintcore}% - [2015/11/22 v1.2e Expandable arithmetic on big integers (jfB)]% + [2016/03/12 1.2f Expandable arithmetic on big integers (JFB)]% % \end{macrocode} % \subsection{Counts for holding needed constants} % \begin{macrocode} @@ -16535,18 +16472,8 @@ $1$ or $-1$. % \end{macrocode} % \subsection{\csh{xintNum}} % \lverb|& -% For example \xintNum {----+-+++---+----000000000000003}$\ -% 1.05 defines \xintiNum, which allows redefinition of \xintNum by xintfrac.sty -% Slightly modified in 1.06b (\R->\xint_relax) to avoid initial re-scan of -% input stack (while still allowing empty #1). In versions earlier than 1.09a -% it was entirely up to the user to apply \xintnum; starting with 1.09a -% arithmetic -% macros of xint.sty (like earlier already xintfrac.sty with its own \xintnum) -% make use of \xintnum. This allows arguments to -% be count registers, or even \numexpr arbitrary long expressions (with the -% trick of braces, see the user documentation). -% -% Note (10/2015): I should take time to revisit this.| +% For example \xintNum {----+-+++---+----000000000000003}$\ +% | % \begin{macrocode} \def\xintiNum {\romannumeral0\xintinum }% \def\xintinum #1% @@ -16589,38 +16516,60 @@ $1$ or $-1$. \def\XINT_num_finish #1\xint_relax #2\Z { #1}% % \end{macrocode} % \subsection{Zeroes} -% \lverb|Changed for 1.2 which has a base model of eight digits rather than -% four for the basic operations.| +% \lverb|Everything had to be changed for 1.2 as it does computations by +% blocks of eight digits rather than four. +% +% Currently many macros are launched by a \romannumeral0. Perhaps I should +% have used \romannumeral and end expansion by \z@ (\xint_c_). +% +% \XINT_cuz_small removes leading zeroes from the first eight digits. Supposed +% to have been launched by a \romannumeral0. At least one digit is produced.| % \begin{macrocode} \edef\XINT_cuz_small #1#2#3#4#5#6#7#8% {% \noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4#5#6#7#8\relax }% -%%%%%%%%%%%% +% \end{macrocode} +% \lverb|This iterately removes all leading zeroes from a sequence of 8N +% digits ended by \R. +% +% Note 2015/11/28: with only four digits the gob_til_fourzeroes had proved +% in some old testing faster than \ifnum test. But with eight digits, the +% execution times are much closer, as I tested only now. Thus, one could as +% well use \ifnum test here. Besides the tests were not exactly for a +% situation like here where \XINT_cuz_z has two 00000000 blocks to grab.| +% \begin{macrocode} \def\XINT_cuz #1#2#3#4#5#6#7#8#9% {% \xint_gob_til_R #9\XINT_cuz_e \R \xint_gob_til_eightzeroes #1#2#3#4#5#6#7#8\XINT_cuz_z 00000000% - \XINT_cuz_clean #1#2#3#4#5#6#7#8#9% + \XINT_cuz_done #1#2#3#4#5#6#7#8#9% }% -\edef\XINT_cuz_clean #1#2#3#4#5#6#7#8#9\R +\def\XINT_cuz_z 00000000\XINT_cuz_done 00000000{\XINT_cuz }% +\edef\XINT_cuz_done #1#2#3#4#5#6#7#8#9\R {\noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4#5#6#7#8\relax #9}% -\edef\XINT_cuz_e\R #1\XINT_cuz_clean #2\R +\edef\XINT_cuz_e\R #1\XINT_cuz_done #2\R {\noexpand\expandafter\space\noexpand\the\numexpr #2\relax }% -\def\XINT_cuz_z 00000000\XINT_cuz_clean 00000000{\XINT_cuz }% -%%%%%%%%%%%% +% \end{macrocode} +% \lverb|This removes eight by eight leading zeroes from a sequence of 8N digits +% ended by \R. Thus, we still have 8N digits on output.| +% \begin{macrocode} \def\XINT_cuz_byviii #1#2#3#4#5#6#7#8#9% {% \xint_gob_til_R #9\XINT_cuz_byviii_e \R \xint_gob_til_eightzeroes #1#2#3#4#5#6#7#8\XINT_cuz_byviii_z 00000000% - \XINT_cuz_byviii_clean #1#2#3#4#5#6#7#8#9% + \XINT_cuz_byviii_done #1#2#3#4#5#6#7#8#9% }% -\def\XINT_cuz_byviii_clean #1\R { #1}% -\def\XINT_cuz_byviii_e\R #1\XINT_cuz_byviii_clean #2\R{ #2}% -\def\XINT_cuz_byviii_z 00000000\XINT_cuz_byviii_clean 00000000{\XINT_cuz_byviii}% +\def\XINT_cuz_byviii_z 00000000\XINT_cuz_byviii_done 00000000{\XINT_cuz_byviii}% +\def\XINT_cuz_byviii_done #1\R { #1}% +\def\XINT_cuz_byviii_e\R #1\XINT_cuz_byviii_done #2\R{ #2}% % \end{macrocode} % \subsection{Blocks of eight digits} -% \lverb|Lingua of release 1.2.| +% \lverb|Lingua of release 1.2. +% +% \romannumeral0\XINT_zeroes_forviii #1\R\R\R\R\R\R\R\R{10}0000001\W$newline +% produces a string of k 0's such that k+length(#1) is smallest bigger multiple +% of eight.| % \begin{macrocode} \def\XINT_zeroes_forviii #1#2#3#4#5#6#7#8% {% @@ -16630,7 +16579,19 @@ $1$ or $-1$. {% \noexpand\expandafter\space\noexpand\xint_gob_til_one #2#3#4#5#6#7#8% }% -%%%%%%%%%%%% +% \end{macrocode} +% \lverb|This is used as$bgroup$obeyspaces$obeylines +% \the\numexpr1\XINT_rsepbyviii <8Ndigits>$% +% \XINT_rsepbyviii_end_A 2345678$% +% \XINT_rsepbyviii_end_B 2345678\relax UV$egroup +% +% $noindent +% and will produce 1<8digits>!1<8digits>.1<8digits>!... where the original +% digits are organized by eight, and the order inside successive pairs of +% blocks separated by ! has been reversed. The output ends with a final 1U. or +% 1V. The former happens when we had an even number of eight blocks, the +% latter an odd number: 1<8d>!1<8d>.1U. or 1<8d>!1<8d>.1<8d>.1V.| +% \begin{macrocode} \def\XINT_rsepbyviii #1#2#3#4#5#6#7#8% {% \XINT_rsepbyviii_b {#1#2#3#4#5#6#7#8}% @@ -16642,7 +16603,18 @@ $1$ or $-1$. }% \def\XINT_rsepbyviii_end_B #1\relax #2#3{#2.}% \def\XINT_rsepbyviii_end_A #11#2\expandafter #3\relax #4#5{#2.1#5.}% -%%%%%%%%%%%% +% \end{macrocode} +% \lverb|This is used typically as$bgroup$obeyspaces$obeylines +% \romannumeral0\expandafter\XINT_sepandrev <8Ndigits>$% +% \XINT_rsepbyviii_end_A 2345678$% +% \XINT_rsepbyviii_end_B 2345678\relax UV\R.\R.\R.\R.\R.\R.\R.\R.\W$egroup +% +% $noindent +% and will produce 1<8digits>!1<8digits>!1<8digits>!... where the blocks have +% been globally reversed. The UV here are only place holders to share same +% syntax as \XINT_sepandrev_andcount, they are gobbled (#2 in +% \XINT_sepandrev_done).| +% \begin{macrocode} \def\XINT_sepandrev {% \expandafter\XINT_sepandrev_a\the\numexpr 1\XINT_rsepbyviii @@ -16655,8 +16627,20 @@ $1$ or $-1$. }% \def\XINT_sepandrev_end\R\XINT_sepandrev_b #1#2\W {\XINT_sepandrev_done #1}% \def\XINT_sepandrev_done #11#2!{ }% -%%%%%%%%%%%% -\def\XINT_sepandrev_andcount +% \end{macrocode} +% \lverb|This is used typically as$bgroup$obeyspaces$obeylines +% \romannumeral0\expandafter\XINT_sepandrev_andcount +% \the\numexpr1\XINT_rsepbyviii <8Ndigits>$% +% \XINT_rsepbyviii_end_A 2345678$% +% \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_iii +% \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii +% \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W$egroup +% +% $noindent +% and will produce <length>.1<8digits>!1<8digits>!1<8digits>!... where the +% blocks have been globally reversed and <length> is the number of blocks.| +% \begin{macrocode} +\def\XINT_sepandrev_andcount {% \expandafter\XINT_sepandrev_andcount_a\the\numexpr 1\XINT_rsepbyviii }% @@ -16668,14 +16652,17 @@ $1$ or $-1$. {#9!#8!#7!#6!#5!#4!#3!#2}% }% \def\XINT_sepandrev_andcount_end\R - \expandafter\XINT_sepandrev_andcount_b\the\numexpr #1+\xint_c_xiv.#2#3#4\W + \expandafter\XINT_sepandrev_andcount_b\the\numexpr #1+\xint_c_xiv.#2#3#4\W {\expandafter\XINT_sepandrev_andcount_done\the\numexpr \xint_c_ii*#3+#1.#2}% \edef\XINT_sepandrev_andcount_done #1.#21#3!% {\noexpand\expandafter\space\noexpand\the\numexpr #1-#3.}% % \end{macrocode} -% \lverb|Needed ending pattern: 1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W. The -% \romannumeral in unrevbyviii_a is for special effects. I must document when -% needed and used.| +% \lverb|Used as \romannumeral0\XINT_unrevbyviii 1<8d>!....1<8d>! terminated +% by$newline 1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W. +% +% The \romannumeral in unrevbyviii_a is for special effects (expand some token +% which was put as 1<token>! at the end of the original blocks). Used by +% subtraction during \XINT_sub_out, in particular.| % \begin{macrocode} \def\XINT_unrevbyviii #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!% {% @@ -16686,9 +16673,9 @@ $1$ or $-1$. {\noexpand\expandafter\space \noexpand\romannumeral`&&@\noexpand\xint_gob_til_Z #1}% % \end{macrocode} -% \lverb|Can work with ending pattern: 1\Z!1\R!1\R!1\R!1\R!1\R!1\R!\W but the -% longer one of unrevbyviii is ok here too. Used currently (1.2) only by -% addition, now (1.2c) with long ending pattern. Does the final clean up of +% \lverb|Can work with shorter ending pattern: 1\Z!1\R!1\R!1\R!1\R!1\R!1\R!\W +% but the longer one of unrevbyviii is ok here too. Used currently (1.2) only +% by addition, now (1.2c) with long ending pattern. Does the final clean up of % leading zeroes contrarily to general \XINT_unrevbyviii.| % \begin{macrocode} \def\XINT_smallunrevbyviii 1#1!1#2!1#3!1#4!1#5!1#6!1#7!1#8!#9\W% @@ -16696,9 +16683,18 @@ $1$ or $-1$. \expandafter\XINT_cuz_small\xint_gob_til_Z #8#7#6#5#4#3#2#1% }% % \end{macrocode} -% \subsection{Blocks of eight, for needs of v1.2 \csh{xintiiDivision}.} +% \subsection{Blocks of eight, for needs of 1.2 \csh{xintiiDivision}.} +% \lverb|This is used as$bgroup$obeyspaces$obeylines +% \the\numexpr\XINT_sepbyviii_andcount <8Ndigits>$% +% \XINT_sepbyviii_end 2345678\relax +% \xint_c_vii!\xint_c_vi!\xint_c_v!\xint_c_iv!% +% \xint_c_iii!\xint_c_ii!\xint_c_i!\xint_c_\W $egroup +% +% $noindent +% It will produce 1<8d>!1<8d>!....1<8d>!1.<count of blocks>. Used by +% \XINT_div_prepare_g for \XINT_div_prepare_h.| % \begin{macrocode} -\def\XINT_sepbyviii_andcount +\def\XINT_sepbyviii_andcount {% \expandafter\XINT_sepbyviii_andcount_a\the\numexpr\XINT_sepbyviii }% @@ -16712,13 +16708,20 @@ $1$ or $-1$. {% #2\expandafter!\the\numexpr#3\expandafter!\the\numexpr#4\expandafter !\the\numexpr#5\expandafter!\the\numexpr#6\expandafter!\the\numexpr - #7\expandafter - !\the\numexpr#8\expandafter!\the\numexpr#9\expandafter!\the\numexpr + #7\expandafter!\the\numexpr#8\expandafter!\the\numexpr#9\expandafter!\the\numexpr \expandafter\XINT_sepbyviii_andcount_b\the\numexpr #1+\xint_c_viii.% }% -\def\XINT_sepbyviii_andcount_end #1\XINT_sepbyviii_andcount_b\the\numexpr +\def\XINT_sepbyviii_andcount_end #1\XINT_sepbyviii_andcount_b\the\numexpr #2+\xint_c_viii.#3#4\W {\expandafter.\the\numexpr #2+#3.}% -%%%%%%%%%%%% +% \end{macrocode} +% \subsection{Blocks of eight, for needs of 1.2 \csh{xintiiDivision}.} +% \lverb|This is used as$newline +% \romannumeral0\XINT_rev_nounsep {}<blocks 1<8d>!>\R!\R!\R!\R!\R!\R!\R!\R!\W +% +% It reverses the blocks, keeping the 1's and ! separators. Used multiple +% times in division algorithm. The inserted {} here is *not* optional. +% Attention does not make disappear a 1!.| +% \begin{macrocode} \def\XINT_rev_nounsep #1#2!#3!#4!#5!#6!#7!#8!#9!% {% \xint_gob_til_R #9\XINT_rev_nounsep_end\R @@ -16726,13 +16729,27 @@ $1$ or $-1$. }% \def\XINT_rev_nounsep_end\R\XINT_rev_nounsep #1#2\W {\XINT_rev_nounsep_done #1}% \def\XINT_rev_nounsep_done #11{ 1}% -%%%%%%%%%%%% +% \end{macrocode} +% \lverb|This is used as$newline +% \the\numexpr\XINT_sepbyviii_Z <8Ndigits>\XINT_sepbyviii_Z_end 2345678\relax +% +% It produces 1<8d>!...1<8d>!1\Z!| +% \begin{macrocode} \def\XINT_sepbyviii_Z #1#2#3#4#5#6#7#8% {% 1#1#2#3#4#5#6#7#8\expandafter!\the\numexpr\XINT_sepbyviii_Z }% \def\XINT_sepbyviii_Z_end #1\relax {\relax\Z!}% -%%%%%%%%%%%% +% \end{macrocode} +% \lverb|This is used as$newline +% \romannumeral0\XINT_unsep_cuzsmall {}<blocks of 1<8d>!>1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W +% +% En fait le {} est optionnel, s'il est absent le premier #1 sera vide, tout +% simplement. It removes the 1's and !'s, and removes the leading zeroes *of +% the first block*. This could have been done with \numexpr and a \cleanup but +% would have restricted due to maximal expansion depth. Probably there where +% already O(N^2) macros, thus I decided that this one would be too.| +% \begin{macrocode} \def\XINT_unsep_cuzsmall #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!% {% \xint_gob_til_R #9\XINT_unsep_cuzsmall_end\R @@ -16742,7 +16759,13 @@ $1$ or $-1$. \XINT_unsep_cuzsmall #1{\XINT_unsep_cuzsmall_done #1}% \def\XINT_unsep_cuzsmall_done #1\R #2\W{\XINT_cuz_small #1}% \def\XINT_unsep_delim {1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W}% -%%%%%%%%%%%% +% \end{macrocode} +% \lverb|This is used by division to remove separators from the produced +% quotient. The quotient is produced in the correct order. The routine will +% also remove leading zeroes. An extra intial block of 8 zeroes is possible +% and thus if present must be removed. Then the next eight digits must be +% cleaned of leading zeroes.| +% \begin{macrocode} \def\XINT_div_unsepQ #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!% {% \xint_gob_til_R #9\XINT_div_unsepQ_end\R @@ -16759,7 +16782,12 @@ $1$ or $-1$. {\the\numexpr #1\relax \Z}% \def\XINT_div_unsepQ_y #1.#2\R #3\W{\XINT_cuz_small #2\Z}% \def\XINT_div_unsepQ_done #1.#2\R #3\W { #1#2\Z}% -%%%%%%%%%%%% +% \end{macrocode} +% \lverb|This is used by division to remove separators from the produced +% remainder. The remainder is here in correct order. It must be cleaned of +% leading zeroes, possibly all the way. Terminator was +% 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W| +% \begin{macrocode} \def\XINT_div_unsepR #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!% {% \xint_gob_til_R #9\XINT_div_unsepR_end\R @@ -16769,7 +16797,7 @@ $1$ or $-1$. \def\XINT_div_unsepR_done #1\R #2\W {\XINT_cuz #1\R}% % \end{macrocode} % \subsection{\csh{xintReverseDigits}} -% \lverb|v1.2. Needed now by \xintLDg.| +% \lverb|1.2. Needed now by \xintLDg.| % \begin{macrocode} \def\XINT_microrevsep #1#2#3#4#5#6#7#8% {% @@ -16785,14 +16813,14 @@ $1$ or $-1$. -{\XINT_reversedigits_a #1}% \krof }% -\def\XINT_reversedigits_a #1\Z -{% +\def\XINT_reversedigits_a #1\Z +{% \expandafter\XINT_revdigits_a\the\numexpr\expandafter\XINT_microrevsep \romannumeral`&&@#1{\XINT_microrevsep_end\W}\XINT_microrevsep_end \XINT_microrevsep_end\XINT_microrevsep_end \XINT_microrevsep_end\XINT_microrevsep_end \XINT_microrevsep_end\XINT_microrevsep_end\Z - 1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W + 1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W }% \def\XINT_revdigits_a {\XINT_revdigits_b {}}% \def\XINT_revdigits_b #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!% @@ -16800,18 +16828,14 @@ $1$ or $-1$. \xint_gob_til_R #9\XINT_revdigits_end\R \XINT_revdigits_b {#9#8#7#6#5#4#3#2#1}% }% -\edef\XINT_revdigits_end\R\XINT_revdigits_b #1#2\W +\edef\XINT_revdigits_end\R\XINT_revdigits_b #1#2\W {\noexpand\expandafter\space\noexpand\xint_gob_til_Z #1}% % \end{macrocode} % \subsection{\csh{xintSgn}, \csh{xintiiSgn}, \csh{XINT_Sgn}, \csh{XINT_cntSgn}} % \lverb|& -% Changed in 1.05. Earlier code was unnecessarily strange. 1.09a with \xintnum -% -% 1.09i defines \XINT_Sgn and \XINT_cntSgn (was \XINT__Sgn in 1.09i) for reasons -% of internal optimizations. -% % xintfrac.sty will overwrite \xintsgn with use of \xintraw rather than -% \xintnum, naturally.| +% \xintnum, naturally. +%| % \begin{macrocode} \def\xintiiSgn {\romannumeral0\xintiisgn }% \def\xintiisgn #1% @@ -16871,11 +16895,6 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintiAbs}, \csh{xintiiAbs}} -% \lverb|Release 1.09a has now \xintiabs which does \xintnum and this is -% inherited by DecSplit, by Sqr, and macros of xintgcd.sty. Attention, car ces -% macros de toute façon doivent passer à la valeur absolue et donc en profite -% pour faire le \xintnum, mais pour optimisation sans overhead il vaut mieux -% utiliser \xintiiAbs ou autre point d'accès.| % \begin{macrocode} \def\xintiiAbs {\romannumeral0\xintiiabs }% \def\xintiiabs #1% @@ -16897,10 +16916,6 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintFDg}, \csh{xintiiFDg}} -% \lverb|& -% FIRST DIGIT. Code simplified in 1.05. -% And prepared for redefinition by xintfrac to parse through \xintNum. Version -% 1.09a inserts the \xintnum already here.| % \begin{macrocode} \def\xintiiFDg {\romannumeral0\xintiifdg }% \def\xintiifdg #1% @@ -16923,16 +16938,6 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintLDg}, \csh{xintiiLDg}} -% \lverb|& -% LAST DIGIT. Simplified in 1.05. And prepared for extension by xintfrac -% to parse through \xintNum. Release 1.09a adds the \xintnum already here, -% and this propagates to \xintOdd, etc... 1.09e The \xintiiLDg is for -% defining \xintiiOdd which is used once (currently) elsewhere . -% -% bug fix (1.1b): \xintiiLDg is needed by the division macros next, thus -% it needs to be in the xintcore.sty. -% -% Rewritten for 1.2.| % \begin{macrocode} \def\xintLDg {\romannumeral0\xintldg }% \def\xintldg #1{\xintiildg {\xintNum{#1}}}% @@ -16941,18 +16946,17 @@ $1$ or $-1$. {% \expandafter\XINT_ldg_done\romannumeral0% \expandafter\XINT_revdigits_a\the\numexpr\expandafter\XINT_microrevsep - \romannumeral0\expandafter\XINT_abs + \romannumeral0\expandafter\XINT_abs \romannumeral`&&@#1{\XINT_microrevsep_end\W}\XINT_microrevsep_end \XINT_microrevsep_end\XINT_microrevsep_end \XINT_microrevsep_end\XINT_microrevsep_end \XINT_microrevsep_end\XINT_microrevsep_end\Z - 1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W + 1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W \Z }% \def\XINT_ldg_done #1#2\Z { #1}% % \end{macrocode} % \subsection{\csh{xintDouble}} -% \lverb|v1.08. Rewritten for v1.2.| % \begin{macrocode} \def\xintDouble {\romannumeral0\xintdouble }% \def\xintdouble #1% @@ -16970,7 +16974,7 @@ $1$ or $-1$. \def\XINT_dbl_zero #1\Z { 0}% \def\XINT_dbl_neg {\expandafter\xint_minus_thenstop\romannumeral0\XINT_dbl_pos }% -\def\XINT_dbl_pos #1\Z +\def\XINT_dbl_pos #1\Z {% \expandafter\XINT_dbl_pos_aa \romannumeral0\expandafter\XINT_sepandrev @@ -16986,7 +16990,6 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintHalf}} -% \lverb|v1.08. Rewritten for v1.2.| % \begin{macrocode} \def\xintHalf {\romannumeral0\xinthalf }% \def\xinthalf #1% @@ -17010,11 +17013,11 @@ $1$ or $-1$. \romannumeral0\XINT_zeroes_forviii #1\R\R\R\R\R\R\R\R{10}0000001\W #1\XINT_rsepbyviii_end_A 2345678% \XINT_rsepbyviii_end_B 2345678\relax XX% - \R.\R.\R.\R.\R.\R.\R.\R.\W + \R.\R.\R.\R.\R.\R.\R.\R.\W 1\Z!% 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W }% -\def\XINT_half_pos_a +\def\XINT_half_pos_a {\expandafter\XINT_half_pos_b\the\numexpr\XINT_verysmallmul 0.5!}% \def\XINT_half_pos_b 1#1#2#3#4#5#6#7#8!1#9% {% @@ -17027,12 +17030,11 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintDec}} -% \lverb|v1.08. Rewritten for v1.2.| % \begin{macrocode} \def\xintDec {\romannumeral0\xintdec }% \def\xintdec #1% {% - \expandafter\XINT_dec\romannumeral`&&@#1\Z + \expandafter\XINT_dec\romannumeral`&&@#1\Z }% \def\XINT_dec #1% {% @@ -17045,7 +17047,7 @@ $1$ or $-1$. \def\XINT_dec_zero #1\Z { -1}% \def\XINT_dec_neg {\expandafter\xint_minus_thenstop\romannumeral0\XINT_inc_pos }% -\def\XINT_dec_pos #1\Z +\def\XINT_dec_pos #1\Z {% \expandafter\XINT_dec_pos_aa \romannumeral0\expandafter\XINT_sepandrev @@ -17058,7 +17060,6 @@ $1$ or $-1$. \def\XINT_dec_pos_aa {\XINT_sub_aa 100000001!\Z!\Z!\Z!\Z!\W }% % \end{macrocode} % \subsection{\csh{xintInc}} -% \lverb!v1.08. Rewritten for v1.2.! % \begin{macrocode} \def\xintInc {\romannumeral0\xintinc }% \def\xintinc #1% @@ -17075,9 +17076,6 @@ $1$ or $-1$. }% \def\XINT_inc_zero #1\Z { 1}% \def\XINT_inc_neg {\expandafter\XINT_opp\romannumeral0\XINT_dec_pos }% -% \end{macrocode} -% \lverb|1.2d interface to addition has changed.| -% \begin{macrocode} \def\XINT_inc_pos #1\Z {% \expandafter\XINT_inc_pos_aa @@ -17092,7 +17090,7 @@ $1$ or $-1$. \def\XINT_inc_pos_aa {\XINT_add_aa 100000001!1\Z!1\Z!1\Z!1\Z!\W }% % \end{macrocode} % \subsection{Core arithmetic} -% \lverb|The four operations have been rewritten entirely for release v1.2. +% \lverb|The four operations have been rewritten entirely for release 1.2. % The new routines works with separated blocks of eight digits. They all measure % first the lengths of the arguments, even addition and subtraction (this was % not the case with xintcore.sty 1.1 or earlier.) @@ -17106,7 +17104,7 @@ $1$ or $-1$. % Side remark: I tested that \the\numexpr was more efficient than \number. But % it reduced the allowable numbers for addition from 19976 digits to 19968 % digits.| -% +% % \subsection{\csbh{xintiAdd}, \csbh{xintiiAdd}} % \begin{macrocode} \def\xintiAdd {\romannumeral0\xintiadd }% @@ -17155,35 +17153,6 @@ $1$ or $-1$. \X #1% }% \let\XINT_add_plusplus \XINT_add_pp_a -% \end{macrocode} -% \lverb|I have been annoyed since the preparation of 1.2 release that -% addition sometimes had the (pre-reverse) output with a final 1! (now 1\Z!) -% sometimes not. It didn' matter for addition itself if it executes the final -% reverse as the 1! was then be swallowed. But if one wants to call addition -% repeatedly or from another routine such as \XINT_mul_loop, keeping reverse -% format, this is annoying. Finally for 1.2c I decide (2015/11/14) to impose -% always the ending 1! (or rather 1\Z!, which thus does not need to be put in -% the pattern for _unrevbyviii). I take this opportunity to move the ending -% pattern needed by \XINT_add_out to \XINT_add_pp_b, thus replacing a final -% fetch of the complete output to clean up the \Z's and \W at the end of the -% input. This was also needed to make \XINT_mul_loop callable directly -% independently of whether the first argument is only one 10^8 digit long. -% -% Impacted callers: \XINT_mul_loop (and through it square and pow) and -% \XINT_inc_pos_ the latter must insert the pattern previously found in -% \XINT_add_out as it calls \XINT_add_aa directly. -% -% I also modify addition to use 1\Z!1\Z!1\Z!1\Z!\W as input delimiter (earlier -% version had \Z!\Z!\Z!\Z!\Z!\W but four are enough and we now have 1's). The -% rationale is that multiplication and now addition always set the output -% (before reversal) to be followed by 1\Z!, thus it makes sense for 1\Z! to -% also serve as (part of) delimiting inputs. Earlier, addition had \Z! for -% input, but this can not be put on output by a \numexpr, hence it used 1! on -% output, but this is not a good delimiter as the 1! may and will arise in -% number part, thus one had to use !1! or 1!\W etc... to use it. With 1\Z ! -% things are more unified and facilitate doing repeated additions and -% multiplications maintaining things reversed.| -% \begin{macrocode} \def\XINT_add_pp_b #1.#2\X #3\Z {% \expandafter\XINT_add_checklengths @@ -17195,7 +17164,7 @@ $1$ or $-1$. \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W 1\Z!1\Z!1\Z!1\Z!\W #21\Z!1\Z!1\Z!1\Z!\W - 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W + 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W }% % \end{macrocode} % \lverb|I keep #1.#2. to check if at most 6 + 6 base 10^8 digits which can be @@ -17203,7 +17172,7 @@ $1$ or $-1$. % \begin{macrocode} \def\XINT_add_checklengths #1.#2.% {% - \ifnum #2>#1 + \ifnum #2>#1 \expandafter\XINT_add_exchange \else \expandafter\XINT_add_A @@ -17223,12 +17192,22 @@ $1$ or $-1$. }% \def\XINT_add_aa {\expandafter\XINT_add_out\the\numexpr\XINT_add_a \xint_c_ii}% \def\XINT_add_out{\expandafter\XINT_cuz_small\romannumeral0\XINT_unrevbyviii {}}% -\def\XINT_add_aa_small +\def\XINT_add_aa_small {\expandafter\XINT_smallunrevbyviii\the\numexpr\XINT_add_a \xint_c_ii}% % \end{macrocode} -% \lverb|2 as first token of #1 stands for "no carry", 3 will mean a carry (we are adding -% 1<8digits> to 1<8digits>.) Version 1.2c has terminators of the shape 1\Z!, -% replacing the \Z! used in 1.2.| +% \lverb|2 as first token of #1 stands for "no carry", 3 will mean a carry (we +% are adding 1<8digits> to 1<8digits>.) Version 1.2c has terminators of the +% shape 1\Z!, replacing the \Z! used in 1.2. +% +% Call: \the\numexpr\XINT_add_a 2#11\Z!1\Z!1\Z!1\Z!\W #21\Z!1\Z!1\Z!1\Z!\W +% where #1 and #2 are blocks of 1<8d>!, and #1 is at most as long as #2. This +% last requirement is a bit annoying (if one wants to do recursive algorithms +% but not have to check lengths), and I will probably remove it at some point. +% +% Output: blocks of 1<8d>! representing the addition, (least significant +% first), and a final 1\Z!. In recursive algotithm this 1\Z! terminator can +% thus conveniently be reused as part of input terminator (up to the length +% problem).| % \begin{macrocode} \def\XINT_add_a #1!#2!#3!#4!#5\W #6!#7!#8!#9!% {% @@ -17290,17 +17269,6 @@ $1$ or $-1$. {% 1#2\expandafter!\the\numexpr\XINT_add_a #1% }% -% \end{macrocode} -% \lverb|These ending routines modified in 1.2c in order to clean up here (and -% not via \XINT_add_out) the tokens up to the final \W, and to always have a -% final 1\Z! (1.2 version had a final 1! not 1\Z!, and only under certain -% circumstances): when the two operands have the same length and the addition -% creates no carry or more generally when we had a carry propagating to the -% last block but the final addition created no carry, we end up in -% \XINT_add_ke with an empty #1 and a \numexpr to stop. This is why we put -% 1\Z! (1.2 had 1!, but 1\Z! is also used by multiplication on output) -% in that case, and now with 1.2c for all other cases as well.| -% \begin{macrocode} \def\XINT_add_k #1{\if #12\expandafter\XINT_add_ke\else\expandafter\XINT_add_l \fi}% \def\XINT_add_ke #11\Z #2\W {\XINT_add_kf #11\Z!}% \def\XINT_add_kf 1{1\relax }% @@ -17315,7 +17283,7 @@ $1$ or $-1$. \def\XINT_add_o #1{\if #12\expandafter\XINT_add_l\else\expandafter\XINT_add_ke \fi}% % \end{macrocode} % \subsection{\csh{xintiSub}, \csh{xintiiSub}} -% \lverb|Entirely rewritten for v1.2.| +% \lverb|Entirely rewritten for 1.2.| % \begin{macrocode} \def\xintiiSub {\romannumeral0\xintiisub }% \def\xintiisub #1{\expandafter\XINT_iisub\romannumeral`&&@#1\Z }% @@ -17351,7 +17319,7 @@ $1$ or $-1$. \def\XINT_sub_minusplus #1#2% {\expandafter\xint_minus_thenstop\romannumeral0\XINT_add_pp_a {}#2}% \def\XINT_sub_minusminus #1#2{\XINT_sub_mm_a {}{}}% -\def\XINT_sub_mm_a #1#2#3\Z +\def\XINT_sub_mm_a #1#2#3\Z {% \expandafter\XINT_sub_mm_b \romannumeral0\expandafter\XINT_sepandrev_andcount @@ -17374,7 +17342,7 @@ $1$ or $-1$. \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W \Z!\Z!\Z!\Z!\W #2\Z!\Z!\Z!\Z!\W }% -\def\XINT_sub_checklengths #1.#2.% +\def\XINT_sub_checklengths #1.#2.% {% \ifnum #2>#1 \expandafter\XINT_sub_exchange @@ -17387,6 +17355,10 @@ $1$ or $-1$. \expandafter\XINT_opp\romannumeral0\XINT_sub_aa #2\W #1\W }% \def\XINT_sub_aa {\expandafter\XINT_sub_out\the\numexpr\XINT_sub_a \xint_c_i }% +% \end{macrocode} +% \lverb|The {} after \XINT_unrevbyviii could be removed, but attention then +% at \XINT_sub_startrescue which must be modified (no need for #1).| +% \begin{macrocode} \def\XINT_sub_out #1\Z #2#3\W {% \if-#2\expandafter\XINT_sub_startrescue\fi @@ -17394,8 +17366,72 @@ $1$ or $-1$. \romannumeral0\XINT_unrevbyviii {}#11\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W }% % \end{macrocode} -% \lverb|The routine starting with \XINT_sub_a requires the first argument to -% be at most as long as second argument.| +% \lverb|1 as first token of #1 stands for "no carry", 0 will mean a carry. +% +% Call: \the\numexpr +% \XINT_sub_a 1#1\Z!\Z!\Z!\Z!\W #2\Z!\Z!\Z!\Z!\W where #1 and #2 +% are blocks of 1<8d>!, and #1 *must* be at most as long as #2. +% +% The routine wants to compute #2-#1. +% +% Notice that currently the terminators on input differ from those for +% addition. Also, currently (1.2f) the routine can not be called without final +% reversal and clean up of the result. +% +% \numexpr governed expansion stops with various possibilities: +% +% 1. #1 was shorter (in number of 8 digits blocks) than #2. +% +% *1a There may be no carry in which case we end up with$\ +% 1<8d>!...1<8d>!\Z!\Z!\Z!\Z!\W +% +% If there is a carry things are more complicated. +% +% *1b If the first hit block of #2 is > 1 no problem we are like in the +% no-carry case. +% +% *1c If it is exactly 1 then we will have leading zeros; but there may be +% also before that arbitrarily many produced zeros, all these leading zeros +% will have to be cleaned up. This is done via ending the expansion with the +% shape +% +% 1<8d>!...1<8d>!1\XINT_cuz_byviii!\Z 0\W\R +% +% *1d If the block value is zero, subtraction produces 99999999 and goes on. +% This is the only situation where the carry can propagate. This case can +% never produce extra blocks of leading zeros but may well end up with an ending +% zero block. In this subcase, the \numexpr is then made to stop with a 1!. +% This 1! will disappear during final reverse. +% +% 2a. #1 was of same length as #2, but <= #2. Then we end up expansion with$\ +% 1<8d>!...1<8d>!1\XINT_cuz_byviii!\Z 0\W\R$\ +% and the blocks will have to cleaned up of leading zeroes after reversal. +% +% 2b. #1 was of same length as #2, but > #2. Then we end up with blocks +% 1<8d>!...1<8d>! followed by -1\Z-\W +% +% Thus \XINT_sub_out examines the token after the first \Z, which may be ! or +% 0 or -. If ! or 0, \XINT_unrevbyviii will be executed (gobbling a possible +% final 1!), and followed in case 2a or 1c by \XINT_cuz_byviii (note the extra \R +% which terminates it), and then in both 1* and 2a by \XINT_cuz_small. +% +% If we were in 2b we proceed to \XINT_sub_startrescue which I will comment +% another day (the extra -1 at the end from -1\Z-\W will become a -1! and the +% - will serve in \XINT_sub_rescue_d as loop terminator). +% +% Currently (1.2f) we can not easily use these low level routines in a binary +% split approach due to the fact that first input must be at most as long as +% second but also because the final reversal is not in a common second stage, +% due to the separate treatment for case 2b. +% +% For the record: subtraction was correct (I think) in xint releases up to +% 1.2, but 1.2 had a broken treatment of the 1d case. For example \xintiiSub +% {10000000112345678}{12345679} produced 99999999. This got fixed in 1.2c, but +% that fix broke the 1c case :((, for example \xintiiSub +% {10000000000000000}{9999999999999997} was now returning 000000003. Alas. +% +% This was only realized later on 2016/02/29 (in fact it impacted +% \xintiiSqrt). Hopefully 1.2f got it right at last. | % \begin{macrocode} \def\XINT_sub_a #1!#2!#3!#4!#5\W #6!#7!#8!#9!% {% @@ -17458,46 +17494,49 @@ $1$ or $-1$. \XINT_sub_k #1#2!% }% % \end{macrocode} -% \lverb|First input terminated. Have we reached the end of second -% (necessarily at least as long) input? If not, then we are certain that even -% if there is carry it will not propagate beyond the end of second input. But -% it may propagate along chains of 00000000. And if its goes to the final -% block which is just 1<00000001>!, we will have at least those eight zeros to -% clean up. But not more than those eight followed by the leading zeroes of -% next to last block (which will be leading block of final output). On the -% other hand if we have also reached the end of the second input, then if -% first input was smaller there might be arbitrarily many zeroes to clean up, -% if it was larger, we will have to rescue the whole thing.| +% \lverb|B terminated. Have we reached the end of A (necessarily at least as +% long as B) ? (we are computing A-B, digits of B come first). +% +% If not, then we are certain that even if there is carry it will not +% propagate beyond the end of A. But it may propagate far transforming chains +% of 00000000 into 99999999, and if it does go to the final block which is +% just 1<00000001>!, we will have those eight zeros to clean up. (but we have +% to be careful that if we encounter 1<00000001>! and this is not the final +% block, we should not make something silly either). +% +% There is the possibility that A has exactly one more <eight-digits> block +% than B and that this block is exactly 1. In that case there can be +% arbitrarily many leading zeros to clean up from A-B. This was done correctly +% up to 1.2b but got broken in 1.2c. Belatedly fixed in 1.2f. +% +% If we have simultaneously reached the end of A, then if B was smaller there +% might be arbitrarily many zeroes to clean up, if it was larger, we will have +% to rescue the whole thing.| % \begin{macrocode} \def\XINT_sub_k #1#2% {% \xint_gob_til_Z #2\XINT_sub_p\Z \XINT_sub_l #1#2% }% -% \end{macrocode} -% \lverb|Here second input was longer. The carry if there is one will be -% extinguished before the end. 1.2c wants subtraction to output before final -% reversal the blocks with the same 1\Z! terminator as addition and -% multiplication. CANCELED FOR THE TIME BEING. -% -% 2015/11/15. I discover with shame that Release 1.2 of 10/10 had a bad bad -% bad bad bug in case of long stretches of zeroes, for example with -% \xintiiSub {10000000112345678}{12345679} which returned 99999999 .... sorry. -% -% I was rewriting inner entry to subtraction to look a bit more for -% input/output as addition and multiplication but I will now rather quickly -% leave everything standing and issue a bugfix release asap.| -% \begin{macrocode} \def\XINT_sub_l #1{\xint_UDzerofork #1\XINT_sub_l_carry 0\XINT_sub_l_nocarry\krof}% \def\XINT_sub_l_nocarry 1{1\relax }% -\def\XINT_sub_l_carry #1!{\expandafter\XINT_sub_m\the\numexpr 1#1-\xint_c_i!}% -\def\XINT_sub_m 1#1{\xint_UDzerofork #1\XINT_sub_n_carry 0\XINT_sub_n_nocarry\krof}% -\def\XINT_sub_n_carry #1!{1#1\expandafter!\the\numexpr\XINT_sub_l_carry }% -\def\XINT_sub_n_nocarry #1!#2#3!% +\def\XINT_sub_l_carry 1#1!{\ifcase #1 + \expandafter \XINT_sub_l_zeroa\or\expandafter\XINT_sub_l_one\else + \expandafter \XINT_sub_l_done\fi 1#1!}% +\def\XINT_sub_l_done {-\xint_c_i+}% +\def\XINT_sub_l_one 1#1!#2% {% - \xint_gob_til_Z #2\xint_gob_til_eightzeroes #1\XINT_sub_n_zero - 00000000\xint_gob_til_Z\Z 1\relax #1!#2#3!% + \xint_gob_til_Z #2\XINT_sub_l_oneone\Z 1\relax 00000000!#2% }% -\def\XINT_sub_n_zero 00000000\xint_gob_til_Z\Z 1\relax 00000000!{1!}% +\def\XINT_sub_l_oneone #1\W {1\relax \XINT_cuz_byviii!\Z 0\W\R }% +\def\XINT_sub_l_zeroa 1#1!{199999999\expandafter!\the\numexpr \XINT_sub_l_zerob }% +\def\XINT_sub_l_zerob 1#1!{\ifcase #1 + \expandafter \XINT_sub_l_zeroa\or\expandafter\XINT_sub_l_zone\else + \expandafter \XINT_sub_l_done\fi 1#1!}% +\def\XINT_sub_l_zone 1#1!#2% +{% + \xint_gob_til_Z #2\XINT_sub_l_zoneone\Z 1\relax 00000000!#2% +}% +\def\XINT_sub_l_zoneone\Z 1\relax 00000000{1}% % \end{macrocode} % \lverb|Here we are in the situation were the two inputs had the same length % in base 10^8. If #1=0 we bitterly discover that first input was greater than @@ -17512,6 +17551,12 @@ $1$ or $-1$. 0{1\relax \XINT_cuz_byviii!\Z 0\W\R }% \krof }% +% \end{macrocode} +% \lverb|We arrive here if #2-#1 concluded #1>#2 (both of the same length in +% base 10^8). To be commented. Here also before the \XINT_sub_rescue_finish +% there will be an ending 1! which will disappear only due to +% \XINT_unrevbyviii. The final \R is for \XINT_cuz.| +% \begin{macrocode} \def\XINT_sub_startrescue\expandafter\XINT_cuz_small \romannumeral0\XINT_unrevbyviii #1#2\Z!#3\W {% @@ -17519,7 +17564,7 @@ $1$ or $-1$. \the\numexpr\XINT_sub_rescue_a #2!% 1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W \R }% -\def\XINT_sub_rescue_finish +\def\XINT_sub_rescue_finish {\expandafter-\romannumeral0\expandafter\XINT_cuz\romannumeral0\XINT_unrevbyviii {}}% \def\XINT_sub_rescue_a #1!% {% @@ -17537,7 +17582,7 @@ $1$ or $-1$. \def\XINT_sub_rescue_z #1.{1!}% % \end{macrocode} % \subsection{\csh{xintiMul}, \csh{xintiiMul}} -% \lverb|Completely rewritten for v1.2.| +% \lverb|Completely rewritten for 1.2.| % \begin{macrocode} \def\xintiMul {\romannumeral0\xintimul }% \def\xintimul #1% @@ -17626,13 +17671,13 @@ $1$ or $-1$. \def\XINT_mul_smallbyfirst #1\XINT_mul_start 1#2!1\Z!\W {% \ifnum#2=\xint_c_i\expandafter\XINT_mul_oneisone\fi - \ifnum#2<\xint_c_xxii\expandafter\XINT_mul_verysmall\fi + \ifnum#2<\xint_c_xxii\expandafter\XINT_mul_verysmall\fi \expandafter\XINT_mul_out\the\numexpr\XINT_smallmul 1#2!% }% -\def\XINT_mul_smallbysecond #1\XINT_mul_start #2\W 1#3!1\Z!% +\def\XINT_mul_smallbysecond #1\XINT_mul_start #2\W 1#3!1\Z!% {% \ifnum#3=\xint_c_i\expandafter\XINT_mul_oneisone\fi - \ifnum#3<\xint_c_xxii\expandafter\XINT_mul_verysmall\fi + \ifnum#3<\xint_c_xxii\expandafter\XINT_mul_verysmall\fi \expandafter\XINT_mul_out\the\numexpr\XINT_smallmul 1#3!#2% }% \def\XINT_mul_oneisone #1!{\XINT_mul_out }% @@ -17640,7 +17685,7 @@ $1$ or $-1$. \the\numexpr\XINT_smallmul 1#1!% {\expandafter\XINT_mul_out\the\numexpr\XINT_verysmallmul 0.#1!}% \def\XINT_mul_exchange #1\XINT_mul_start #2\W #31\Z!% - {\fi\fi\XINT_mul_start #31\Z!\W #2}% + {\fi\fi\XINT_mul_start #31\Z!\W #2}% % \end{macrocode} % \lverb|1.2c: earlier version of addition had sometimes a final 1!, but not % in all cases. Version 1.2c of \XINT_add_a always has an ending 1\Z!, which @@ -17648,7 +17693,7 @@ $1$ or $-1$. % \begin{macrocode} \def\XINT_mul_start {\expandafter\XINT_mul_out\the\numexpr\XINT_mul_loop 100000000!1\Z!\W}% -\def\XINT_mul_out +\def\XINT_mul_out {\expandafter\XINT_cuz_small\romannumeral0\XINT_unrevbyviii {}}% % \end{macrocode} % \lverb|The 1.2 \XINT_mul_loop could *not* be called directly with a small @@ -17673,12 +17718,27 @@ $1$ or $-1$. % never happens when called via \xintiiMul. % % The delimiting patterns for addition was changed to use 1\Z! to fit what is -% used on output (by necessity).| +% used on output (by necessity). +% +% Call: \the\numexpr \XINT_mul_loop 100000000!1\Z!\W #11\Z!\W #21\Z!$newline +% where #1 and #2 are (globally reversed) blocks 1<8d>!. Its is generally more +% efficient to have #1 as the shorter one, but a better recipe is implemented +% in \XINT_mul_checklengths which as executed earlier. One may call +% \XINT_mul_loop directly (but multiplication by zero will produce many +% 100000000! blocks on output). +% +% Ends after having produced: 1<8d>!....1<8d>!1\Z!. The most significant +% digit block is the last one. It can not be 100000000! except if naturally +% the loop was called with a zero operand. +% +% Thus \XINT_mul_loop can be conveniently called directly in recursive +% routines, as the output terminator can serve as input terminator, we can +% arrange to not have to grab the whole thing again.| % \begin{macrocode} \def\XINT_mul_loop #1\W #2\W 1#3!% {% \xint_gob_til_Z #3\XINT_mul_e \Z - \expandafter\XINT_mul_a\the\numexpr \XINT_smallmul 1#3!#2\W + \expandafter\XINT_mul_a\the\numexpr \XINT_smallmul 1#3!#2\W #1\W #2\W }% % \end{macrocode} @@ -17694,7 +17754,17 @@ $1$ or $-1$. % \end{macrocode} % \lverb|1.2 small and mini multiplication in base 10^8 with carry. Used by % the main multiplication routines. But division, float factorial, etc.. have -% their own variants as they need output with specific constraints.| +% their own variants as they need output with specific constraints. +% +% The minimulwc has 1<8digits carry>.<4 high digits>.<4 low digits!<8digits>. +% +% It produces a block 1<8d>! and then jump back into \XINT_smallmul_a with the +% new 8digits carry as argument. The \XINT_smallmul_a fetches a new 1<8d>! +% block to multiply, and calls back \XINT_minimul_wc having stored the +% multiplicand for re-use later. When the loop terminates, the final carry is +% checked for being nul, and in all cases the output is terminated by a 1\Z! +% +% Multiplication by zero will produce blocks of zeros.| % \begin{macrocode} \def\XINT_minimulwc_a 1#1.#2.#3!#4#5#6#7#8.% {% @@ -17703,7 +17773,7 @@ $1$ or $-1$. }% \def\XINT_minimulwc_b 1#1#2#3#4#5#6.#7.% {% - \expandafter\XINT_minimulwc_c + \expandafter\XINT_minimulwc_c \the\numexpr \xint_c_x^ix+#1#2#3#4#5+#7.#6.% }% \def\XINT_minimulwc_c 1#1#2#3#4#5#6.#7.#8.% @@ -17723,7 +17793,9 @@ $1$ or $-1$. \def\XINT_smallmul_f 000000001\relax 00000000!1{1\relax}% % \end{macrocode} % \lverb|This is multiplication by 1 up to 21. Last time I checked it is never -% called with a wasteful multiplicand of 1.| +% called with a wasteful multiplicand of 1. Here also always the output +% terminated by a 1\Z! and the last block of digits is not zero. I imagine +% multiplication by zero produces blocks of zeroes. Will check another day.| % \begin{macrocode} \def\XINT_verysmallmul #1.#2!1#3!% {% @@ -17749,7 +17821,10 @@ $1$ or $-1$. {1#3\expandafter!\the\numexpr\XINT_verysmallmul #1#2.}% % \end{macrocode} % \lverb|Used by division and by squaring, not by multiplication itself. -% Attention, returns least significant 1<8digits> first.| +% +% This routine does not loop, it only does one mini multiplication with input +% format <4 high digits>.<4 low digits>!<8 digits>!, and on output +% 1<8d>!1<8d>!, with least significant block first.| % \begin{macrocode} \def\XINT_minimul_a #1.#2!#3#4#5#6#7!% {% @@ -17758,7 +17833,7 @@ $1$ or $-1$. }% \def\XINT_minimul_b 1#1#2#3#4#5.#6.% {% - \expandafter\XINT_minimul_c + \expandafter\XINT_minimul_c \the\numexpr \xint_c_x^ix+#1#2#3#4+#6.#5.% }% \def\XINT_minimul_c 1#1#2#3#4#5#6.#7.#8.% @@ -17767,7 +17842,7 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintiSqr}, \csh{xintiiSqr}} -% \lverb|Rewritten for v1.2.| +% \lverb|Rewritten for 1.2.| % \begin{macrocode} \def\xintiiSqr {\romannumeral0\xintiisqr }% \def\xintiisqr #1% @@ -17791,16 +17866,15 @@ $1$ or $-1$. \Z }% % \end{macrocode} -% \lverb|1.2c \XINT_mul_loop can be called directly even with small arguments, -% thus the following is not anymore a necessity. The 1!\R in \XINT_sqr_start -% is to obey the new calling pattern of \XINT_mul_loop.| +% \lverb|1.2c \XINT_mul_loop can now be called directly even with small +% arguments, thus the following check is not anymore a necessity.| % \begin{macrocode} \def\XINT_sqr_a #1.% -{% +{% \ifnum #1=\xint_c_i \expandafter\XINT_sqr_small \else\expandafter\XINT_sqr_start\fi }% -\def\XINT_sqr_small 1#1#2#3#4#5!\Z +\def\XINT_sqr_small 1#1#2#3#4#5!\Z {% \ifnum #1#2#3#4#5<46341 \expandafter\XINT_sqr_verysmall\fi \expandafter\XINT_sqr_small_out @@ -17813,6 +17887,11 @@ $1$ or $-1$. {% \XINT_cuz #2#1\R }% +% \end{macrocode} +% \lverb|An ending 1\Z! is produced on output for \XINT_mul_loop and gets +% incorporated to the delimiter needed by the \XINT_unrevbyviii done by +% \XINT_mul_out.| +% \begin{macrocode} \def\XINT_sqr_start #1\Z {% \expandafter\XINT_mul_out @@ -17823,76 +17902,64 @@ $1$ or $-1$. % \subsection{\csh{xintiPow}, \csh{xintiiPow}} % \lverb|& % The exponent is not limited but with current default settings of tex memory, -% with xint 1.2, the maximal exponent for 2^N is N = 2^17 = 131072.| +% with xint 1.2, the maximal exponent for 2^N is N = 2^17 = 131072. +% +% 1.2f Modifies the initial steps: 1) in order to be able to let more easily +% \xintiPow use \xintNum on the exponent once xintfrac.sty is loaded; 2) also +% because I noticed it was not very well coded. And it did only a \numexpr on +% the exponent, contradicting the documentation related to the "i" convention +% in names.| % \begin{macrocode} \def\xintiiPow {\romannumeral0\xintiipow }% -\def\xintiipow #1% +\def\xintiipow #1#2% {% - \expandafter\xint_pow\romannumeral`&&@#1\Z% + \expandafter\xint_pow\the\numexpr #2\expandafter.\romannumeral`&&@#1\Z% }% -\def\xintiPow {\romannumeral0\xintipow }% -\def\xintipow #1% +\def\xintiPow {\romannumeral0\xintipow }% +\def\xintipow #1#2% {% - \expandafter\xint_pow\romannumeral0\xintnum{#1}\Z% + \expandafter\xint_pow\the\numexpr #2\expandafter.\romannumeral0\xintnum{#1}\Z% }% -\def\xint_pow #1#2\Z +\def\xint_pow #1.#2%#3\Z {% - \xint_UDsignfork - #1\XINT_pow_Aneg - -\XINT_pow_Anonneg - \krof - #1{#2}% + \xint_UDzerominusfork + #2-\XINT_pow_AisZero + 0#2\XINT_pow_Aneg + 0-{\XINT_pow_Apos #2}% + \krof {#1}% }% -\def\XINT_pow_Aneg #1#2#3% +\def\XINT_pow_AisZero #1#2\Z {% - \expandafter\XINT_pow_Aneg_\expandafter{\the\numexpr #3}#2\Z + \ifcase\XINT_cntSgn #1\Z + \xint_afterfi { 1}% + \or + \xint_afterfi { 0}% + \else + \xint_afterfi {\xintError:DivisionByZero\space 0}% + \fi }% -\def\XINT_pow_Aneg_ #1% +\def\XINT_pow_Aneg #1% {% \ifodd #1 - \expandafter\XINT_pow_Aneg_Bodd + \expandafter\XINT_opp\romannumeral0% \fi - \XINT_pow_Anonneg_ {#1}% -}% -\def\XINT_pow_Aneg_Bodd #1% -{% - \expandafter\XINT_opp\romannumeral0\XINT_pow_Anonneg_ + \XINT_pow_Apos {}{#1}% }% -% \end{macrocode} -% \lverb|B = #3, faire le xpxp. Modified with 1.06: use of \numexpr.| -% \begin{macrocode} -\def\XINT_pow_Anonneg #1#2#3% +\def\XINT_pow_Apos #1#2{\XINT_pow_Apos_a {#2}#1}% +\def\XINT_pow_Apos_a #1#2#3% {% - \expandafter\XINT_pow_Anonneg_\expandafter {\the\numexpr #3}#1#2\Z + \xint_gob_til_Z #3\XINT_pow_Apos_short\Z + \XINT_pow_AatleastTwo {#1}#2#3% }% -% \end{macrocode} -% \lverb+#1 = B, #2 = |A|. Modifié pour v1.1, car utilisait \XINT_Cmp, ce qui -% d'ailleurs n'était sans doute pas super efficace, et m'obligeait à mettre -% \xintCmp dans xintcore. Donc ici A est déjà #2#3 et il y a un \Z après.+ -% \begin{macrocode} -\def\XINT_pow_Anonneg_ #1#2#3\Z +\def\XINT_pow_Apos_short\Z\XINT_pow_AatleastTwo #1#2\Z {% - \if\relax #3\relax\xint_dothis - {\ifcase #2 \expandafter\XINT_pow_AisZero - \or\expandafter\XINT_pow_AisOne - \else\expandafter\XINT_pow_AatleastTwo - \fi }\fi - \xint_orthat \XINT_pow_AatleastTwo {#1}{#2#3}% -}% -\def\XINT_pow_AisOne #1#2{ 1}% -% \end{macrocode} -% \lverb|#1 = B| -% \begin{macrocode} -\def\XINT_pow_AisZero #1#2% -{% - \ifcase\XINT_cntSgn #1\Z - \xint_afterfi { 1}% - \or - \xint_afterfi { 0}% - \else - \xint_afterfi {\xintError:DivisionByZero\space 0}% - \fi + \ifcase #2 + \xintError:thiscannothappen! + \or \expandafter\XINT_pow_AisOne + \else\expandafter\XINT_pow_AatleastTwo + \fi {#1}#2\Z }% +\def\XINT_pow_AisOne #1\Z{ 1}% \def\XINT_pow_AatleastTwo #1% {% \ifcase\XINT_cntSgn #1\Z @@ -17904,14 +17971,14 @@ $1$ or $-1$. \fi {#1}% }% -\edef\XINT_pow_BisNegative #1#2% +\edef\XINT_pow_BisNegative #1\Z {\noexpand\xintError:FractionRoundedToZero\space 0}% -\def\XINT_pow_BisZero #1#2{ 1}% +\def\XINT_pow_BisZero #1\Z{ 1}% % \end{macrocode} % \lverb|B = #1 > 0, A = #2 > 1. Earlier code checked if size of B did not % exceed a given limit (for example 131000).| % \begin{macrocode} -\def\XINT_pow_I_in #1#2% +\def\XINT_pow_I_in #1#2\Z {% \expandafter\XINT_pow_I_loop \the\numexpr #1\expandafter.% @@ -17954,9 +18021,9 @@ $1$ or $-1$. {% \XINT_smallmul 1#1!% }% -\def\XINT_pow_II_in #1.#2\W +\def\XINT_pow_II_in #1.#2\W {% - \expandafter\XINT_pow_II_loop + \expandafter\XINT_pow_II_loop \the\numexpr #1/\xint_c_ii-\xint_c_i\expandafter.% \the\numexpr\XINT_pow_mulbutcheckifsmall #2\W #2\W #2\W }% @@ -17969,9 +18036,9 @@ $1$ or $-1$. \expandafter\XINT_pow_II_even \fi #1.% }% -\def\XINT_pow_II_exit\ifodd #1\fi #2.#3\W #4\W +\def\XINT_pow_II_exit\ifodd #1\fi #2.#3\W #4\W {% - \expandafter\XINT_mul_out + \expandafter\XINT_mul_out \the\numexpr\XINT_pow_mulbutcheckifsmall #4\W #3% }% \def\XINT_pow_II_even #1.#2\W @@ -17986,7 +18053,7 @@ $1$ or $-1$. \the\numexpr #1/\xint_c_ii-\xint_c_i\expandafter.% \the\numexpr\XINT_pow_mulbutcheckifsmall #3\W #2\W #2\W }% -\def\XINT_pow_II_oddb #1.#2\W #3\W +\def\XINT_pow_II_oddb #1.#2\W #3\W {% \expandafter\XINT_pow_II_loop \the\numexpr #1\expandafter.% @@ -17994,11 +18061,12 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintiFac}, \csh{xintiiFac}} -% \lverb|Moved to xintcore.sty with release 1.2 (to be usable by \bnumexpr). +% \lverb|Moved here from xint.sty with release 1.2 (to be usable by \bnumexpr). % % The routine has been partially rewritten with release 1.2 to exploit the new % inner structure of multiplication. I impose an intrinsic limit of the -% argument at maximal value 9999. Anyhow with current default settings of the +% argument at maximal value 9999 (1.2f sets it at 10000, there was no reason +% for 9999 and not 10000). Anyhow with current default settings of the % etex memory and the current 1.2 routine (last commit: eada1b1), the maximal % possible computation is 5971! (which has 19956 digits). Also, I add % \xintiiFac which does only \romannumeral-`0 and not \numexpr on its @@ -18007,58 +18075,62 @@ $1$ or $-1$. % occur in the \ifnum. This is not as good as in the \numexpr, but well. % % 2015/11/14 added note on the implementation: we can roughly estimate for big -% n that we do n/2 "small" multiplications of numbers of size k log(k) with k -% along a step 2 arithmetic sequence up to n. Each small multiplication should -% have a linear cost O(k log(k)) (as we maintain the reversed representation) -% hence a total cost of O(n^2 log(n)); and this seems to be confirmed -% experimentally, or rather on computing n! for n=100, 200, ..., 2000 I -% obtained a good fit (only roughly 20$char37 $space variation) of the -% computation time with the square of the length of n! -- to the extent the -% big variability of \pdfelapsedtime allows to draw any conclusion -- I did -% not repeat the computations at least 100 times as I should have. With an -% approach based on binary splitting n!=AB and A=[n/2]! each of A and B will -% be of size n/2 log(n), but xint schoolbook multiplication in TeX is worse -% than quadratic due to penalty when TeX needs to fetch arguments and it -% didn't seem promising. I didn't even test. Binary splitting is good when a -% fast multiplication is available. -% -% No wait! incredibly a very naive five lines of code implementation of binary -% splitting approach with recursive uses of \xintiiMul is only about 1.6x--2x +% n that we do n/2 multiplications alpha*X where alpha=(k+1)(k+2)<10^8 and +% X=k! has size of order k log(k), with k along a step 2 arithmetic sequence +% up to n. Each small multiplication should have a linear cost hence O(k +% log(k)) (as we maintain the reversed representation) hence a total cost of +% O(n^2 log(n)); on computing n! for n=100, 200, ..., 2000 I obtained a good +% fit (only roughly 20$char37 $space variation) of the computation time with +% the square of the length of n! -- to the extent that the big variability of +% \pdfelapsedtime allows to draw any conclusion -- I did not repeat the +% computations as many times as I should have. I currently do not quite +% understand why in this range it seems computation times are better fitted by +% O(n^2 log^2 n) than by O(n^2 log n). True, final reverse is O(N^2) with N of +% order n log n, but for this range of n's this is marginal (and I tested also +% with this final reverse skipped). +% +% On the other hand with an approach based on binary splitting n!=AB and +% A=[n/2]! each of A and B will be of size n/2 log(n), but xint schoolbook +% multiplication in TeX is worse than quadratic due to penalty when TeX needs +% to fetch arguments and it didn't seem promising. I didn't even test. Binary +% splitting is good when a fast multiplication is available. +% +% No wait! incredibly a very naive recursive implementation with five lines of +% code via a binary splitting approach with \xintiiMul is only about 1.6x--2x % slower in the range N=200 to 2000 ! this seems to say that the reversing % done by \xintiiMul both on input and for output is quite efficient. The best % case seems to be around N=1000, hence multiplication of 500 digits numbers, % after that the impact of over-quadratic computation time seems to show: for % N=4000, the naive binary splitting approach is about 3.4x slower than the % naive iterated small multiplications as here (naturally with sub-quadratic -% multiplication that would be otherwise).| +% multiplication that would be otherwise). +% +% +% 2015/11/29 for 1.2f: no more a \xintFac, only \xintiFac/\xintiiFac. I could +% not go on like this with \xintFac/\xintiFac/\xintiiFac.| % \begin{macrocode} -\def\xintiFac {\romannumeral0\xintifac }% -\def\xintifac #1% -{% - \expandafter\XINT_fac_fork\expandafter {\the\numexpr#1}% -}% \def\xintiiFac {\romannumeral0\xintiifac }% -\def\xintiifac #1% -{% - \expandafter\XINT_fac_fork\expandafter {\romannumeral`&&@#1}% -}% -\let\xintFac\xintiFac \let\xintfac\xintifac -\def\XINT_fac_fork #1% +\def\xintiifac #1{\expandafter\XINT_fac_fork\the\numexpr#1.}% +\def\xintiFac {\romannumeral0\xintifac }% +\let\xintifac\xintiifac +% \end{macrocode} +% \lverb|Vieux style. Bon je modifie pour 1.2f. Le cas négatif devrait faire +% un 1/0 et créer un Inf.| +% \begin{macrocode} +\def\XINT_fac_fork #1#2.% {% - \ifcase\XINT_cntSgn #1\Z - \xint_afterfi{\expandafter\space\expandafter 1\xint_gobble_i }% - \or - \expandafter\XINT_fac_checksize - \else - \xint_afterfi{\expandafter\xintError:FactorialOfNegativeNumber - \expandafter\space\expandafter 1\xint_gobble_i }% - \fi - {#1}% + \xint_UDzerominusfork + #1-\XINT_fac_zero + 0#1\XINT_fac_neg + 0-\XINT_fac_checksize + \krof #1#2.% }% -\def\XINT_fac_checksize #1% +\def\XINT_fac_zero #1.{ 1}% +\edef\XINT_fac_neg #1.{\noexpand\xintError:FactorialOfNegative\space 1}% +\def\XINT_fac_checksize #1.% {% - \ifnum #1>9999 - \xint_dothis{\expandafter\xintError:FactorialOfTooBigNumber + \ifnum #1>\xint_c_x^iv + \xint_dothis{\expandafter\xintError:TooBigFactorial \expandafter\space\expandafter 1\xint_gob_til_W }\fi \ifnum #1>465 \xint_dothis{\XINT_fac_bigloop_a #1.}\fi \ifnum #1>101 \xint_dothis{\XINT_fac_medloop_a #1.\XINT_mul_out}\fi @@ -18067,7 +18139,7 @@ $1$ or $-1$. }% \def\XINT_fac_bigloop_a #1.% {% - \expandafter\XINT_fac_bigloop_b \the\numexpr + \expandafter\XINT_fac_bigloop_b \the\numexpr #1+\xint_c_i-\xint_c_ii*((#1-464)/\xint_c_ii).#1.% }% \def\XINT_fac_bigloop_b #1.#2.% @@ -18108,12 +18180,12 @@ $1$ or $-1$. \def\XINT_fac_medloop_mul #1!% {% \expandafter\XINT_smallmul - \the\numexpr + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% }% \def\XINT_fac_smallloop_a #1.% {% - \csname + \csname XINT_fac_smallloop_\the\numexpr #1-\xint_c_iv*(#1/\xint_c_iv)\relax \endcsname #1.% }% @@ -18143,14 +18215,14 @@ $1$ or $-1$. \def\XINT_fac_smallloop_mul #1!% {% \expandafter\XINT_smallmul - \the\numexpr + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% }% \def\XINT_fac_loop_exit #1!#2\Z!#3{#3#2\Z!}% % \end{macrocode} % \subsection{\csh{xintiDivision}, \csh{xintiQuo}, \csh{xintiRem}, % \csh{xintiiDivision}, \csh{xintiiQuo}, \csh{xintiiRem}} -% \lverb|Completely rewritten for v1.2. +% \lverb|Completely rewritten for 1.2. % % WARNING: some comments below try to describe the flow of tokens but they % date back to xint 1.09j and I updated them on the fly while doing the 1.2 @@ -18161,14 +18233,14 @@ $1$ or $-1$. % describing what the macro parameters stand for are necessarily wrong. % % Side remark: the way tokens are grouped was not essentially modified in -% v1.2, although the situation has changed. It was fine-tuned in xint -% v1.0/v1.1 but the context has changed, and perhaps I should revisit this. +% 1.2, although the situation has changed. It was fine-tuned in xint +% 1.0/1.1 but the context has changed, and perhaps I should revisit this. % As a corollary to the fact that quotient digits are now left behind thanks -% to the chains of \numexpr, some macros which in v1.0/v1.1 fetched up to 9 +% to the chains of \numexpr, some macros which in 1.0/1.1 fetched up to 9 % parameters now need handle less such parameters. Thus, some rationale for % the way the code was structured has disappeared. % -% v1.2 2015/10/15 had a bad bug which got corrected in v1.2b of 2015/10/29: a +% 1.2 2015/10/15 had a bad bug which got corrected in 1.2b of 2015/10/29: a % divisor starting with 99999999xyz... would cause a failure, simply because % it was attempted to use the \XINT_div_mini routine with a divisor of % 1+99999999=100000000 having 9 digits. Fortunately the origin of the bug was @@ -18197,6 +18269,9 @@ $1$ or $-1$. \def\xintiidivision #1{\expandafter\XINT_iidivision \romannumeral`&&@#1\Z }% \def\XINT_iidivision #1#2\Z #3{\expandafter\XINT_iidivision_a\expandafter #1% \romannumeral`&&@#3\Z #2\Z }% +% \end{macrocode} +% \lverb|On regarde les signes de A et de B.| +% \begin{macrocode} \def\XINT_iidivision_a #1#2% #1 de A, #2 de B. {% \if0#2\xint_dothis\XINT_iidivision_divbyzero\fi @@ -18216,6 +18291,15 @@ $1$ or $-1$. -{\XINT_iidivision_apos #1}% \krof }% +% \end{macrocode} +% \lverb|Donc attention malgré son nom \XINT_div_prepare va jusqu'au bout. +% C'est donc en fait l'entrée principale (pour B>0, A>0) mais elle va +% regarder si B est < 10^8 et s'il vaut alors 1 ou 2, et si A < 10^8. Dans +% tous les cas le résultat est produit sous la forme {Q}{R}, avec Q et R sous +% leur forme final. On doit ensuite ajuster si le B ou le A initial était +% négatif. Je n'ai pas fait beaucoup d'efforts pour être un minimum efficace +% si A ou B n'est pas positif.| +% \begin{macrocode} \def\XINT_iidivision_apos #1#2\Z #3\Z{\XINT_div_prepare {#2}{#1#3}}% \def\XINT_iidivision_aneg #1\Z #2\Z {\expandafter @@ -18236,7 +18320,10 @@ $1$ or $-1$. \expandafter\xint_exchangetwo_keepbraces \expandafter{\romannumeral0\XINT_sub_mm_a {}{}#3\Z #2\Z}{#1}% r-> b-r }% -%%%%%%%%%%%% +% \end{macrocode} +% \lverb|Le diviseur B va être étendu par des zéros pour que sa longueur soit +% multiple de huit. Les zéros seront mis du côté non significatif.| +% \begin{macrocode} \def\XINT_div_prepare #1% {% \XINT_div_prepare_a #1\R\R\R\R\R\R\R\R {10}0000001\W !{#1}% @@ -18246,7 +18333,11 @@ $1$ or $-1$. \xint_gob_til_R #9\XINT_div_prepare_small\R \XINT_div_prepare_b #9% }% -%%%%%%%%%%%% +% \end{macrocode} +% \lverb|B a au plus huit chiffres. On se débarrasse des trucs superflus. Si +% B>0 n'est ni 1 ni 2, le point d'entrée est \XINT_div_small_a {B}{A} (avec un +% A positif).| +% \begin{macrocode} \def\XINT_div_prepare_small\R #1!#2% {% \ifcase #2 @@ -18265,28 +18356,46 @@ $1$ or $-1$. {% \expandafter{\romannumeral0\xinthalf {#2}}{#1}% }% +% \end{macrocode} +% \lverb|B a au plus huit chiffres et est au moins 3. On va l'utiliser +% directement, sans d'abord le multiplier par une puissance de 10 pour qu'il +% ait 8 chiffres.| +% \begin{macrocode} \def\XINT_div_small_a #1#2% {% - \expandafter\XINT_div_small_b + \expandafter\XINT_div_small_b \the\numexpr #1/\xint_c_ii\expandafter .\the\numexpr \xint_c_x^viii+#1\expandafter!% \romannumeral0% \XINT_div_small_ba #2\R\R\R\R\R\R\R\R{10}0000001\W #2\XINT_sepbyviii_Z_end 2345678\relax }% +% \end{macrocode} +% \lverb|Le #2 poursuivra l'expansion par \XINT_div_dosmallsmall ou par +% \XINT_smalldivx_a suivi de \XINT_sdiv_out.| +% \begin{macrocode} \def\XINT_div_small_b #1!#2{#2#1!}% +% \end{macrocode} +% \lverb|On ajoute des zéros avant A, puis on le prépare sous la forme de +% blocs 1<8d>! Au passage on repère le cas d'un A<10^8.| +% \begin{macrocode} \def\XINT_div_small_ba #1#2#3#4#5#6#7#8#9% {% \xint_gob_til_R #9\XINT_div_smallsmall\R \expandafter\XINT_div_dosmalldiv \the\numexpr\expandafter\XINT_sepbyviii_Z - \romannumeral0\XINT_zeroes_forviii + \romannumeral0\XINT_zeroes_forviii #1#2#3#4#5#6#7#8#9% }% +% \end{macrocode} +% \lverb|Si A<10^8, on va poursuivre par \XINT_div_dosmallsmall +% round(B/2).10^8+B!{A}. On fait la division directe par \numexpr. Le résultat +% est produit sous la forme {Q}{R}.| +% \begin{macrocode} \def\XINT_div_smallsmall\R \expandafter\XINT_div_dosmalldiv \the\numexpr\expandafter\XINT_sepbyviii_Z - \romannumeral0\XINT_zeroes_forviii #1\R #2\relax + \romannumeral0\XINT_zeroes_forviii #1\R #2\relax {{\XINT_div_dosmallsmall}{#1}}% \def\XINT_div_dosmallsmall #1.1#2!#3% {% @@ -18295,10 +18404,19 @@ $1$ or $-1$. }% \def\XINT_div_smallsmallend #1.#2.#3.{\expandafter {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #3-#1*#2}}% -\def\XINT_div_dosmalldiv +% \end{macrocode} +% \lverb|Si A>=10^8, il est maintenant sous la forme 1<8d>!...1<8d>!1\Z! avec +% plus significatifs en premier. Donc on poursuit par$newline +% \expandafter\XINT_sdiv_out\the\numexpr\XINT_smalldivx_a +% x.1B!1<8d>!...1<8d>!1\Z! avec x =round(B/2), 1B=10^8+B.| +% \begin{macrocode} +\def\XINT_div_dosmalldiv {{\expandafter\XINT_sdiv_out\the\numexpr\XINT_smalldivx_a}}% -%%%%%%%%%%%% -\def\XINT_div_prepare_b +% \end{macrocode} +% \lverb|Ici B est au moins 10^8, on détermine combien de zéros lui adjoindre +% pour qu'il soit de longueur 8N.| +% \begin{macrocode} +\def\XINT_div_prepare_b {\expandafter\XINT_div_prepare_c\romannumeral0\XINT_zeroes_forviii }% \def\XINT_div_prepare_c #1!% {% @@ -18316,9 +18434,9 @@ $1$ or $-1$. % \lverb|attention qu'on calcule ici x'=x+1 (x = huit premiers chiffres du % diviseur) et que si x=99999999, x' aura donc 9 chiffres, pas compatible avec % div_mini (avant 1.2, x avait 4 chiffres, et on faisait la division avec x' -% dans un \numexpr). Bon, facile à dire après avoir laissé passer ce bug dans -% v1.2. C'est le problème lorsqu'au lieu de tout refaire à partir de zéro on -% recycle d'anciennes routines qui avaient un contexte différent.| +% dans un \numexpr). Bon, facile à dire après avoir laissé passer ce bug dans +% 1.2. C'est le problème lorsqu'au lieu de tout refaire à partir de zéro on +% recycle d'anciennes routines qui avaient un contexte différent.| % \begin{macrocode} \def\XINT_div_prepare_f #1#2#3#4#5#6#7#8#9\X {% @@ -18331,17 +18449,17 @@ $1$ or $-1$. \XINT_rsepbyviii_end_B 2345678% \relax\xint_c_ii\xint_c_iii \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii - \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W + \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W \X }% \def\XINT_div_prepare_g #1.#2.#3.#4.#5\X #6#7#8% {% \expandafter\XINT_div_prepare_h \the\numexpr\expandafter\XINT_sepbyviii_andcount - \romannumeral0\XINT_zeroes_forviii #8#7\R\R\R\R\R\R\R\R{10}0000001\W + \romannumeral0\XINT_zeroes_forviii #8#7\R\R\R\R\R\R\R\R{10}0000001\W #8#7\XINT_sepbyviii_end 2345678\relax \xint_c_vii!\xint_c_vi!\xint_c_v!\xint_c_iv!% - \xint_c_iii!\xint_c_ii!\xint_c_i!\xint_c_\W + \xint_c_iii!\xint_c_ii!\xint_c_i!\xint_c_\W {#1}{#2}{#3}{#4}{#5}{#6}% }% \def\XINT_div_prepare_h #11.#2.#3#4#5#6%#7#8% @@ -18349,9 +18467,9 @@ $1$ or $-1$. \XINT_div_start_a {#2}{#6}{#1}{#3}{#4}{#5}%{#7}{#8}% }% % \end{macrocode} -% \lverb|L, K, A, x',y,x, B, «c». Attention que K est diminué de 1 plus loin. -% Comme xint 1.2 a déjà repéré K=1, on a ici au minimum K=2. Attention B est à -% l'envers, A est à l'endroit et les deux avec séparateurs. Attention que ce +% \lverb|L, K, A, x',y,x, B, «c». Attention que K est diminué de 1 plus loin. +% Comme xint 1.2 a déjà repéré K=1, on a ici au minimum K=2. Attention B est à +% l'envers, A est à l'endroit et les deux avec séparateurs. Attention que ce % n'est pas ici qu'on boucle mais en \XINT_div_I_a.| % \begin{macrocode} \def\XINT_div_start_a #1#2% @@ -18372,7 +18490,7 @@ $1$ or $-1$. \def\XINT_div_zeroQ_end #1.#2% {\expandafter{\expandafter0\expandafter}\XINT_div_cleanR #1#2.}% % \end{macrocode} -% \lverb|L, K, A, x',y,x, B, «c»->K.A.x{LK{x'y}x}B«c»| +% \lverb|L, K, A, x',y,x, B, «c»->K.A.x{LK{x'y}x}B«c»| % \begin{macrocode} \def\XINT_div_start_b #1#2#3#4#5#6% {% @@ -18385,7 +18503,7 @@ $1$ or $-1$. }% \def\XINT_div_finish_a #1\Z #2.{\XINT_div_finish_b #2.{#1}}% % \end{macrocode} -% \lverb|Ici ce sont routines de fin. Le reste déjà nettoyé. R.Q«c».| +% \lverb|Ici ce sont routines de fin. Le reste déjà nettoyé. R.Q«c».| % \begin{macrocode} \def\XINT_div_finish_b #1% {% @@ -18398,18 +18516,18 @@ $1$ or $-1$. }% \def\XINT_div_finish_bRzero 0.#1#2{{#1}{0}}% \def\XINT_div_finish_bRpos #1.#2#3% -{% +{% \expandafter\xint_exchangetwo_keepbraces\XINT_div_cleanR #1#3.{#2}% }% \def\XINT_div_cleanR #100000000.{{#1}}% % \end{macrocode} -% \lverb|Kalpha.A.x{LK{x'y}x}, B, «c», au début #2=alpha est vide. On fait une -% boucle pour prendre K unités de A (on a au moins L égal à K) et les mettre +% \lverb|Kalpha.A.x{LK{x'y}x}, B, «c», au début #2=alpha est vide. On fait une +% boucle pour prendre K unités de A (on a au moins L égal à K) et les mettre % dans alpha.| % \begin{macrocode} \def\XINT_div_start_c #1% {% - \ifnum #1>\xint_c_vi + \ifnum #1>\xint_c_vi \expandafter\XINT_div_start_ca \else \expandafter\XINT_div_start_cb @@ -18435,9 +18553,9 @@ $1$ or $-1$. \def\XINT_div_start_c_vi #1.#2!#3!#4!#5!#6!#7!% {\XINT_div_start_c_ #1#2!#3!#4!#5!#6!#7!.}% % \end{macrocode} -% \lverb|#1=a, #2=alpha (de longueur K, à l'endroit).#3=reste de A.#4=x, -% #5={LK{x'y}x},#6=B,«c» -> a, x, alpha, B, {00000000}, L, K, {x'y},x, -% alpha'=reste de A, B«c».| +% \lverb|#1=a, #2=alpha (de longueur K, à l'endroit).#3=reste de A.#4=x, +% #5={LK{x'y}x},#6=B,«c» -> a, x, alpha, B, {00000000}, L, K, {x'y},x, +% alpha'=reste de A, B«c».| % \begin{macrocode} \def\XINT_div_start_c_ 1#1!#2.#3.#4#5#6% {% @@ -18445,7 +18563,7 @@ $1$ or $-1$. }% % \end{macrocode} % \lverb|Ceci est le point de retour de la boucle principale. a, x, alpha, B, -% q0, L, K, {x'y}, x, alpha', B«c» | +% q0, L, K, {x'y}, x, alpha', B«c» | % \begin{macrocode} \def\XINT_div_I_a #1#2% {% @@ -18457,8 +18575,8 @@ $1$ or $-1$. }% % \end{macrocode} % \lverb|On intercepte petit quotient nul: #1=a, x, alpha, B, #5=q0, L, K, -% {x'y}, x, alpha', B«c» -> on lâche un q puis {alpha} L, K, {x'y}, x, -% alpha', B«c».| +% {x'y}, x, alpha', B«c» -> on lâche un q puis {alpha} L, K, {x'y}, x, +% alpha', B«c».| % \begin{macrocode} \def\XINT_div_I_czero 0\XINT_div_I_c 0.#1#2#3#4#5{1#5\XINT_div_I_g {#3}}% \def\XINT_div_I_c #1.#2#3% @@ -18466,7 +18584,7 @@ $1$ or $-1$. \expandafter\XINT_div_I_da\the\numexpr #2-#1*#3.#1.{#2}{#3}% }% % \end{macrocode} -% \lverb|r.q.alpha, B, q0, L, K, {x'y}, x, alpha', B«c»| +% \lverb|r.q.alpha, B, q0, L, K, {x'y}, x, alpha', B«c»| % \begin{macrocode} \def\XINT_div_I_da #1.% {% @@ -18481,7 +18599,7 @@ $1$ or $-1$. \fi }% % \end{macrocode} -% \lverb|attention très mauvaises notations avec _b et _db.| +% \lverb|attention très mauvaises notations avec _b et _db.| % \begin{macrocode} \def\XINT_div_I_dN #1.% {% @@ -18496,7 +18614,7 @@ $1$ or $-1$. \Z {#4}{#5}% }% % \end{macrocode} -% \lverb|La soustraction spéciale renvoie simplement - si le chiffre q est +% \lverb|La soustraction spéciale renvoie simplement - si le chiffre q est % trop grand. On invoque dans ce cas I_dP.| % \begin{macrocode} \def\XINT_div_I_dc #1#2% @@ -18515,8 +18633,8 @@ $1$ or $-1$. }% \def\XINT_div_I_de #1#2\Z #3#4#5{1#5+#1\XINT_div_I_g {#2}}% % \end{macrocode} -% \lverb|q.alpha, B, q0, L, K, {x'y},x, alpha'B«c» (q=0 has been intercepted) -% -> 1nouveauq.nouvel alpha, L, K, {x'y}, x, alpha',B«c»| +% \lverb|q.alpha, B, q0, L, K, {x'y},x, alpha'B«c» (q=0 has been intercepted) +% -> 1nouveauq.nouvel alpha, L, K, {x'y}, x, alpha',B«c»| % \begin{macrocode} \def\XINT_div_I_dP #1.#2#3#4#5#6% {% @@ -18527,11 +18645,11 @@ $1$ or $-1$. }% }% % \end{macrocode} -% \lverb|1#1=nouveau q. nouvel alpha, L, K, {x'y},x,alpha', BQ«c»| +% \lverb|1#1=nouveau q. nouvel alpha, L, K, {x'y},x,alpha', BQ«c»| % \begin{macrocode} % \end{macrocode} % \lverb|#1=q,#2=nouvel alpha,#3=L, #4=K, #5={x'y}, #6=x, #7= alpha',#8=B, -% «c» -> on laisse q puis {x'y}alpha.alpha'.{{x'y}xKL}B«c»| +% «c» -> on laisse q puis {x'y}alpha.alpha'.{{x'y}xKL}B«c»| % \begin{macrocode} \def\XINT_div_I_g #1#2#3#4#5#6#7% {% @@ -18544,9 +18662,9 @@ $1$ or $-1$. {#4}#1.#6.{{#4}{#5}{#3}{#2}}{#7}% }% % \end{macrocode} -% \lverb|{x'y}alpha.alpha'.{{x'y}xKL}B«c» -> Attention retour à l'envoyeur ici -% par terminaison des \the\numexpr. On doit reprendre le Q déjà sorti, qui n'a -% plus de séparateurs, ni de leading 1. Ensuite R sans leading zeros.«c»| +% \lverb|{x'y}alpha.alpha'.{{x'y}xKL}B«c» -> Attention retour à l'envoyeur ici +% par terminaison des \the\numexpr. On doit reprendre le Q déjà sorti, qui n'a +% plus de séparateurs, ni de leading 1. Ensuite R sans leading zeros.«c»| % \begin{macrocode} \def\XINT_div_exittofinish #1#2.#3.#4#5% {% @@ -18554,16 +18672,16 @@ $1$ or $-1$. \romannumeral0\XINT_div_unsepR #2#31\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W.% }% % \end{macrocode} -% \lverb|ATTENTION DESCRIPTION OBSOLÈTE. #1={x'y}alpha.#2!#3=reste de A. -% #4={{x'y},x,K,L},#5=B,«c» devient {x'y},alpha sur K+4 chiffres.B, -% {{x'y},x,K,L}, #6= nouvel alpha',B,«c»| +% \lverb|ATTENTION DESCRIPTION OBSOLÈTE. #1={x'y}alpha.#2!#3=reste de A. +% #4={{x'y},x,K,L},#5=B,«c» devient {x'y},alpha sur K+4 chiffres.B, +% {{x'y},x,K,L}, #6= nouvel alpha',B,«c»| % \begin{macrocode} \def\XINT_div_I_h #1.#2!#3.#4#5% {% \XINT_div_II_b #1#2!.{#5}{#4}{#3}{#5}% }% % \end{macrocode} -% \lverb|{x'y}alpha.B, {{x'y},x,K,L}, nouveau alpha',B,«c»| +% \lverb|{x'y}alpha.B, {{x'y},x,K,L}, nouveau alpha',B,«c»| % \begin{macrocode} \def\XINT_div_II_b #11#2!#3!% {% @@ -18572,23 +18690,23 @@ $1$ or $-1$. }% % \end{macrocode} % \lverb|x'y{100000000}{1<8>}reste de alpha.#6=B,#7={{x'y},x,K,L}, alpha',B, -% «c» -> {x'y}x,K,L (à diminuer de 4), {alpha sur -% K}B{q1=00000000}{alpha'}B,«c»| +% «c» -> {x'y}x,K,L (à diminuer de 4), {alpha sur +% K}B{q1=00000000}{alpha'}B,«c»| % \begin{macrocode} \def\XINT_div_II_skipc 00000000\XINT_div_II_c #1#2#3#4#5.#6#7% {% \XINT_div_II_k #7{#4!#5}{#6}{00000000}% }% % \end{macrocode} -% \lverb|x'ya->1qx'yalpha.B, {{x'y},x,K,L}, nouveau alpha',B, «c». En fait, -% attention, ici #3 et #4 sont les 16 premiers chiffres du numérateur,sous la +% \lverb|x'ya->1qx'yalpha.B, {{x'y},x,K,L}, nouveau alpha',B, «c». En fait, +% attention, ici #3 et #4 sont les 16 premiers chiffres du numérateur,sous la % forme blocs 1<8chiffres>. % % ATTENTION! % -% 2015/10/29 :j'avais introduit un bug ici dans v1.2 2015/10/15, car -% \XINT_div_mini veut un diviseur de huit chiffres, or si le dénominateur B -% débute par x=99999999, on aura x'=100000000, d'où évidemment un bug. Bon il +% 2015/10/29 :j'avais introduit un bug ici dans 1.2 2015/10/15, car +% \XINT_div_mini veut un diviseur de huit chiffres, or si le dénominateur B +% débute par x=99999999, on aura x'=100000000, d'où évidemment un bug. Bon il % faut intercepter x'=100000000. % % I need to recognize x'=100000000 in some not too penalizing way. Anyway, @@ -18600,7 +18718,7 @@ $1$ or $-1$. #1.#2!#3!#4!{#1}{#2}#3!#4!% }% \def\XINT_div_xmini #1% -{% +{% \xint_gob_til_one #1\XINT_div_xmini_a 1\XINT_div_mini #1% }% \def\XINT_div_xmini_a 1\XINT_div_mini 1#1% @@ -18608,7 +18726,7 @@ $1$ or $-1$. \xint_gob_til_zero #1\XINT_div_xmini_b 0\XINT_div_mini 1#1% }% \def\XINT_div_xmini_b 0\XINT_div_mini 10#1#2#3#4#5#6#7% -{% +{% \xint_gob_til_zero #7\XINT_div_xmini_c 0\XINT_div_mini 10#1#2#3#4#5#6#7% }% % \end{macrocode} @@ -18617,8 +18735,8 @@ $1$ or $-1$. \def\XINT_div_xmini_c 0\XINT_div_mini 100000000.50000000!#1!#2!{#1!}% % \end{macrocode} % \lverb|1 suivi de q1 sur huit chiffres! #2=x', #3=y, #4=alpha.#5=B, -% {{x'y},x,K,L}, alpha', B, «c» --> nouvel alpha.x',y,B,q1,{{x'y},x,K,L}, -% alpha', B, «c» | +% {{x'y},x,K,L}, alpha', B, «c» --> nouvel alpha.x',y,B,q1,{{x'y},x,K,L}, +% alpha', B, «c» | % \begin{macrocode} \def\XINT_div_II_d 1#1#2#3#4#5!#6#7#8.#9% {% @@ -18629,8 +18747,8 @@ $1$ or $-1$. .{#6}{#7}{#9}{#1#2#3#4#5}% }% % \end{macrocode} -% \lverb|alpha.x',y,B,q1, {{x'y},x,K,L}, alpha', B, «c». Attention la -% soustraction spéciale doit maintenir les blocs 1<8>!| +% \lverb|alpha.x',y,B,q1, {{x'y},x,K,L}, alpha', B, «c». Attention la +% soustraction spéciale doit maintenir les blocs 1<8>!| % \begin{macrocode} \def\XINT_div_II_e 1#1!% {% @@ -18639,8 +18757,8 @@ $1$ or $-1$. }% % \end{macrocode} % \lverb|100000000!alpha sur K chiffres.#2=x',#3=y,#4=B,#5=q1, #6={{x'y},x,K,L}, -% #7=alpha',B«c» -> {x'y}x,K,L (à diminuer de 1), -% {alpha sur K}B{q1}{alpha'}B«c»| +% #7=alpha',B«c» -> {x'y}x,K,L (à diminuer de 1), +% {alpha sur K}B{q1}{alpha'}B«c»| % \begin{macrocode} \def\XINT_div_II_skipf 00000000\XINT_div_II_f 100000000!#1.#2#3#4#5#6% {% @@ -18648,7 +18766,7 @@ $1$ or $-1$. }% % \end{macrocode} % \lverb|1<a1>!1<a2>!, alpha (sur K+1 blocs de 8). x', y, B, q1, {{x'y},x,K,L}, -% alpha', B,«c». +% alpha', B,«c». % % Here also we are dividing with x' which could be 10^8 in the exceptional % case x=99999999. Must intercept it before sending to \XINT_div_mini.| @@ -18662,9 +18780,9 @@ $1$ or $-1$. \expandafter\XINT_div_II_g \the\numexpr\XINT_div_xmini #3.#4!#1{#2}% }% % \end{macrocode} -% \lverb|#1=q, #2=alpha (K+4), #3=B, #4=q1, {{x'y},x,K,L}, alpha', BQ«c» +% \lverb|#1=q, #2=alpha (K+4), #3=B, #4=q1, {{x'y},x,K,L}, alpha', BQ«c» % -> 1 puis nouveau q sur 8 chiffres. nouvel alpha sur K blocs, -% B, {{x'y},x,K,L}, alpha',B«c» | +% B, {{x'y},x,K,L}, alpha',B«c» | % \begin{macrocode} \def\XINT_div_II_g 1#1#2#3#4#5!#6#7#8% {% @@ -18679,17 +18797,17 @@ $1$ or $-1$. }% % \end{macrocode} % \lverb|1 puis nouveau q sur 8 chiffres, #2=nouvel alpha sur K blocs, -% #3=B, #4={{x'y},x,K,L} avec L à ajuster, alpha', BQ«c» -% -> {x'y}x,K,L à diminuer de 1, {alpha}B{q}, alpha', BQ«c»| +% #3=B, #4={{x'y},x,K,L} avec L à ajuster, alpha', BQ«c» +% -> {x'y}x,K,L à diminuer de 1, {alpha}B{q}, alpha', BQ«c»| % \begin{macrocode} \def\XINT_div_II_h 1#1.#2#3#4% {% \XINT_div_II_k #4{#2}{#3}{#1}% }% % \end{macrocode} -% \lverb|{x'y}x,K,L à diminuer de 1, alpha, B{q}alpha',B«c» -% ->nouveau L.K,x',y,x,alpha.B,q,alpha',B,«c» -% ->{LK{x'y}x},x,a,alpha.B,q,alpha',B,«c»| +% \lverb|{x'y}x,K,L à diminuer de 1, alpha, B{q}alpha',B«c» +% ->nouveau L.K,x',y,x,alpha.B,q,alpha',B,«c» +% ->{LK{x'y}x},x,a,alpha.B,q,alpha',B,«c»| % \begin{macrocode} \def\XINT_div_II_k #1#2#3#4#5% {% @@ -18701,15 +18819,15 @@ $1$ or $-1$. }% % \end{macrocode} % \lverb|{LK{x'y}x},x,a,alpha.B{q}alpha'B -> a, x, alpha, B, q, -% L, K, {x'y}, x, alpha', B«c» | +% L, K, {x'y}, x, alpha', B«c» | % \begin{macrocode} \def\XINT_div_II_m #1#2#3#4.#5#6% {% \XINT_div_I_a {#3}{#2}{#4}{#5}{#6}#1% }% % \end{macrocode} -% \lverb|This multiplication is exactly like \XINT_smallmul, but it always -% keeps the ending carry. For optimization I duplicated the whole code.| +% \lverb|This multiplication is exactly like \XINT_smallmul -- apart from not +% inserting an ending 1\Z! --, but keeps ever a vanishing ending carry.| % \begin{macrocode} \def\XINT_div_minimulwc_a 1#1.#2.#3!#4#5#6#7#8.% {% @@ -18718,7 +18836,7 @@ $1$ or $-1$. }% \def\XINT_div_minimulwc_b 1#1#2#3#4#5#6.#7.% {% - \expandafter\XINT_div_minimulwc_c + \expandafter\XINT_div_minimulwc_c \the\numexpr \xint_c_x^ix+#1#2#3#4#5+#7.#6.% }% \def\XINT_div_minimulwc_c 1#1#2#3#4#5#6.#7.#8.% @@ -18737,7 +18855,8 @@ $1$ or $-1$. % \lverb|Special very small multiplication for division. We only need to cater % for multiplicands from 1 to 9. The ending is different from standard % verysmallmul, a zero carry is not suppressed. And no final 1\Z! is added. If -% #1=1 let's not forget to add the 100000000! at the end.| +% multiplicand is just 1 let's not forget to add the zero carry 100000000! at +% the end.| % \begin{macrocode} \def\XINT_div_verysmallmul #1% {\xint_gob_til_one #1\XINT_div_verysmallisone 1\XINT_div_verysmallmul_a 0.#1}% @@ -18753,9 +18872,11 @@ $1$ or $-1$. {1#2\expandafter!\the\numexpr\XINT_div_verysmallmul_a #1.}% \def\XINT_div_verysmallmul_e\Z #1\Z +#2#3!{1\relax 0000000#2!}% % \end{macrocode} -% \lverb|Special subtraction for division purposes.| +% \lverb|Special subtraction for division purposes. If the subtracted thing +% turns out to be bigger, then just return a -. If not, then we must reverse +% the result, keeping the separators.| % \begin{macrocode} -\def\XINT_div_sub #1#2% +\def\XINT_div_sub #1#2% {% \expandafter\XINT_div_sub_clean \the\numexpr\expandafter\XINT_div_sub_a\expandafter @@ -18764,7 +18885,7 @@ $1$ or $-1$. \def\XINT_div_sub_clean #1-#2#3\W {% \if1#2\expandafter\XINT_rev_nounsep\else\expandafter\XINT_div_sub_neg\fi - {}#1\R!\R!\R!\R!\R!\R!\R!\R!\W + {}#1\R!\R!\R!\R!\R!\R!\R!\R!\W }% \def\XINT_div_sub_neg #1\W { -}% \def\XINT_div_sub_a #1!#2!#3!#4!#5\W #6!#7!#8!#9!% @@ -18838,32 +18959,66 @@ $1$ or $-1$. {% -\ifnum 0#1=\xint_c_ 1\else2\fi\relax }% -%%%%%%%%%%%% -\def\XINT_sdiv_out #1\Z #2\W% +% \end{macrocode} +% \lverb|Ici B<10^8 (et est >2). On +% exécute$newline +% \expandafter\XINT_sdiv_out\the\numexpr\XINT_smalldivx_a +% x.1B!1<8d>!...1<8d>!1\Z!$newline +% avec x =round(B/2), 1B=10^8+B, et A déjà en +% blocs 1<8d>! (non renversés). Le \the\numexpr\XINT_smalldivx_a va produire +% Q\Z R\W avec un R<10^8, et un Q sous forme de blocs 1<8d>! terminé par 1! +% et nécessitant le nettoyage du premier bloc. Dans cette branche le B n'a pas +% été multiplié par une puissance de 10, il peut avoir moins de huit chiffres. +% +% | +% \begin{macrocode} +\def\XINT_sdiv_out #1\Z!#2!% {\expandafter {\romannumeral0\XINT_unsep_cuzsmall#11\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W}% {#2}}% +% \end{macrocode} +% \lverb|La toute première étape fait la première division pour être sûr par +% la suite d'avoir un premier bloc pour A qui sera < B.| +% \begin{macrocode} \def\XINT_smalldivx_a #1.1#2!1#3!% {% \expandafter\XINT_smalldivx_b \the\numexpr (#3+#1)/#2-\xint_c_i!#1.#2!#3!% }% -\def\XINT_smalldivx_b #1!% +\def\XINT_smalldivx_b #1#2!% {% \if0#1\else - \xint_c_x^viii+#1\xint_afterfi{\expandafter!\the\numexpr}\fi - \XINT_smalldiv_c #1!% + \xint_c_x^viii+#1#2\xint_afterfi{\expandafter!\the\numexpr}\fi + \XINT_smalldiv_c #1#2!% }% \def\XINT_smalldiv_c #1!#2.#3!#4!% {% \expandafter\XINT_smalldiv_d\the\numexpr #4-#1*#3!#2.#3!% }% -\def\XINT_smalldiv_d #1!#2!#3#4!% +% \end{macrocode} +% \lverb|On va boucler ici: #1 est un reste, #2 est x.B (avec B sans le 1 mais +% sur huit chiffres). #3#4 est le premier bloc qui reste de A. Si on a terminé +% avec A, alors #1 est le reste final. Le quotient lui est terminé par un 1!: +% ce 1! disparaîtra dans le nettoyage par \XINT_unsep_cuzsmall. Ce dernier, +% malgré le fait qu'on soit dans le bon ordre déjà fait une macro dans le +% style O(N^2) car sinon le nombre maximal de chiffres serait moitié moins à +% cause des nettoyages nécessaires après \numexpr. Je suis obligé de faire un +% nettoyage final car comme l'expansion est engendrée par \numexpr, elle me +% boufferait des leading zeros si je ne mettais pas un 1 devant chaque bloc en +% sortie de Q.| +% \begin{macrocode} +\def\XINT_smalldiv_d #1!#2!1#3#4!% {% - \xint_gob_til_Z #4\XINT_smalldiv_end \Z - \XINT_smalldiv_e #1!#2!#3#4!% + \xint_gob_til_Z #3\XINT_smalldiv_end \Z + \XINT_smalldiv_e #1!#2!1#3#4!% }% -\def\XINT_smalldiv_end\Z\XINT_smalldiv_e #1!#2!1\Z!{1!\Z #1\W }% +\def\XINT_smalldiv_end\Z\XINT_smalldiv_e #1!#2!1\Z!{1!\Z!#1!}% +% \end{macrocode} +% \lverb|Il est crucial que le reste #1 est < #3. J'ai documenté cette routine +% dans le fichier où j'ai préparé 1.2, il faudra transférer ici. Il n'est pas +% nécessaire pour cette routine que le diviseur B ait au moins 8 chiffres. +% Mais il doit être < 10^8.| +% \begin{macrocode} \def\XINT_smalldiv_e #1!#2.#3!% {% \expandafter\XINT_smalldiv_f\the\numexpr @@ -18883,24 +19038,24 @@ $1$ or $-1$. }% \def\XINT_smalldiv_g 1#1!1#2!#3!#4!#5!#6!% {% - \expandafter\XINT_smalldiv_h - \the\numexpr 1#6-#1.#2!#5!#3!#4!% + \expandafter\XINT_smalldiv_h\the\numexpr 1#6-#1.#2!#5!#3!#4!% }% \def\XINT_smalldiv_h 1#1#2.#3!#4!% {% - \expandafter\XINT_smalldiv_i - \the\numexpr #4-#3+#1-\xint_c_i.#2!% + \expandafter\XINT_smalldiv_i\the\numexpr #4-#3+#1-\xint_c_i.#2!% }% \def\XINT_smalldiv_i #1.#2!#3!#4.#5!% {% - \expandafter\XINT_smalldiv_j - \the\numexpr (#1#2+#4)/#5-\xint_c_i!#3!#1#2!#4.#5!% + \expandafter\XINT_smalldiv_j\the\numexpr (#1#2+#4)/#5-\xint_c_i!#3!#1#2!#4.#5!% }% \def\XINT_smalldiv_j #1!#2!% {% - \xint_c_x^viii+#1+#2\expandafter!\the\numexpr\XINT_smalldiv_k + \xint_c_x^viii+#1+#2\expandafter!\the\numexpr\XINT_smalldiv_k #1!% }% +% \end{macrocode} +% \lverb|On boucle vers \XINT_smalldiv_d.| +% \begin{macrocode} \def\XINT_smalldiv_k #1!#2!#3.#4!% {% \expandafter\XINT_smalldiv_d\the\numexpr #2-#1*#4!#3.#4!% @@ -18908,13 +19063,17 @@ $1$ or $-1$. % \end{macrocode} % \lverb|Cette routine fait la division euclidienne d'un nombre de seize % chiffres par #1 = C = diviseur sur huit chiffres >= 10^7, avec #2 = sa -% moitié utilisée dans \numexpr pour contrebalancer l'arrondi -% (ARRRRRRGGGGGHHHH) fait par /. Le nombre divisé XY = X*10^8+Y se présente +% moitié utilisée dans \numexpr pour contrebalancer l'arrondi +% (ARRRRRRGGGGGHHHH) fait par /. Le nombre divisé XY = X*10^8+Y se présente % sous la forme 1<8chiffres>!1<8chiffres>! avec plus significatif en premier. % -% ATTENTION UNIQUEMENT UTILISÉ POUR DES SITUATIONS OÙ IL EST GARANTI QUE X < C -% !! le quotient euclidien de X*10^8+Y par C sera donc < 10^8. Il sera -% renvoyé sous la forme 1<8chiffres>.| +% Seul le quotient est calculé, pas le reste. En effet la routine de division +% principale va utiliser ce quotient pour déterminer le "grand" reste, et le +% petit reste ici ne nous serait d'à peu près aucune utilité. +% +% ATTENTION UNIQUEMENT UTILISÉ POUR DES SITUATIONS OÙ IL EST GARANTI QUE X < C +% !! (et C au moins 10^7) le quotient euclidien de X*10^8+Y par C sera donc < +% 10^8. Il sera renvoyé sous la forme 1<8chiffres>.| % \begin{macrocode} \def\XINT_div_mini #1.#2!1#3!% {% @@ -18922,7 +19081,7 @@ $1$ or $-1$. \xint_c_xi_e_viii_mone+#3*\xint_c_x^viii/#1!#1.#2!#3!% }% % \end{macrocode} -% \lverb|Note (2015/10/08). Attention à la différence dans l'ordre des +% \lverb|Note (2015/10/08). Attention à la différence dans l'ordre des % arguments avec ce que je vois en dans \XINT_smalldiv_f. Je ne me souviens % plus du tout s'il y a une raison quelconque.| % \begin{macrocode} @@ -18954,7 +19113,7 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintiDivRound}, \csh{xintiiDivRound}} -% \lverb|v1.1, transferred from first release of bnumexpr. Rewritten for v1.2.| +% \lverb|1.1, transferred from first release of bnumexpr. Rewritten for 1.2.| % \begin{macrocode} \def\xintiDivRound {\romannumeral0\xintidivround }% \def\xintidivround #1% @@ -19017,35 +19176,15 @@ $1$ or $-1$. \fi 1#1#2#3#4#5#6#70!1#9% }% -\def\XINT_iidivround_pos_up +\def\XINT_iidivround_pos_up {% \expandafter\XINT_iidivround_pos_finish \the\numexpr\XINT_add_a\xint_c_ii 100000010!1\Z!1\Z!1\Z!1\Z!\W }% -% \end{macrocode} -% \lverb|2015/11/17 Damn'ed. I added a bug in \XINT_iidivround_pos_finish when -% I was preparing 1.2c and was still doing modifications to the format for -% calling \XINT_add_a, and then I did a hurried release because I had found a -% bug in the subtraction from release 1.2. The 1.2c pattern #2\R was only ok -% if addition had been executed else obviously we have many extra 1\Z!'s. And -% we have to inject an explicit 1\Z! for unrevbyviii. Sadly xint.pdf itself -% obviously did not have a single example of an integer division not rounded -% up ... Anyway, 1.2d then. -% -% Why wasn't the 1.2c typo detected ? mainly because my main test file -% compared with usage of bigintcalc which has no macro for rounded division, -% hence \xintiiDivision was tested but not \xintiiDivRound. And my newer -% generic test files somehow only tested \xintiiDivision also. Of course I -% have separate test files for \xintiiDivRound, but they were used at the time -% of first creation of this macro. In the future I must have a test suite -% which will have entries for all macros and will be integrated to the last -% pre-build before release... the description of the macros in xint.pdf -% usually contain at least one example, but there are lacunae.| -% \begin{macrocode} \def\XINT_iidivround_pos_finish #10!#21\Z!#3\R {% \expandafter\XINT_cuz_small\romannumeral0\XINT_unrevbyviii {}% - #1!#21\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W + #1!#21\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W }% \def\XINT_iidivround_small\Z\ifnum #1>#2\fi 1#30!#4\W\R {% @@ -19138,22 +19277,24 @@ $1$ or $-1$. \def\xintSqr {\Did_you_mean_iiSqr?or_load_xintfrac!}% \XINT_restorecatcodes_endinput% % \end{macrocode} -%\catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11 -%\let</xintcore>\relax -%\def<*xint>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 } -%</xintcore> -%<*xint> +% % \StoreCodelineNo {xintcore} % +%\gardesactifs +%\let</xintcore>\relax +%\let<*xint>\gardesinactifs +%</xintcore>^^A--------------------------------------------------- +%<*xint>^^A------------------------------------------------------- +% \clearpage % \section{Package \xintnameimp implementation} % \label{sec:xintimp} % % \localtableofcontents -% +% % With release |1.1| the core arithmetic routines |\xintiiAdd|, % |\xintiiSub|, |\xintiiMul|, |\xintiiQuo|, |\xintiiPow| were separated to be % the main component of the then new -% \xintcorenameimp. +% \xintcorenameimp. % \begin{macrocode} \begingroup\catcode61\catcode48\catcode32=10\relax% \catcode13=5 % ^^M @@ -19203,7 +19344,7 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xint}% - [2015/11/22 v1.2e Expandable operations on big integers (jfB)]% + [2016/03/12 1.2f Expandable operations on big integers (JFB)]% % \end{macrocode} % \subsection{More token management} % \begin{macrocode} @@ -19517,12 +19658,6 @@ $1$ or $-1$. {% \expandafter\XINT_cmp_nfork\expandafter #1\romannumeral`&&@#3\Z #2\Z }% -% \end{macrocode} -% \lverb|New fork of 1.2 makes it less convenient here for \XINT_cmp_pre and -% \XINT_Cmp, which just avoided the \romannumeral-`0. Nanosecond loss ? I -% vaguely recalled that for \xintNewExpr things, I did need another name such -% as \XINT_cmp for \xintiiCmp.| -% \begin{macrocode} \let\XINT_Cmp \xintiiCmp \def\XINT_icmp #1#2\Z #3% {% @@ -19549,7 +19684,7 @@ $1$ or $-1$. 0#2{ 1}% 0-{ -1}% \krof -}% +}% \def\XINT_cmp_secondiszero #1\krof #20#3\Z #4\Z {% \xint_UDzerominusfork @@ -19557,12 +19692,12 @@ $1$ or $-1$. 0#2{ -1}% 0-{ 1}% \krof -}% +}% \def\XINT_cmp_plusminus #1\Z #2\Z{ 1}% \def\XINT_cmp_minusplus #1\Z #2\Z{ -1}% -\def\XINT_cmp_minusminus +\def\XINT_cmp_minusminus --{\expandafter\XINT_opp\romannumeral0\XINT_cmp_plusplus {}{}}% -\def\XINT_cmp_plusplus #1#2#3\Z +\def\XINT_cmp_plusplus #1#2#3\Z {% \expandafter\XINT_cmp_pp \romannumeral0\expandafter\XINT_sepandrev_andcount @@ -19585,7 +19720,7 @@ $1$ or $-1$. \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W \Z!\Z!\Z!\Z!\Z!\W #2\Z!\Z!\Z!\Z!\Z!\W }% -\def\XINT_cmp_checklengths #1.#2.% +\def\XINT_cmp_checklengths #1.#2.% {% \ifnum #1=#2 \expandafter\xint_firstoftwo @@ -19603,9 +19738,7 @@ $1$ or $-1$. \fi { -1}{ 1}% }% -%%%%%%%%%%%% \def\XINT_cmp_aa {\expandafter\XINT_cmp_w\the\numexpr\XINT_cmp_a \xint_c_i }% -%%%%%%%%%%%% \def\XINT_cmp_a #1!#2!#3!#4!#5\W #6!#7!#8!#9!% {% \XINT_cmp_b #1!#6!#2!#7!#3!#8!#4!#9!#5\W @@ -19666,7 +19799,6 @@ $1$ or $-1$. {% \XINT_cmp_k #1#2!% }% -%%%%%%%%%%%% \def\XINT_cmp_k #1#2\W {% \xint_UDzerofork @@ -19797,7 +19929,7 @@ $1$ or $-1$. % \end{macrocode} % \subsection{\csh{xintGeq}, \csh{xintiiGeq}} % \lverb|& -% PLUS GRAND OU ÉGAL +% PLUS GRAND OU ÉGAL % attention compare les **valeurs absolues**| % \begin{macrocode} \def\xintGeq {\romannumeral0\xintgeq }% @@ -19808,8 +19940,8 @@ $1$ or $-1$. {% \expandafter\XINT_geq_fork\expandafter #1\romannumeral`&&@#3\Z #2\Z }% -\let\XINT_geq_pre \xintiigeq % TEMPORAIRE -\let\XINT_Geq \xintGeq % TEMPORAIRE ATTENTION FAIT xintNum +\let\XINT_geq_pre \xintiigeq % TEMPORAIRE (oui, mais depuis quand ?) +\let\XINT_Geq \xintGeq % TEMPORAIRE ATTENTION FAIT xintNum (et alors?) \def\XINT_geq #1#2\Z #3% {% \expandafter\XINT_geq_fork\expandafter #1\romannumeral0\xintnum{#3}\Z #2\Z @@ -19828,7 +19960,7 @@ $1$ or $-1$. --\XINT_geq_plusplus \krof #1#2% }% -\def\XINT_geq_firstiszero #1\krof 0#2#3\Z #4\Z +\def\XINT_geq_firstiszero #1\krof 0#2#3\Z #4\Z {\xint_UDzerofork #2{ 1}0{ 0}\krof }% \def\XINT_geq_secondiszero #1\krof #20#3\Z #4\Z { 1}% \def\XINT_geq_plusminus #1-{\XINT_geq_plusplus #1{}}% @@ -19858,14 +19990,14 @@ $1$ or $-1$. \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W \Z!\Z!\Z!\Z!\Z!\W #2\Z!\Z!\Z!\Z!\Z!\W }% -\def\XINT_geq_checklengths #1.#2.% +\def\XINT_geq_checklengths #1.#2.% {% \ifnum #1=#2 \expandafter\xint_firstoftwo \else \expandafter\xint_secondoftwo \fi - \XINT_geq_aa {\XINT_geq_distinctlengths {#1}{#2}} + \XINT_geq_aa {\XINT_geq_distinctlengths {#1}{#2}}% }% \def\XINT_geq_distinctlengths #1#2#3\W #4\W {% @@ -19876,9 +20008,7 @@ $1$ or $-1$. \fi { 1}{ 0}% }% -%%%%%%%%%%%% \def\XINT_geq_aa {\expandafter\XINT_geq_w\the\numexpr\XINT_geq_a \xint_c_i }% -%%%%%%%%%%%% \def\XINT_geq_a #1!#2!#3!#4!#5\W #6!#7!#8!#9!% {% \XINT_geq_b #1!#6!#2!#7!#3!#8!#4!#9!#5\W @@ -19939,7 +20069,6 @@ $1$ or $-1$. {% \XINT_geq_k #1#2!% }% -%%%%%%%%%%%% \def\XINT_geq_k #1#2\W {% \xint_UDzerofork @@ -19951,15 +20080,6 @@ $1$ or $-1$. % \end{macrocode} % \subsection{\csh{xintiMax}, \csh{xintiiMax}} % \lverb|& -% The rationale is that it is more efficient than using \xintCmp. -% 1.03 makes the code a tiny bit slower but easier to re-use for fractions. -% Note: actually since 1.08a code for fractions does not all reduce to these -% entry points, so perhaps I should revert the changes made in 1.03. Release -% 1.09a has \xintnum added into \xintiMax. -% -% 1.1 adds the missing \xintiiMax. Using \xintMax and not \xintiMax in xint is -% deprecated. -% % 1.2 REMOVES \xintMax, \xintMin, \xintMaxof, \xintMinof.| % \begin{macrocode} \def\xintiMax {\romannumeral0\xintimax }% @@ -20155,28 +20275,8 @@ $1$ or $-1$. \def\XINT_iiminof_e #1\Z #2\Z { #2}% % \end{macrocode} % \subsection{\csh{xintiiSum}} -% \lverb|& -% \xintiiSum {{a}{b}...{z}}$\ -% \xintiiSumExpr {a}{b}...{z}\relax$\ -% 1.03 (drastically) simplifies and makes the routines more efficient (for big -% computations). Also the way \xintSum and \xintSumExpr ...\relax are related. -% has been modified. Now \xintSumExpr \z \relax is accepted input when -% \z expands to a list of braced terms (prior only \xintSum {\z} or \xintSum \z -% was possible). -% -% 1.09a does NOT add the \xintnum overhead. 1.09h renames \xintiSum to -% \xintiiSum to correctly reflect this. -% -% The xint 1.0x routine could benefit from the fact that addition and -% subtraction did not check the lengths of the arguments and were able to do -% their job independently of the order (but not at equal speed). Thus it was -% possible to add separately positive and negative summands and do one big -% subtraction at the end, keeping during all that time the intermediate result -% in reverse order suitable for both addition and subtraction. The lazy -% programmer being a bit tired after the 95$% rewrite of xintcore has not -% tried to do the same with the new model. Thus we just do stupidly repeated -% additions. The code is thus much shorter... and in fact I just copied the -% routine for products and changed products to sums.| +% \lverb|\xintiiSum {{a}{b}...{z}}, \xintiiSumExpr {a}{b}...{z}\relax +%| % \begin{macrocode} \def\xintiiSum {\romannumeral0\xintiisum }% \def\xintiisum #1{\xintiisumexpr #1\relax }% @@ -20192,31 +20292,8 @@ $1$ or $-1$. \def\XINT_sum_finished #1\Z #2\Z \Z { #2}% % \end{macrocode} % \subsection{\csh{xintiiPrd}} -% \lverb|& -% \xintiiPrd {{a}...{z}}$\ -% \xintiiPrdExpr {a}...{z}\relax$\ -% Release 1.02 modified the product routine. The earlier version was faster in -% situations where each new term is bigger than the product of all previous -% terms, a situation which arises in the algorithm for computing powers. The -% 1.02 version was changed to be more efficient on big products, where the new -% term is small compared to what has been computed so far (the power algorithm -% now has its own product routine). -% -% Finally, the 1.03 version just simplifies everything as the multiplication now -% decides what is best, with the price of a little overhead. So the code has -% been dramatically reduced here. -% -% In 1.03 I also modify the way \xintPrd and \xintPrdExpr ...\relax are -% related. Now \xintPrdExpr \z \relax is accepted input when \z expands -% to a list of braced terms (prior only \xintPrd {\z} or \xintPrd \z was -% possible). -% -% In 1.06a I suddenly decide that \xintProductExpr was a silly name, and as the -% package is new and certainly not used, I decide I may just switch to -% \xintPrdExpr which I should have used from the beginning. -% -% 1.09a does NOT add the \xintnum overhead. 1.09h renames \xintiPrd to -% \xintiiPrd to correctly reflect this.| +% \lverb|\xintiiPrd {{a}...{z}}, \xintiiPrdExpr {a}...{z}\relax +%| % \begin{macrocode} \def\xintiiPrd {\romannumeral0\xintiiprd }% \def\xintiiprd #1{\xintiiprdexpr #1\relax }% @@ -20233,9 +20310,9 @@ $1$ or $-1$. % \end{macrocode} % \lverb|& % & -% -----------------------------------------------------------------$\ -% -----------------------------------------------------------------$\ -% DECIMAL OPERATIONS: FIRST DIGIT, LASTDIGIT, (<- moved to xintcore +% -----------------------------------------------------------------$\ +% -----------------------------------------------------------------$\ +% DECIMAL OPERATIONS: FIRST DIGIT, LASTDIGIT, (<- moved to xintcore % because xintiiLDg need by division macros) % ODDNESS, % MULTIPLICATION BY TEN, QUOTIENT BY TEN, QUOTIENT OR @@ -20282,11 +20359,6 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintOdd}, \csh{xintiiOdd}, \csh{xintEven}, \csh{xintiiEven}} -% \lverb|1.05 has \xintiOdd, whereas \xintOdd parses through \xintNum. -% Inadvertently, 1.09a redefined \xintiLDg hence \xintiOdd also parsed through -% \xintNum. Anyway, having a \xintOdd and a \xintiOdd was silly. Removed in -% 1.09f, now only \xintOdd and \xintiiOdd. 1.1: \xintEven and \xintiiEven -% added for \xintiiexpr.| % \begin{macrocode} \def\xintiiOdd {\romannumeral0\xintiiodd }% \def\xintiiodd #1% @@ -20326,8 +20398,7 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintDSL}} -% \lverb|& -% DECIMAL SHIFT LEFT (=MULTIPLICATION PAR 10)| +% \lverb|DECIMAL SHIFT LEFT (=MULTIPLICATION PAR 10)| % \begin{macrocode} \def\xintDSL {\romannumeral0\xintdsl }% \def\xintdsl #1% @@ -20343,11 +20414,8 @@ $1$ or $-1$. \def\XINT_dsl_ #1\Z { #10}% % \end{macrocode} % \subsection{\csh{xintDSR}} -% \lverb|& -% DECIMAL SHIFT RIGHT (=DIVISION PAR 10). Release 1.06b which replaced all @'s -% by -% underscores left undefined the \xint_minus used in \XINT_dsr_b, and this bug -% was fixed only later in release 1.09b| +% \lverb|DECIMAL SHIFT RIGHT (=DIVISION PAR 10). +% | % \begin{macrocode} \def\xintDSR {\romannumeral0\xintdsr }% \def\xintdsr #1% @@ -20370,15 +20438,13 @@ $1$ or $-1$. \def\XINT_dsr_removew #1\W { }% % \end{macrocode} % \subsection{\csh{xintDSH}, \csh{xintDSHr}} -% \lverb+DECIMAL SHIFTS \xintDSH {x}{A}$\ -% si x <= 0, fait A -> A.10^(|x|). v1.03 corrige l'oversight pour A=0.$\ -% si x > 0, et A >=0, fait A -> quo(A,10^(x))$\ -% si x > 0, et A < 0, fait A -> -quo(-A,10^(x))$\ -% (donc pour x > 0 c'est comme DSR itéré x fois)$\ -% \xintDSHr donne le `reste' (si x<=0 donne zéro). -% -% Release 1.06 now feeds x to a \numexpr first. I will have to revise this code -% at some point.+ +% \lverb+DECIMAL SHIFTS \xintDSH {x}{A}$\ +% si x <= 0, fait A -> A.10^(|x|). +% si x > 0, et A >=0, fait A -> quo(A,10^(x))$\ +% si x > 0, et A < 0, fait A -> -quo(-A,10^(x))$\ +% (donc pour x > 0 c'est comme DSR itéré x fois)$\ +% \xintDSHr donne le `reste' (si x<=0 donne zéro). +% + % \begin{macrocode} \def\xintDSHr {\romannumeral0\xintdshr }% \def\xintdshr #1% @@ -20423,38 +20489,28 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintDSx}} -% \lverb+Je fais cette routine pour la version 1.01, après modification de -% \xintDecSplit. Dorénavant \xintDSx fera appel à \xintDecSplit et de même -% \xintDSH fera appel à \xintDSx. J'ai donc supprimé entièrement l'ancien code -% de \xintDSH et re-écrit entièrement celui de \xintDecSplit pour x positif. -% -% --> Attention le cas x=0 est traité dans la même catégorie que x > 0 <--$\ -% si x < 0, fait A -> A.10^(|x|)$\ -% si x >= 0, et A >=0, fait A -> {quo(A,10^(x))}{rem(A,10^(x))}$\ -% si x >= 0, et A < 0, d'abord on calcule {quo(-A,10^(x))}{rem(-A,10^(x))}$\ -% puis, si le premier n'est pas nul on lui donne le signe -$\ +% \lverb+& +% --> Attention le cas x=0 est traité dans la même catégorie que x > 0 <--$\ +% si x < 0, fait A -> A.10^(|x|)$\ +% si x >= 0, et A >=0, fait A -> {quo(A,10^(x))}{rem(A,10^(x))}$\ +% si x >= 0, et A < 0, d'abord on calcule {quo(-A,10^(x))}{rem(-A,10^(x))}$\ +% puis, si le premier n'est pas nul on lui donne le signe -$\ % si le premier est nul on donne le signe - au second. % % On peut donc toujours reconstituer l'original A par 10^x Q \pm R -% où il faut prendre le signe plus si Q est positif ou nul et le signe moins si -% Q est strictement négatif. -% -% Release 1.06 has a faster and more compactly coded \XINT_dsx_zeroloop. -% Also, x is now given to a \numexpr. The earlier code should be then -% simplified, but I leave as is for the time being. -% -% Release 1.07 modified the coding of \XINT_dsx_zeroloop, to avoid impacting the -% input stack. Indeed the truncating, rounding, and conversion to float routines -% all use internally \XINT_dsx_zeroloop (via \XINT_dsx_addzerosnofuss), and they -% were thus roughly limited to generating N = 8 times the input save stack size -% digits. On TL2012 and TL2013, this means 40000 = 8x5000 digits. Although -% generating more than 40000 digits is more like a one shot thing, I wanted to -% open the possibility of outputting tens of thousands of digits to faile, thus -% I re-organized \XINT_dsx_zeroloop. -% -% January 5, 2014: but it is only with the new division implementation of 1.09j -% and also with its special \xintXTrunc routine that the possibility mentioned -% in the last paragraph has become a concrete one in terms of computation time.+ +% où il faut prendre le signe plus si Q est positif ou nul et le signe moins si +% Q est strictement négatif. +% +% December 4, 2015: As the new techniques of the 1.2 release limit the basic +% arithmetic to less than about 20000 digits, I should again consider a faster +% dsx_loop possibly impacting the input save stack impacting style; preserving +% a special routine if really needed for \xintXTrunc or the other concerned +% routines (if \xintXTrunc really needs it, which I have to check.) +% +% 2016/03/12: this is old code. 1.2f has removed the part of it which +% checked the size of x parameter. +% +% + % \begin{macrocode} \def\xintDSx {\romannumeral0\xintdsx }% \def\xintdsx #1#2% @@ -20475,7 +20531,7 @@ $1$ or $-1$. 0-{\XINT_dsx_xisPos #1}% \krof }% -\def\XINT_dsx_xisZero #1\Z #2{ {#2}{0}}% attention comme x > 0 +\def\XINT_dsx_xisZero #1\Z #2{{#2}{0}}% attention comme x > 0 \def\XINT_dsx_xisNeg_checkA #1\Z #2% {% \XINT_dsx_xisNeg_checkA_ #2\Z {#1}% @@ -20483,34 +20539,21 @@ $1$ or $-1$. \def\XINT_dsx_xisNeg_checkA_ #1#2\Z #3% {% \xint_gob_til_zero #1\XINT_dsx_xisNeg_Azero 0% - \XINT_dsx_xisNeg_checkx {#3}{#3}{}\Z {#1#2}% + \XINT_dsx_zeroloop #3.{}\Z {#1#2}% }% \def\XINT_dsx_xisNeg_Azero #1\Z #2{ 0}% -\def\XINT_dsx_xisNeg_checkx #1% -{% - \ifnum #1>1000000 - \xint_afterfi - {\xintError:TooBigDecimalShift - \expandafter\space\expandafter 0\xint_gobble_iv }% - \else - \expandafter \XINT_dsx_zeroloop - \fi -}% -\def\XINT_dsx_addzerosnofuss #1{\XINT_dsx_zeroloop {#1}{}\Z }% -\def\XINT_dsx_zeroloop #1#2% -{% - \ifnum #1<\xint_c_ix \XINT_dsx_exita\fi - \expandafter\XINT_dsx_zeroloop\expandafter - {\the\numexpr #1-\xint_c_viii}{#200000000}% -}% -\def\XINT_dsx_exita\fi\expandafter\XINT_dsx_zeroloop +\def\XINT_dsx_addzerosnofuss #1{\XINT_dsx_zeroloop #1.{}\Z }% +\def\XINT_dsx_zeroloop #1.#2% {% - \fi\expandafter\XINT_dsx_exitb + \ifnum #1<\xint_c_ix \expandafter\XINT_dsx_exita\fi + \expandafter\XINT_dsx_zeroloop\the\numexpr #1-\xint_c_viii.{#200000000}% }% -\def\XINT_dsx_exitb #1#2% +\def\XINT_dsx_exita + \expandafter\XINT_dsx_zeroloop\the\numexpr #1-\xint_c_viii.#2% {% \expandafter\expandafter\expandafter - \XINT_dsx_addzeros\csname xint_gobble_\romannumeral -#1\endcsname #2% + \XINT_dsx_addzeros\csname xint_gobble_\expandafter + \romannumeral\numexpr \xint_c_viii-(#1)\endcsname #2% }% \def\XINT_dsx_addzeros #1\Z #2{ #2#1}% \def\XINT_dsx_xisPos #1\Z #2% @@ -20525,28 +20568,23 @@ $1$ or $-1$. 0-{\XINT_dsx_AisPos #1}% \krof }% -\def\XINT_dsx_AisZero #1\Z #2{ {0}{0}}% +\def\XINT_dsx_AisZero #1\Z #2{{0}{0}}% \def\XINT_dsx_AisNeg #1\Z #2% {% - \expandafter\XINT_dsx_AisNeg_dosplit_andcheckfirst - \romannumeral0\XINT_split_checksizex {#2}{#1}% -}% -\def\XINT_dsx_AisNeg_dosplit_andcheckfirst #1% -{% - \XINT_dsx_AisNeg_checkiffirstempty #1\Z + \expandafter\XINT_dsx_AisNeg_checkiffirstempty + \romannumeral0\XINT_split_xfork #2.#1\W\W\W\W\W\W\W\W\Z }% \def\XINT_dsx_AisNeg_checkiffirstempty #1% {% - \xint_gob_til_Z #1\XINT_dsx_AisNeg_finish_zero\Z + \xint_gob_til_dot #1\XINT_dsx_AisNeg_finish_zero.% \XINT_dsx_AisNeg_finish_notzero #1% }% -\def\XINT_dsx_AisNeg_finish_zero\Z - \XINT_dsx_AisNeg_finish_notzero\Z #1% +\def\XINT_dsx_AisNeg_finish_zero.\XINT_dsx_AisNeg_finish_notzero.#1.% {% \expandafter\XINT_dsx_end \expandafter {\romannumeral0\XINT_num {-#1}}{0}% }% -\def\XINT_dsx_AisNeg_finish_notzero #1\Z #2% +\def\XINT_dsx_AisNeg_finish_notzero #1.#2.% {% \expandafter\XINT_dsx_end \expandafter {\romannumeral0\XINT_num {#2}}{-#1}% @@ -20554,18 +20592,15 @@ $1$ or $-1$. \def\XINT_dsx_AisPos #1\Z #2% {% \expandafter\XINT_dsx_AisPos_finish - \romannumeral0\XINT_split_checksizex {#2}{#1}% + \romannumeral0\XINT_split_xfork #2.#1\W\W\W\W\W\W\W\W\Z }% -\def\XINT_dsx_AisPos_finish #1#2% +\def\XINT_dsx_AisPos_finish #1.#2.% {% \expandafter\XINT_dsx_end \expandafter {\romannumeral0\XINT_num {#2}}% {\romannumeral0\XINT_num {#1}}% }% -\edef\XINT_dsx_end #1#2% -{% - \noexpand\expandafter\space\noexpand\expandafter{#2}{#1}% -}% +\def\XINT_dsx_end #1#2{\expandafter{#2}{#1}}% % \end{macrocode} % \subsection{\csh{xintDecSplit}, \csh{xintDecSplitL}, \csh{xintDecSplitR}} % \lverb!DECIMAL SPLIT @@ -20582,58 +20617,35 @@ $1$ or $-1$. % (*) warning: this may change in a future version. Only the behavior % for A non-negative is guaranteed to remain the same. % -% v1.05a: \XINT_split_checksizex does not compute the length anymore, rather the -% error will be from a \numexpr; but the limit of 999999999 does not make much -% sense. +% 2016/03/12: this is old code. 1.2f has removed the part of it which +% checked the size of x parameter. % -% v1.06: Improvements in \XINT_split_fromleft_loop, \XINT_split_fromright_loop -% and related macros. More readable coding, speed gains. -% Also, I now feed immediately a \numexpr with x. Some simplifications should -% probably be made to the code, which is kept as is for the time being. -% -% 1.09e pays attention to the use of xintiabs which acquired in 1.09a the -% xintnum overhead. So xintiiabs rather without that overhead. % ! % \begin{macrocode} -\def\xintDecSplitL {\romannumeral0\xintdecsplitl }% -\def\xintDecSplitR {\romannumeral0\xintdecsplitr }% -\def\xintdecsplitl -{% - \expandafter\xint_firstoftwo_thenstop - \romannumeral0\xintdecsplit -}% -\def\xintdecsplitr -{% - \expandafter\xint_secondoftwo_thenstop - \romannumeral0\xintdecsplit -}% \def\xintDecSplit {\romannumeral0\xintdecsplit }% \def\xintdecsplit #1#2% {% - \expandafter \xint_split \expandafter - {\romannumeral0\xintiiabs {#2}}{#1}% fait expansion de A -}% -\def\xint_split #1#2% -{% - \expandafter\XINT_split_checksizex\expandafter{\the\numexpr #2}{#1}% + \expandafter\XINT_split_finish + \romannumeral0\expandafter\XINT_split_xfork + \the\numexpr #1\expandafter.\romannumeral0\xintiiabs {#2}\W\W\W\W\W\W\W\W\Z }% -\def\XINT_split_checksizex #1% 999999999 is anyhow very big, could be reduced +\def\xintDecSplitL {\romannumeral0\xintdecsplitl }% +\def\xintdecsplitl #1#2% {% - \ifnum\numexpr\XINT_Abs{#1}>999999999 - \xint_afterfi {\xintError:TooBigDecimalSplit\XINT_split_bigx }% - \else - \expandafter\XINT_split_xfork - \fi - #1\Z + \expandafter\XINT_splitl_finish + \romannumeral0\expandafter\XINT_split_xfork + \the\numexpr #1\expandafter.\romannumeral0\xintiiabs {#2}\W\W\W\W\W\W\W\W\Z }% -\def\XINT_split_bigx #1\Z #2% +\def\xintDecSplitR {\romannumeral0\xintdecsplitr }% +\def\xintdecsplitr #1#2% {% - \ifcase\XINT_cntSgn #1\Z - \or \xint_afterfi { {}{#2}}% positive big x - \else - \xint_afterfi { {#2}{}}% negative big x - \fi + \expandafter\XINT_splitr_finish + \romannumeral0\expandafter\XINT_split_xfork + \the\numexpr #1\expandafter.\romannumeral0\xintiiabs {#2}\W\W\W\W\W\W\W\W\Z }% +\def\XINT_split_finish #1.#2.{{#1}{#2}}% +\def\XINT_splitl_finish #1.#2.{{#1}}% +\def\XINT_splitr_finish #1.#2.{{#2}}% \def\XINT_split_xfork #1% {% \xint_UDzerominusfork @@ -20642,36 +20654,35 @@ $1$ or $-1$. 0-{\XINT_split_fromright #1}% \krof }% -\def\XINT_split_zerosplit #1\Z #2{ {#2}{}}% -\def\XINT_split_fromleft #1\Z #2% +\def\XINT_split_zerosplit #1.#2\W\W\W\W\W\W\W\W\Z{ #2..}% +\def\XINT_split_fromleft #1.%#2\W\W\W\W\W\W\W\W\Z {% - \XINT_split_fromleft_loop {#1}{}#2\W\W\W\W\W\W\W\W\Z + \XINT_split_fromleft_loop #1.{}%#2\W\W\W\W\W\W\W\W\Z }% -\def\XINT_split_fromleft_loop #1% +\def\XINT_split_fromleft_loop #1.% {% - \ifnum #1<\xint_c_viii\XINT_split_fromleft_exita\fi - \expandafter\XINT_split_fromleft_loop_perhaps\expandafter - {\the\numexpr #1-\xint_c_viii\expandafter}\XINT_split_fromleft_eight + \ifnum #1<\xint_c_viii\expandafter\XINT_split_fromleft_exita\fi + \expandafter\XINT_split_fromleft_loop_perhaps + \the\numexpr #1-\xint_c_viii\expandafter.\XINT_split_fromleft_eight }% \def\XINT_split_fromleft_eight #1#2#3#4#5#6#7#8#9{#9{#1#2#3#4#5#6#7#8#9}}% -\def\XINT_split_fromleft_loop_perhaps #1#2% +\def\XINT_split_fromleft_loop_perhaps #1.#2% {% \xint_gob_til_W #2\XINT_split_fromleft_toofar\W - \XINT_split_fromleft_loop {#1}% + \XINT_split_fromleft_loop #1.% }% -\def\XINT_split_fromleft_toofar\W\XINT_split_fromleft_loop #1#2#3\Z +\def\XINT_split_fromleft_toofar\W\XINT_split_fromleft_loop #1.#2#3\Z {% \XINT_split_fromleft_toofar_b #2\Z }% -\def\XINT_split_fromleft_toofar_b #1\W #2\Z { {#1}{}}% -\def\XINT_split_fromleft_exita\fi - \expandafter\XINT_split_fromleft_loop_perhaps\expandafter #1#2% - {\fi \XINT_split_fromleft_exitb #1}% -\def\XINT_split_fromleft_exitb\the\numexpr #1-\xint_c_viii\expandafter +\def\XINT_split_fromleft_toofar_b #1\W #2\Z { #1..}% +\def\XINT_split_fromleft_exita + \expandafter\XINT_split_fromleft_loop_perhaps + \the\numexpr #1-\xint_c_viii\expandafter.\XINT_split_fromleft_eight {% \csname XINT_split_fromleft_endsplit_\romannumeral #1\endcsname }% -\def\XINT_split_fromleft_endsplit_ #1#2\W #3\Z { {#1}{#2}}% +\def\XINT_split_fromleft_endsplit_ #1#2\W #3\Z { #1.#2.}% \def\XINT_split_fromleft_endsplit_i #1#2% {\XINT_split_fromleft_checkiftoofar #2{#1#2}}% \def\XINT_split_fromleft_endsplit_ii #1#2#3% @@ -20688,47 +20699,41 @@ $1$ or $-1$. {\XINT_split_fromleft_checkiftoofar #8{#1#2#3#4#5#6#7#8}}% \def\XINT_split_fromleft_checkiftoofar #1#2#3\W #4\Z {% - \xint_gob_til_W #1\XINT_split_fromleft_wenttoofar\W - \space {#2}{#3}% + \xint_gob_til_W #1\XINT_split_fromleft_wenttoofar\W \space#2.#3.% }% -\def\XINT_split_fromleft_wenttoofar\W\space #1% +\def\XINT_split_fromleft_wenttoofar\W\space #1.% {% \XINT_split_fromleft_wenttoofar_b #1\Z }% -\def\XINT_split_fromleft_wenttoofar_b #1\W #2\Z { {#1}}% -\def\XINT_split_fromright #1\Z #2% -{% - \expandafter \XINT_split_fromright_a \expandafter - {\romannumeral0\xintreverseorder {#2}}{#1}{#2}% -}% -\def\XINT_split_fromright_a #1#2% +\def\XINT_split_fromleft_wenttoofar_b #1\W #2\Z { #1.}% +\def\XINT_split_fromright #1.#2\W\W\W\W\W\W\W\W\Z {% - \XINT_split_fromright_loop {#2}{}#1\W\W\W\W\W\W\W\W\Z + \expandafter\XINT_split_fromright_loop + \the\numexpr #1\expandafter.\expandafter{\expandafter}% + \romannumeral0\xintreverseorder{#2}\W\W\W\W\W\W\W\W\Z #2.% }% -\def\XINT_split_fromright_loop #1% +\def\XINT_split_fromright_loop #1.% {% - \ifnum #1<\xint_c_viii\XINT_split_fromright_exita\fi - \expandafter\XINT_split_fromright_loop_perhaps\expandafter - {\the\numexpr #1-\xint_c_viii\expandafter }\XINT_split_fromright_eight + \ifnum #1<\xint_c_viii\expandafter\XINT_split_fromright_exita\fi + \expandafter\XINT_split_fromright_loop_perhaps + \the\numexpr #1-\xint_c_viii\expandafter.\XINT_split_fromright_eight }% \def\XINT_split_fromright_eight #1#2#3#4#5#6#7#8#9{#9{#9#8#7#6#5#4#3#2#1}}% -\def\XINT_split_fromright_loop_perhaps #1#2% +\def\XINT_split_fromright_loop_perhaps #1.#2% {% \xint_gob_til_W #2\XINT_split_fromright_toofar\W - \XINT_split_fromright_loop {#1}% + \XINT_split_fromright_loop #1.% }% -\def\XINT_split_fromright_toofar\W\XINT_split_fromright_loop #1#2#3\Z { {}}% -\def\XINT_split_fromright_exita\fi - \expandafter\XINT_split_fromright_loop_perhaps\expandafter #1#2% - {\fi \XINT_split_fromright_exitb #1}% -\def\XINT_split_fromright_exitb\the\numexpr #1-\xint_c_viii\expandafter +\def\XINT_split_fromright_toofar\W\XINT_split_fromright_loop #1\Z {.}% +\def\XINT_split_fromright_exita + \expandafter\XINT_split_fromright_loop_perhaps + \the\numexpr #1-\xint_c_viii\expandafter.\XINT_split_fromright_eight {% \csname XINT_split_fromright_endsplit_\romannumeral #1\endcsname }% -\edef\XINT_split_fromright_endsplit_ #1#2\W #3\Z #4% +\def\XINT_split_fromright_endsplit_ #1#2\W #3\Z #4.% {% - \noexpand\expandafter\space\noexpand\expandafter - {\noexpand\romannumeral0\noexpand\xintreverseorder {#2}}{#1}% + \xintreverseorder {#2}.#1.% }% \def\XINT_split_fromright_endsplit_i #1#2% {\XINT_split_fromright_checkiftoofar #2{#2#1}}% @@ -20749,23 +20754,41 @@ $1$ or $-1$. \xint_gob_til_W #1\XINT_split_fromright_wenttoofar\W \XINT_split_fromright_endsplit_ }% -\def\XINT_split_fromright_wenttoofar\W\XINT_split_fromright_endsplit_ #1\Z #2% - { {}{#2}}% +\def\XINT_split_fromright_wenttoofar\W + \XINT_split_fromright_endsplit_ #1\Z {.}% % \end{macrocode} % \subsection{\csh{xintiiSqrt}, \csh{xintiiSqrtR}, \csh{xintiiSquareRoot}} -% \lverb|v1.08. 1.09a uses \xintnum. -% -% Some overhead was added inadvertently in 1.09a to inner routines when -% \xintiquo and \xintidivision were also promoted to use \xintnum; release 1.09f -% thus uses \xintiiquo and \xintiidivision which avoid this \xintnum overhead. +% \lverb|First done with 1.08. % -% 1.09j replaced the previous long \ifcase from \XINT_sqrt_c by some nested -% \ifnum's. +% 1.1 added \xintiiSquareRoot. % -% 1.1 Ajout de \xintiiSqrt et \xintiiSquareRoot. +% 1.1a added \xintiiSqrtR. +% +% 1.2f (2016/03/01-02-03) has rewritten the implementation, the underlying +% mathematics remaining about the same. The routine is much faster for inputs +% having up to 16 digits (because it does it all with \numexpr directly now), +% and also much faster for very long inputs (because it now fetches only the +% needed new digits after the first 16 (or 17) ones, via the geometric +% sequence 16, then 32, then 64, etc...; earlier version did the computations +% with all remaining digits after a suitable starting point with correct 4 or +% 5 leading digits). Note however that the fetching of tokens is via +% intrinsically O(N^2) macros, hence inevitably inputs with thousands of +% digits start being treated less well. +% +% Actually there is some room for improvements, one could prepare better +% input X for the upcoming treatment of fetching its digits by 16, then 32, +% then 64, etc... +% +% Incidently, as \xintiiSqrt uses subtraction and subtraction was broken from +% 1.2 to 1.2c, then for another reason from 1.2c to 1.2f, it could +% get wrong in certain (relatively rare) cases. There was also a bug that +% made it unneedlessly slow for odd number of digits on input. +% +% 1.2f also modifies \xintFloatSqrt in xintfrac.sty which now has more +% code in common with here and benefits from the same speed improvements. +% +% | % -% 1.1a ajoute \xintiiSqrtR, which provides the rounded, not truncated square -% root.| % \begin{macrocode} \def\xintiiSqrt {\romannumeral0\xintiisqrt }% \def\xintiiSqrtR {\romannumeral0\xintiisqrtr }% @@ -20797,159 +20820,729 @@ $1$ or $-1$. \edef\XINT_sqrt_isneg #1\Z {\noexpand\xintError:RootOfNegative\space 11}% \def\XINT_sqrt #1\Z {% - \expandafter\XINT_sqrt_start\expandafter {\romannumeral0\xintlength {#1}}{#1}% + \expandafter\XINT_sqrt_start\romannumeral0\xintlength {#1}.#1.% }% -\def\XINT_sqrt_start #1% +\def\XINT_sqrt_start #1.% {% - \ifnum #1<\xint_c_x - \expandafter\XINT_sqrt_small_a - \else - \expandafter\XINT_sqrt_big_a - \fi - {#1}% + \ifnum #1<\xint_c_x\xint_dothis\XINT_sqrt_small_a\fi + \xint_orthat\XINT_sqrt_big_a #1.% }% -\def\XINT_sqrt_small_a #1{\XINT_sqrt_a {#1}\XINT_sqrt_small_d }% -\def\XINT_sqrt_big_a #1{\XINT_sqrt_a {#1}\XINT_sqrt_big_d }% -\def\XINT_sqrt_a #1% +\def\XINT_sqrt_small_a #1.{\XINT_sqrt_a #1.\XINT_sqrt_small_d }% +\def\XINT_sqrt_big_a #1.{\XINT_sqrt_a #1.\XINT_sqrt_big_d }% +\def\XINT_sqrt_a #1.% {% \ifodd #1 - \expandafter\XINT_sqrt_bB + \expandafter\XINT_sqrt_bO \else - \expandafter\XINT_sqrt_bA + \expandafter\XINT_sqrt_bE \fi - {#1}% + #1.% }% -\def\XINT_sqrt_bA #1#2#3% +\def\XINT_sqrt_bE #1.#2#3#4% {% - \XINT_sqrt_bA_b #3\Z #2{#1}{#3}% + \XINT_sqrt_c {#3#4}#2{#1}#3#4% }% -\def\XINT_sqrt_bA_b #1#2#3\Z +\def\XINT_sqrt_bO #1.#2#3% {% - \XINT_sqrt_c {#1#2}% + \XINT_sqrt_c #3#2{#1}#3% }% -\def\XINT_sqrt_bB #1#2#3% +\def\XINT_sqrt_c #1#2% {% - \XINT_sqrt_bB_b #3\Z #2{#1}{#3}% + \expandafter #2% + \the\numexpr \ifnum #1>\xint_c_ii + \ifnum #1>\xint_c_vi + \ifnum #1>12 \ifnum #1>20 \ifnum #1>30 + \ifnum #1>42 \ifnum #1>56 \ifnum #1>72 + \ifnum #1>90 + 10\else 9\fi \else 8\fi \else 7\fi \else 6\fi \else 5\fi + \else 4\fi \else 3\fi \else 2\fi \else 1\fi .% }% -\def\XINT_sqrt_bB_b #1#2\Z +\def\XINT_sqrt_small_d #1.#2% {% - \XINT_sqrt_c #1% + \expandafter\XINT_sqrt_small_e + \the\numexpr #1\ifcase \numexpr #2/\xint_c_ii-\xint_c_i\relax + \or 0\or 00\or 000\or 0000\fi .% }% -\def\XINT_sqrt_c #1#2% +\def\XINT_sqrt_small_e #1.#2.% {% - \expandafter #2\expandafter - {\the\numexpr\ifnum #1>\xint_c_iii - \ifnum #1>\xint_c_viii - \ifnum #1>15 \ifnum #1>24 \ifnum #1>35 - \ifnum #1>48 \ifnum #1>63 \ifnum #1>80 - 10\else 9\fi \else 8\fi \else 7\fi \else 6\fi - \else 5\fi \else 4\fi \else 3\fi \else 2\fi \relax }% + \expandafter\XINT_sqrt_small_ea\the\numexpr #1*#1-#2.#1.% }% -\def\XINT_sqrt_small_d #1#2% +\def\XINT_sqrt_small_ea #1% {% - \expandafter\XINT_sqrt_small_e\expandafter - {\the\numexpr #1\ifcase \numexpr #2/\xint_c_ii-\xint_c_i\relax - \or 0\or 00\or 000\or 0000\fi }% + \if0#1\xint_dothis\XINT_sqrt_small_ez\fi + \if-#1\xint_dothis\XINT_sqrt_small_eb\fi + \xint_orthat\XINT_sqrt_small_f #1% }% -\def\XINT_sqrt_small_e #1#2% +\def\XINT_sqrt_small_ez 0.#1.{\expandafter{\the\numexpr#1+\xint_c_i + \expandafter}\expandafter{\the\numexpr #1*\xint_c_ii+\xint_c_i}}% +\def\XINT_sqrt_small_eb -#1.#2.% {% - \expandafter\XINT_sqrt_small_f\expandafter {\the\numexpr #1*#1-#2}{#1}% + \expandafter\XINT_sqrt_small_ec \the\numexpr + (#1-\xint_c_i+#2)/(\xint_c_ii*#2).#1.#2.% }% -\def\XINT_sqrt_small_f #1#2% +\def\XINT_sqrt_small_ec #1.#2.#3.% {% - \expandafter\XINT_sqrt_small_g\expandafter - {\the\numexpr ((#1+#2)/(\xint_c_ii*#2))-\xint_c_i}{#1}{#2}% + \expandafter\XINT_sqrt_small_f \the\numexpr + -#2+\xint_c_ii*#3*#1+#1*#1\expandafter.\the\numexpr #3+#1.% }% -\def\XINT_sqrt_small_g #1% +\def\XINT_sqrt_small_f #1.#2.% {% - \ifnum #1>\xint_c_ - \expandafter\XINT_sqrt_small_h - \else + \expandafter\XINT_sqrt_small_g + \the\numexpr (#1+#2)/(\xint_c_ii*#2)-\xint_c_i.#1.#2.% +}% +\def\XINT_sqrt_small_g #1#2.% +{% + \if 0#1% \expandafter\XINT_sqrt_small_end + \else + \expandafter\XINT_sqrt_small_h \fi - {#1}% + #1#2.% }% -\def\XINT_sqrt_small_h #1#2#3% +\def\XINT_sqrt_small_h #1.#2.#3.% {% - \expandafter\XINT_sqrt_small_f\expandafter - {\the\numexpr #2-\xint_c_ii*#1*#3+#1*#1\expandafter}\expandafter - {\the\numexpr #3-#1}% + \expandafter\XINT_sqrt_small_f + \the\numexpr #2-\xint_c_ii*#1*#3+#1*#1\expandafter.% + \the\numexpr #3-#1.% }% -\def\XINT_sqrt_small_end #1#2#3{ {#3}{#2}}% -\def\XINT_sqrt_big_d #1#2% +\def\XINT_sqrt_small_end #1.#2.#3.{{#3}{#2}}% +\def\XINT_sqrt_big_d #1.#2% {% - \ifodd #2 - \expandafter\expandafter\expandafter\XINT_sqrt_big_eB - \else - \expandafter\expandafter\expandafter\XINT_sqrt_big_eA - \fi - \expandafter {\the\numexpr #2/\xint_c_ii }{#1}% + \ifodd #2 \xint_dothis{\expandafter\XINT_sqrt_big_eO}\fi + \xint_orthat{\expandafter\XINT_sqrt_big_eE}% + \the\numexpr (#2-\xint_c_i)/\xint_c_ii.#1;% +}% +\def\XINT_sqrt_big_eE #1;#2#3#4#5#6#7#8#9% +{% + \XINT_sqrt_big_eE_a #1;{#2#3#4#5#6#7#8#9}% +}% +\def\XINT_sqrt_big_eE_a #1.#2;#3% +{% + \expandafter\XINT_sqrt_bigormed_f + \romannumeral0\XINT_sqrt_small_e #2000.#3.#1;% +}% +\def\XINT_sqrt_big_eO #1;#2#3#4#5#6#7#8#9% +{% + \XINT_sqrt_big_eO_a #1;{#2#3#4#5#6#7#8#9}% +}% +\def\XINT_sqrt_big_eO_a #1.#2;#3#4% +{% + \expandafter\XINT_sqrt_bigormed_f + \romannumeral0\XINT_sqrt_small_e #20000.#3#4.#1;% +}% +\def\XINT_sqrt_bigormed_f #1#2#3;% +{% + \ifnum#3<\xint_c_ix + \xint_dothis {\csname XINT_sqrt_med_f\romannumeral#3\endcsname}% + \fi + \xint_orthat\XINT_sqrt_big_f #1.#2.#3;% +}% +\def\XINT_sqrt_med_fv {\XINT_sqrt_med_fa .}% +\def\XINT_sqrt_med_fvi {\XINT_sqrt_med_fa 0.}% +\def\XINT_sqrt_med_fvii {\XINT_sqrt_med_fa 00.}% +\def\XINT_sqrt_med_fviii{\XINT_sqrt_med_fa 000.}% +\def\XINT_sqrt_med_fa #1.#2.#3.#4;% +{% + \expandafter\XINT_sqrt_med_fb + \the\numexpr (#30#1-5#1)/(\xint_c_ii*#2).#1.#2.#3.% +}% +\def\XINT_sqrt_med_fb #1.#2.#3.#4.#5.% +{% + \expandafter\XINT_sqrt_small_ea + \the\numexpr (#40#2-\xint_c_ii*#3*#1)*10#2+(#1*#1-#5)\expandafter.% + \the\numexpr #30#2-#1.% +}% +\def\XINT_sqrt_big_f #1;#2#3#4#5#6#7#8#9% +{% + \XINT_sqrt_big_fa #1;{#2#3#4#5#6#7#8#9}% +}% +\def\XINT_sqrt_big_fa #1.#2.#3;#4% +{% + \expandafter\XINT_sqrt_big_ga + \the\numexpr #3-\xint_c_viii\expandafter.% + \romannumeral0\XINT_sqrt_med_fa 000.#1.#2.;#4.% +}% +% +\def\XINT_sqrt_big_ga #1.#2#3% +{% + \ifnum #1>\xint_c_viii + \expandafter\XINT_sqrt_big_gb\else + \expandafter\XINT_sqrt_big_ka + \fi #1.#3.#2.% +}% +\def\XINT_sqrt_big_gb #1.#2.#3.% +{% + \expandafter\XINT_sqrt_big_gc + \the\numexpr (\xint_c_ii*#2-\xint_c_i)*\xint_c_x^viii/(\xint_c_iv*#3).% + #3.#2.#1;% +}% +\def\XINT_sqrt_big_gc #1.#2.#3.% +{% + \expandafter\XINT_sqrt_big_gd + \romannumeral0\xintiiadd + {\xintiiSub {#300000000}{\xintDouble{\xintiiMul{#2}{#1}}}00000000}% + {\xintiiSqr {#1}}.% + \romannumeral0\xintiisub{#200000000}{#1}.% +}% +\def\XINT_sqrt_big_gd #1.#2.% +{% + \expandafter\XINT_sqrt_big_ge #2.#1.% +}% +\def\XINT_sqrt_big_ge #1;#2#3#4#5#6#7#8#9% + {\XINT_sqrt_big_gf #1.#2#3#4#5#6#7#8#9;}% +\def\XINT_sqrt_big_gf #1;#2#3#4#5#6#7#8#9% + {\XINT_sqrt_big_gg #1#2#3#4#5#6#7#8#9.}% +\def\XINT_sqrt_big_gg #1.#2.#3.#4.% +{% + \expandafter\XINT_sqrt_big_gloop + \expandafter\xint_c_xvi\expandafter.% + \the\numexpr #3-\xint_c_viii\expandafter.% + \romannumeral0\xintiisub {#2}{\xintiNum{#4}}.#1.% +}% +\def\XINT_sqrt_big_gloop #1.#2.% +{% + \unless\ifnum #1<#2 \xint_dothis\XINT_sqrt_big_ka \fi + \xint_orthat{\XINT_sqrt_big_gi #1.}#2.% }% -\def\XINT_sqrt_big_eA #1#2#3% +\def\XINT_sqrt_big_gi #1.% {% - \XINT_sqrt_big_eA_a #3\Z {#2}{#1}{#3}% + \expandafter\XINT_sqrt_big_gj + \romannumeral0\XINT_dsx_addzerosnofuss{#1}{}.#1.% }% -\def\XINT_sqrt_big_eA_a #1#2#3#4#5#6#7#8#9\Z +\def\XINT_sqrt_big_gj #1.#2.#3.#4.#5.% {% - \XINT_sqrt_big_eA_b {#1#2#3#4#5#6#7#8}% + \expandafter\XINT_sqrt_big_gk + \romannumeral0\xintiidivision {#4#1}{\XINT_dbl_pos #5\Z}.% + #1.#5.#2.#3.% }% -\def\XINT_sqrt_big_eA_b #1#2% +\def\XINT_sqrt_big_gk #1#2.#3.#4.% {% - \expandafter\XINT_sqrt_big_f - \romannumeral0\XINT_sqrt_small_e {#2000}{#1}{#1}% + \expandafter\XINT_sqrt_big_gl + \romannumeral0\xintiiadd {#2#3}{\xintiiSqr{#1}}.% + \romannumeral0\xintiisub {#4#3}{#1}.% }% -\def\XINT_sqrt_big_eB #1#2#3% +\def\XINT_sqrt_big_gl #1.#2.% {% - \XINT_sqrt_big_eB_a #3\Z {#2}{#1}{#3}% + \expandafter\XINT_sqrt_big_gm #2.#1.% }% -\def\XINT_sqrt_big_eB_a #1#2#3#4#5#6#7#8#9% +\def\XINT_sqrt_big_gm #1.#2.#3.#4.#5.% {% - \XINT_sqrt_big_eB_b {#1#2#3#4#5#6#7#8#9}% + \expandafter\XINT_sqrt_big_gn + \romannumeral0\expandafter\XINT_split_fromleft_loop + \the\numexpr\xint_c_ii*#3.{}#5\W\W\W\W\W\W\W\W\Z + #1.#2.#3.#4.% }% -\def\XINT_sqrt_big_eB_b #1#2\Z #3% +\def\XINT_sqrt_big_gn #1.#2.#3.#4.#5.#6.% {% - \expandafter\XINT_sqrt_big_f - \romannumeral0\XINT_sqrt_small_e {#30000}{#1}{#1}% + \expandafter\XINT_sqrt_big_gloop + \the\numexpr \xint_c_ii*#5\expandafter.% + \the\numexpr #6-#5\expandafter.% + \romannumeral0\xintiisub{#4}{\xintiNum{#1}}.#3.#2.% }% -\def\XINT_sqrt_big_f #1#2#3#4% +\def\XINT_sqrt_big_ka #1.#2.#3.#4.% {% - \expandafter\XINT_sqrt_big_f_a\expandafter - {\the\numexpr #2+#3\expandafter}\expandafter - {\romannumeral0\XINT_dsx_addzerosnofuss - {\numexpr #4-\xint_c_iv\relax}{#1}}{#4}% + \expandafter\XINT_sqrt_big_kb + \romannumeral0\XINT_dsx_addzerosnofuss {#1}{#3}.% + \romannumeral0\xintiisub + {\XINT_dsx_addzerosnofuss {\numexpr\xint_c_ii*#1}{#2}}% + {\xintiNum{#4}}.% }% -\def\XINT_sqrt_big_f_a #1#2#3#4% +\def\XINT_sqrt_big_kb #1.#2.% {% - \expandafter\XINT_sqrt_big_g\expandafter - {\romannumeral0\xintiisub - {\XINT_dsx_addzerosnofuss - {\numexpr \xint_c_ii*#3-\xint_c_viii\relax}{#1}}{#4}}% - {#2}{#3}% + \expandafter\XINT_sqrt_big_kc #2.#1.% }% -\def\XINT_sqrt_big_g #1#2% +\def\XINT_sqrt_big_kc #1% {% - \expandafter\XINT_sqrt_big_j + \if0#1\xint_dothis\XINT_sqrt_big_kz\fi + \xint_orthat\XINT_sqrt_big_kloop #1% +}% +\def\XINT_sqrt_big_kz 0.#1.% +{% + \expandafter\XINT_sqrt_big_kend + \romannumeral0\xintinc{\XINT_dbl_pos #1\Z}.#1.% +}% +\def\XINT_sqrt_big_kend #1.#2.% +{% + \expandafter{\romannumeral0\xintinc{#2}}{#1}% +}% +\def\XINT_sqrt_big_kloop #1.#2.% +{% + \expandafter\XINT_sqrt_big_ke \romannumeral0\xintiidivision{#1}{\romannumeral0\XINT_dbl_pos #2\Z}{#2}% }% -\def\XINT_sqrt_big_j #1% +\def\XINT_sqrt_big_ke #1% {% \if0\XINT_Sgn #1\Z \expandafter \XINT_sqrt_big_end - \else \expandafter \XINT_sqrt_big_k + \else \expandafter \XINT_sqrt_big_kf \fi {#1}% }% -\def\XINT_sqrt_big_k #1#2#3% +\def\XINT_sqrt_big_kf #1#2#3% {% - \expandafter\XINT_sqrt_big_l\expandafter - {\romannumeral0\xintiisub {#3}{#1}}% - {\romannumeral0\xintiiadd {#2}{\xintiiSqr {#1}}}% + \expandafter\XINT_sqrt_big_kg + \romannumeral0\xintiisub {#3}{#1}.% + \romannumeral0\xintiiadd {#2}{\xintiiSqr {#1}}.% }% -\def\XINT_sqrt_big_l #1#2% +\def\XINT_sqrt_big_kg #1.#2.% {% - \expandafter\XINT_sqrt_big_g\expandafter - {#2}{#1}% + \expandafter\XINT_sqrt_big_kloop #2.#1.% +}% +\def\XINT_sqrt_big_end #1#2#3{{#3}{#2}}% +% \end{macrocode} +% \subsection{\csh{xintiiBinomial}, \csh{xintiBinomial}} +% \lverb|2015/11/28-29 for 1.2f.| +% \begin{macrocode} +\def\xintiiBinomial {\romannumeral0\xintiibinomial }% +\def\xintiibinomial #1#2% +{% + \expandafter\XINT_binom_pre\the\numexpr #1\expandafter.\the\numexpr #2.% +}% +\def\XINT_binom_pre #1.#2.% +{% + \expandafter\XINT_binom_fork \the\numexpr#1-#2.#2.#1.% +}% +\def\xintiBinomial{\romannumeral0\xintibinomial}% +\let\xintibinomial\xintiibinomial +% \end{macrocode} +% \lverb|k.x-k.x. I hesitated to restrict maximal allowed value of x to 10000. +% Finally I don't. But due to using small multiplication and small division, x +% must have at most eight digits. If x>=2^31 an arithmetic overflow error will +% have happened already.| +% \begin{macrocode} +\def\XINT_binom_fork #1#2.#3#4.#5#6.% +{% + \if-#1\xint_dothis {\xintError:OutOfRangeBinomial\space 0}\fi + \if-#3\xint_dothis {\xintError:OutOfRangeBinomial\space 0}\fi + \if0#1\xint_dothis{ 1}\fi + \if0#3\xint_dothis{ 1}\fi + \ifnum #5#6>\xint_c_x^viii_mone\xint_dothis{\xintError:OutOfRangeBinomial\space 0}\fi + \ifnum #1#2>#3#4 \xint_dothis{\XINT_binom_a #1#2.#3#4.}\fi + \xint_orthat{\XINT_binom_a #3#4.#1#2.}% +}% +% \end{macrocode} +% \lverb|x-k.k. avec 0<k<x, k<=x-k. Les divisions produiront en extra après le +% quotient un terminateur 1!\Z!0!. On va procéder par petite multiplication +% suivie par petite division. Donc ici on met le 1!\Z!0! pour amorcer. +% +% Le 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W est le terminateur pour le +% \XINT_unsep_cuzsmall final.| +% \begin{macrocode} +\def\XINT_binom_a #1.#2.% +{% + \expandafter\XINT_binom_b\the\numexpr \xint_c_i+#1.1.#2.100000001!1!\Z!0!% +}% +% \end{macrocode} +% \lverb|y=x-k+1.j=1.k. On va évaluer par y/1*(y+1)/2*(y+2)/3 etc... On essaie +% de regrouper de manière à utiliser au mieux \numexpr. On peut aller jusqu'à +% x=10000 car 9999*10000<10^8. 463*464*465=99896880, 98*99*100*101=97990200. +% On va vérifier à chaque étape si on dépasse un seuil. Le style de +% l'implémentation diffère de celui que j'avais utilisé pour \xintiiFac. On +% pourrait tout-à -fait avoir une verybigloop, mais bon. Je rajoute aussi un +% verysmall. Le traitement est un peu différent pour elle afin d'aller jusqu'à +% x=29 (et pas seulement 26 si je suivais le modèle des autres, mais je veux +% pouvoir faire binomial(29,1), binomial(29,2), ... en vsmall).| +% \begin{macrocode} +\def\XINT_binom_b #1.% +{% + \ifnum #1>9999 \xint_dothis\XINT_binom_vbigloop \fi + \ifnum #1>463 \xint_dothis\XINT_binom_bigloop \fi + \ifnum #1>98 \xint_dothis\XINT_binom_medloop \fi + \ifnum #1>29 \xint_dothis\XINT_binom_smallloop \fi + \xint_orthat\XINT_binom_vsmallloop #1.% +}% +% \end{macrocode} +% \lverb|y.j.k. Au départ on avait x-k+1.1.k. Ensuite on a des blocs 1<8d>! +% donnant le résultat intermédiaire, dans l'ordre, et à la fin on a 1!1\Z!0!. +% Dans smallloop on peut prendre 4 par 4.| +% \begin{macrocode} +\def\XINT_binom_smallloop #1.#2.#3.% +{% + \ifcase\numexpr #3-#2\relax + \expandafter\XINT_binom_end_ + \or \expandafter\XINT_binom_end_i + \or \expandafter\XINT_binom_end_ii + \or \expandafter\XINT_binom_end_iii + \else\expandafter\XINT_binom_smallloop_a + \fi #1.#2.#3.% +}% +% \end{macrocode} +% \lverb|Ça m'ennuie un peu de reprendre les #1, #2, #3 ici. On a besoin de +% \numexpr pour \XINT_binom_div, mais de \romannumeral0 pour le unsep après +% \XINT_binom_mul.| +% \begin{macrocode} +\def\XINT_binom_smallloop_a #1.#2.#3.% +{% + \expandafter\XINT_binom_smallloop_b + \the\numexpr #1+\xint_c_iv\expandafter.% + \the\numexpr #2+\xint_c_iv\expandafter.% + \the\numexpr #3\expandafter.% + \the\numexpr\expandafter\XINT_binom_div + \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)*(#2+\xint_c_iii)\expandafter + !\romannumeral0\expandafter\XINT_binom_mul + \the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% +}% +\def\XINT_binom_smallloop_b #1.% +{% + \ifnum #1>98 \expandafter\XINT_binom_medloop \else + \expandafter\XINT_binom_smallloop \fi #1.% +}% +% \end{macrocode} +% \lverb|Ici on prend trois par trois.| +% \begin{macrocode} +\def\XINT_binom_medloop #1.#2.#3.% +{% + \ifcase\numexpr #3-#2\relax + \expandafter\XINT_binom_end_ + \or \expandafter\XINT_binom_end_i + \or \expandafter\XINT_binom_end_ii + \else\expandafter\XINT_binom_medloop_a + \fi #1.#2.#3.% +}% +\def\XINT_binom_medloop_a #1.#2.#3.% +{% + \expandafter\XINT_binom_medloop_b + \the\numexpr #1+\xint_c_iii\expandafter.% + \the\numexpr #2+\xint_c_iii\expandafter.% + \the\numexpr #3\expandafter.% + \the\numexpr\expandafter\XINT_binom_div + \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)\expandafter + !\romannumeral0\expandafter\XINT_binom_mul + \the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% +}% +\def\XINT_binom_medloop_b #1.% +{% + \ifnum #1>463 \expandafter\XINT_binom_bigloop \else + \expandafter\XINT_binom_medloop \fi #1.% +}% +% \end{macrocode} +% \lverb|Ici on prend deux par deux.| +% \begin{macrocode} +\def\XINT_binom_bigloop #1.#2.#3.% +{% + \ifcase\numexpr #3-#2\relax + \expandafter\XINT_binom_end_ + \or \expandafter\XINT_binom_end_i + \else\expandafter\XINT_binom_bigloop_a + \fi #1.#2.#3.% +}% +\def\XINT_binom_bigloop_a #1.#2.#3.% +{% + \expandafter\XINT_binom_bigloop_b + \the\numexpr #1+\xint_c_ii\expandafter.% + \the\numexpr #2+\xint_c_ii\expandafter.% + \the\numexpr #3\expandafter.% + \the\numexpr\expandafter\XINT_binom_div + \the\numexpr #2*(#2+\xint_c_i)\expandafter + !\romannumeral0\expandafter\XINT_binom_mul + \the\numexpr #1*(#1+\xint_c_i)!% +}% +\def\XINT_binom_bigloop_b #1.% +{% + \ifnum #1>9999 \expandafter\XINT_binom_vbigloop \else + \expandafter\XINT_binom_bigloop \fi #1.% +}% +% \end{macrocode} +% \lverb|Et finalement un par un.| +% \begin{macrocode} +\def\XINT_binom_vbigloop #1.#2.#3.% +{% + \ifnum #3=#2 + \expandafter\XINT_binom_end_ + \else\expandafter\XINT_binom_vbigloop_a + \fi #1.#2.#3.% +}% +\def\XINT_binom_vbigloop_a #1.#2.#3.% +{% + \expandafter\XINT_binom_vbigloop + \the\numexpr #1+\xint_c_i\expandafter.% + \the\numexpr #2+\xint_c_i\expandafter.% + \the\numexpr #3\expandafter.% + \the\numexpr\expandafter\XINT_binom_div\the\numexpr #2\expandafter + !\romannumeral0\XINT_binom_mul #1!% +}% +% \end{macrocode} +% \lverb|y.j.k. La partie very small. y est au plus 26 (non 29 mais retesté +% dans \XINT_binom_vsmallloop_a), et tous les binomial(29,n) sont <10^8. On +% peut donc faire y(y+1)(y+2)(y+3) et aussi il y a le fait que etex fait a*b/c +% en double precision. Pour ne pas bifurquer à la fin sur smallloop, si n=27, +% 27, ou 29 on procède un peu différemment des autres boucles. Si je testais +% aussi #1 après #3-#2 pour les autres il faudrait des terminaisons +% différentes.| +% \begin{macrocode} +\def\XINT_binom_vsmallloop #1.#2.#3.% +{% + \ifcase\numexpr #3-#2\relax + \expandafter\XINT_binom_vsmallend_ + \or \expandafter\XINT_binom_vsmallend_i + \or \expandafter\XINT_binom_vsmallend_ii + \or \expandafter\XINT_binom_vsmallend_iii + \else\expandafter\XINT_binom_vsmallloop_a + \fi #1.#2.#3.% +}% +\def\XINT_binom_vsmallloop_a #1.% +{% + \ifnum #1>26 \expandafter\XINT_binom_smallloop_a \else + \expandafter\XINT_binom_vsmallloop_b \fi #1.% +}% +\def\XINT_binom_vsmallloop_b #1.#2.#3.% +{% + \expandafter\XINT_binom_vsmallloop + \the\numexpr #1+\xint_c_iv\expandafter.% + \the\numexpr #2+\xint_c_iv\expandafter.% + \the\numexpr #3\expandafter.% + \the\numexpr \expandafter\XINT_binom_vsmallmuldiv + \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)*(#2+\xint_c_iii)\expandafter + !\the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% +}% +\def\XINT_binom_mul #1!#21!\Z!0!% +{% + \expandafter\XINT_rev_nounsep\expandafter{\expandafter}% + \the\numexpr\expandafter\XINT_smallmul + \the\numexpr\xint_c_x^viii+#1\expandafter + !\romannumeral0\XINT_rev_nounsep {}1\Z!#2% + \R!\R!\R!\R!\R!\R!\R!\R!\W + \R!\R!\R!\R!\R!\R!\R!\R!\W + 1\Z!% +}% +\def\XINT_binom_div #1!1\Z!% +{% + \expandafter\XINT_smalldivx_a + \the\numexpr #1/\xint_c_ii\expandafter.% + \the\numexpr \xint_c_x^viii+#1!% +}% +% \end{macrocode} +% \lverb|Vaguement envisagé d'éviter le 10^8+ mais bon.| +% \begin{macrocode} +\def\XINT_binom_vsmallmuldiv #1!#2!1#3!{\xint_c_x^viii+#2*#3/#1!}% +% \end{macrocode} +% \lverb|On a des terminaisons communes aux trois situations small, med, big, +% et on est sûr de pouvoir faire les multiplications dans \numexpr, car on +% vient ici *après* avoir comparé à 9999 ou 463 ou 98.| +% \begin{macrocode} +\def\XINT_binom_end_iii #1.#2.#3.% +{% + \expandafter\XINT_binom_finish + \the\numexpr\expandafter\XINT_binom_div + \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)*(#2+\xint_c_iii)\expandafter + !\romannumeral0\expandafter\XINT_binom_mul + \the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% +}% +\def\XINT_binom_end_ii #1.#2.#3.% +{% + \expandafter\XINT_binom_finish + \the\numexpr\expandafter\XINT_binom_div + \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)\expandafter + !\romannumeral0\expandafter\XINT_binom_mul + \the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% +}% +\def\XINT_binom_end_i #1.#2.#3.% +{% + \expandafter\XINT_binom_finish + \the\numexpr\expandafter\XINT_binom_div + \the\numexpr #2*(#2+\xint_c_i)\expandafter + !\romannumeral0\expandafter\XINT_binom_mul + \the\numexpr #1*(#1+\xint_c_i)!% +}% +\def\XINT_binom_end_ #1.#2.#3.% +{% + \expandafter\XINT_binom_finish + \the\numexpr\expandafter\XINT_binom_div\the\numexpr #2\expandafter + !\romannumeral0\XINT_binom_mul #1!% +}% +\def\XINT_binom_finish #1\Z!0!% + {\XINT_unsep_cuzsmall #11\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W }% +% \end{macrocode} +% \lverb|Duplication de code seulement pour la boucle avec très +% petits coeffs, mais en plus on fait au maximum des possibilités. (on +% pourrait tester plus le résultat déjà obtenu).| +% \begin{macrocode} +\def\XINT_binom_vsmallend_iii #1.% +{% + \ifnum #1>26 \expandafter\XINT_binom_end_iii \else + \expandafter\XINT_binom_vsmallend_iiib \fi #1.% +}% +\def\XINT_binom_vsmallend_iiib #1.#2.#3.% +{% + \expandafter\XINT_binom_vsmallfinish + \the\numexpr \expandafter\XINT_binom_vsmallmuldiv + \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)*(#2+\xint_c_iii)\expandafter + !\the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% +}% +\def\XINT_binom_vsmallend_ii #1.% +{% + \ifnum #1>27 \expandafter\XINT_binom_end_ii \else + \expandafter\XINT_binom_vsmallend_iib \fi #1.% +}% +\def\XINT_binom_vsmallend_iib #1.#2.#3.% +{% + \expandafter\XINT_binom_vsmallfinish + \the\numexpr \expandafter\XINT_binom_vsmallmuldiv + \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)\expandafter + !\the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% +}% +\def\XINT_binom_vsmallend_i #1.% +{% + \ifnum #1>28 \expandafter\XINT_binom_end_i \else + \expandafter\XINT_binom_vsmallend_ib \fi #1.% +}% +\def\XINT_binom_vsmallend_ib #1.#2.#3.% +{% + \expandafter\XINT_binom_vsmallfinish + \the\numexpr \expandafter\XINT_binom_vsmallmuldiv + \the\numexpr #2*(#2+\xint_c_i)\expandafter + !\the\numexpr #1*(#1+\xint_c_i)!% +}% +\def\XINT_binom_vsmallend_ #1.% +{% + \ifnum #1>29 \expandafter\XINT_binom_end_ \else + \expandafter\XINT_binom_vsmallend_b \fi #1.% +}% +\def\XINT_binom_vsmallend_b #1.#2.#3.% +{% + \expandafter\XINT_binom_vsmallfinish + \the\numexpr\XINT_binom_vsmallmuldiv #2!#1!% +}% +\edef\XINT_binom_vsmallfinish 1#1!1!\Z!0!% + {\noexpand\expandafter\space\noexpand\the\numexpr #1\relax}% +% \end{macrocode} +% \subsection{\csh{xintiiPFactorial}, \csh{xintiPFactorial}} +% \lverb|2015/11/29 for 1.2f. Partial factorial pfac(a,b)=(a+1)...b, only for +% non-negative integers with a<=b<10^8.| +% \begin{macrocode} +\def\xintiiPFactorial {\romannumeral0\xintiipfactorial }% +\def\xintiipfactorial #1#2% +{% + \expandafter\XINT_pfac_fork\the\numexpr#1\expandafter.\the\numexpr #2.% +}% +\def\xintiPFactorial{\romannumeral0\xintipfactorial}% +\let\xintipfactorial\xintiipfactorial +% \end{macrocode} +% \lverb|Code is a simplified version of the one for \xintiiBinomial, with no +% attempt is made at doing a "very small" portion if applicable.| +% \begin{macrocode} +\def\XINT_pfac_fork #1#2.#3.% +{% + \if-#1\xint_dothis {\xintError:OutOfRangePFac\space 0}\fi + \ifnum #1#2=#3 \xint_dothis{ 1}\fi + \ifnum #1#2>#3 \xint_dothis{\xintError:OutOfRangePFac\space 0}\fi + \ifnum #3>\xint_c_x^viii_mone\xint_dothis{\xintError:OutOfRangePFac\space 0}\fi + \xint_orthat {\XINT_pfac_a #1#2.#3.}% +}% +\def\XINT_pfac_a #1.#2.% +{% + \expandafter\XINT_pfac_b\the\numexpr \xint_c_i+#1.#2.100000001!1\Z!% + 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W +}% +\def\XINT_pfac_b #1.% +{% + \ifnum #1>9999 \xint_dothis\XINT_pfac_vbigloop \fi + \ifnum #1>463 \xint_dothis\XINT_pfac_bigloop \fi + \ifnum #1>98 \xint_dothis\XINT_pfac_medloop \fi + \xint_orthat\XINT_pfac_smallloop #1.% +}% +\def\XINT_pfac_smallloop #1.#2.% +{% + \ifcase\numexpr #2-#1\relax + \expandafter\XINT_pfac_end_ + \or \expandafter\XINT_pfac_end_i + \or \expandafter\XINT_pfac_end_ii + \or \expandafter\XINT_pfac_end_iii + \else\expandafter\XINT_pfac_smallloop_a + \fi #1.#2.% +}% +\def\XINT_pfac_smallloop_a #1.#2.% +{% + \expandafter\XINT_pfac_smallloop_b + \the\numexpr #1+\xint_c_iv\expandafter.% + \the\numexpr #2\expandafter.% + \the\numexpr\expandafter\XINT_smallmul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% +}% +\def\XINT_pfac_smallloop_b #1.% +{% + \ifnum #1>98 \expandafter\XINT_pfac_medloop \else + \expandafter\XINT_pfac_smallloop \fi #1.% +}% +\def\XINT_pfac_medloop #1.#2.% +{% + \ifcase\numexpr #2-#1\relax + \expandafter\XINT_pfac_end_ + \or \expandafter\XINT_pfac_end_i + \or \expandafter\XINT_pfac_end_ii + \else\expandafter\XINT_pfac_medloop_a + \fi #1.#2.% +}% +\def\XINT_pfac_medloop_a #1.#2.% +{% + \expandafter\XINT_pfac_medloop_b + \the\numexpr #1+\xint_c_iii\expandafter.% + \the\numexpr #2\expandafter.% + \the\numexpr\expandafter\XINT_smallmul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% +}% +\def\XINT_pfac_medloop_b #1.% +{% + \ifnum #1>463 \expandafter\XINT_pfac_bigloop \else + \expandafter\XINT_pfac_medloop \fi #1.% +}% +\def\XINT_pfac_bigloop #1.#2.% +{% + \ifcase\numexpr #2-#1\relax + \expandafter\XINT_pfac_end_ + \or \expandafter\XINT_pfac_end_i + \else\expandafter\XINT_pfac_bigloop_a + \fi #1.#2.% +}% +\def\XINT_pfac_bigloop_a #1.#2.% +{% + \expandafter\XINT_pfac_bigloop_b + \the\numexpr #1+\xint_c_ii\expandafter.% + \the\numexpr #2\expandafter.% + \the\numexpr\expandafter + \XINT_smallmul\the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!% +}% +\def\XINT_pfac_bigloop_b #1.% +{% + \ifnum #1>9999 \expandafter\XINT_pfac_vbigloop \else + \expandafter\XINT_pfac_bigloop \fi #1.% +}% +\def\XINT_pfac_vbigloop #1.#2.% +{% + \ifnum #2=#1 + \expandafter\XINT_pfac_end_ + \else\expandafter\XINT_pfac_vbigloop_a + \fi #1.#2.% +}% +\def\XINT_pfac_vbigloop_a #1.#2.% +{% + \expandafter\XINT_pfac_vbigloop + \the\numexpr #1+\xint_c_i\expandafter.% + \the\numexpr #2\expandafter.% + \the\numexpr\expandafter\XINT_smallmul\the\numexpr\xint_c_x^viii+#1!% +}% +\def\XINT_pfac_end_iii #1.#2.% +{% + \expandafter\XINT_mul_out + \the\numexpr\expandafter\XINT_smallmul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% +}% +\def\XINT_pfac_end_ii #1.#2.% +{% + \expandafter\XINT_mul_out + \the\numexpr\expandafter\XINT_smallmul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% +}% +\def\XINT_pfac_end_i #1.#2.% +{% + \expandafter\XINT_mul_out + \the\numexpr\expandafter\XINT_smallmul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!% +}% +\def\XINT_pfac_end_ #1.#2.% +{% + \expandafter\XINT_mul_out + \the\numexpr\expandafter\XINT_smallmul\the\numexpr \xint_c_x^viii+#1!% }% -\def\XINT_sqrt_big_end #1#2#3#4{ {#3}{#2}}% % \end{macrocode} % \subsection{\csh{xintiiE}} % \lverb|Originally was used in \xintiiexpr. Transferred from xintfrac for 1.1.| @@ -20974,14 +21567,15 @@ $1$ or $-1$. \def\xintSumExpr {\Did_you_mean_iiSumExpr?or_load_xintfrac!}% \XINT_restorecatcodes_endinput% % \end{macrocode} -%\catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11 -%\let</xint>\relax -%\def<*xintbinhex>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 } -%</xint> -%<*xintbinhex> % % \StoreCodelineNo {xint} % +%\gardesactifs +%\let</xint>\relax +%\let<*xintbinhex>\gardesinactifs +%</xint>^^A------------------------------------------------------- +%<*xintbinhex>^^A------------------------------------------------- +% \clearpage % \section{Package \xintbinhexnameimp implementation} % \label{sec:binheximp} % @@ -21046,10 +21640,10 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintbinhex}% - [2015/11/22 v1.2e Expandable binary and hexadecimal conversions (jfB)]% + [2016/03/12 1.2f Expandable binary and hexadecimal conversions (JFB)]% % \end{macrocode} % \subsection{Constants, etc...} -% \lverb!v1.08! +% \lverb!1.08! % \begin{macrocode} \newcount\xint_c_ii^xv \xint_c_ii^xv 32768 \newcount\xint_c_ii^xvi \xint_c_ii^xvi 65536 @@ -21183,7 +21777,7 @@ $1$ or $-1$. \def\XINT_OQ_end_i \Z #1#2#3#4#5#6#7#8\Z { #1#2#3#4#5#6#7#80}% % \end{macrocode} % \subsection{\csh{xintDecToHex}, \csh{xintDecToBin}} -% \lverb!v1.08! +% \lverb!1.08! % \begin{macrocode} \def\xintDecToHex {\romannumeral0\xintdectohex }% \def\xintdectohex #1% @@ -21335,7 +21929,7 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintHexToDec}} -% \lverb!v1.08! +% \lverb!1.08! % \begin{macrocode} \def\xintHexToDec {\romannumeral0\xinthextodec }% \def\xinthextodec #1% @@ -21423,7 +22017,7 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintBinToDec}} -% \lverb!v1.08! +% \lverb!1.08! % \begin{macrocode} \def\xintBinToDec {\romannumeral0\xintbintodec }% \def\xintbintodec #1{\expandafter\XINT_btd_checkin @@ -21532,7 +22126,7 @@ $1$ or $-1$. \def\XINT_btd_I_end_bz 000\XINT_btd_I_end_c 000{\XINT_btd_I }% % \end{macrocode} % \subsection{\csh{xintBinToHex}} -% \lverb!v1.08! +% \lverb!1.08! % \begin{macrocode} \def\xintBinToHex {\romannumeral0\xintbintohex }% \def\xintbintohex #1% @@ -21575,7 +22169,7 @@ $1$ or $-1$. \def\XINT_bth_end_z0\space 0{ }% % \end{macrocode} % \subsection{\csh{xintHexToBin}} -% \lverb!v1.08! +% \lverb!1.08! % \begin{macrocode} \def\xintHexToBin {\romannumeral0\xinthextobin }% \def\xinthextobin #1% @@ -21619,7 +22213,7 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintCHexToBin}} -% \lverb!v1.08! +% \lverb!1.08! % \begin{macrocode} \def\xintCHexToBin {\romannumeral0\xintchextobin }% \def\xintchextobin #1% @@ -21666,14 +22260,15 @@ $1$ or $-1$. }% \XINT_restorecatcodes_endinput% % \end{macrocode} -%\catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11 -%\let</xintbinhex>\relax -%\def<*xintgcd>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 } -%</xintbinhex> -%<*xintgcd> % % \StoreCodelineNo {xintbinhex} % +%\gardesactifs +%\let</xintbinhex>\relax +%\let<*xintgcd>\gardesinactifs +%</xintbinhex>^^A------------------------------------------------- +%<*xintgcd>^^A---------------------------------------------------- +% \clearpage % \section{Package \xintgcdnameimp implementation} % \label{sec:gcdimp} % @@ -21747,16 +22342,9 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintgcd}% - [2015/11/22 v1.2e Euclide algorithm with xint package (jfB)]% + [2016/03/12 1.2f Euclide algorithm with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintGCD}, \csh{xintiiGCD}} -% \lverb|The macros of 1.09a benefits from the \xintnum which has been inserted -% inside \xintiabs in \xintnameimp; -% this is a little overhead but is more convenient for the -% user and also makes it easier to use into \xintexpr-essions. 1.1a adds -% \xintiiGCD mainly for \xintiiexpr benefit. Perhaps one should always have -% had ONLY ii versions from the beginning. And perhaps for sake of -% consistency, \xintGCD should be named \xintiGCD? too late.| % \begin{macrocode} \def\xintGCD {\romannumeral0\xintgcd }% \def\xintgcd #1% @@ -21809,11 +22397,6 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintLCM}, \csh{xintiiLCM}} -% \lverb|New with 1.09a. Inadvertent use of \xintiQuo which was promoted at the -% same time to add the \xintnum overhead. So with 1.09f \xintiiQuo without the -% overhead. However \xintiabs has the \xintnum thing. The advantage is that we -% can thus use lcm in \xintexpr. The disadvantage is that this has overhead in -% \xintiiexpr. Thus 1.1a has \xintiiLCM.| % \begin{macrocode} \def\xintLCM {\romannumeral0\xintlcm}% \def\xintlcm #1% @@ -21848,7 +22431,6 @@ $1$ or $-1$. \def\XINT_lcm_notzero #1#2#3{\xintiimul {#2}{\xintiiQuo{#3}{#1}}}% % \end{macrocode} % \subsection{\csh{xintBezout}} -% \lverb|1.09a inserts use of \xintnum| % \begin{macrocode} \def\xintBezout {\romannumeral0\xintbezout }% \def\xintbezout #1% @@ -21883,7 +22465,7 @@ $1$ or $-1$. }% % \end{macrocode} % \lverb|& -% attention première entrée doit être ici (-1)^n donc 1$\ +% attention première entrée doit être ici (-1)^n donc 1$\ % #4#2 = 0 = A, B = #3#1| % \begin{macrocode} \def\XINT_bezout_firstiszero #1#2#3#4#5#6% @@ -21967,7 +22549,7 @@ $1$ or $-1$. \romannumeral0\XINT_bezout_loop_a 1{#3#1}{#4#2}1001% }% % \end{macrocode} -% \lverb|la parité (-1)^N est en #1, et on la jette ici.| +% \lverb|la parité (-1)^N est en #1, et on la jette ici.| % \begin{macrocode} \edef\XINT_bezout_pp_post #1#2#3#4#5% {% @@ -21975,9 +22557,9 @@ $1$ or $-1$. }% % \end{macrocode} % \lverb|& -% n = 0: 1BAalpha(0)beta(0)alpha(-1)beta(-1)$\ -% n général: -% {(-1)^n}{r(n-1)}{r(n-2)}{alpha(n-1)}{beta(n-1)}{alpha(n-2)}{beta(n-2)}$\ +% n = 0: 1BAalpha(0)beta(0)alpha(-1)beta(-1)$\ +% n général: +% {(-1)^n}{r(n-1)}{r(n-2)}{alpha(n-1)}{beta(n-1)}{alpha(n-2)}{beta(n-2)}$\ % #2 = B, #3 = A| % \begin{macrocode} \def\XINT_bezout_loop_a #1#2#3% @@ -21988,10 +22570,10 @@ $1$ or $-1$. }% % \end{macrocode} % \lverb|& -% Le q(n) a ici une existence éphémère, dans le version Bezout Algorithm -% il faudra le conserver. On voudra à la fin +% Le q(n) a ici une existence éphémère, dans le version Bezout Algorithm +% il faudra le conserver. On voudra à la fin % {{q(n)}{r(n)}{alpha(n)}{beta(n)}}. -% De plus ce n'est plus (-1)^n que l'on veut mais n. (ou dans un autre ordre)$\ +% De plus ce n'est plus (-1)^n que l'on veut mais n. (ou dans un autre ordre)$\ % {-(-1)^n}{q(n)}{r(n)}{r(n-1)}{alpha(n-1)}{beta(n-1)}{alpha(n-2)}{beta(n-2)}| % \begin{macrocode} \def\XINT_bezout_loop_b #1#2#3#4#5#6#7#8% @@ -22033,7 +22615,7 @@ $1$ or $-1$. }% % \end{macrocode} % \lverb|{(-1)^(n+1)}{r(n)}{r(n-1)}{alpha(n)}{beta(n)}{alpha(n-1)}{beta(n-1)} -% et itération| +% et itération| % \begin{macrocode} \def\xint_bezout_loop_exit0\XINT_bezout_loop_f #1#2% {% @@ -22054,8 +22636,8 @@ $1$ or $-1$. % \subsection{\csh{xintEuclideAlgorithm}} % \lverb|& % Pour Euclide: -% {N}{A}{D=r(n)}{B}{q1}{r1}{q2}{r2}{q3}{r3}....{qN}{rN=0}$\ -% u<2n> = u<2n+3>u<2n+2> + u<2n+4> à la n ième étape| +% {N}{A}{D=r(n)}{B}{q1}{r1}{q2}{r2}{q3}{r3}....{qN}{rN=0}$\ +% u<2n> = u<2n+3>u<2n+2> + u<2n+4> à la n ième étape| % \begin{macrocode} \def\xintEuclideAlgorithm {\romannumeral0\xinteuclidealgorithm }% \def\xinteuclidealgorithm #1% @@ -22080,17 +22662,17 @@ $1$ or $-1$. }% % \end{macrocode} % \lverb|& -% Le {} pour protéger {{A}{B}} si on s'arrête après une étape (B divise +% Le {} pour protéger {{A}{B}} si on s'arrête après une étape (B divise % A). -% On va renvoyer:$\ +% On va renvoyer:$\ % {N}{A}{D=r(n)}{B}{q1}{r1}{q2}{r2}{q3}{r3}....{qN}{rN=0}| % \begin{macrocode} \def\XINT_euc_AisZero #1#2#3#4#5#6{ {1}{0}{#2}{#2}{0}{0}}% \def\XINT_euc_BisZero #1#2#3#4#5#6{ {1}{0}{#3}{#3}{0}{0}}% % \end{macrocode} % \lverb|& -% {n}{rn}{an}{{qn}{rn}}...{{A}{B}}{}\Z$\ -% a(n) = r(n-1). Pour n=0 on a juste {0}{B}{A}{{A}{B}}{}\Z$\ +% {n}{rn}{an}{{qn}{rn}}...{{A}{B}}{}\Z$\ +% a(n) = r(n-1). Pour n=0 on a juste {0}{B}{A}{{A}{B}}{}\Z$\ % \XINT_div_prepare {u}{v} divise v par u| % \begin{macrocode} \def\XINT_euc_a #1#2#3% @@ -22107,7 +22689,7 @@ $1$ or $-1$. \XINT_euc_c #3\Z {#1}{#3}{#4}{{#2}{#3}}% }% % \end{macrocode} -% \lverb|r(n+1)\Z {n+1}{r(n+1)}{r(n)}{{q(n+1)}{r(n+1)}}{{qn}{rn}}...$\ +% \lverb|r(n+1)\Z {n+1}{r(n+1)}{r(n)}{{q(n+1)}{r(n+1)}}{{qn}{rn}}...$\ % Test si r(n+1) est nul.| % \begin{macrocode} \def\XINT_euc_c #1#2\Z @@ -22117,8 +22699,8 @@ $1$ or $-1$. % \end{macrocode} % \lverb|& % {n+1}{r(n+1)}{r(n)}{{q(n+1)}{r(n+1)}}...{}\Z -% Ici r(n+1) = 0. On arrête on se prépare à inverser -% {n+1}{0}{r(n)}{{q(n+1)}{r(n+1)}}.....{{q1}{r1}}{{A}{B}}{}\Z$\ +% Ici r(n+1) = 0. On arrête on se prépare à inverser +% {n+1}{0}{r(n)}{{q(n+1)}{r(n+1)}}.....{{q1}{r1}}{{A}{B}}{}\Z$\ % On veut renvoyer: {N=n+1}{A}{D=r(n)}{B}{q1}{r1}{q2}{r2}{q3}{r3}....{qN}{rN=0}| % \begin{macrocode} \def\xint_euc_end0\XINT_euc_a #1#2#3#4\Z% @@ -22138,9 +22720,9 @@ $1$ or $-1$. % \end{macrocode} % \subsection{\csh{xintBezoutAlgorithm}} % \lverb|& -% Pour Bezout: objectif, renvoyer$\ -% {N}{A}{0}{1}{D=r(n)}{B}{1}{0}{q1}{r1}{alpha1=q1}{beta1=1}$\ -% {q2}{r2}{alpha2}{beta2}....{qN}{rN=0}{alphaN=A/D}{betaN=B/D}$\ +% Pour Bezout: objectif, renvoyer$\ +% {N}{A}{0}{1}{D=r(n)}{B}{1}{0}{q1}{r1}{alpha1=q1}{beta1=1}$\ +% {q2}{r2}{alpha2}{beta2}....{qN}{rN=0}{alphaN=A/D}{betaN=B/D}$\ % alpha0=1, beta0=0, alpha(-1)=0, beta(-1)=1| % \begin{macrocode} \def\xintBezoutAlgorithm {\romannumeral0\xintbezoutalgorithm }% @@ -22168,7 +22750,7 @@ $1$ or $-1$. \def\XINT_bezalg_BisZero #1#2#3#4\Z{ {1}{0}{0}{1}{#3}{#3}{1}{0}{0}{0}{0}{1}}% % \end{macrocode} % \lverb|& -% pour préparer l'étape n+1 il faut +% pour préparer l'étape n+1 il faut % {n}{r(n)}{r(n-1)}{alpha(n)}{beta(n)}{alpha(n-1)}{beta(n-1)}& % {{q(n)}{r(n)}{alpha(n)}{beta(n)}}... % division de #3 par #2| @@ -22206,8 +22788,8 @@ $1$ or $-1$. \XINT_bezalg_e #4\Z {#2}{#4}{#5}{#1}{#6}{#7}{#8}{{#3}{#4}{#1}{#6}}% }% % \end{macrocode} -% \lverb|r(n+1)\Z {n+1}{r(n+1)}{r(n)}{alpha(n+1)}{beta(n+1)}$\ -% {alpha(n)}{beta(n)}{q,r,alpha,beta(n+1)}$\ +% \lverb|r(n+1)\Z {n+1}{r(n+1)}{r(n)}{alpha(n+1)}{beta(n+1)}$\ +% {alpha(n)}{beta(n)}{q,r,alpha,beta(n+1)}$\ % Test si r(n+1) est nul.| % \begin{macrocode} \def\XINT_bezalg_e #1#2\Z @@ -22216,11 +22798,11 @@ $1$ or $-1$. }% % \end{macrocode} % \lverb|& -% Ici r(n+1) = 0. On arrête on se prépare à inverser.$\ -% {n+1}{r(n+1)}{r(n)}{alpha(n+1)}{beta(n+1)}{alpha(n)}{beta(n)}$\ -% {q,r,alpha,beta(n+1)}...{{A}{B}}{}\Z$\ -% On veut renvoyer$\ -% {N}{A}{0}{1}{D=r(n)}{B}{1}{0}{q1}{r1}{alpha1=q1}{beta1=1}$\ +% Ici r(n+1) = 0. On arrête on se prépare à inverser.$\ +% {n+1}{r(n+1)}{r(n)}{alpha(n+1)}{beta(n+1)}{alpha(n)}{beta(n)}$\ +% {q,r,alpha,beta(n+1)}...{{A}{B}}{}\Z$\ +% On veut renvoyer$\ +% {N}{A}{0}{1}{D=r(n)}{B}{1}{0}{q1}{r1}{alpha1=q1}{beta1=1}$\ % {q2}{r2}{alpha2}{beta2}....{qN}{rN=0}{alphaN=A/D}{betaN=B/D}| % \begin{macrocode} \def\xint_bezalg_end0\XINT_bezalg_a #1#2#3#4#5#6#7#8\Z @@ -22235,10 +22817,10 @@ $1$ or $-1$. }% % \end{macrocode} % \lverb|& -% {N}{D}{A}{B}{q1}{r1}{alpha1=q1}{beta1=1}{q2}{r2}{alpha2}{beta2}$\ -% ....{qN}{rN=0}{alphaN=A/D}{betaN=B/D}$\ -% On veut renvoyer$\ -% {N}{A}{0}{1}{D=r(n)}{B}{1}{0}{q1}{r1}{alpha1=q1}{beta1=1}$\ +% {N}{D}{A}{B}{q1}{r1}{alpha1=q1}{beta1=1}{q2}{r2}{alpha2}{beta2}$\ +% ....{qN}{rN=0}{alphaN=A/D}{betaN=B/D}$\ +% On veut renvoyer$\ +% {N}{A}{0}{1}{D=r(n)}{B}{1}{0}{q1}{r1}{alpha1=q1}{beta1=1}$\ % {q2}{r2}{alpha2}{beta2}....{qN}{rN=0}{alphaN=A/D}{betaN=B/D}| % \begin{macrocode} \edef\xint_bezalg_end_ #1#2#3#4% @@ -22247,9 +22829,6 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintGCDof}} -% \lverb|New with 1.09a. I also tried an optimization (not working two by two) -% which I thought was clever but -% it seemed to be less efficient ...| % \begin{macrocode} \def\xintGCDof {\romannumeral0\xintgcdof }% \def\xintgcdof #1{\expandafter\XINT_gcdof_a\romannumeral`&&@#1\relax }% @@ -22276,14 +22855,14 @@ $1$ or $-1$. % % Organisation: % -% {N}{A}{D}{B}{q1}{r1}{q2}{r2}{q3}{r3}....{qN}{rN=0}$\ -% \U1 = N = nombre d'étapes, \U3 = PGCD, \U2 = A, \U4=B +% {N}{A}{D}{B}{q1}{r1}{q2}{r2}{q3}{r3}....{qN}{rN=0}$\ +% \U1 = N = nombre d'étapes, \U3 = PGCD, \U2 = A, \U4=B % q1 = \U5, q2 = \U7 --> qn = \U<2n+3>, rn = \U<2n+4> % bn = rn. B = r0. A=r(-1) % -% r(n-2) = q(n)r(n-1)+r(n) (n e étape) +% r(n-2) = q(n)r(n-1)+r(n) (n e étape) % -% \U{2n} = \U{2n+3} \times \U{2n+2} + \U{2n+4}, n e étape. +% \U{2n} = \U{2n+3} \times \U{2n+2} + \U{2n+4}, n e étape. % (avec n entre 1 et N) % % 1.09h uses \xintloop, and \par rather than \endgraf; and \par rather than @@ -22320,12 +22899,12 @@ $1$ or $-1$. % \subsection{\csh{xintTypesetBezoutAlgorithm}} % \lverb|& % Pour Bezout on a: -% {N}{A}{0}{1}{D=r(n)}{B}{1}{0}{q1}{r1}{alpha1=q1}{beta1=1}$\ +% {N}{A}{0}{1}{D=r(n)}{B}{1}{0}{q1}{r1}{alpha1=q1}{beta1=1}$\ % {q2}{r2}{alpha2}{beta2}....{qN}{rN=0}{alphaN=A/D}{betaN=B/D}% % Donc 4N+8 termes: -% U1 = N, U2= A, U5=D, U6=B, q1 = U9, qn = U{4n+5}, n au moins 1$\ -% rn = U{4n+6}, n au moins -1$\ -% alpha(n) = U{4n+7}, n au moins -1$\ +% U1 = N, U2= A, U5=D, U6=B, q1 = U9, qn = U{4n+5}, n au moins 1$\ +% rn = U{4n+6}, n au moins -1$\ +% alpha(n) = U{4n+7}, n au moins -1$\ % beta(n) = U{4n+8}, n au moins -1 % % 1.09h uses \xintloop, and \par rather than \endgraf; and no more \parindent0pt @@ -22377,14 +22956,15 @@ $1$ or $-1$. }% \XINT_restorecatcodes_endinput% % \end{macrocode} -%\catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11 -%\let</xintgcd>\relax -%\def<*xintfrac>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 } -%</xintgcd> -%<*xintfrac> % % \StoreCodelineNo {xintgcd} % +%\gardesactifs +%\let</xintgcd>\relax +%\let<*xintfrac>\gardesinactifs +%</xintgcd>^^A---------------------------------------------------- +%<*xintfrac>^^A--------------------------------------------------- +% \clearpage % \section{Package \xintfracnameimp implementation} % \label{sec:fracimp} % @@ -22449,11 +23029,11 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintfrac}% - [2015/11/22 v1.2e Expandable operations on fractions (jfB)]% + [2016/03/12 1.2f Expandable operations on fractions (JFB)]% % \end{macrocode} % \subsection{\csh{XINT_cntSgnFork}} % \lverb|1.09i. Used internally, #1 must expand to \m@ne, \z@, or \@ne or -% equivalent. Does not insert a space token to stop a romannumeral0 expansion.| +% equivalent. \XINT_cntSgnFork does not insert a romannumeral stopper.| % \begin{macrocode} \def\XINT_cntSgnFork #1% {% @@ -22464,6 +23044,8 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintLen}} +% \lverb|The used formula is disputable, the idea is that A/1 and A should have +% same length.| % \begin{macrocode} \def\xintLen {\romannumeral0\xintlen }% \def\xintlen #1% @@ -22477,18 +23059,23 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{XINT_lenrord_loop}} +% \lverb|& attention que & est comment dans mes \lverb +% Faire \romannumeral`$&$&@\XINT_lenrord_loop 0.{}foobar\Z\W\W\W\W\W\W\W\Z, et +% en sortie on aura : longueur.raboof\Z. C'est une vieille routine, employée +% uniquement par \xintFloat et \XINTinFloat, et uniquement pour des chiffres. +% Donc j'ai plus rapide maintenant mais elle n'est utilisée que pour des +% choses assez courtes, alors à voir.| % \begin{macrocode} -\def\XINT_lenrord_loop #1#2#3#4#5#6#7#8#9% -{% faire \romannumeral`&&@\XINT_lenrord_loop 0{}#1\Z\W\W\W\W\W\W\W\Z +\def\XINT_lenrord_loop #1.#2#3#4#5#6#7#8#9% +{% \xint_gob_til_W #9\XINT_lenrord_W\W - \expandafter\XINT_lenrord_loop\expandafter - {\the\numexpr #1+7}{#9#8#7#6#5#4#3#2}% + \expandafter\XINT_lenrord_loop\the\numexpr #1+\xint_c_vii.{#9#8#7#6#5#4#3#2}% }% -\def\XINT_lenrord_W\W\expandafter\XINT_lenrord_loop\expandafter #1#2#3\Z +\def\XINT_lenrord_W\W\expandafter\XINT_lenrord_loop #1.#2#3\Z {% - \expandafter\XINT_lenrord_X\expandafter {#1}#2\Z + \expandafter\XINT_lenrord_X #1.#2\Z }% -\def\XINT_lenrord_X #1#2\Z +\def\XINT_lenrord_X #1.#2\Z {% \XINT_lenrord_Y #2\R\R\R\R\R\R\T {#1}% }% @@ -22503,21 +23090,10 @@ $1$ or $-1$. #2\XINT_lenrord_Z \xint_c_iii \W\XINT_lenrord_Z \xint_c_ii \Z }% -\def\XINT_lenrord_Z #1#2\Z #3% retourne: {longueur}renverse\Z -{% - \expandafter{\the\numexpr #3-#1\relax}% -}% +\def\XINT_lenrord_Z #1#2\Z #3{\the\numexpr #3-#1.}% % \end{macrocode} % \subsection{\csh{XINT_outfrac}} % \lverb|& -% 1.06a version now outputs 0/1[0] and not 0[0] in case of zero. More generally -% all macros have been checked in xintfrac, xintseries, xintcfrac, to make sure -% the output format for fractions was always A/B[n]. (except \xintIrr, -% \xintJrr, \xintRawWithZeros) -% -% The problem with statements like those in the previous paragraph is that it is -% hard to maintain consistencies across relases. -% % Months later (2014/10/22): perhaps I should document what this macro does % before I forget? from {e}{N}{D} it outputs N/D[e], checking in passing if % D=0 or if N=0. It also makes sure D is not < 0. I am not sure but I don't @@ -22561,26 +23137,43 @@ $1$ or $-1$. % 2014/10/22...), before I forget! It prepares the fraction in the internal % format {exponent}{Numerator}{Denominator} where Denominator is at least 1. % -% 2015/10/09: this venerable macro from the early days (1.03, 2013/04/14) has -% gotten a lifting for release 1.2. There were two kinds of issues: +% 2015/10/09: this venerable macro from the very early days (1.03, 2013/04/14) +% has gotten a lifting for release 1.2. There were two kinds of issues: % % 1) use of \W, \Z, \T delimiters was very poor choice as this could clash with % user input, % % 2) the new \XINT_frac_gen handles macros (possibly empty) in the input as % general as \A.\Be\C/\D.\Ee\F. The earlier version would not have expanded -% the \B for example (only \A, \D, \C, \F). -% -% I wanted to make stricter the restricted A/B[N] case, doing no expansion of -% B, but this clashed with some established uses in the documentation like -% 1/\xintiiSqr{...}[0] for example. Thus I maintained it despite overhead of -% having to go over A one more time. Careful also here about potential brace -% removals if one does stuff like #1/#2#3[#4] regarding the #3. And while I -% was at it I added \numexpr parsing of the N, which earlier was restricted to -% be only explicit digits, and I even allowed [] with an empty N. +% the \B or \E: digits after decimal mark were constrained to arise from +% expansion of the first token. Thus the 1.03 original code would have +% expanded only \A, \D, \C, and \F for this input. +% +% This reminded me think I should revisit the remaining earlier +% portions of code, as I was still learning TeX coding when I wrote them. +% +% Also I thought about parsing even faster the A/B[N] input, not expanding B, +% but this turned out to clash with some established uses in the documentation +% such as 1/\xintiiSqr{...}[0]. For the implementation, careful here about +% potential brace removals with parameter patterns such as like #1/#2#3[#4]for +% example. +% +% While I was at it 1.2 added \numexpr parsing of the N, which earlier was +% restricted to be only explicit digits. I allowed [] with empty N, but the +% way I did it in 1.2 with \the\numexpr 0#1 was buggy, as it did not allow #1 +% to be a \count for example or itself a \numexpr (although such inputs were +% not previously allowed, I later turned out to use them in the code itself, +% e.g. the float factorial of version 1.2f). The better way would be +% \the\numexpr#1+\xint_c_ but 1.2f finally does only \the\numexpr #1 and #1 is +% not allowed to be empty. +% +% The 1.2 \XINT_frac_gen had two locations with such a problematic \numexpr +% 0#1 which I replaced for 1.2f with \numexpr#1+\xint_c_. +% +% Note: regarding calling the macro with A[<expression>], the / must be +% suitably hidden for example in \firstofone type constructs. % -% This little event makes me think I should read again other remaining -% portions my early code, as I was still learning TeX coding at that time.| +%| % \begin{macrocode} \def\XINT_inFrac {\romannumeral0\XINT_infrac }% \def\XINT_infrac #1% @@ -22608,21 +23201,30 @@ $1$ or $-1$. \krof #1/#2% }% -\def\XINT_infrac_res_ca #1[#2]/\XINT_W[\XINT_W\XINT_T - {\expandafter{\the\numexpr 0#2}{#1}{1}}% +% \end{macrocode} +% \lverb|An empty [] is not allowed. (this was authorized in 1.2, removed in +% 1.2f). As nobody reads xint documentation, noone will have noticed the +% fleeting possibility.| +% \begin{macrocode} +\def\XINT_infrac_res_ca #1[#2]/\XINT_W[\XINT_W\XINT_T + {\expandafter{\the\numexpr #2}{#1}{1}}% \def\XINT_infrac_res_cb #1/#2[% {\expandafter\XINT_infrac_res_cc\romannumeral`&&@#2~#1[}% -\def\XINT_infrac_res_cc #1~#2[#3]/\XINT_W[\XINT_W\XINT_T - {\expandafter{\the\numexpr 0#3}{#2}{#1}}% +\def\XINT_infrac_res_cc #1~#2[#3]/\XINT_W[\XINT_W\XINT_T + {\expandafter{\the\numexpr #3}{#2}{#1}}% % \end{macrocode} % \subsection{\csh{XINT_frac_gen}} % \lverb|Extended in 1.07 to recognize and accept scientific notation both at -% the numerator and (possible) denominator. Only a lowercase e will do here, but -% uppercase E is possible within an \xintexpr..\relax +% the numerator and (possible) denominator. Only a lowercase e will do here, +% but uppercase E is possible within an \xintexpr..\relax % -% Completely rewritten for 1.2 2015/10/10. It now is able to handles inputs -% such as \A.\Be\C/\D.\Ee\F where each of \A, \B, \D, and \E may need -% \fexpan sion and \C and \F will end up in \numexpr.| +% Completely rewritten for 1.2 2015/10/10. The parsing handles inputs such as +% \A.\Be\C/\D.\Ee\F where each of \A, \B, \D, and \E may need \fexpan sion and +% \C and \F will end up in \numexpr. +% +% 1.2f corrects an issue to allow \C and \F to be \count variable (or +% expressions with \numexpr): 1.2 did a bad \numexpr0#1 which allowed only +% explicit digits for expanded #1.| % \begin{macrocode} \def\XINT_frac_gen #1/#2% {% @@ -22646,16 +23248,24 @@ $1$ or $-1$. \krof #1.#2% }% -\def\XINT_frac_gen_Bb #1e#2e#3\XINT_Z - {\expandafter\XINT_frac_gen_C\the\numexpr 0#2~#1!}% +\def\XINT_frac_gen_Bb #1e#2e#3\XINT_Z + {\expandafter\XINT_frac_gen_C\the\numexpr #2+\xint_c_~#1!}% \def\XINT_frac_gen_Bc #1.#2e% {% \expandafter\XINT_frac_gen_Bd\romannumeral`&&@#2.#1e% }% +% \end{macrocode} +% \lverb|Here in \XINT_frac_gen_Bd, the 1.2 rewrite of \XINT_infrac did +% \the\numexpr0#3-, but if #3 is a \count for example this was bad (although +% such inputs never have been explicitely allowed in the doc). And why this 0? +% to handle empty #3? But empty #3 was fine here. Another bug of 1.2 ! Fixed +% in 1.2f. Same in \XINT_frac_gen_Bb above, with the difference however that +% an empty #2 there indeed had to be handled properly.| +% \begin{macrocode} \def\XINT_frac_gen_Bd #1.#2e#3e#4\XINT_Z {% - \expandafter\XINT_frac_gen_C\the\numexpr 0#3-\romannumeral0\expandafter - \XINT_length_loop + \expandafter\XINT_frac_gen_C\the\numexpr #3-\romannumeral0\expandafter + \XINT_length_loop 0.#1\xint_relax\xint_relax\xint_relax\xint_relax \xint_relax\xint_relax\xint_relax\xint_relax\xint_bye~#2#1!% }% @@ -22706,12 +23316,12 @@ $1$ or $-1$. }% \def\XINT_frac_gen_Gdivbyzero_a #1~#2~% {% - \xintError:DivisionByZero {#2}{#1}{0}% + \xintError:DivisionByZero {#2}{#1}{0}% }% \def\XINT_frac_gen_G #1#2#3~#4~#5~% {% \expandafter\XINT_frac_gen_Ga - \romannumeral0\XINT_num_loop + \romannumeral0\XINT_num_loop #1#5\xint_relax\xint_relax\xint_relax\xint_relax \xint_relax\xint_relax\xint_relax\xint_relax\Z~#3~{#2#4}% }% @@ -22723,6 +23333,7 @@ $1$ or $-1$. \def\XINT_frac_gen_zero 0#1#2#3{{0}{0}{1}}% % \end{macrocode} % \subsection{\csh{XINT_factortens}, \csh{XINT_cuz_cnt}} +% \lverb|Old routines.| % \begin{macrocode} \def\XINT_factortens #1% {% @@ -22819,16 +23430,15 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{XINT_addm_A}} -% \lverb|This is a routine from xintcore 1.0x, which is needed by \xintFloat, -% \XINTinFloat and \xintRound, for the time being. I should moved it here, now -% that xintcore has been entirely rewritten with release 1.2.| +% \lverb|This is a routine from xintcore 1.0x, which is now only needed by +% \xintFloat, \XINTinFloat and \xintRound, for the time being.| % \begin{macrocode} \def\XINT_addm_A #1#2#3#4#5#6% {% - \xint_gob_til_W #3\xint_addm_az\W + \xint_gob_til_W #3\XINT_addm_az\W \XINT_addm_AB #1{#3#4#5#6}{#2}% }% -\def\xint_addm_az\W\XINT_addm_AB #1#2% +\def\XINT_addm_az\W\XINT_addm_AB #1#2% {% \XINT_addm_AC_checkcarry #1% }% @@ -22846,9 +23456,9 @@ $1$ or $-1$. }% \def\XINT_addm_AC_checkcarry #1% {% - \xint_gob_til_zero #1\xint_addm_AC_nocarry 0\XINT_addm_C + \xint_gob_til_zero #1\XINT_addm_AC_nocarry 0\XINT_addm_C }% -\def\xint_addm_AC_nocarry 0\XINT_addm_C #1#2\W\X\Y\Z +\def\XINT_addm_AC_nocarry 0\XINT_addm_C #1#2\W\X\Y\Z {% \expandafter \xint_cleanupzeros_andstop @@ -22863,10 +23473,10 @@ $1$ or $-1$. \def\XINT_addm_C #1#2#3#4#5% {% \xint_gob_til_W - #5\xint_addm_cw - #4\xint_addm_cx - #3\xint_addm_cy - #2\xint_addm_cz + #5\XINT_addm_cw + #4\XINT_addm_cx + #3\XINT_addm_cy + #2\XINT_addm_cz \W\XINT_addm_CD {#5#4#3#2}{#1}% }% \def\XINT_addm_CD #1% @@ -22877,10 +23487,10 @@ $1$ or $-1$. {% \XINT_addm_AC_checkcarry #2{#3#4}% }% -\def\xint_addm_cw - #1\xint_addm_cx - #2\xint_addm_cy - #3\xint_addm_cz +\def\XINT_addm_cw + #1\XINT_addm_cx + #2\XINT_addm_cy + #3\XINT_addm_cz \W\XINT_addm_CD {% \expandafter\XINT_addm_CDw\the\numexpr 1+#1#2#3.% @@ -22889,9 +23499,9 @@ $1$ or $-1$. {% \XINT_addm_end #1#3% }% -\def\xint_addm_cx - #1\xint_addm_cy - #2\xint_addm_cz +\def\XINT_addm_cx + #1\XINT_addm_cy + #2\XINT_addm_cz \W\XINT_addm_CD {% \expandafter\XINT_addm_CDx\the\numexpr 1+#1#2.% @@ -22900,8 +23510,8 @@ $1$ or $-1$. {% \XINT_addm_end #1#3% }% -\def\xint_addm_cy - #1\xint_addm_cz +\def\XINT_addm_cy + #1\XINT_addm_cz \W\XINT_addm_CD {% \expandafter\XINT_addm_CDy\the\numexpr 1+#1.% @@ -22910,7 +23520,7 @@ $1$ or $-1$. {% \XINT_addm_end #1#3% }% -\def\xint_addm_cz\W\XINT_addm_CD #1#2#3{\XINT_addm_end #1#3}% +\def\XINT_addm_cz\W\XINT_addm_CD #1#2#3{\XINT_addm_end #1#3}% \edef\XINT_addm_end #1#2#3#4#5% {\noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4#5\relax}% % \end{macrocode} @@ -23040,6 +23650,7 @@ $1$ or $-1$. \def\XINT_denom_B #1#2#3{\xint_dsh {#3}{#1}}% % \end{macrocode} % \subsection{\csh{xintFrac}} +% \lverb|Useless typesetting macro.| % \begin{macrocode} \def\xintFrac {\romannumeral0\xintfrac }% \def\xintfrac #1% @@ -23150,6 +23761,7 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintREZ}} +% \lverb|Removes trailing zeros from A and B and adjust the N in A/B[N].| % \begin{macrocode} \def\xintREZ {\romannumeral0\xintrez }% \def\xintrez @@ -23185,32 +23797,11 @@ $1$ or $-1$. }% \def\XINT_rez_E #1#2#3{ #3/#2[#1]}% % \end{macrocode} -% \subsection{\csh{xintE}, \csh{xintFloatE}, \csh{XINTinFloatE}} +% \subsection{\csh{xintE}} % \lverb|1.07: The fraction is the first argument contrarily to \xintTrunc and % \xintRound. % -% \xintfE (1.07) and \xintiE (1.09i) are for \xintexpr and cousins. It is quite -% annoying that \numexpr does not know how to deal correctly with a minus sign - -% as prefix: \numexpr -(1)\relax is illegal! (one can do \numexpr 0-(1)\relax). -% -% the 1.07 \xintE puts directly its second argument in a \numexpr. The \xintfE -% first uses \xintNum on it, this is necessary for use in \xintexpr. (but -% one cannot use directly infix notation in the second argument of \xintfE) -% -% 1.09i also adds \xintFloatE and modifies \XINTinFloatfE, although currently -% the latter is only used from \xintfloatexpr hence always with \XINTdigits, it -% comes equipped with its first argument within brackets as the other -% \XINTinFloat... macros. -% -% 1.09m ceases here and elsewhere, also in \xintcfracname, to use \Z as -% delimiter in the code for the optional argument, as this is unsafe (it -% makes impossible to the user to employ \Z as argument to the macro). -% Replaced by \xint_relax. 1.09e had already done that in \xintSeq, but -% this should have been systematic. -% -% 1.1 modifies and moves \xintiiE to xint.sty, and cleans up some unneeded -% stuff, now that expressions implement scientific notation directly at the -% number parsing level.| +% 1.1 modifies and moves \xintiiE to xint.sty.| % \begin{macrocode} \def\xintE {\romannumeral0\xinte }% \def\xinte #1% @@ -23219,46 +23810,11 @@ $1$ or $-1$. }% \def\XINT_e #1#2#3#4% {% - \expandafter\XINT_e_end\expandafter{\the\numexpr #1+#4}{#2}{#3}% -}% -\def\XINT_e_end #1#2#3{ #2/#3[#1]}% -\def\xintFloatE {\romannumeral0\xintfloate }% -\def\xintfloate #1{\XINT_floate_chkopt #1\xint_relax }% -\def\XINT_floate_chkopt #1% -{% - \ifx [#1\expandafter\XINT_floate_opt - \else\expandafter\XINT_floate_noopt - \fi #1% + \expandafter\XINT_e_end\the\numexpr #1+#4.{#2}{#3}% }% -\def\XINT_floate_noopt #1\xint_relax -{% - \expandafter\XINT_floate_a\expandafter\XINTdigits - \romannumeral0\XINT_infrac {#1}% -}% -\def\XINT_floate_opt [\xint_relax #1]#2% -{% - \expandafter\XINT_floate_a\expandafter - {\the\numexpr #1\expandafter}\romannumeral0\XINT_infrac {#2}% -}% -\def\XINT_floate_a #1#2#3#4#5% -{% - \expandafter\expandafter\expandafter\XINT_float_a - \expandafter\xint_exchangetwo_keepbraces\expandafter - {\the\numexpr #2+#5}{#1}{#3}{#4}\XINT_float_Q -}% -\def\XINTinFloatE {\romannumeral0\XINTinfloate }% -\def\XINTinfloate {\expandafter\XINT_infloate\romannumeral0\XINTinfloat [\XINTdigits]}% -\def\XINT_infloate #1[#2]#3% - {\expandafter\XINT_infloate_end\expandafter {\the\numexpr #3+#2}{#1}}% -\def\XINT_infloate_end #1#2{ #2[#1]}% +\def\XINT_e_end #1.#2#3{ #2/#3[#1]}% % \end{macrocode} % \subsection{\csh{xintIrr}} -% \lverb|& -% 1.04 fixes a buggy \xintIrr {0}. -% 1.05 modifies the initial parsing and post-processing to use \xintrawwithzeros -% and to -% more quickly deal with an input denominator equal to 1. 1.08 version does -% not remove a /1 denominator.| % \begin{macrocode} \def\xintIrr {\romannumeral0\xintirr }% \def\xintirr #1% @@ -23305,9 +23861,9 @@ $1$ or $-1$. }% \def\XINT_irr_loop_e #1#2\Z {% - \xint_gob_til_zero #1\xint_irr_loop_exit0\XINT_irr_loop_a {#1#2}% + \xint_gob_til_zero #1\XINT_irr_loop_exit0\XINT_irr_loop_a {#1#2}% }% -\def\xint_irr_loop_exit0\XINT_irr_loop_a #1#2#3#4% +\def\XINT_irr_loop_exit0\XINT_irr_loop_a #1#2#3#4% {% \expandafter\XINT_irr_loop_exitb\expandafter {\romannumeral0\xintiiquo {#3}{#2}}% @@ -23320,8 +23876,6 @@ $1$ or $-1$. \def\XINT_irr_finish #1#2#3{#3#1/#2}% changed in 1.08 % \end{macrocode} % \subsection{\csh{xintifInt}} -% \lverb|1.09e. xintfrac.sty only. Fixed in 1.1 to not use \xintIrr anymore -% as it was really stupid overhead.| % \begin{macrocode} \def\xintifInt {\romannumeral0\xintifint }% \def\xintifint #1{\expandafter\XINT_ifint\romannumeral0\xintrawwithzeros {#1}.}% @@ -23335,9 +23889,6 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintJrr}} -% \lverb|& -% Modified similarly as \xintIrr in release 1.05. 1.08 version does -% not remove a /1 denominator.| % \begin{macrocode} \def\xintJrr {\romannumeral0\xintjrr }% \def\xintjrr #1% @@ -23394,9 +23945,9 @@ $1$ or $-1$. }% \def\XINT_jrr_loop_e #1#2\Z {% - \xint_gob_til_zero #1\xint_jrr_loop_exit0\XINT_jrr_loop_a {#1#2}% + \xint_gob_til_zero #1\XINT_jrr_loop_exit0\XINT_jrr_loop_a {#1#2}% }% -\def\xint_jrr_loop_exit0\XINT_jrr_loop_a #1#2#3#4#5#6% +\def\XINT_jrr_loop_exit0\XINT_jrr_loop_a #1#2#3#4#5#6% {% \XINT_irr_finish {#3}{#4}% }% @@ -23424,42 +23975,7 @@ $1$ or $-1$. \def\XINT_tfrac_P #1/#2\Z {\expandafter\XINT_rez_AB \romannumeral0\xintiirem{#1}{#2}\Z {0}{#2}}% % \end{macrocode} -% \subsection{\csh{XINTinFloatFracdigits}} -% \lverb|1.09i, for frac in \xintfloatexpr. This version computes -% exactly from the input the fractional part and then only converts it -% into a float with the asked-for number of digits. I will have to think -% it again some day, certainly. -% -% 1.1 removes optional argument for which there was anyhow no interface, for -% technical reasons having to do with \xintNewExpr. -% -% 1.1a renames the macro as \XINTinFloatFracdigits (from \XINTinFloatFrac) to -% be synchronous with the \XINTinFloatSqrt and \XINTinFloat habits related to -% \xintNewExpr problems. -% -% Note to myself: I still have to rethink the whole thing about what is the best -% to do, the initial way of going through \xinttfrac was just a first -% implementation.| -% \begin{macrocode} -\def\XINTinFloatFracdigits {\romannumeral0\XINTinfloatfracdigits }% -\def\XINTinfloatfracdigits #1% -{% - \expandafter\XINT_infloatfracdg_a\expandafter {\romannumeral0\xinttfrac{#1}}% -}% -\def\XINT_infloatfracdg_a {\XINTinfloat [\XINTdigits]}% -% \end{macrocode} % \subsection{\csh{xintTrunc}, \csh{xintiTrunc}} -% \lverb|& -% Modified in 1.06 to give the first argument to a \numexpr. -% -% 1.09f fixes the overhead added in 1.09a to some inner routines when \xintiquo -% was redefined to use \xintnum. Now uses \xintiiquo, rather. -% -% 1.09j: minor improvements, \XINT_trunc_E was very strange and defined two -% never occuring branches; also, optimizes the call to the division routine, and -% the zero loops. -% -% 1.1 adds \xintTTrunc as a shortcut to what \xintiTrunc 0 does, and maps \xintNum to it.| % \begin{macrocode} \def\xintTrunc {\romannumeral0\xinttrunc }% \def\xintiTrunc {\romannumeral0\xintitrunc }% @@ -23507,13 +24023,13 @@ $1$ or $-1$. \def\XINT_trunc_C #1#2#3% {% \expandafter\XINT_trunc_CE\expandafter - {\romannumeral0\XINT_dsx_zeroloop {-#1}{}\Z {#3}}{#2}% + {\romannumeral0\XINT_dsx_zeroloop -#1.{}\Z {#3}}{#2}% }% \def\XINT_trunc_CE #1#2{\XINT_trunc_E #2.{#1}}% \def\XINT_trunc_D #1#2% {% \expandafter\XINT_trunc_E - \romannumeral0\XINT_dsx_zeroloop {#1}{}\Z {#2}.% + \romannumeral0\XINT_dsx_zeroloop #1.{}\Z {#2}.% }% \def\XINT_trunc_E #1% {% @@ -23556,12 +24072,13 @@ $1$ or $-1$. \def\XINT_trunc_Hb #1#2#3% {% \expandafter #3\expandafter0\expandafter.% - \romannumeral0\XINT_dsx_zeroloop {#1}{}\Z {}#2% #1=-0 autoris\'e ! + \romannumeral0\XINT_dsx_zeroloop #1.{}\Z {}#2% #1=-0 autoris\'e ! }% % \end{macrocode} % \subsection{\csh{xintTTrunc}} % \lverb|1.1, a tiny bit more efficient than doing \xintiTrunc0. I map \xintNum -% to it, and I use it in \xintexpr for various things. Faster I guess than the \xintiFloor.| +% to it, and I use it in \xintexpr for various things. Faster I guess than the +% \xintiFloor.| % \begin{macrocode} \def\xintTTrunc {\romannumeral0\xintttrunc }% \def\xintttrunc #1% @@ -23573,27 +24090,11 @@ $1$ or $-1$. \def\XINT_ttrunc_A #1#2#3{\XINT_trunc_checkifzero {#1}#2\Z {#3}}% % \end{macrocode} % \subsection{\csh{xintNum}} -% \lverb|This extension of the xint original xintNum is added in 1.05, as a -% synonym to \xintIrr, but raising an error when the input does not evaluate to -% an integer. Usable with not too much overhead on integer input as \xintIrr -% checks quickly for a denominator equal to 1 (which will be put there by the -% \XINT_infrac called by \xintrawwithzeros). This way, macros such as \xintQuo -% can be modified with minimal overhead to accept fractional input as long as -% it evaluates to an integer. -% -% 22 june 2014 (dev 1.1) I just don't understand what was the point of going through -% \xintIrr if to raise an arror afterwards... and raising errors is silly, so -% let's do it sanely at last. In between I added \xintiFloor, thus, let's just -% let it to it. -% -% 24 october 2014 (final 1.1) (I left it taking dust since -% June...), I did \xintTTrunc, and will thus map \xintNum to it| % \begin{macrocode} \let\xintNum \xintTTrunc \let\xintnum \xintttrunc % \end{macrocode} % \subsection{\csh{xintRound}, \csh{xintiRound}} -% \lverb|Modified in 1.06 to give the first argument to a \numexpr.| % \begin{macrocode} \def\xintRound {\romannumeral0\xintround }% \def\xintiRound {\romannumeral0\xintiround }% @@ -23741,8 +24242,8 @@ $1$ or $-1$. }% \def\XINT_xtrunc_zero .#1#2#3#4#5% {% - 0.\romannumeral0\expandafter\XINT_dsx_zeroloop\expandafter - {\the\numexpr #5}{}\Z {}% + 0.\romannumeral0\expandafter\XINT_dsx_zeroloop + \the\numexpr #5.{}\Z {}% \xintiloop [#4+-1] \ifnum \xintiloopindex>\xint_c_ 0000000000000000000000000000000000000000000000000000000000000000% @@ -23808,12 +24309,12 @@ $1$ or $-1$. \def\XINT_xtrunc_negNDa #1#2% {% \expandafter\XINT_xtrunc_negNDb% - \romannumeral0\XINT_split_fromleft_loop {#1}{}#2\W\W\W\W\W\W\W\W\Z + \romannumeral0\XINT_split_fromleft_loop #1.{}#2\W\W\W\W\W\W\W\W\Z }% -\def\XINT_xtrunc_negNDb #1#2{#1.#2}% +\def\XINT_xtrunc_negNDb #1.#2.{#1.#2}% \def\XINT_xtrunc_negNE #1#2% {% - 0.\romannumeral0\XINT_dsx_zeroloop {-#1}{}\Z {}#2% + 0.\romannumeral0\XINT_dsx_zeroloop -#1.{}\Z {}#2% }% % \end{macrocode} % \lverb+#1=D-|N|<=0, #2=|N|, #3=D, #4=R, #5=B, #6=Q+ @@ -23828,11 +24329,10 @@ $1$ or $-1$. \expandafter\XINT_xtrunc_negNC\expandafter {\the\numexpr\xintLength {#1}-#2}{#1}% }% -%%%%%%%%%%%% \def\XINT_xtrunc_BisOne #1#2#3#4#5#6#7% {% - #5.\romannumeral0\expandafter\XINT_dsx_zeroloop\expandafter - {\the\numexpr #7}{}\Z {}% + #5.\romannumeral0\expandafter\XINT_dsx_zeroloop + \the\numexpr #7.{}\Z {}% \xintiloop [#6+-1] \ifnum \xintiloopindex>\xint_c_ 0000000000000000000000000000000000000000000000000000000000000000% @@ -23841,18 +24341,17 @@ $1$ or $-1$. \def\XINT_xtrunc_BisTwo #1#2#3#4#5#6#7% {% \xintHalf {#5}.\ifodd\xintiiLDg{#5} 5\else 0\fi - \romannumeral0\expandafter\XINT_dsx_zeroloop\expandafter - {\the\numexpr #7-\xint_c_i}{}\Z {}% + \romannumeral0\expandafter\XINT_dsx_zeroloop + \the\numexpr #7-\xint_c_i.{}\Z {}% \xintiloop [#6+-1] \ifnum \xintiloopindex>\xint_c_ 0000000000000000000000000000000000000000000000000000000000000000% \repeat }% -%%%%%%%%%%%% \def\XINT_xtrunc_Q #1% {% \expandafter\XINT_xtrunc_prepare - \romannumeral0\XINT_dsx_zeroloop {#1}{}\Z + \romannumeral0\XINT_dsx_zeroloop #1.{}\Z }% \def\XINT_xtrunc_prepare #1.#2#3% {% @@ -23860,7 +24359,6 @@ $1$ or $-1$. {\romannumeral0% \XINT_xtrunc_prepare_a #2\R\R\R\R\R\R\R\R {10}0000001\W !{#2}}{#1}% }% -%%%%%%%%%%%% \def\XINT_xtrunc_prepare_a #1#2#3#4#5#6#7#8#9% {% \xint_gob_til_R #9\XINT_xtrunc_prepare_small\R @@ -23880,7 +24378,6 @@ $1$ or $-1$. \the\numexpr #1/\xint_c_ii\expandafter .\the\numexpr \xint_c_x^viii+#1!% }% -%%%%%%%%%%%% \def\XINT_xtrunc_small_a #1.#2!#3% {% \expandafter\XINT_div_small_b\the\numexpr #1\expandafter @@ -23888,7 +24385,6 @@ $1$ or $-1$. \romannumeral0\XINT_div_small_ba #3\R\R\R\R\R\R\R\R{10}0000001\W #3\XINT_sepbyviii_Z_end 2345678\relax }% -%%%%%%%%%%%% \def\XINT_xtrunc_prepare_b {\expandafter\XINT_xtrunc_prepare_c\romannumeral0\XINT_zeroes_forviii }% \def\XINT_xtrunc_prepare_c #1!% @@ -23917,7 +24413,6 @@ $1$ or $-1$. \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W \X }% -%%%%%%%%%%%% \def\XINT_xtrunc_Pa #1#2% {% \expandafter\XINT_xtrunc_Pb\romannumeral0#1{#2}{#1}% @@ -23936,8 +24431,8 @@ $1$ or $-1$. }% \def\XINT_xtrunc_D #1#2#3% {% - \romannumeral0\expandafter\XINT_dsx_zeroloop\expandafter - {\the\numexpr \xint_c_ii^vi-\xintLength{#1}}{}\Z {}#1% + \romannumeral0\expandafter\XINT_dsx_zeroloop + \the\numexpr \xint_c_ii^vi-\xintLength{#1}.{}\Z {}#1% \XINT_xtrunc_A {#3}{#2}% }% \def\XINT_xtrunc_transition\fi @@ -23946,7 +24441,7 @@ $1$ or $-1$. \fi \ifnum #4=\xint_c_ \XINT_xtrunc_abort\fi \expandafter\XINT_xtrunc_x\expandafter - {\romannumeral0\XINT_dsx_zeroloop {#4}{}\Z {#2}}{#3}{#4}% + {\romannumeral0\XINT_dsx_zeroloop #4.{}\Z {#2}}{#3}{#4}% }% \def\XINT_xtrunc_x #1#2% {% @@ -23954,377 +24449,26 @@ $1$ or $-1$. }% \def\XINT_xtrunc_y #1#2#3% {% - \romannumeral0\expandafter\XINT_dsx_zeroloop\expandafter - {\the\numexpr #3-\xintLength{#1}}{}\Z {}#1% + \romannumeral0\expandafter\XINT_dsx_zeroloop + \the\numexpr #3-\xintLength{#1}.{}\Z {}#1% }% \def\XINT_xtrunc_abort\fi\expandafter\XINT_xtrunc_x\expandafter #1#2#3{\fi}% % \end{macrocode} % \subsection{\csh{xintDigits}} -% \lverb|The mathchardef used to be called \XINT_digits, but for reasons originating in -% \xintNewExpr (and now obsolete), release 1.09a uses \XINTdigits without underscore.| +% \lverb|The mathchardef used to be called \XINT_digits, but for reasons +% originating in \xintNewExpr (and now obsolete), release 1.09a uses +% \XINTdigits without underscore.| % \begin{macrocode} \mathchardef\XINTdigits 16 \def\xintDigits #1#2% {\afterassignment \xint_gobble_i \mathchardef\XINTdigits=}% \def\xinttheDigits {\number\XINTdigits }% % \end{macrocode} -% \subsection{\csh{xintFloat}} -% \lverb|1.07. Completely re-written in 1.08a, with spectacular speed -% gains. The earlier version was seriously silly when dealing with -% inputs having a big power of ten. Again some modifications in 1.08b -% for a better treatment of cases with long explicit numerators or -% denominators.| -% \begin{macrocode} -\def\xintFloat {\romannumeral0\xintfloat }% -\def\xintfloat #1{\XINT_float_chkopt #1\xint_relax }% -\def\XINT_float_chkopt #1% -{% - \ifx [#1\expandafter\XINT_float_opt - \else\expandafter\XINT_float_noopt - \fi #1% -}% -\def\XINT_float_noopt #1\xint_relax -{% - \expandafter\XINT_float_a\expandafter\XINTdigits - \romannumeral0\XINT_infrac {#1}\XINT_float_Q -}% -\def\XINT_float_opt [\xint_relax #1]#2% -{% - \expandafter\XINT_float_a\expandafter - {\the\numexpr #1\expandafter}% - \romannumeral0\XINT_infrac {#2}\XINT_float_Q -}% -\def\XINT_float_a #1#2#3% #1=P, #2=n, #3=A, #4=B -{% - \XINT_float_fork #3\Z {#1}{#2}% #1 = precision, #2=n -}% -\def\XINT_float_fork #1% -{% - \xint_UDzerominusfork - #1-\XINT_float_zero - 0#1\XINT_float_J - 0-{\XINT_float_K #1}% - \krof -}% -\def\XINT_float_zero #1\Z #2#3#4#5{ 0.e0}% -\def\XINT_float_J {\expandafter\xint_minus_thenstop\romannumeral0\XINT_float_K }% -\def\XINT_float_K #1\Z #2% #1=A, #2=P, #3=n, #4=B -{% - \expandafter\XINT_float_L\expandafter - {\the\numexpr\xintLength{#1}\expandafter}\expandafter - {\the\numexpr #2+\xint_c_ii}{#1}{#2}% -}% -\def\XINT_float_L #1#2% -{% - \ifnum #1>#2 - \expandafter\XINT_float_Ma - \else - \expandafter\XINT_float_Mc - \fi {#1}{#2}% -}% -\def\XINT_float_Ma #1#2#3% -{% - \expandafter\XINT_float_Mb\expandafter - {\the\numexpr #1-#2\expandafter\expandafter\expandafter}% - \expandafter\expandafter\expandafter - {\expandafter\xint_firstoftwo - \romannumeral0\XINT_split_fromleft_loop {#2}{}#3\W\W\W\W\W\W\W\W\Z - }{#2}% -}% -\def\XINT_float_Mb #1#2#3#4#5#6% #2=A', #3=P+2, #4=P, #5=n, #6=B -{% - \expandafter\XINT_float_N\expandafter - {\the\numexpr\xintLength{#6}\expandafter}\expandafter - {\the\numexpr #3\expandafter}\expandafter - {\the\numexpr #1+#5}% - {#6}{#3}{#2}{#4}% -}% long de B, P+2, n', B, |A'|=P+2, A', P -\def\XINT_float_Mc #1#2#3#4#5#6% -{% - \expandafter\XINT_float_N\expandafter - {\romannumeral0\xintlength{#6}}{#2}{#5}{#6}{#1}{#3}{#4}% -}% long de B, P+2, n, B, |A|, A, P -\def\XINT_float_N #1#2% -{% - \ifnum #1>#2 - \expandafter\XINT_float_O - \else - \expandafter\XINT_float_P - \fi {#1}{#2}% -}% -\def\XINT_float_O #1#2#3#4% -{% - \expandafter\XINT_float_P\expandafter - {\the\numexpr #2\expandafter}\expandafter - {\the\numexpr #2\expandafter}\expandafter - {\the\numexpr #3-#1+#2\expandafter\expandafter\expandafter}% - \expandafter\expandafter\expandafter - {\expandafter\xint_firstoftwo - \romannumeral0\XINT_split_fromleft_loop {#2}{}#4\W\W\W\W\W\W\W\W\Z - }% -}% |B|,P+2,n,B,|A|,A,P -\def\XINT_float_P #1#2#3#4#5#6#7#8% -{% - \expandafter #8\expandafter {\the\numexpr #1-#5+#2-\xint_c_i}% - {#6}{#4}{#7}{#3}% -}% |B|-|A|+P+1,A,B,P,n -\def\XINT_float_Q #1% -{% - \ifnum #1<\xint_c_ - \expandafter\XINT_float_Ri - \else - \expandafter\XINT_float_Rii - \fi {#1}% -}% -\def\XINT_float_Ri #1#2#3% -{% - \expandafter\XINT_float_Sa - \romannumeral0\xintiiquo {#2}% - {\XINT_dsx_addzerosnofuss {-#1}{#3}}\Z {#1}% -}% -\def\XINT_float_Rii #1#2#3% -{% - \expandafter\XINT_float_Sa - \romannumeral0\xintiiquo - {\XINT_dsx_addzerosnofuss {#1}{#2}}{#3}\Z {#1}% -}% -\def\XINT_float_Sa #1% -{% - \if #19% - \xint_afterfi {\XINT_float_Sb\XINT_float_Wb }% - \else - \xint_afterfi {\XINT_float_Sb\XINT_float_Wa }% - \fi #1% -}% -\def\XINT_float_Sb #1#2\Z #3#4% -{% - \expandafter\XINT_float_T\expandafter - {\the\numexpr #4+\xint_c_i\expandafter}% - \romannumeral`&&@\XINT_lenrord_loop 0{}#2\Z\W\W\W\W\W\W\W\Z #1{#3}{#4}% -}% -\def\XINT_float_T #1#2#3% -{% - \ifnum #2>#1 - \xint_afterfi{\XINT_float_U\XINT_float_Xb}% - \else - \xint_afterfi{\XINT_float_U\XINT_float_Xa #3}% - \fi -}% -\def\XINT_float_U #1#2% -{% - \ifnum #2<\xint_c_v - \expandafter\XINT_float_Va - \else - \expandafter\XINT_float_Vb - \fi #1% -}% -\def\XINT_float_Va #1#2\Z #3% -{% - \expandafter#1% - \romannumeral0\expandafter\XINT_float_Wa - \romannumeral0\XINT_rord_main {}#2% - \xint_relax - \xint_bye\xint_bye\xint_bye\xint_bye - \xint_bye\xint_bye\xint_bye\xint_bye - \xint_relax \Z -}% -\def\XINT_float_Vb #1#2\Z #3% -{% - \expandafter #1% - \romannumeral0\expandafter #3% - \romannumeral0\XINT_addm_A 0{}1000\W\X\Y\Z #2000\W\X\Y\Z \Z -}% -\def\XINT_float_Wa #1{ #1.}% -\def\XINT_float_Wb #1#2% - {\if #11\xint_afterfi{ 10.}\else\xint_afterfi{ #1.#2}\fi }% -\def\XINT_float_Xa #1\Z #2#3#4% -{% - \expandafter\XINT_float_Y\expandafter - {\the\numexpr #3+#4-#2}{#1}% -}% -\def\XINT_float_Xb #1\Z #2#3#4% -{% - \expandafter\XINT_float_Y\expandafter - {\the\numexpr #3+#4+\xint_c_i-#2}{#1}% -}% -\def\XINT_float_Y #1#2{ #2e#1}% -% \end{macrocode} -% \subsection{\csh{xintPFloat}} -% \lverb|1.1| -% \begin{macrocode} -\def\xintPFloat {\romannumeral0\xintpfloat }% -\def\xintpfloat #1{\XINT_pfloat_chkopt #1\xint_relax }% -\def\XINT_pfloat_chkopt #1% -{% - \ifx [#1\expandafter\XINT_pfloat_opt - \else\expandafter\XINT_pfloat_noopt - \fi #1% -}% -\def\XINT_pfloat_noopt #1\xint_relax -{% - \expandafter\XINT_pfloat_a\expandafter\XINTdigits - \romannumeral0\XINTinfloat [\XINTdigits]{#1}% -}% -\def\XINT_pfloat_opt [\xint_relax #1]%#2% -{% - \expandafter\XINT_pfloat_a\expandafter {\the\numexpr #1\expandafter}% - \romannumeral0\XINTinfloat [\numexpr #1\relax]%{#2}% -}% -\def\XINT_pfloat_a #1#2% -{% - \xint_UDzerominusfork - #2-\XINT_pfloat_zero - 0#2\XINT_pfloat_neg - 0-{\XINT_pfloat_pos #2}% - \krof {#1}% -}% -\def\XINT_pfloat_zero #1[#2]{ 0}% -\def\XINT_pfloat_neg - {\expandafter\xint_minus_thenstop\romannumeral0\XINT_pfloat_pos {}}% -\def\XINT_pfloat_pos #1#2#3[#4]% -{% - \ifnum#4>0 \xint_dothis\XINT_pfloat_no\fi - \ifnum#4>\numexpr-#2\relax \xint_dothis\XINT_pfloat_b\fi - \ifnum#4>\numexpr-#2-\xint_c_v\relax \xint_dothis\XINT_pfloat_B\fi - \xint_orthat\XINT_pfloat_no {#2}{#4}{#1#3}% -}% -\def\XINT_pfloat_no #1#2% -{% - \expandafter\XINT_pfloat_no_b\expandafter{\the\numexpr #2+#1-\xint_c_i\relax}% -}% -\def\XINT_pfloat_no_b #1#2{\XINT_pfloat_no_c #2e#1}% -\def\XINT_pfloat_no_c #1{ #1.}% -\def\XINT_pfloat_b #1#2#3% - {\expandafter\XINT_pfloat_c - \romannumeral0\expandafter\XINT_split_fromleft_loop - \expandafter {\the\numexpr #1+#2-\xint_c_i}#3\W\W\W\W\W\W\W\W\Z }% -\def\XINT_pfloat_c #1#2{ #1.#2}% #2 peut \^etre vide -\def\XINT_pfloat_B #1#2#3% - {\expandafter\XINT_pfloat_C - \romannumeral0\XINT_dsx_zeroloop {\numexpr -#1-#2}{}\Z {}#3}% -\def\XINT_pfloat_C { 0.}% -% \end{macrocode} -% \subsection{\csh{XINTinFloat}} -% \lverb|1.07. Completely rewritten in 1.08a for immensely greater efficiency -% when the power of ten is big: previous version had some very serious -% bottlenecks arising from the creation of long strings of zeros, which made -% things such as 2^999999 completely impossible, but now even 2^999999999 with -% 24 significant digits is no problem! Again (slightly) improved in 1.08b. -% -% I decide in 1.09a not to use anymore \romannumeral`-0 mais \romannumeral0 also -% in the float routines, for consistency of style. -% -% Here again some inner macros used the \xintiquo with extra \xintnum overhead -% in 1.09a, 1.09f fixed that to use \xintiiquo for example. -% -% 1.09i added a stupid bug to \XINT_infloat_zero when it changed 0[0] to a silly -% 0/1[0], breaking in particular \xintFloatAdd when one of the argument is zero -% :((( -% -% 1.09j fixes this. Besides, for notational coherence \XINT_inFloat and -% \XINT_infloat have been renamed respectively \XINTinFloat and \XINTinfloat in -% release 1.09j.| -% \begin{macrocode} -\def\XINTinFloat {\romannumeral0\XINTinfloat }% -\def\XINTinfloat [#1]#2% -{% - \expandafter\XINT_infloat_a\expandafter - {\the\numexpr #1\expandafter}% - \romannumeral0\XINT_infrac {#2}\XINT_infloat_Q -}% -\def\XINT_infloat_a #1#2#3% #1=P, #2=n, #3=A, #4=B -{% - \XINT_infloat_fork #3\Z {#1}{#2}% #1 = precision, #2=n -}% -\def\XINT_infloat_fork #1% -{% - \xint_UDzerominusfork - #1-\XINT_infloat_zero - 0#1\XINT_infloat_J - 0-{\XINT_float_K #1}% - \krof -}% -\def\XINT_infloat_zero #1\Z #2#3#4#5{ 0[0]}% -% \end{macrocode} -% \lverb|the 0[0] was stupidly changed to 0/1[0] in 1.09i, with the result -% that the Float addition would crash when an operand was zero.| -% \begin{macrocode} -\def\XINT_infloat_J {\expandafter-\romannumeral0\XINT_float_K }% -\def\XINT_infloat_Q #1% -{% - \ifnum #1<\xint_c_ - \expandafter\XINT_infloat_Ri - \else - \expandafter\XINT_infloat_Rii - \fi {#1}% -}% -\def\XINT_infloat_Ri #1#2#3% -{% - \expandafter\XINT_infloat_S\expandafter - {\romannumeral0\xintiiquo {#2}% - {\XINT_dsx_addzerosnofuss {-#1}{#3}}}{#1}% -}% -\def\XINT_infloat_Rii #1#2#3% -{% - \expandafter\XINT_infloat_S\expandafter - {\romannumeral0\xintiiquo - {\XINT_dsx_addzerosnofuss {#1}{#2}}{#3}}{#1}% -}% -\def\XINT_infloat_S #1#2#3% -{% - \expandafter\XINT_infloat_T\expandafter - {\the\numexpr #3+\xint_c_i\expandafter}% - \romannumeral`&&@\XINT_lenrord_loop 0{}#1\Z\W\W\W\W\W\W\W\Z - {#2}% -}% -\def\XINT_infloat_T #1#2#3% -{% - \ifnum #2>#1 - \xint_afterfi{\XINT_infloat_U\XINT_infloat_Wb}% - \else - \xint_afterfi{\XINT_infloat_U\XINT_infloat_Wa #3}% - \fi -}% -\def\XINT_infloat_U #1#2% -{% - \ifnum #2<\xint_c_v - \expandafter\XINT_infloat_Va - \else - \expandafter\XINT_infloat_Vb - \fi #1% -}% -\def\XINT_infloat_Va #1#2\Z -{% - \expandafter#1% - \romannumeral0\XINT_rord_main {}#2% - \xint_relax - \xint_bye\xint_bye\xint_bye\xint_bye - \xint_bye\xint_bye\xint_bye\xint_bye - \xint_relax \Z -}% -\def\XINT_infloat_Vb #1#2\Z -{% - \expandafter #1% - \romannumeral0\XINT_addm_A 0{}1000\W\X\Y\Z #2000\W\X\Y\Z \Z -}% -\def\XINT_infloat_Wa #1\Z #2#3% -{% - \expandafter\XINT_infloat_X\expandafter - {\the\numexpr #3+\xint_c_i-#2}{#1}% -}% -\def\XINT_infloat_Wb #1\Z #2#3% -{% - \expandafter\XINT_infloat_X\expandafter - {\the\numexpr #3+\xint_c_ii-#2}{#1}% -}% -\def\XINT_infloat_X #1#2{ #2[#1]}% -% \end{macrocode} % \subsection{\csh{xintAdd}} -% \lverb|modified in v1.1. Et aussi 25 juin pour intercepter summand nul.| % \begin{macrocode} \def\xintAdd {\romannumeral0\xintadd }% -\def\xintadd #1{\expandafter\xint_fadd\romannumeral0\xintraw {#1}}% -\def\xint_fadd #1{\xint_gob_til_zero #1\XINT_fadd_Azero 0\XINT_fadd_a #1}% +\def\xintadd #1{\expandafter\XINT_fadd\romannumeral0\xintraw {#1}}% +\def\XINT_fadd #1{\xint_gob_til_zero #1\XINT_fadd_Azero 0\XINT_fadd_a #1}% \def\XINT_fadd_Azero #1]{\xintraw }% \def\XINT_fadd_a #1/#2[#3]#4% {\expandafter\XINT_fadd_b\romannumeral0\xintraw {#4}{#3}{#1}{#2}}% @@ -24348,13 +24492,13 @@ $1$ or $-1$. \def\XINT_fadd_Ba #1#2#3#4#5#6#7% {% \expandafter\XINT_fadd_C\expandafter - {\romannumeral0\XINT_dsx_zeroloop {#1}{}\Z {#6}}% + {\romannumeral0\XINT_dsx_zeroloop #1.{}\Z {#6}}% {#7}{#5}{#4}[#2]% }% \def\XINT_fadd_Bb #1#2#3#4#5#6#7% {% \expandafter\XINT_fadd_C\expandafter - {\romannumeral0\XINT_dsx_zeroloop {-#1}{}\Z {#4}}% + {\romannumeral0\XINT_dsx_zeroloop -#1.{}\Z {#4}}% {#5}{#7}{#6}[#3]% }% \def\XINT_fadd_C #1#2#3% @@ -24416,11 +24560,10 @@ $1$ or $-1$. \edef\XINT_fadd_iszero\fi #1[#2]{\noexpand\fi\space 0/1[0]}% ou [#2] originel? % \end{macrocode} % \subsection{\csh{xintSub}} -% \lverb|refait dans 1.1 pour vérifier si summands nuls.| % \begin{macrocode} \def\xintSub {\romannumeral0\xintsub }% -\def\xintsub #1{\expandafter\xint_fsub\romannumeral0\xintraw {#1}}% -\def\xint_fsub #1{\xint_gob_til_zero #1\XINT_fsub_Azero 0\XINT_fsub_a #1}% +\def\xintsub #1{\expandafter\XINT_fsub\romannumeral0\xintraw {#1}}% +\def\XINT_fsub #1{\xint_gob_til_zero #1\XINT_fsub_Azero 0\XINT_fsub_a #1}% \def\XINT_fsub_Azero #1]{\xintopp }% \def\XINT_fsub_a #1/#2[#3]#4% {\expandafter\XINT_fsub_b\romannumeral0\xintraw {#4}{#3}{#1}{#2}}% @@ -24453,11 +24596,10 @@ $1$ or $-1$. \def\XINT_fsum_finished #1\Z #2{ #2}% % \end{macrocode} % \subsection{\csh{xintMul}} -% \lverb|modif 1.1 25-juin-14 pour vérifier plus tôt si nul| % \begin{macrocode} \def\xintMul {\romannumeral0\xintmul }% -\def\xintmul #1{\expandafter\xint_fmul\romannumeral0\xintraw {#1}.}% -\def\xint_fmul #1{\xint_gob_til_zero #1\XINT_fmul_zero 0\XINT_fmul_a #1}% +\def\xintmul #1{\expandafter\XINT_fmul\romannumeral0\xintraw {#1}.}% +\def\XINT_fmul #1{\xint_gob_til_zero #1\XINT_fmul_zero 0\XINT_fmul_a #1}% \def\XINT_fmul_a #1[#2].#3% {\expandafter\XINT_fmul_b\romannumeral0\xintraw {#3}#1[#2.]}% \def\XINT_fmul_b #1{\xint_gob_til_zero #1\XINT_fmul_zero 0\XINT_fmul_c #1}% @@ -24476,12 +24618,17 @@ $1$ or $-1$. \def\XINT_fmul_zero #1.#2{ 0/1[0]}% % \end{macrocode} % \subsection{\csh{xintSqr}} -% \lverb|1.1 modifs comme xintMul| +% \lverb|1.1 modifs comme xintMul. +% +% ARRRRRGGGGGGH! I realize only on 2016/02/29 that this was broken since +% 1.1 of 2014/10/28 due to a typo in \XINT_fsqr_a, which was written +% \xint_fsqr_a :((((((((. My test files are highly deficient... (they test +% only the xint/xintcore version).| % \begin{macrocode} \def\xintSqr {\romannumeral0\xintsqr }% -\def\xintsqr #1{\expandafter\xint_fsqr\romannumeral0\xintraw {#1}}% -\def\xint_fsqr #1{\xint_gob_til_zero #1\XINT_fsqr_zero 0\XINT_fsqr_a #1}% -\def\xint_fsqr_a #1/#2[#3]% +\def\xintsqr #1{\expandafter\XINT_fsqr\romannumeral0\xintraw {#1}}% +\def\XINT_fsqr #1{\xint_gob_til_zero #1\XINT_fsqr_zero 0\XINT_fsqr_a #1}% +\def\XINT_fsqr_a #1/#2[#3]% {% \expandafter\XINT_fsqr_b \expandafter{\the\numexpr #3+#3\expandafter}% @@ -24493,24 +24640,23 @@ $1$ or $-1$. % \end{macrocode} % \subsection{\csh{xintPow}} % \lverb|& -% Modified in 1.06 to give the exponent to a \numexpr. -% -% With 1.07 and for use within the \xintexpr parser, we must allow -% fractions (which are integers in disguise) as input to the exponent, so we -% must have a variant which uses \xintNum and not only \numexpr -% for normalizing the input. Hence the \xintfPow here. -% -% 1.08b: well actually I -% think that with xintfrac.sty loaded the exponent should always be allowed to -% be a fraction giving an integer. So I do as for \xintFac, and remove here the -% duplicated. Then \xintexpr can use the \xintPow as defined here.| +% 1.2f: to be coherent with the "i" convention \xintiPow should parse also its +% exponent via \xintNum when xintfrac.sty is loaded. This was not the case so +% far. Cependant le problème est que le fait d'appliquer \xintNum rend +% impossible certains inputs qui auraient pu être gérès par \numexpr. Le +% \numexpr externe est ici pour intercepter trop grand input. +% | % \begin{macrocode} +\def\xintipow #1#2% +{% + \expandafter\xint_pow\the\numexpr \xintNum{#2}\expandafter.\romannumeral0\xintnum{#1}\Z% +}% \def\xintPow {\romannumeral0\xintpow }% \def\xintpow #1% {% - \expandafter\xint_fpow\expandafter {\romannumeral0\XINT_infrac {#1}}% + \expandafter\XINT_fpow\expandafter {\romannumeral0\XINT_infrac {#1}}% }% -\def\xint_fpow #1#2% +\def\XINT_fpow #1#2% {% \expandafter\XINT_fpow_fork\the\numexpr \xintNum{#2}\relax\Z #1% }% @@ -24544,21 +24690,36 @@ $1$ or $-1$. }% \def\XINT_fpow_pos_B #1#2{\XINT_outfrac {#2}{#1}}% % \end{macrocode} -% \subsection{\csh{xintFac}} -% \lverb|1.07: to be used by the \xintexpr scanner which needs to be able to -% apply \xintFac -% to a fraction which is an integer in disguise; so we use \xintNum and not only -% \numexpr. Je modifie cela dans 1.08b, au lieu d'avoir un \xintfFac -% spécialement pour \xintexpr, tout simplement j'étends \xintFac comme les -% autres macros, pour qu'elle utilise \xintNum. Remarque: bien sûr si on -% n'utilisait pas \xintNum ici, il faudrait que la macro s'appelât \xintiiFac. -% Qui est celle définit dans xintcore.sty. Donc ce n'est pas seulement le -% problème de l'utilisation dans \xintexpr..\relax.| +% \subsection{\csh{xintiFac}} +% \lverb|& +% +% Note pour 1.2f: il y avait un peu de confusion avec \xintFac, \xintiFac, +% \xintiiFac, car \xintiFac aurait dû aussi utiliser \xintNum une fois +% xintfrac.sty chargé ce qu'elle ne faisait pas. \xintNum est nécessaire pour +% gérer des inputs fractionnaires ou avec [N], car il les transforme en entiers +% stricts, et la doc dit que les macros avec "i" l'utilise. Maintenant +% \xintiFac fait la chose correcte. \xintFac est synonyme. +% +% 2015/11/29: NO MORE a \xintFac, only \xintiFac/\xintiiFac.| +% \begin{macrocode} +\def\xintifac #1{\expandafter\XINT_fac_fork\the\numexpr \xintNum{#1}.}% +% \end{macrocode} +% \subsection{\csh{xintiBinomial}} +% \lverb|1.2f. Binomial coefficients.| +% \begin{macrocode} +\def\xintibinomial #1#2% +{% + \expandafter\XINT_binom_pre + \the\numexpr\xintNum{#1}\expandafter.\the\numexpr\xintNum{#2}.% +}% +% \end{macrocode} +% \subsection{\csh{xintiPFactorial}} +% \lverb|1.2f. Partial factorial.| % \begin{macrocode} -\def\xintFac {\romannumeral0\xintfac }% -\def\xintfac #1% +\def\xintipfactorial #1#2% {% - \expandafter\XINT_fac_fork\expandafter{\the\numexpr \xintNum{#1}}% + \expandafter\XINT_pfac_fork + \the\numexpr\xintNum{#1}\expandafter.\the\numexpr\xintNum{#2}.% }% % \end{macrocode} % \subsection{\csh{xintPrd}} @@ -24588,9 +24749,9 @@ $1$ or $-1$. \def\xintDiv {\romannumeral0\xintdiv }% \def\xintdiv #1% {% - \expandafter\xint_fdiv\expandafter {\romannumeral0\XINT_infrac {#1}}% + \expandafter\XINT_fdiv\expandafter {\romannumeral0\XINT_infrac {#1}}% }% -\def\xint_fdiv #1#2% +\def\XINT_fdiv #1#2% {\expandafter\XINT_fdiv_A\romannumeral0\XINT_infrac {#2}#1}% \def\XINT_fdiv_A #1#2#3#4#5#6% {% @@ -24627,7 +24788,8 @@ $1$ or $-1$. % \subsection{\csh{xintMod}} % \lverb|1.1. \xintMod {q1}{q2} computes q2*t(q1/q2) with t(q1/q2) equal to % the truncated division of two arbitrary fractions q1 and q2. We put some -% efforts into minimizing the amount of computations.| +% efforts into minimizing the amount of computations. Oui, et bien cela aurait +% été bien si j'avais aussi daigné commenté ce que je faisais.| % \begin{macrocode} \def\xintMod {\romannumeral0\xintmod }% \def\xintmod #1{\expandafter\XINT_mod_a\romannumeral0\xintraw{#1}.}% @@ -24666,20 +24828,9 @@ $1$ or $-1$. }% \def\XINT_mod_pos_a #1.#2#3#4{\xintiirem {#3}{#4}/#2[#1]}% % \end{macrocode} -% \subsection{\csh{XINTinFloatMod}} -% \lverb|Pour emploi dans xintexpr 1.1| -% \begin{macrocode} -\def\XINTinFloatMod {\romannumeral0\XINTinfloatmod [\XINTdigits]}% -\def\XINTinfloatmod [#1]#2#3{\expandafter\XINT_infloatmod\expandafter - {\romannumeral0\XINTinfloat[#1]{#2}}% - {\romannumeral0\XINTinfloat[#1]{#3}}{#1}}% -\def\XINT_infloatmod #1#2{\expandafter\XINT_infloatmod_a\expandafter {#2}{#1}}% -\def\XINT_infloatmod_a #1#2#3{\XINTinfloat [#3]{\xintMod {#2}{#1}}}% -% \end{macrocode} % \subsection{\csh{xintIsOne}} -% \lverb|& -% New with 1.09a. Could be more efficient. For fractions with big powers of -% tens, it is better to use \xintCmp{f}{1}. Restyled in 1.09i.| +% \lverb|New with 1.09a. Could be more efficient. For fractions with big +% powers of tens, it is better to use \xintCmp{f}{1}. Restyled in 1.09i.| % \begin{macrocode} \def\xintIsOne {\romannumeral0\xintisone }% \def\xintisone #1{\expandafter\XINT_fracisone @@ -24688,16 +24839,13 @@ $1$ or $-1$. {\if0\XINT_Cmp {#1}{#2}\xint_afterfi{ 1}\else\xint_afterfi{ 0}\fi}% % \end{macrocode} % \subsection{\csh{xintGeq}} -% \lverb|& -% Rewritten completely in 1.08a to be less dumb when comparing fractions having -% big powers of tens.| % \begin{macrocode} \def\xintGeq {\romannumeral0\xintgeq }% \def\xintgeq #1% {% - \expandafter\xint_fgeq\expandafter {\romannumeral0\xintabs {#1}}% + \expandafter\XINT_fgeq\expandafter {\romannumeral0\xintabs {#1}}% }% -\def\xint_fgeq #1#2% +\def\XINT_fgeq #1#2% {% \expandafter\XINT_fgeq_A \romannumeral0\xintabs {#2}#1% }% @@ -24747,15 +24895,13 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintMax}} -% \lverb|& -% Rewritten completely in 1.08a.| % \begin{macrocode} \def\xintMax {\romannumeral0\xintmax }% \def\xintmax #1% {% - \expandafter\xint_fmax\expandafter {\romannumeral0\xintraw {#1}}% + \expandafter\XINT_fmax\expandafter {\romannumeral0\xintraw {#1}}% }% -\def\xint_fmax #1#2% +\def\XINT_fmax #1#2% {% \expandafter\XINT_fmax_A\romannumeral0\xintraw {#2}#1% }% @@ -24799,15 +24945,13 @@ $1$ or $-1$. \def\XINT_maxof_e #1\Z #2\Z { #2}% % \end{macrocode} % \subsection{\csh{xintMin}} -% \lverb|& -% Rewritten completely in 1.08a.| % \begin{macrocode} \def\xintMin {\romannumeral0\xintmin }% \def\xintmin #1% {% - \expandafter\xint_fmin\expandafter {\romannumeral0\xintraw {#1}}% + \expandafter\XINT_fmin\expandafter {\romannumeral0\xintraw {#1}}% }% -\def\xint_fmin #1#2% +\def\XINT_fmin #1#2% {% \expandafter\XINT_fmin_A\romannumeral0\xintraw {#2}#1% }% @@ -24851,15 +24995,13 @@ $1$ or $-1$. \def\XINT_minof_e #1\Z #2\Z { #2}% % \end{macrocode} % \subsection{\csh{xintCmp}} -% \lverb|Rewritten completely in 1.08a to be less dumb when comparing -% fractions having big powers of tens.| % \begin{macrocode} %\def\xintCmp {\romannumeral0\xintcmp }% \def\xintcmp #1% {% - \expandafter\xint_fcmp\expandafter {\romannumeral0\xintraw {#1}}% + \expandafter\XINT_fcmp\expandafter {\romannumeral0\xintraw {#1}}% }% -\def\xint_fcmp #1#2% +\def\XINT_fcmp #1#2% {% \expandafter\XINT_fcmp_A\romannumeral0\xintraw {#2}#1% }% @@ -24946,26 +25088,729 @@ $1$ or $-1$. \def\xintsgn #1{\expandafter\XINT_sgn\romannumeral0\xintraw {#1}\Z }% % \end{macrocode} % \subsection{Floating point macros} -% \begin{framed} -% 1.2 release has not touched the floating point routines apart from adding -% the new \csh{xintFloatFac}.(*) The others should be revised for some -% optimizations related to the underlying model of the new core routines. -% This is particularly the case for \csh{xintFloatPow} and -% \csh{xintFloatPower} which should keep intermediate results in a suitable -% format, like \csh{xintiiPow} does. -% -% The switch to 1.2 was smooth (apart from the writing up of the new -% \csh{xintFloatFac}), as I didn't have to change a single line of code -% anywhere here ! -% -% (*) note 2015/11/19: the |1.2| \csh{xintFloatFac} had the bug not to -% normalize its input via \csh{xintNum}, using only \csh{numexpr}. Fixed in -% 1.2e. -% \end{framed} -% +% For a long time the float routines from releases |1.07/1.08a| (May-June +% 2013) were not modified. +% +% |1.2| release did not touch either the floating point routines apart from +% adding the new \csh{xintFloatFac}. +% +% +% |1.2f| added \csh{xintFloatPFactorial} and \csh{xintFloatBinomial} and +% improved the speed of |\xintFloatPow| and |\xintFloatPower|. And its +% |\xintFloat| tries to be more efficient in handling inputs which are not +% fractions to start with. +% +% But some parts of the code in |\xintFloat| are still in the pre-|1.2| style +% and could be improved, anyhow in the future quite probably \xintfracnameimp +% will have to adopt an inner format for floats with for example their +% precision P as a visible data first in front and things will have to be +% modified again. +% +% Next major release will have made fondamental decisions regarding the +% handling of inputs having originally more than the target precision, or even +% worse are expressed as fractions. +% +% Currently |\xintFloat| still handles fractional input |A/B| via an initial +% replacement to |A'/B'| (up to powers of ten) with |A'| and |B'| the |A| and +% |B| truncated to P+2 digits. In the future |\xintFloat| will produce the +% correctly rounded value with P digits of precision independently of the +% fraction representative |A/B|, which is not the case with the current +% procedure. +% +% But already |1.2f| has changed an important aspect: the four operations +% first round their arguments to P-floats, not (P+2)-floats as earlier. +% +% +% +% +% \subsection{\csh{xintFloat}} +% \lverb|1.07. May 2013. The original macro did the exact rounding of the input +% fraction to P digits of float precision. +% +% It was completely re-written in 1.08a (June 2013), with "spectacular speed +% gains", so said my comment back then and further: "The earlier version was +% seriously silly when dealing with inputs having a big power of ten. Again +% some modifications in 1.08b for a better treatment of cases with long +% explicit numerators or denominators." +% +% 2015/12. I finally add more comments two years later (for 1.2f). +% +% The important thing I had forgotten to document was that the initial 1.07 +% version did the *exact* rounding of fractional inputs A/B whereas the 1.08 +% version **first truncated A and B to P+2 digits**: to round A/B 10^n to P +% digits of precision the routine first truncates A and B to P+2 digits and +% after that does the exact rounding of A/B. Naturally this means that it may +% then not necessarily compute the correct rounding of A/B. +% +% Example : \xintFloat {1/17597472569900621233}$newline +% with xintfrac 1.07: 5.682634230727187e-20$newline +% with xintfrac 1.08b or later: 5.682634230727188e-20$newline +% and the exact value is 5.682634230727187499924124...e-20. +% +% 1.07 computed the exact rounding for all inputs but as explained from 1.08 +% on, \xintFloat first truncates the denominator to 16+2=18 digits, and here +% this increases 1/x enough to make the final rounding produce a result 1ulp +% higher. +% +% In fact already dropping the last digit is enough to make the quotient cross +% the border:$newline +% 1/17597472569900621233=5.682634230727187499924124...e-20$newline +% 1/1759747256990062123 =56.82634230727187500892894...e-20 +% +% 1.2f did some minor improvements to the code, there was in particular a +% never-used branch. And it tries to handle more swiftly the case of inputs +% which are not fractions. +% +% This routine uses old macros \XINT_addm_a and \XINT_lenrord_loop. This could +% now be penalizing for P exceeding a few dozens, compared to doing it the 1.2 +% way. +% +% I have always hesitated about the policy of printing 10.00...0 in case of +% rounding upwards towards next power of ten. It does make sense because it +% tells the (higher) precision of the rounding and moreover it is not to hard +% easy to test on output, although it is a bit cumbersome not to be certain to +% have exactly P digits. +% +% New: since 1.2f \XINTinFloat (which is the variant of \xintFloat used by +% float macros when they need to round their input or round some pre-final +% result) always guarantees that A exactly has P digits. This simplifies +% things; and goes hand in hand with the fact that I have decided float macros +% should not aim like MPFR at correct rounding from the exact inputs, but only +% from inputs rounded to target precision P. +% +% | +% \begin{macrocode} +\def\xintFloat {\romannumeral0\xintfloat }% +\def\xintfloat #1{\XINT_float_chkopt #1\xint_relax }% +\def\XINT_float_chkopt #1% +{% + \ifx [#1\expandafter\XINT_float_opt + \else\expandafter\XINT_float_noopt + \fi #1% +}% +\def\XINT_float_noopt #1\xint_relax +{% + \expandafter\XINT_float_a\expandafter\XINTdigits\expandafter.% + \romannumeral0\XINT_infrac {#1}\XINT_float_Q +}% +\def\XINT_float_opt [\xint_relax #1]#2% +{% + \expandafter\XINT_float_a\the\numexpr #1\expandafter.% + \romannumeral0\XINT_infrac {#2}\XINT_float_Q +}% +% \end{macrocode} +% \lverb|Note 2015/12/02. Le but de ce code de 1.08 (2013), jusqu'à +% l'exécution de \XINT_float_Q, est simplement de tronquer numérateur et +% dénominateur à au plus P+2 chiffres en ajustant la partie décimale "n". +% | +% \begin{macrocode} +\def\XINT_float_a #1.#2#3% #1=P, #2=n, #3=A, #4=B +{% + \XINT_float_fork #3\Z {#1}{#2}% #1 = precision, #2=n +}% +% \end{macrocode} +% \lverb?A\Z {P}{n}{B}\XINT_float_Q? +% \begin{macrocode} +\def\XINT_float_fork #1% +{% + \xint_UDzerominusfork + #1-\XINT_float_zero + 0#1\XINT_float_J + 0-{\XINT_float_K #1}% + \krof +}% +\def\XINT_float_zero #1\Z #2#3#4#5{ 0.e0}% +\def\XINT_float_J {\expandafter\xint_minus_thenstop\romannumeral0\XINT_float_K }% +\def\XINT_float_K #1\Z #2% #1=A, #2=P, #3=n, #4=B +{% + \expandafter\XINT_float_L + \the\numexpr\xintLength{#1}\expandafter.\the\numexpr #2+\xint_c_ii.{#1}{#2}% +}% +% \end{macrocode} +% \lverb?|A|.P+2.{A}{P}{n}{B}\XINT_float_Q. We check if A already has length +% <= P+2.? +% \begin{macrocode} +\def\XINT_float_L #1.#2.% +{% + \ifnum #1>#2 + \expandafter\XINT_float_Ma + \else + \expandafter\XINT_float_Mb + \fi #1.#2.% +}% +% \end{macrocode} +% \lverb?|A|.P+2.{A}{P}{n}{B}\XINT_float_Q. We will keep only the first P+2 +% digits of A. We use A' for notation.? +% \begin{macrocode} +\def\XINT_float_Ma #1.#2.#3% +{% + \expandafter\XINT_float_MatoN + \the\numexpr #1-#2\expandafter.% + \romannumeral0\XINT_split_fromleft_loop #2.{}#3\W\W\W\W\W\W\W\W\Z + {#2}% +}% +% \end{macrocode} +% \lverb?|A|-(P+2).{A'=P+2 premiers chiffres de +% A}.{junk}.{P+2}{P}{n}{B}\XINT_float_Q devient +% |B|.n'=n+|A|-(P+2).P+2.{B}{P+2}{A'}{P}. Car ici P+2=|A'|.? +% \begin{macrocode} +\def\XINT_float_MatoN #1.#2.#3.#4#5#6#7% +{% + \expandafter\XINT_float_N + \the\numexpr\xintLength{#7}\expandafter.\the\numexpr #1+#6.#4.% + {#7}{#4}{#2}{#5}% +}% +% \end{macrocode} +% \lverb?Dans cette branche A'=A. En entrée |A|.P+2.{A}{P}{n}{B}, en sortie +% |B|.n.P+2.{B}{|A|}{A}{P}? +% \begin{macrocode} +\def\XINT_float_Mb #1.#2.#3#4#5#6% +{% + \expandafter\XINT_float_N + \romannumeral0\xintlength{#6}.#5.#2.{#6}{#1}{#3}{#4}% +}% +% \end{macrocode} +% \lverb?Ce qu'on a fait avec A on le fait maintenant avec B. Mais on va +% repérer B=1 avant de faire une division.$newline +% En entrée: |B|.n'.P+2.{B}{|A'|}{A'}{P}\XINT_float_Q? +% \begin{macrocode} +\def\XINT_float_N #1.#2.#3.% +{% + \ifnum #1>#3 \xint_dothis\XINT_float_N_Blong\fi + \ifnum #1=\xint_c_i\xint_dothis\XINT_float_N_Bshort\fi + \xint_orthat{\XINT_float_P 0.}% + #1.#2.#3.% +}% +% \end{macrocode} +% \lverb?Ici B est de longueur > P+2. On va le tronquer. En entrée #1=|B|, +% #2=n', #3=P+2, #4=B. En sortie: +% n''=n'-(|B|-(P+2)).{B'}{junk}{P+2}? +% \begin{macrocode} +\def\XINT_float_N_Blong #1.#2.#3.#4% +{% + \expandafter\XINT_float_NaP + \the\numexpr #2-#1+#3\expandafter.% + \romannumeral0\XINT_split_fromleft_loop #3.{}#4\W\W\W\W\W\W\W\W\Z {#3}% +}% +% \end{macrocode} +% \lverb?n''=n'-(|B|-(P+2)).{B'}.{junk}.{P+2}->0.P+2.n''.P+2.{B'}? +% \begin{macrocode} +\def\XINT_float_NaP #1.#2.#3.#4{\XINT_float_P 0.#4.#1.#4.{#2}}% +% \end{macrocode} +% \lverb?Ici B est court, mais on va repérer les cas avec B=1 pour aller plus +% vite.? +% \begin{macrocode} +\def\XINT_float_N_Bshort 1.#1.#2.#3% +{% + \ifnum #3=\xint_c_i \xint_dothis{\XINT_float_P 1.}\fi + \xint_orthat{\XINT_float_P 0.}1.#1.#2.#3% +}% +% \end{macrocode} +% \lverb?Si B est de longueur <= P+2 on arrive ici avec en entrée 0 ou +% 1.|B|.n'.P+2.{B}, sinon avec i.P+2.n''.P+2.{B'}, suivi dans les deux cas par +% {|A'|}{A'}{P} et #9=\XINT_float_Q. On va invoquer \XINT_float_Q, mais on lui +% passe l'indicateur i qui repère le cas B=1 que l'on veut traiter plus +% rapidement (en attendant que j'introduise une vraie notion de type pour les +% flottants; à laquelle je ne pourrai pas échapper bien plus longtemps). On +% aura donc \XINT_float_Q i|B|-|A|+P+1.{A}{B}{P}{n} avec les nouveaux A, B, +% n. Ici on a doit passer au-dessus de A et |A| pour aller chercher #9. +% à revoir car pas satisfaisant.? +% \begin{macrocode} +\def\XINT_float_P #1.#2.#3.#4.#5#6#7#8#9% +{% + \expandafter #9\expandafter#1% + \the\numexpr #2-#6+#4-\xint_c_i.{#7}{#5}{#8}{#3}% +}% +% \end{macrocode} +% \lverb?On arrive ici avec |B|-|A|+P+1.{A}{B}{P}{n}, les A et B étant ceux +% d'origine tronqués à au plus P+2 chiffres, le n a été ajusté si besoin. +% +% On calcule maintenant le quotient euclidien de A 10^{|B|-|A|+P+1} (qui a P+1 +% chiffres de plus que B) par B. Ce quotient Q aura P+1 ou P+2 chiffres. +% +% 2015/12/07: nouveau premier token indicateur i=1 si B=1, i=0 sinon. +% ? +% \begin{macrocode} +\def\XINT_float_Q #1% +{% + \if 1#1\expandafter\XINT_float_Ri\else\expandafter\XINT_float_Rii\fi +}% +\def\XINT_float_Ri #1.#2#3% +{% + \expandafter\XINT_float_Sa + \romannumeral0\XINT_dsx_addzerosnofuss {#1}{#2}\Z {#1}% +}% +\def\XINT_float_Rii #1.#2#3% +{% + \expandafter\XINT_float_Sa + \romannumeral0\xintiiquo{\XINT_dsx_addzerosnofuss {#1}{#2}}{#3}\Z {#1}% +}% +% \end{macrocode} +% \lverb?On a Q\Z {|B|-|A|+P+1}{P}{n}. Comme Q = trunc (A/B 1O^x), +% x=|B|-|A|+P+1, Q peut avoir P+1 ou P+2 chiffres. Ce qui compte c'est qu'il a +% au moins P+1 chiffres. On va examiner si le (P+1)e chiffre est 5. Mais on +% fait une sous-branche pour les cas exceptionnels qui donnent un arrondi est +% vers le haut vers la prochaine puissance de 10. Ceci ne pourra se produire +% que si le premier chiffre significatif de Q est un 9.? +% \begin{macrocode} +\def\XINT_float_Sa #1% +{% + \if #19\xint_dothis {\XINT_float_Sb\XINT_float_Wb }\fi + \xint_orthat {\XINT_float_Sb\XINT_float_Wa }#1% +}% +% \end{macrocode} +% \lverb?En entrée \XINT_float_W(a ou b) Q\Z {|B|-|A|+P+1}{P}{n}. On va +% renverser Q en comptant sa longueur L = P+1 ou P+2 au passage. Pour le +% moment avec la vieille routine \XINT_lenrord_loop mais il faudra voir si je +% modifie cela.? +% \begin{macrocode} +\def\XINT_float_Sb #1#2\Z #3#4% +{% + \expandafter\XINT_float_T + \the\numexpr #4+\xint_c_i\expandafter.% + \romannumeral`&&@\XINT_lenrord_loop 0.{}#2\Z\W\W\W\W\W\W\W\Z #1{#3}{#4}% +}% +% \end{macrocode} +% \lverb?Si L>P+1, c'est que L=P+2, on laisse tomber le chiffre le moins +% significatif de Q. En sortie on a \token Q à l'envers\Z \token +% {|B|-|A|+P+1}{P}{n}? +% \begin{macrocode} +\def\XINT_float_T #1.#2.#3% +{% + \ifnum #2>#1 \xint_dothis{\XINT_float_U\XINT_float_Xb}\fi + \xint_orthat{\XINT_float_U\XINT_float_Xa #3}% +}% +\def\XINT_float_U #1#2% +{% + \ifnum #2<\xint_c_v + \expandafter\XINT_float_Va + \else + \expandafter\XINT_float_Vb + \fi #1% +}% +% \end{macrocode} +% \lverb?Chiffre moins significatif de Q est <5. Suffit de tronquer. On va +% ensuite embrayer soit sur \XINT_float_Xa si on avait P+1 chiffres, soit sur +% \XINT_float_Xb si on en avait P+2. Dans ce cas de troncation, on n'a pas à +% se préoccuper d'un arrondi éventuel vers le haut vers une puissance de dix, +% donc le #3 est ici remplacé par \XINT_float_Wa.? +% \begin{macrocode} +\def\XINT_float_Va #1#2\Z #3% +{% + \expandafter#1% + \romannumeral0\expandafter\XINT_float_Wa + \romannumeral0\XINT_rord_main {}#2% + \xint_relax + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_relax \Z +}% +% \end{macrocode} +% \lverb?Chiffre moins significatif de Q est au moins 5. Faut aussi ajouter 1. +% On utilise la vieille routine d'addition spéciale \XINT_addm_A qui renvoie +% son résultat à l'endroit. De plus on doit ensuite vérifier si l'arrondi +% s'est fait vers la puissance de 10 supérieure. Cela ne peut se produire que +% si le premier chiffre était 9, donc dans ce cas on a #3=\XINT_float_Wb, +% sinon on a #3=\XINT_float_Wa.? +% \begin{macrocode} +\def\XINT_float_Vb #1#2\Z #3% +{% + \expandafter #1% + \romannumeral0\expandafter #3% + \romannumeral0\XINT_addm_A 0{}1000\W\X\Y\Z #2000\W\X\Y\Z \Z +}% +% \end{macrocode} +% \lverb|Wa insère la virgule. Wb regarde si on a arrondi vers le haut vers +% une puissance de 10. Il n'est exécuté que si le premier chiffre était un 9, +% donc il regarde si maintenant le premier chiffre est devenu un 1. Est-il sûr +% que Wb trouve deux chiffres si P=1? Pour n'en avoir qu'un, il faudrait que +% le quotient Q aie eu seulement deux chiffres. Mais si on arrive en Wb le +% premier chiffre était 9 et si Q avait eu seulement deux chiffres il aurait +% été 95 au plus, et ici on serait avec 10 qui ne pose pas de problème.| +% \begin{macrocode} +\def\XINT_float_Wa #1{ #1.}% +\def\XINT_float_Wb #1#2{\if #11\xint_dothis{ 10.}\fi\xint_orthat{ #1.#2}}% +% \end{macrocode} +% \lverb?Il faut faire l'ajustement final de n. On doit regrabber notre +% mantisse, maintenant avec sa virgule. On a {|B|-|A|+P+1}{P}{n} après le \Z. +% On exécute _Xb si le quotient produit avait P+2 chifffres. On n'a pas à +% faire d'ajustement en cas d'arrondi vers un 10.00...0.? +% \begin{macrocode} +\def\XINT_float_Xa #1\Z #2#3#4% +{% + \expandafter\XINT_float_Y\the\numexpr #3+#4-#2.{#1}% +}% +\def\XINT_float_Xb #1\Z #2#3#4% +{% + \expandafter\XINT_float_Y\the\numexpr #3+#4+\xint_c_i-#2.{#1}% +}% +\def\XINT_float_Y #1.#2{ #2e#1}% +% \end{macrocode} +% \subsection{\csh{XINTinFloat}} +% \lverb|1.07. +% +% This routine is like \xintFloat but produces an output of the shape A[N] +% which is then parsed faster on input to other float macros. +% +% For 1.2f I modify it : contrarily to current \xintFloat, in the exceptional +% case of rounding up to a power of ten, it does not produce anymore a +% mantissa 10^P with P+1 digits, but 10^{P-1}. Indeed not knowing for sure the +% number of digits of the mantissa caused various complications in other +% routines, and I really got tired of this. This means however that it is a +% tiny bit slower than earlier. I need to copy over most of the code of +% \xintFloat because sharing is a bit cumbersome. +% +% 2016/03/11. +% 1.2f \XINTinFloat clones somes of the \XINT_infrac start code to handle more +% swiftly inputs of the shape A[N] (still allowing N to be an <expression> for +% \numexpr). This is done without yet introducting a private format for +% floats, as I want to conclude now and doing this would need some extra time. +% +% As this is surgery on pre-existing code where a more complete rewrite would +% be needed it is a bit ugly though. +% +% Each time \XINTinFloat is called it at least computes a length. +% Naturally if we had some format for floats that would be dispensed of... +% Something like <letterP><length of mantissa>.mantissa.exponent, etc... +% +% Not yet. But obviously we can not go one re-parsing each input that way, +% although the situation is better with 1.2f. +% +%| +% \begin{macrocode} +\def\XINTinFloat {\romannumeral0\XINTinfloat }% +\def\XINTinfloat [#1]#2% +{% + \expandafter\XINT_infloat\the\numexpr #1\expandafter.% + \romannumeral0\expandafter\XINT_infloat_in + \romannumeral`&&@#2/\XINT_W[\XINT_W\XINT_T\XINT_infloat_Q +}% +\def\XINT_infloat #1.#2{#2#1.}% +\def\XINT_infloat_in #1[#2% +{% + \xint_UDXINTWfork + #2\XINT_infloat_gen + \XINT_W\XINT_infloat_res_a + \krof + #1[#2% +}% +\edef\XINT_infloat_gen {\noexpand\expandafter\space\noexpand\expandafter + \noexpand\XINT_infloat_a + \noexpand\romannumeral0\noexpand\XINT_frac_gen }% +\def\XINT_infloat_res_a #1% +{% + \xint_gob_til_zero #1\XINT_infloat_res_zero 0\XINT_infloat_res_b #1% +}% +\def\XINT_infloat_res_zero #1\XINT_infloat_Q { \XINT_infloat_sp_zero}% +\def\XINT_infloat_sp_zero #1.{ 0[0]}% +\def\XINT_infloat_res_b #1/#2% +{% + \xint_UDXINTWfork + #2\XINT_infloat_res_ca + \XINT_W\XINT_infloat_res_cb + \krof + #1/#2% +}% +\def\XINT_infloat_res_ca #1[#2]/\XINT_W[\XINT_W\XINT_T\XINT_infloat_Q + { \XINT_infloat_sp #1.#2.}% +\def\XINT_infloat_res_cb #1/#2[% + {\expandafter\XINT_infloat_res_cc\romannumeral`&&@#2~#1[}% +\edef\XINT_infloat_res_cc #1~#2[#3]/\XINT_W[\XINT_W\XINT_T + {\noexpand\expandafter\space\noexpand\expandafter + \noexpand\XINT_infloat_a\noexpand\expandafter + {\noexpand\the\numexpr #3}{#2}{#1}}% +% \end{macrocode} +% \lverb|1.2f adds (2016/03/11) special quick treatment for A[N] inputs.| +% \begin{macrocode} +\def\XINT_infloat_sp #1.#2% +{% + \if-#2\xint_dothis{\expandafter-\romannumeral0\XINT_infloat_sp_a {}}\fi + \xint_orthat{\XINT_infloat_sp_a #2}#1.% +}% +\def\XINT_infloat_sp_a #1#2.#3.% +{% + \expandafter\XINT_infloat_sp_b\the\numexpr#2-\xintLength{#1#3}.#1#3.#2.% +}% +\def\XINT_infloat_sp_b #1% +{% + \xint_UDzerominusfork + #1-\XINT_infloat_sp_quick + 0#1\XINT_infloat_sp_c + 0-{\XINT_infloat_sp_addzeroes #1}% + \krof +}% +\def\XINT_infloat_sp_quick .#1.#2.#3.{ #1[#3]}% +\def\XINT_infloat_sp_addzeroes #1.#2.#3.#4.% +{% + \expandafter\XINT_infloat_sp_done + \the\numexpr #4-#1\expandafter.% + \romannumeral0\XINT_dsx_addzerosnofuss {#1}{#2};% +}% +\def\XINT_infloat_sp_done #1.#2;{ #2[#1]}% +% \end{macrocode} +% \lverb|I should re-use truncating/rounding routines but I wrote them too +% much time ago. Faster to do it again.| +% \begin{macrocode} +\def\XINT_infloat_sp_c #1.#2% +{% + \if #29\xint_dothis {\XINT_infloat_sp_d\XINT_infloat_Wb }\fi + \xint_orthat {\XINT_infloat_sp_d\xint_c_ }#1.#2% +}% +\def\XINT_infloat_sp_d #1#2.#3.#4.%#5.% +{% + \expandafter\XINT_infloat_sp_e + \romannumeral0\expandafter\XINT_split_fromleft_loop + \the\numexpr #4+\xint_c_i.{}#3\W\W\W\W\W\W\W\W\Z #1#2.% +}% +% \end{macrocode} +% \lverb|Still using old Reverse routine because presumably we are handling +% numbers up to a few dozens digits. But a faster \xintReverseDigits is +% available. No time now. +% +% #1=first P+1 digits of A, #2=junk| +% \begin{macrocode} +\def\XINT_infloat_sp_e #1.#2.% +{% + \expandafter\XINT_infloat_sp_f + \romannumeral0\XINT_rord_main {}#1% + \xint_relax + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_relax ;% +}% +\def\XINT_infloat_sp_f #1% +{% + \ifnum #1<\xint_c_v + \expandafter\XINT_infloat_sp_ga\else\expandafter\XINT_infloat_sp_h\fi +}% +\def\XINT_infloat_sp_ga #1;#2#3.#4.% +{% + \expandafter\XINT_infloat_sp_done\the\numexpr #3+#4\expandafter.% + \romannumeral0\XINT_rord_main {}#1% + \xint_relax + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_relax ;% +}% +\def\XINT_infloat_sp_h #1;#2% +{% + \expandafter\XINT_infloat_sp_i + \romannumeral0\expandafter#2% + \romannumeral0\XINT_addm_A 0{}1000\W\X\Y\Z #1000\W\X\Y\Z;% +}% +\def\XINT_infloat_sp_i #1#2;#3.#4.% +{% + \expandafter\XINT_infloat_sp_done\the\numexpr #1+#3+#4.#2;% +}% +% \end{macrocode} +% \lverb|General branch handling A/B[N] inputs. Still, 1.2f identifies faster +% B=1 case.| +% \begin{macrocode} +\def\XINT_infloat_a #1.#2#3% #1=P, #2=n, #3=A, #4=B +{% + \XINT_infloat_fork #3\Z {#1}{#2}% #1 = precision, #2=n +}% +\def\XINT_infloat_fork #1% +{% + \xint_UDzerominusfork + #1-\XINT_infloat_zero + 0#1\XINT_infloat_J + 0-{\XINT_float_K #1}% + \krof +}% +\def\XINT_infloat_zero #1\Z #2#3#4#5{ 0[0]}% +\def\XINT_infloat_J {\expandafter-\romannumeral0\XINT_float_K }% +\def\XINT_infloat_Q #1% +{% + \if 1#1\expandafter\XINT_infloat_Ri\else\expandafter\XINT_infloat_Rii\fi +}% +\def\XINT_infloat_Ri #1.#2#3% +{% + \expandafter\XINT_infloat_Sa + \romannumeral0\XINT_dsx_addzerosnofuss {#1}{#2}\Z {#1}% +}% +\def\XINT_infloat_Rii #1.#2#3% +{% + \expandafter\XINT_infloat_Sa + \romannumeral0\xintiiquo{\XINT_dsx_addzerosnofuss {#1}{#2}}{#3}\Z {#1}% +}% +\def\XINT_infloat_Sa #1% +{% + \if #19\xint_dothis {\XINT_infloat_Sb\XINT_infloat_Wb }\fi + \xint_orthat {\XINT_infloat_Sb\xint_c_ }#1% +}% +\def\XINT_infloat_Sb #1#2\Z #3#4% +{% + \expandafter\XINT_infloat_T + \the\numexpr #4+\xint_c_i\expandafter.% + \romannumeral`&&@\XINT_lenrord_loop 0.{}#2\Z\W\W\W\W\W\W\W\Z #1{#3}% +}% +\def\XINT_infloat_T #1.#2.#3% +{% + \ifnum #2>#1 \xint_dothis{\XINT_infloat_U\XINT_infloat_Xb}\fi + \xint_orthat{\XINT_infloat_U\XINT_infloat_Xa #3}% +}% +\def\XINT_infloat_U #1#2% +{% + \ifnum #2<\xint_c_v + \expandafter\XINT_infloat_Va + \else + \expandafter\XINT_infloat_Vb + \fi #1% +}% +\def\XINT_infloat_Va #1#2\Z #3% +{% + \expandafter#1% + \romannumeral0\expandafter\xint_c_ + \romannumeral0\XINT_rord_main {}#2% + \xint_relax + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_relax \Z +}% +\def\XINT_infloat_Vb #1#2\Z #3% +{% + \expandafter #1% + \romannumeral0\expandafter #3% + \romannumeral0\XINT_addm_A 0{}1000\W\X\Y\Z #2000\W\X\Y\Z \Z +}% +\def\XINT_infloat_Wb #1#2% + {\if #11\xint_dothis{\xint_c_i1}\fi\xint_orthat{\xint_c_#1#2}}% +\def\XINT_infloat_Xa #1#2\Z #3#4% +{% + \expandafter\XINT_infloat_Y\the\numexpr #1+\xint_c_i+#4-#3.{#2}% +}% +\def\XINT_infloat_Xb #1#2\Z #3#4% +{% + \expandafter\XINT_infloat_Y\the\numexpr #1+\xint_c_ii+#4-#3.{#2}% +}% +\def\XINT_infloat_Y #1.#2{ #2[#1]}% +% \end{macrocode} +% \subsection{\csh{xintPFloat}} +% \lverb|1.1. This is a prettifying printing macro for floats. +% +% 2016/03/07. +% +% 1.2f modifies the macro: among the now obsoleted rules there was one which +% told it to employ decimal notation as soon as possible without extra zeroes, +% for example a...z<decimal mark>A...Z if the total length is at most the +% precision, but obviously for large precisions the human eye has difficulties +% with that, this was not a good choice. +% +% +% The new rule is simply that 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. There is the +% exceptional cases where x=10, and yz..=0000.... from rounding up to the next +% power of ten. +% +% | +% \begin{macrocode} +\def\xintPFloat {\romannumeral0\xintpfloat }% +\def\xintpfloat #1{\XINT_pfloat_chkopt #1\xint_relax }% +\def\XINT_pfloat_chkopt #1% +{% + \ifx [#1\expandafter\XINT_pfloat_opt + \else\expandafter\XINT_pfloat_noopt + \fi #1% +}% +\def\XINT_pfloat_noopt #1\xint_relax +{% + \expandafter\XINT_pfloat_a + \romannumeral0\xintfloat [\XINTdigits]{#1};\XINTdigits.% +}% +\def\XINT_pfloat_opt [\xint_relax #1]%#2% +{% + \expandafter\XINT_pfloat_opt_a \the\numexpr #1.% +}% +\def\XINT_pfloat_opt_a #1.#2% +{% + \expandafter\XINT_pfloat_a\romannumeral0\xintfloat [#1]{#2};#1.% +}% +\def\XINT_pfloat_a #1% +{% + \xint_UDzerominusfork + #1-\XINT_pfloat_zero + 0#1\XINT_pfloat_neg + 0-{\XINT_pfloat_pos #1}% + \krof +}% +\def\XINT_pfloat_zero #1;#2.{ 0.}% +\def\XINT_pfloat_neg + {\expandafter\xint_minus_thenstop\romannumeral0\XINT_pfloat_pos }% +\def\XINT_pfloat_pos #1e#2;#3.% +{% + \ifnum #2>\xint_c_v \xint_dothis\XINT_pfloat_no\fi + \ifnum #2<-\xint_c_v \xint_dothis\XINT_pfloat_no\fi + \ifnum #2<\xint_c_ \xint_dothis\XINT_pfloat_N\fi + \ifnum #2>\numexpr #3-\xint_c_i\relax \xint_dothis\XINT_pfloat_Ps\fi + \xint_orthat\XINT_pfloat_P #1e#2;% +}% +\def\XINT_pfloat_no #1;{ #1}% +\def\XINT_pfloat_N #1#2.#3e#4;% +{% + \csname XINT_pfloat_N\romannumeral-#4\endcsname #2#10.#3;% +}% +\def\XINT_pfloat_Ni #1#2#3.#4;{ #2.#1#4}% +\def\XINT_pfloat_Nii #1#2#3.#4;{ 0.#2#1#4}% +\def\XINT_pfloat_Niii#1#2#3.#4;{ 0.0#2#1#4}% +\def\XINT_pfloat_Niv #1#2#3.#4;{ 0.00#2#1#4}% +\def\XINT_pfloat_Nv #1#2#3.#4;{ 0.000#2#1#4}% +\def\XINT_pfloat_P #1#2.#3e#4;% +{% + \csname XINT_pfloat_P_\romannumeral#4\endcsname #3.#1#2;% +}% +\def\XINT_pfloat_P_ #1.#2;{ #2.#1}% +\def\XINT_pfloat_P_i #1#2.#3;{ #3#1.#2}% +\def\XINT_pfloat_P_ii #1#2#3.#4;{ #4#1#2.#3}% +\def\XINT_pfloat_P_iii#1#2#3#4.#5;{ #5#1#2#3.#4}% +\def\XINT_pfloat_P_iv #1#2#3#4#5.#6;{ #6#1#2#3#4.#5}% +\def\XINT_pfloat_P_v #1#2#3#4#5#6.#7;{ #7#1#2#3#4#5.#6}% +\def\XINT_pfloat_Ps #1#2.#3e#4;% +{% + \csname XINT_pfloat_Ps\romannumeral#4\endcsname #300000.#1#2;% +}% +\def\XINT_pfloat_Psi #1#2.#3;{ #3#1.}% +\def\XINT_pfloat_Psii #1#2#3.#4;{ #4#1#2.}% +\def\XINT_pfloat_Psiii#1#2#3#4.#5;{ #5#1#2#3.}% +\def\XINT_pfloat_Psiv #1#2#3#4#5.#6;{ #6#1#2#3#4.}% +\def\XINT_pfloat_Psv #1#2#3#4#5#6.#7;{ #7#1#2#3#4#5.}% +% \end{macrocode} +% \subsection{\csh{XINTinFloatFracdigits}} +% \lverb|1.09i, for frac function in \xintfloatexpr. This version computes +% exactly from the input the fractional part and then only converts it +% into a float with the asked-for number of digits. I will have to think +% it again some day, certainly. +% +% 1.1 removes optional argument for which there was anyhow no interface, for +% technical reasons having to do with \xintNewExpr. +% +% 1.1a renames the macro as \XINTinFloatFracdigits (from \XINTinFloatFrac) to +% be synchronous with the \XINTinFloatSqrt and \XINTinFloat habits related to +% \xintNewExpr problems. +% +% Note to myself: I still have to rethink the whole thing about what is the best +% to do, the initial way of going through \xinttfrac was just a first +% implementation.| +% \begin{macrocode} +\def\XINTinFloatFracdigits {\romannumeral0\XINTinfloatfracdigits }% +\def\XINTinfloatfracdigits #1% +{% + \expandafter\XINT_infloatfracdg_a\expandafter {\romannumeral0\xinttfrac{#1}}% +}% +\def\XINT_infloatfracdg_a {\XINTinfloat [\XINTdigits]}% +% \end{macrocode} % \subsection{\csh{xintFloatAdd}, \csh{XINTinFloatAdd}} -% \lverb|1.07; 1.09ka improves a bit the efficieny of the coding of -% \XINT_FL_Add_d.| +% \lverb|First included in release 1.07. +% +% 1.09ka improved a bit the efficiency. However the add, sub, mul, div +% routines were provisory and supposed to be revised soon. +% +% Which didn't happen until 1.2f. Now, the inputs are first rounded to P +% digits, not P+2 as earlier. +% +% +%| % \begin{macrocode} \def\xintFloatAdd {\romannumeral0\xintfloatadd }% \def\xintfloatadd #1{\XINT_fladd_chkopt \xintfloat #1\xint_relax }% @@ -24979,50 +25824,47 @@ $1$ or $-1$. }% \def\XINT_fladd_noopt #1#2\xint_relax #3% {% - #1[\XINTdigits]{\XINT_FL_Add {\XINTdigits+\xint_c_ii}{#2}{#3}}% + #1[\XINTdigits]% + {\expandafter\XINT_FL_add_a + \romannumeral0\XINTinfloat[\XINTdigits]{#2}\XINTdigits.{#3}}% }% -\def\XINT_fladd_opt #1[\xint_relax #2]#3#4% +\def\XINT_fladd_opt #1[\xint_relax #2]%#3#4% {% - #1[#2]{\XINT_FL_Add {#2+\xint_c_ii}{#3}{#4}}% + \expandafter\XINT_fladd_opt_a\the\numexpr #2.#1% }% -\def\XINT_FL_Add #1#2% +\def\XINT_fladd_opt_a #1.#2#3#4% {% - \expandafter\XINT_FL_Add_a\expandafter{\the\numexpr #1\expandafter}% - \expandafter{\romannumeral0\XINTinfloat [#1]{#2}}% + #2[#1]{\expandafter\XINT_FL_add_a\romannumeral0\XINTinfloat[#1]{#3}#1.{#4}}% }% -\def\XINT_FL_Add_a #1#2#3% +\def\XINT_FL_add_a #1% {% - \expandafter\XINT_FL_Add_b\romannumeral0\XINTinfloat [#1]{#3}#2{#1}% + \xint_gob_til_zero #1\XINT_FL_add_zero 0\XINT_FL_add_b #1% }% -\def\XINT_FL_Add_b #1% +\def\XINT_FL_add_zero #1.#2{#2}% +\def\XINT_FL_add_b #1]#2.#3% {% - \xint_gob_til_zero #1\XINT_FL_Add_zero 0\XINT_FL_Add_c #1% + \expandafter\XINT_FL_add_c\romannumeral0\XINTinfloat[#2]{#3}#2.#1]% }% -\def\XINT_FL_Add_c #1[#2]#3% +\def\XINT_FL_add_c #1% {% - \xint_gob_til_zero #3\XINT_FL_Add_zerobis 0\XINT_FL_Add_d #1[#2]#3% + \xint_gob_til_zero #1\XINT_FL_add_zero 0\XINT_FL_add_d #1% }% -\def\XINT_FL_Add_d #1[#2]#3[#4]#5% +\def\XINT_FL_add_d #1[#2]#3.#4[#5]% {% - \ifnum \numexpr #2-#4-#5>\xint_c_i - \expandafter \xint_secondofthree_thenstop - \else - \ifnum \numexpr #4-#2-#5>\xint_c_i - \expandafter\expandafter\expandafter\xint_thirdofthree_thenstop - \fi - \fi - \xintadd {#1[#2]}{#3[#4]}% + \ifnum\numexpr #2-#3-#5>\xint_c_\xint_dothis\xint_firstoftwo\fi + \ifnum\numexpr #5-#3-#2>\xint_c_\xint_dothis\xint_secondoftwo\fi + \xint_orthat\xintAdd {#1[#2]}{#4[#5]}% }% -\def\XINT_FL_Add_zero 0\XINT_FL_Add_c 0[0]#1[#2]#3{#1[#2]}% -\def\XINT_FL_Add_zerobis 0\XINT_FL_Add_d #1[#2]0[0]#3{#1[#2]}% % \end{macrocode} % \subsection{\csh{xintFloatSub}, \csh{XINTinFloatSub}} -% \lverb|1.07| +% \lverb|First done 1.07. +% +% 1.2f does not use two extra rounding digits on inputs.| % \begin{macrocode} -\def\xintFloatSub {\romannumeral0\xintfloatsub }% +\def\xintFloatSub {\romannumeral0\xintfloatsub }% \def\xintfloatsub #1{\XINT_flsub_chkopt \xintfloat #1\xint_relax }% -\def\XINTinFloatSub {\romannumeral0\XINTinfloatsub }% -\def\XINTinfloatsub #1{\XINT_flsub_chkopt \XINTinfloat #1\xint_relax }% +\def\XINTinFloatSub {\romannumeral0\XINTinfloatsub }% +\def\XINTinfloatsub #1{\XINT_flsub_chkopt \XINTinfloat #1\xint_relax }% \def\XINT_flsub_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flsub_opt @@ -25031,11 +25873,17 @@ $1$ or $-1$. }% \def\XINT_flsub_noopt #1#2\xint_relax #3% {% - #1[\XINTdigits]{\XINT_FL_Add {\XINTdigits+\xint_c_ii}{#2}{\xintOpp{#3}}}% + #1[\XINTdigits]% + {\expandafter\XINT_FL_add_a + \romannumeral0\XINTinfloat[\XINTdigits]{#2}\XINTdigits.{\xintOpp{#3}}}% +}% +\def\XINT_flsub_opt #1[\xint_relax #2]%#3#4% +{% + \expandafter\XINT_flsub_opt_a\the\numexpr #2.#1% }% -\def\XINT_flsub_opt #1[\xint_relax #2]#3#4% +\def\XINT_flsub_opt_a #1.#2#3#4% {% - #1[#2]{\XINT_FL_Add {#2+\xint_c_ii}{#3}{\xintOpp{#4}}}% + #2[#1]{\expandafter\XINT_FL_add_a\romannumeral0\XINTinfloat[#1]{#3}#1.{\xintOpp{#4}}}% }% % \end{macrocode} % \subsection{\csh{xintFloatMul}, \csh{XINTinFloatMul}} @@ -25043,10 +25891,12 @@ $1$ or $-1$. % It is a long-standing issue here that I must at some point revise the code % and avoid compute with 2P digits the exact intermediate result. % \end{framed} -% \lverb|1.07| +% \lverb|1.07. +% +% 1.2f does not use two extra rounding digits on inputs.| % \begin{macrocode} -\def\xintFloatMul {\romannumeral0\xintfloatmul}% -\def\xintfloatmul #1{\XINT_flmul_chkopt \xintfloat #1\xint_relax }% +\def\xintFloatMul {\romannumeral0\xintfloatmul }% +\def\xintfloatmul #1{\XINT_flmul_chkopt \xintfloat #1\xint_relax }% \def\XINTinFloatMul {\romannumeral0\XINTinfloatmul }% \def\XINTinfloatmul #1{\XINT_flmul_chkopt \XINTinfloat #1\xint_relax }% \def\XINT_flmul_chkopt #1#2% @@ -25057,30 +25907,33 @@ $1$ or $-1$. }% \def\XINT_flmul_noopt #1#2\xint_relax #3% {% - #1[\XINTdigits]{\XINT_FL_Mul {\XINTdigits+\xint_c_ii}{#2}{#3}}% + #1[\XINTdigits]% + {\expandafter\XINT_FL_mul_a + \romannumeral0\XINTinfloat[\XINTdigits]{#2}\XINTdigits.{#3}}% }% -\def\XINT_flmul_opt #1[\xint_relax #2]#3#4% +\def\XINT_flmul_opt #1[\xint_relax #2]%#3#4% {% - #1[#2]{\XINT_FL_Mul {#2+\xint_c_ii}{#3}{#4}}% + \expandafter\XINT_flmul_opt_a\the\numexpr #2.#1% }% -\def\XINT_FL_Mul #1#2% +\def\XINT_flmul_opt_a #1.#2#3#4% {% - \expandafter\XINT_FL_Mul_a\expandafter{\the\numexpr #1\expandafter}% - \expandafter{\romannumeral0\XINTinfloat [#1]{#2}}% + #2[#1]{\expandafter\XINT_FL_mul_a\romannumeral0\XINTinfloat[#1]{#3}#1.{#4}}% }% -\def\XINT_FL_Mul_a #1#2#3% +\def\XINT_FL_mul_a #1[#2]#3.#4% {% - \expandafter\XINT_FL_Mul_b\romannumeral0\XINTinfloat [#1]{#3}#2% + \expandafter\XINT_FL_mul_b\romannumeral0\XINTinfloat [#3]{#4}#1[#2]% }% -\def\XINT_FL_Mul_b #1[#2]#3[#4]{\xintE{\xintiiMul {#1}{#3}}{#2+#4}}% +\def\XINT_FL_mul_b #1[#2]#3[#4]{\xintE{\xintiiMul {#3}{#1}}{#4+#2}}% % \end{macrocode} % \subsection{\csh{xintFloatDiv}, \csh{XINTinFloatDiv}} -% \lverb|1.07| +% \lverb|1.07. +% +% 1.2f does not use two extra rounding digits on inputs.| % \begin{macrocode} -\def\xintFloatDiv {\romannumeral0\xintfloatdiv}% -\def\xintfloatdiv #1{\XINT_fldiv_chkopt \xintfloat #1\xint_relax }% -\def\XINTinFloatDiv {\romannumeral0\XINTinfloatdiv }% -\def\XINTinfloatdiv #1{\XINT_fldiv_chkopt \XINTinfloat #1\xint_relax }% +\def\xintFloatDiv {\romannumeral0\xintfloatdiv }% +\def\xintfloatdiv #1{\XINT_fldiv_chkopt \xintfloat #1\xint_relax }% +\def\XINTinFloatDiv {\romannumeral0\XINTinfloatdiv }% +\def\XINTinfloatdiv #1{\XINT_fldiv_chkopt \XINTinfloat #1\xint_relax }% \def\XINT_fldiv_chkopt #1#2% {% \ifx [#2\expandafter\XINT_fldiv_opt @@ -25089,33 +25942,40 @@ $1$ or $-1$. }% \def\XINT_fldiv_noopt #1#2\xint_relax #3% {% - #1[\XINTdigits]{\XINT_FL_Div {\XINTdigits+\xint_c_ii}{#2}{#3}}% + #1[\XINTdigits]% + {\expandafter\XINT_FL_div_a + \romannumeral0\XINTinfloat[\XINTdigits]{#2}\XINTdigits.{#3}}% }% -\def\XINT_fldiv_opt #1[\xint_relax #2]#3#4% +\def\XINT_fldiv_opt #1[\xint_relax #2]%#3#4% {% - #1[#2]{\XINT_FL_Div {#2+\xint_c_ii}{#3}{#4}}% + \expandafter\XINT_fldiv_opt_a\the\numexpr #2.#1% }% -\def\XINT_FL_Div #1#2% +\def\XINT_fldiv_opt_a #1.#2#3#4% {% - \expandafter\XINT_FL_Div_a\expandafter{\the\numexpr #1\expandafter}% - \expandafter{\romannumeral0\XINTinfloat [#1]{#2}}% + #2[#1]{\expandafter\XINT_FL_div_a\romannumeral0\XINTinfloat[#1]{#3}#1.{#4}}% }% -\def\XINT_FL_Div_a #1#2#3% +\def\XINT_FL_div_a #1[#2]#3.#4% {% - \expandafter\XINT_FL_Div_b\romannumeral0\XINTinfloat [#1]{#3}#2% + \expandafter\XINT_FL_div_b\romannumeral0\XINTinfloat[#3]{#4}#1[#2]% }% -\def\XINT_FL_Div_b #1[#2]#3[#4]{\xintE{#3/#1}{#4-#2}}% -% \end{macrocode} +\def\XINT_FL_div_b #1[#2]#3[#4]{\xintE{#3/#1}{#4-#2}}% % \subsection{\csh{xintFloatPow}, \csh{XINTinFloatPow}} -% \begin{framed} -% This definitely should be revised to better take into account the new -% multiplication to maintain through intermediate states a suitable internal -% format, optimized for calls to \csh{XINT_mul_loop}. -% \end{framed} -% \lverb|1.07. Release 1.09j has re-organized the core loop, and -% \XINT_flpow_prd sub-routine has been removed.| +% \lverb|1.07: initial version. 1.09j has re-organized the core loop. +% +% 2015/12/07. I have hesitated to maintain the mapping of ^ in expressions to +% \xintFloatPow rather than \xintFloatPower. But for 1.234567890123456 to the +% power 2145678912 with P=16, using Pow rather than Power seems to bring only +% about 5$char$37$space gain. +% +% This routine requires the exponent x to be compatible with \numexpr parsing. +% +% 1.2f has rewritten the code for better efficiency. Also, now the argument A +% for A^x is first rounded to P digits before switching to the increased +% working precision (which depends upon x). +% +% | % \begin{macrocode} -\def\xintFloatPow {\romannumeral0\xintfloatpow}% +\def\xintFloatPow {\romannumeral0\xintfloatpow}% \def\xintfloatpow #1{\XINT_flpow_chkopt \xintfloat #1\xint_relax }% \def\XINTinFloatPow {\romannumeral0\XINTinfloatpow }% \def\XINTinfloatpow #1{\XINT_flpow_chkopt \XINTinfloat #1\xint_relax }% @@ -25124,276 +25984,331 @@ $1$ or $-1$. \ifx [#2\expandafter\XINT_flpow_opt \else\expandafter\XINT_flpow_noopt \fi - #1#2% + #1#2% }% \def\XINT_flpow_noopt #1#2\xint_relax #3% {% - \expandafter\XINT_flpow_checkB_start\expandafter - {\the\numexpr #3\expandafter}\expandafter - {\the\numexpr \XINTdigits}{#2}{#1[\XINTdigits]}% + \expandafter\XINT_flpow_checkB_a + \the\numexpr #3.\XINTdigits.{#2}{#1[\XINTdigits]}% +}% +\def\XINT_flpow_opt #1[\xint_relax #2]% +{% + \expandafter\XINT_flpow_opt_a\the\numexpr #2.#1% }% -\def\XINT_flpow_opt #1[\xint_relax #2]#3#4% +\def\XINT_flpow_opt_a #1.#2#3#4% {% - \expandafter\XINT_flpow_checkB_start\expandafter - {\the\numexpr #4\expandafter}\expandafter - {\the\numexpr #2}{#3}{#1[#2]}% + \expandafter\XINT_flpow_checkB_a\the\numexpr #4.#1.{#3}{#2[#1]}% }% -\def\XINT_flpow_checkB_start #1{\XINT_flpow_checkB_a #1\Z }% \def\XINT_flpow_checkB_a #1% {% \xint_UDzerominusfork #1-\XINT_flpow_BisZero - 0#1{\XINT_flpow_checkB_b 1}% - 0-{\XINT_flpow_checkB_b 0#1}% + 0#1{\XINT_flpow_checkB_b -}% + 0-{\XINT_flpow_checkB_b {}#1}% \krof }% -\def\XINT_flpow_BisZero \Z #1#2#3{#3{1/1[0]}}% -\def\XINT_flpow_checkB_b #1#2\Z #3% +\def\XINT_flpow_BisZero .#1.#2#3{#3{1[0]}}% +\def\XINT_flpow_checkB_b #1#2.#3.% {% - \expandafter\XINT_flpow_checkB_c \expandafter - {\romannumeral0\xintlength{#2}}{#3}{#2}#1% + \expandafter\XINT_flpow_checkB_c + \the\numexpr\xintLength{#2}+\xint_c_iii.#3.#2.{#1}% }% -\def\XINT_flpow_checkB_c #1#2% +\def\XINT_flpow_checkB_c #1.#2.% {% - \expandafter\XINT_flpow_checkB_d \expandafter - {\the\numexpr \expandafter\xintLength\expandafter - {\the\numexpr #1*20/\xint_c_iii }+#1+#2+\xint_c_i }% + \expandafter\XINT_flpow_checkB_d\the\numexpr#1+#2.#1.#2.% }% -\def\XINT_flpow_checkB_d #1#2#3#4% +% \end{macrocode} +%\lverb|1.2f rounds input to P digits, first.| +% \begin{macrocode} +\def\XINT_flpow_checkB_d #1.#2.#3.#4.#5#6% +{% + \expandafter \XINT_flpow_aa + \romannumeral0\XINTinfloat [#3]{#6}{#2}{#1}{#4}{#5}% +}% +\def\XINT_flpow_aa #1[#2]#3% {% - \expandafter \XINT_flpow_a - \romannumeral0\XINTinfloat [#1]{#4}{#1}{#2}#3% + \expandafter\XINT_flpow_ab\the\numexpr #2-#3\expandafter.% + \romannumeral0\XINT_dsx_addzerosnofuss {#3}{}.#1.% }% +\def\XINT_flpow_ab #1.#2.#3.{\XINT_flpow_a #3#2[#1]}% \def\XINT_flpow_a #1% {% \xint_UDzerominusfork #1-\XINT_flpow_zero - 0#1{\XINT_flpow_b 1}% - 0-{\XINT_flpow_b 0#1}% + 0#1{\XINT_flpow_b \iftrue}% + 0-{\XINT_flpow_b \iffalse#1}% \krof }% +\def\XINT_flpow_zero #1[#2]#3#4#5#6% +{% + \if 1#51\xint_afterfi {#6{0[0]}}\else + \xint_afterfi {\xintError:DivisionByZero #6{1[2147483648]}}\fi +}% \def\XINT_flpow_b #1#2[#3]#4#5% {% - \XINT_flpow_loopI {#5}{#2[#3]}{\romannumeral0\XINTinfloatmul [#4]}% - {#1*\ifodd #5 1\else 0\fi}% + \XINT_flpow_loopI #5.#3.#2.#4.{#1\ifodd #5 \xint_c_i\fi\fi}% }% -\def\XINT_flpow_zero [#1]#2#3#4#5% -% \end{macrocode} -% \lverb|xint is not equipped to signal infinity, the 2^31 will provoke -% deliberately a number too big and arithmetic overflow in \XINT_float_Xb| -% \begin{macrocode} +\def\XINT_flpow_truncate #1.#2.#3.% {% - \if #41\xint_afterfi {\xintError:DivisionByZero #5{1[2147483648]}}% - \else \xint_afterfi {#5{0[0]}}\fi + \expandafter\XINT_flpow_truncate_a + \romannumeral0\XINT_split_fromleft_loop #3.{}#2\W\W\W\W\W\W\W\W\Z + #1.#3.% }% -\def\XINT_flpow_loopI #1% +\def\XINT_flpow_truncate_a #1.#2.#3.{#3+\xintLength{#2}.#1.}% +\def\XINT_flpow_loopI #1.% {% - \ifnum #1=\xint_c_i\XINT_flpow_ItoIII\fi + \ifnum #1=\xint_c_i\expandafter\XINT_flpow_ItoIII\fi \ifodd #1 \expandafter\XINT_flpow_loopI_odd \else \expandafter\XINT_flpow_loopI_even \fi - {#1}% + #1.% }% -\def\XINT_flpow_ItoIII\fi #1\fi #2#3#4#5% +\def\XINT_flpow_ItoIII\ifodd #1\fi #2.#3.#4.#5.#6% {% - \fi\expandafter\XINT_flpow_III\the\numexpr #5\relax #3% + \expandafter\XINT_flpow_III\the\numexpr #6+\xint_c_.#3.#4.#5.% }% -\def\XINT_flpow_loopI_even #1#2#3% +\def\XINT_flpow_loopI_even #1.#2.#3.%#4.% {% - \expandafter\XINT_flpow_loopI\expandafter - {\the\numexpr #1/\xint_c_ii\expandafter}\expandafter - {#3{#2}{#2}}{#3}% + \expandafter\XINT_flpow_loopI + \the\numexpr #1/\xint_c_ii\expandafter.% + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.% }% -\def\XINT_flpow_loopI_odd #1#2#3% +\def\XINT_flpow_loopI_odd #1.#2.#3.#4.% {% - \expandafter\XINT_flpow_loopII\expandafter - {\the\numexpr #1/\xint_c_ii-\xint_c_i\expandafter}\expandafter - {#3{#2}{#2}}{#3}{#2}% + \expandafter\XINT_flpow_loopII + \the\numexpr #1/\xint_c_ii-\xint_c_i\expandafter.% + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.#4.#2.#3.% }% -\def\XINT_flpow_loopII #1% +\def\XINT_flpow_loopII #1.% {% - \ifnum #1 = \xint_c_i\XINT_flpow_IItoIII\fi + \ifnum #1 = \xint_c_i\expandafter\XINT_flpow_IItoIII\fi \ifodd #1 \expandafter\XINT_flpow_loopII_odd \else \expandafter\XINT_flpow_loopII_even \fi - {#1}% + #1.% }% -\def\XINT_flpow_loopII_even #1#2#3% +\def\XINT_flpow_loopII_even #1.#2.#3.%#4.% {% - \expandafter\XINT_flpow_loopII\expandafter - {\the\numexpr #1/\xint_c_ii\expandafter}\expandafter - {#3{#2}{#2}}{#3}% + \expandafter\XINT_flpow_loopII + \the\numexpr #1/\xint_c_ii\expandafter.% + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.% }% -\def\XINT_flpow_loopII_odd #1#2#3#4% +\def\XINT_flpow_loopII_odd #1.#2.#3.#4.#5.#6.% {% - \expandafter\XINT_flpow_loopII_odda\expandafter - {#3{#2}{#4}}{#1}{#2}{#3}% + \expandafter\XINT_flpow_loopII_odda + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr#2+#5\expandafter.\romannumeral0\xintiimul{#3}{#6}.#4.% + #1.#2.#3.% }% -\def\XINT_flpow_loopII_odda #1#2#3#4% +\def\XINT_flpow_loopII_odda #1.#2.#3.#4.#5.#6.% {% - \expandafter\XINT_flpow_loopII\expandafter - {\the\numexpr #2/\xint_c_ii-\xint_c_i\expandafter}\expandafter - {#4{#3}{#3}}{#4}{#1}% + \expandafter\XINT_flpow_loopII + \the\numexpr #4/\xint_c_ii-\xint_c_i\expandafter.% + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#5\expandafter.\romannumeral0\xintiisqr{#6}.#3.% + #1.#2.% }% -\def\XINT_flpow_IItoIII\fi #1\fi #2#3#4#5#6% +\def\XINT_flpow_IItoIII\ifodd #1\fi #2.#3.#4.#5.#6.#7.#8% {% - \fi\expandafter\XINT_flpow_III\the\numexpr #6\expandafter\relax - #4{#3}{#5}% + \expandafter\XINT_flpow_III\the\numexpr #8+\xint_c_\expandafter.% + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr#3+#6\expandafter.\romannumeral0\xintiimul{#4}{#7}.#5.% }% -\def\XINT_flpow_III #1#2[#3]#4% +% \end{macrocode} +% \lverb|This ending is common with \xintFloatPower. In the case of negative +% exponent we will inverse the Q-digits mantissa, keeping Q significant +% digits (exceptionally 10^Q) before the final rounding to P digits. Here Q +% is working precision. Releases prior to 1.2f trusted the final inverse to +% \xintFloat on output but this worked only with P+2 digits on denominator. +% Enough for 0.1 ulp extra error, but as our goal is to get <0.6ulp, and +% there is already 0.5ulp from rounding error, this was not enough. When +% \xintFloat will achieve correct rounding for arbitrary fractions, the step +% here will not be needed.| +% \begin{macrocode} +\def\XINT_flpow_III #1.#2.#3.#4.#5% {% - \expandafter\XINT_flpow_IIIend\expandafter - {\the\numexpr\if #41-\fi#3\expandafter}% - \xint_UDzerofork - #4{{#2}}% - 0{{1/#2}}% + \expandafter\XINT_flpow_IIIend + \xint_UDsignfork + #5{{\xintNum{1/#3[\xint_c_ii*#4-\xint_c_i]}[\xint_c_i-\xint_c_ii*#4-#2]}}% + -{{#3[#2]}}% \krof #1% }% -\def\XINT_flpow_IIIend #1#2#3#4% -{% - \xint_UDzerofork - #3{#4{#2[#1]}}% - 0{#4{-#2[#1]}}% - \krof -}% +\def\XINT_flpow_IIIend #1#2#3% + {#3{\if#21\xint_afterfi{\expandafter-\romannumeral`&&@}\fi#1}}% % \end{macrocode} % \subsection{\csh{xintFloatPower}, \csh{XINTinFloatPower}} % \lverb|1.07. The core loop has been re-organized in 1.09j for some slight -% efficiency gain. | +% efficiency gain. The exponent B is given to \xintNum. The ^ in expressions +% is mapped to this routine. +% +% Same modifications as in \xintFloatPow for 1.2f. +% +% 1.2f adds a special macro for allowing half-integral exponents for use with +% ^ within \xintfloatexpr. The exponent will be first truncated to either an +% integer or an half-integer.| % \begin{macrocode} -\def\xintFloatPower {\romannumeral0\xintfloatpower}% +\def\xintFloatPower {\romannumeral0\xintfloatpower}% \def\xintfloatpower #1{\XINT_flpower_chkopt \xintfloat #1\xint_relax }% -\def\XINTinFloatPower {\romannumeral0\XINTinfloatpower}% +\def\XINTinFloatPower {\romannumeral0\XINTinfloatpower }% \def\XINTinfloatpower #1{\XINT_flpower_chkopt \XINTinfloat #1\xint_relax }% +\def\XINTinFloatPowerH {\romannumeral0\XINTinfloatpowerH }% +\def\XINTinfloatpowerH #1#2% + {\expandafter\XINT_flpowerh_a \romannumeral0\xinttrunc 1{#2}.0;% + \XINTdigits.{#1}{\XINTinfloat[\XINTdigits]}}% +\def\XINT_flpowerh_a #1.#2% +{% + \ifnum#2>\xint_c_iv\xint_dothis\XINT_flpowerh_b\fi + \xint_orthat\XINT_flpowerh_i #1.#2% +}% +\def\XINT_flpowerh_i #1.#2;% + {\expandafter\XINT_flpower_checkB_a\romannumeral0\xintinum{#1}.}% +\def\XINT_flpowerh_b #1% +{% + \if#1-\xint_dothis\XINT_flpowerh_bneg\fi + \xint_orthat{\XINT_flpowerh_bpos #1}% +}% +\def\XINT_flpowerh_bpos #1.#2;\XINTdigits.#3#4% +{% + \expandafter\XINT_flpower_checkB_a + \romannumeral0\xintinc{\xintDouble{#1}}.% + \XINTdigits.{#3}{\XINTinfloatsqrt[\XINTdigits]}% +}% +\def\XINT_flpowerh_bneg #1.#2;\XINTdigits.#3#4% +{% + \expandafter\XINT_flpower_checkB_a + \expandafter-\romannumeral0\xintinc{\xintDouble{#1}}.% + \XINTdigits.{#3}{\XINTinfloatsqrt[\XINTdigits]}% +}% \def\XINT_flpower_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flpower_opt \else\expandafter\XINT_flpower_noopt \fi - #1#2% + #1#2% }% \def\XINT_flpower_noopt #1#2\xint_relax #3% {% - \expandafter\XINT_flpower_checkB_start\expandafter - {\the\numexpr \XINTdigits\expandafter}\expandafter - {\romannumeral0\xintnum{#3}}{#2}{#1[\XINTdigits]}% + \expandafter\XINT_flpower_checkB_a + \romannumeral0\xintnum{#3}.\XINTdigits.{#2}{#1[\XINTdigits]}% +}% +\def\XINT_flpower_opt #1[\xint_relax #2]% +{% + \expandafter\XINT_flpower_opt_a\the\numexpr #2.#1% }% -\def\XINT_flpower_opt #1[\xint_relax #2]#3#4% +\def\XINT_flpower_opt_a #1.#2#3#4% {% - \expandafter\XINT_flpower_checkB_start\expandafter - {\the\numexpr #2\expandafter}\expandafter - {\romannumeral0\xintnum{#4}}{#3}{#1[#2]}% + \expandafter\XINT_flpower_checkB_a + \romannumeral0\xintnum{#4}.#1.{#3}{#2[#1]}% }% -\def\XINT_flpower_checkB_start #1#2{\XINT_flpower_checkB_a #2\Z {#1}}% \def\XINT_flpower_checkB_a #1% {% \xint_UDzerominusfork #1-\XINT_flpower_BisZero - 0#1{\XINT_flpower_checkB_b 1}% - 0-{\XINT_flpower_checkB_b 0#1}% + 0#1{\XINT_flpower_checkB_b -}% + 0-{\XINT_flpower_checkB_b {}#1}% \krof }% -\def\XINT_flpower_BisZero \Z #1#2#3{#3{1/1[0]}}% -\def\XINT_flpower_checkB_b #1#2\Z #3% +\def\XINT_flpower_BisZero .#1.#2#3{#3{1[0]}}% +\def\XINT_flpower_checkB_b #1#2.#3.% {% - \expandafter\XINT_flpower_checkB_c \expandafter - {\romannumeral0\xintlength{#2}}{#3}{#2}#1% + \expandafter\XINT_flpower_checkB_c + \the\numexpr\xintLength{#2}+\xint_c_iii.#3.#2.{#1}% }% -\def\XINT_flpower_checkB_c #1#2% +\def\XINT_flpower_checkB_c #1.#2.% {% - \expandafter\XINT_flpower_checkB_d \expandafter - {\the\numexpr \expandafter\xintLength\expandafter - {\the\numexpr #1*20/\xint_c_iii }+#1+#2+\xint_c_i }% + \expandafter\XINT_flpower_checkB_d\the\numexpr#1+#2.#1.#2.% }% -\def\XINT_flpower_checkB_d #1#2#3#4% +\def\XINT_flpower_checkB_d #1.#2.#3.#4.#5#6% {% - \expandafter \XINT_flpower_a - \romannumeral0\XINTinfloat [#1]{#4}{#1}{#2}#3% + \expandafter \XINT_flpower_aa + \romannumeral0\XINTinfloat [#3]{#6}{#2}{#1}{#4}{#5}% }% +\def\XINT_flpower_aa #1[#2]#3% +{% + \expandafter\XINT_flpower_ab\the\numexpr #2-#3\expandafter.% + \romannumeral0\XINT_dsx_addzerosnofuss {#3}{}.#1.% +}% +\def\XINT_flpower_ab #1.#2.#3.{\XINT_flpower_a #3#2[#1]}% \def\XINT_flpower_a #1% {% \xint_UDzerominusfork #1-\XINT_flpow_zero - 0#1{\XINT_flpower_b 1}% - 0-{\XINT_flpower_b 0#1}% + 0#1{\XINT_flpower_b \iftrue}% + 0-{\XINT_flpower_b \iffalse#1}% \krof }% \def\XINT_flpower_b #1#2[#3]#4#5% {% - \XINT_flpower_loopI {#5}{#2[#3]}{\romannumeral0\XINTinfloatmul [#4]}% - {#1*\xintiiOdd {#5}}% + \XINT_flpower_loopI #5.#3.#2.#4.{#1\xintiiOdd{#5}\fi}% }% -\def\XINT_flpower_loopI #1% +\def\XINT_flpower_loopI #1.% {% - \if1\XINT_isOne {#1}\XINT_flpower_ItoIII\fi - \if1\xintiiOdd{#1}% - \expandafter\expandafter\expandafter\XINT_flpower_loopI_odd - \else - \expandafter\expandafter\expandafter\XINT_flpower_loopI_even - \fi - \expandafter {\romannumeral0\xinthalf{#1}}% + \if1\XINT_isOne {#1}\xint_dothis\XINT_flpower_ItoIII\fi + \if1\xintiiOdd {#1}\xint_dothis{\expandafter\XINT_flpower_loopI_odd}\fi + \xint_orthat{\expandafter\XINT_flpower_loopI_even}% + \romannumeral0\xinthalf{#1}.% }% -\def\XINT_flpower_ItoIII\fi #1\fi\expandafter #2#3#4#5% +\def\XINT_flpower_ItoIII #1.#2.#3.#4.#5% {% - \fi\expandafter\XINT_flpow_III \the\numexpr #5\relax #3% + \expandafter\XINT_flpow_III\the\numexpr #5+\xint_c_.#2.#3.#4.% }% -\def\XINT_flpower_loopI_even #1#2#3% +\def\XINT_flpower_loopI_even #1.#2.#3.#4.% {% - \expandafter\XINT_flpower_toI\expandafter {#3{#2}{#2}}{#1}{#3}% + \expandafter\XINT_flpower_toloopI + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.#4.#1.% }% -\def\XINT_flpower_loopI_odd #1#2#3% +\def\XINT_flpower_toloopI #1.#2.#3.#4.{\XINT_flpower_loopI #4.#1.#2.#3.}% +\def\XINT_flpower_loopI_odd #1.#2.#3.#4.% {% - \expandafter\XINT_flpower_toII\expandafter {#3{#2}{#2}}{#1}{#3}{#2}% + \expandafter\XINT_flpower_toloopII + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.#4.% + #1.#2.#3.% }% -\def\XINT_flpower_toI #1#2{\XINT_flpower_loopI {#2}{#1}}% -\def\XINT_flpower_toII #1#2{\XINT_flpower_loopII {#2}{#1}}% -\def\XINT_flpower_loopII #1% +\def\XINT_flpower_toloopII #1.#2.#3.#4.{\XINT_flpower_loopII #4.#1.#2.#3.}% +\def\XINT_flpower_loopII #1.% {% - \if1\XINT_isOne {#1}\XINT_flpower_IItoIII\fi - \if1\xintiiOdd{#1}% - \expandafter\expandafter\expandafter\XINT_flpower_loopII_odd - \else - \expandafter\expandafter\expandafter\XINT_flpower_loopII_even - \fi - \expandafter {\romannumeral0\xinthalf{#1}}% + \if1\XINT_isOne{#1}\xint_dothis\XINT_flpower_IItoIII\fi + \if1\xintiiOdd{#1}\xint_dothis{\expandafter\XINT_flpower_loopII_odd}\fi + \xint_orthat{\expandafter\XINT_flpower_loopII_even}% + \romannumeral0\xinthalf{#1}.% }% -\def\XINT_flpower_loopII_even #1#2#3% +\def\XINT_flpower_loopII_even #1.#2.#3.#4.% {% - \expandafter\XINT_flpower_toII\expandafter - {#3{#2}{#2}}{#1}{#3}% + \expandafter\XINT_flpower_toloopII + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.#4.#1.% }% -\def\XINT_flpower_loopII_odd #1#2#3#4% +\def\XINT_flpower_loopII_odd #1.#2.#3.#4.#5.#6.% {% - \expandafter\XINT_flpower_loopII_odda\expandafter - {#3{#2}{#4}}{#2}{#3}{#1}% + \expandafter\XINT_flpower_loopII_odda + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr#2+#5\expandafter.\romannumeral0\xintiimul{#3}{#6}.#4.% + #1.#2.#3.% }% -\def\XINT_flpower_loopII_odda #1#2#3#4% +\def\XINT_flpower_loopII_odda #1.#2.#3.#4.#5.#6.% {% - \expandafter\XINT_flpower_toII\expandafter - {#3{#2}{#2}}{#4}{#3}{#1}% + \expandafter\XINT_flpower_toloopII + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#5\expandafter.\romannumeral0\xintiisqr{#6}.#3.% + #4.#1.#2.% }% -\def\XINT_flpower_IItoIII\fi #1\fi\expandafter #2#3#4#5#6% +\def\XINT_flpower_IItoIII #1.#2.#3.#4.#5.#6.#7% {% - \fi\expandafter\XINT_flpow_III\the\numexpr #6\expandafter\relax - #4{#3}{#5}% + \expandafter\XINT_flpow_III\the\numexpr #7+\xint_c_\expandafter.% + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr#2+#5\expandafter.\romannumeral0\xintiimul{#3}{#6}.#4.% }% % \end{macrocode} % \subsection{\csh{xintFloatFac}, \csh{XINTFloatFac}} -% \lverb|1.2. Je dois documenter le raisonnement sur la précision à imposer -% pour les calculs par blocs de huit faits en sous-main. Par ailleurs j'ai été -% amené à une routine smallmul spéciale. -% -% Comment 2015/11/13: at least I do have a file which privately document my -% choice of precision (I could reduce by one unit here). I hesitated with doing -% a divide and conquer approach, but last time I thought about it I did not see -% an obvious advantage in this context. But I should implement and compare. -% -% 2015/11/19: there was a bug here that the input was only subjected to -% \numexpr. It should have used \xintNum. Fixed in 1.2e | % \begin{macrocode} \def\xintFloatFac {\romannumeral0\xintfloatfac}% \def\xintfloatfac #1{\XINT_flfac_chkopt \xintfloat #1\xint_relax }% @@ -25408,57 +26323,105 @@ $1$ or $-1$. }% \def\XINT_flfac_noopt #1#2\xint_relax {% - \expandafter\XINT_FL_fac_start\expandafter - {\the\numexpr \xintNum{#2}}{\XINTdigits}{#1[\XINTdigits]}% + \expandafter\XINT_FL_fac_fork_a + \the\numexpr \xintNum{#2}.\xint_c_i \XINTdigits\XINT_FL_fac_out{#1[\XINTdigits]}% }% -% \end{macrocode} -% \lverb|#2 should arguably be subjected to \numexpr only once. Here it will -% again be during final \xintfloat, or \XINTinfloat.| -% \begin{macrocode} -\def\XINT_flfac_opt #1[\xint_relax #2]#3% +\def\XINT_flfac_opt #1[\xint_relax #2]% {% - \expandafter\XINT_FL_fac_start\expandafter - {\the\numexpr \xintNum{#3}\expandafter}\expandafter{\the\numexpr#2}{#1[#2]}% + \expandafter\XINT_flfac_opt_a\the\numexpr #2.#1% }% -\def\XINT_FL_fac_start #1% +\def\XINT_flfac_opt_a #1.#2#3% {% - \ifcase\XINT_cntSgn #1\Z - \expandafter\XINT_FL_fac_iszero - \or - \expandafter\XINT_FL_fac_increaseP - \else - \expandafter\XINT_FL_fac_isneg - \fi {#1}% + \expandafter\XINT_FL_fac_fork_a\the\numexpr \xintNum{#3}.\xint_c_i {#1}\XINT_FL_fac_out{#2[#1]}% }% -\def\XINT_FL_fac_iszero #1#2#3{#3{1/1[0]}}% -\def\XINT_FL_fac_isneg #1#2#3% - {\expandafter\xintError:FactorialOfNegativeNumber #3{1/1[0]}}% -\def\XINT_FL_fac_increaseP #1#2% +\def\XINT_FL_fac_fork_a #1% {% - \expandafter\XINT_FL_fac_fork - \the\numexpr \xint_c_viii*% - ((\xint_c_v+#2+\XINT_FL_fac_extradigits #187654321\Z)/\xint_c_viii).% - #1.% + \xint_UDzerominusfork + #1-\XINT_FL_fac_iszero + 0#1\XINT_FL_fac_isneg + 0-{\XINT_FL_fac_fork_b #1}% + \krof }% -\def\XINT_FL_fac_extradigits #1#2#3#4#5#6#7#8{\XINT_FL_fac_extra_a }% -\def\XINT_FL_fac_extra_a #1#2\Z {#1}% -\def\XINT_FL_fac_fork #1.#2.#3% +\def\XINT_FL_fac_iszero #1.#2#3#4#5{#5{1/1[0]}}% +% \end{macrocode} +% \lverb|1.2f XINT_FL_fac_isneg returns 0, earlier versions used 1 here.| +% \begin{macrocode} +\def\XINT_FL_fac_isneg #1.#2#3#4#5{\expandafter\xintError:FactorialOfNegative #5{0/1[0]}}% +\def\XINT_FL_fac_fork_b #1.% {% - \ifnum #2>99999999 \xint_dothis{\XINT_FL_fac_toobig }\fi - \ifnum #2>9999 \xint_dothis{\XINT_FL_fac_vbigloop_a }\fi - \ifnum #2>465 \xint_dothis{\XINT_FL_fac_bigloop_a }\fi - \ifnum #2>101 \xint_dothis{\XINT_FL_fac_medloop_a }\fi - \xint_orthat{\XINT_FL_fac_smallloop_a }% - #2.#1.{\XINT_FL_fac_out}{#3}% + \ifnum #1>\xint_c_x^viii_mone\xint_dothis\XINT_FL_fac_toobig\fi + \ifnum #1>\xint_c_x^iv\xint_dothis\XINT_FL_fac_vbig \fi + \ifnum #1>465 \xint_dothis\XINT_FL_fac_big\fi + \ifnum #1>101 \xint_dothis\XINT_FL_fac_med\fi + \xint_orthat\XINT_FL_fac_small + #1.% }% -\def\XINT_FL_fac_toobig #1.#2.#3#4% - {\expandafter\xintError:FactorialOfTooBigNumber #4{1/1[0]}}% -\def\XINT_FL_fac_out #1\Z![#2]#3{#3{\romannumeral0\XINT_mul_out +\def\XINT_FL_fac_toobig #1.#2#3#4#5{\expandafter\xintError:TooBigFactorial #5{1/1[0]}}% +% \end{macrocode} +% \lverb?Computations are done with Q blocks of eight digits. When a +% multiplication has a carry, hence creates Q+1 blocks, the least significant +% one is dropped. The goal is to compute an approximate value X' to the exact +% value X, such that the final relative error (X-X')/X will be at most +% 10^{-P-1} with P the desired precision. Then, when we round X' to X'' with P +% significant digits, we can prove that the absolute error |X-X''| is bounded +% (strictly) by 0.6 ulp(X''). (ulp= unit in the last (significant) place). Let +% N be the number of such operations, the formula for Q deduces from the +% previous explanations is that 8Q should be at least P+9+k, with k the number +% of digits of N (in base 10). Note that 1.2 version used P+10+k, for 1.2f I +% reduced to P+9+k. Also, k should be the number of digits of the number N of +% multiplications done, hence for n<=10000 we can take N=n/2, or N/3, or N/4. +% This is rounded above by numexpr and always an overestimate of the actual +% number of approximate multiplications done (the first ones are exact). +% (vérifier ce que je raconte, j'ai la flemme là ). +% +% We then want ceil((P+k+n)/8). Using \numexpr rounding division +% (ARRRRRGGGHHHH), if m is a positive integer, ceil(m/8) can be computed as +% (m+3)/8. Thus with m=P+10+k, this gives Q<-(P+13+k)/8. The routine actually +% computes 8(Q-1) for use in \XINT_FL_fac_addzeros. +% +% With 1.2f the formula is m=P+9+k, Q<-(P+12+k)/8, and we use now 4=12-8 rather +% than the earlier 5=13-8. Whatever happens, the value computed in +% \XINT_FL_fac_increaseP is at least 8. There will always be an extra block. +% +% Note: with Digits:=32; Maple gives for 200!:$bgroup$obeylines$obeyspaces +% > factorial(200.); +% 375 +% 0.78865786736479050355236321393218 10 +% My 1.2f routine (and also 1.2) outputs: +% 7.8865786736479050355236321393219e374 +% and this is the correct rounding because for 40 digits it computes +% 7.886578673647905035523632139321850622951e374 +% $egroup +% Maple's result (contrarily to xint) is thus not the correct rounding but +% still it is less than 0.6 ulp wrong. +% ? +% \begin{macrocode} +\def\XINT_FL_fac_vbig + {\expandafter\XINT_FL_fac_vbigloop_a + \the\numexpr \XINT_FL_fac_increaseP \xint_c_i }% +\def\XINT_FL_fac_big + {\expandafter\XINT_FL_fac_bigloop_a + \the\numexpr \XINT_FL_fac_increaseP \xint_c_ii }% +\def\XINT_FL_fac_med + {\expandafter\XINT_FL_fac_medloop_a + \the\numexpr \XINT_FL_fac_increaseP \xint_c_iii }% +\def\XINT_FL_fac_small + {\expandafter\XINT_FL_fac_smallloop_a + \the\numexpr \XINT_FL_fac_increaseP \xint_c_iv }% +\def\XINT_FL_fac_increaseP #1#2.#3#4% +{% + #2\expandafter.\the\numexpr\xint_c_viii*% + ((\xint_c_iv+#4+\expandafter\XINT_FL_fac_countdigits + \the\numexpr #2/(#1*#3)\relax 87654321\Z)/\xint_c_viii).% +}% +\def\XINT_FL_fac_countdigits #1#2#3#4#5#6#7#8{\XINT_FL_fac_countdone }% +\def\XINT_FL_fac_countdone #1#2\Z {#1}% +\def\XINT_FL_fac_out #1\Z![#2]#3{#3{\romannumeral0\XINT_mul_out #1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W [#2]}}% \def\XINT_FL_fac_vbigloop_a #1.#2.% {% - \XINT_FL_fac_bigloop_a 9999.#2.% - {\expandafter\XINT_FL_fac_vbigloop_loop\the\numexpr 100010000\expandafter.% + \XINT_FL_fac_bigloop_a \xint_c_x^iv.#2.% + {\expandafter\XINT_FL_fac_vbigloop_loop\the\numexpr 100010001\expandafter.% \the\numexpr \xint_c_x^viii+#1.}% }% \def\XINT_FL_fac_vbigloop_loop #1.#2.% @@ -25470,7 +26433,7 @@ $1$ or $-1$. }% \def\XINT_FL_fac_bigloop_a #1.% {% - \expandafter\XINT_FL_fac_bigloop_b \the\numexpr + \expandafter\XINT_FL_fac_bigloop_b \the\numexpr #1+\xint_c_i-\xint_c_ii*((#1-464)/\xint_c_ii).#1.% }% \def\XINT_FL_fac_bigloop_b #1.#2.#3.% @@ -25510,12 +26473,12 @@ $1$ or $-1$. \def\XINT_FL_fac_medloop_mul #1!% {% \expandafter\XINT_FL_fac_mul - \the\numexpr + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% }% \def\XINT_FL_fac_smallloop_a #1.% {% - \csname + \csname XINT_FL_fac_smallloop_\the\numexpr #1-\xint_c_iv*(#1/\xint_c_iv)\relax \endcsname #1.% }% @@ -25540,8 +26503,13 @@ $1$ or $-1$. \ifnum #1=\xint_c_viii \expandafter\XINT_FL_fac_addzeros_exit\fi \expandafter\XINT_FL_fac_addzeros\the\numexpr #1-\xint_c_viii.100000000!% }% -\def\XINT_FL_fac_addzeros_exit #1.#2.#3#4% - {\XINT_FL_fac_smallloop_loop #3#21\Z![-#4]}% +% \end{macrocode} +% \lverb|We will manipulate by successive *small* multiplications Q blocks +% 1<8d>!, terminated by 1\Z!. We need a custom small multiplication which +% tells us when it has create a new block, and the least significant one +% should be dropped.| +% \begin{macrocode} +\def\XINT_FL_fac_addzeros_exit #1.#2.#3#4{\XINT_FL_fac_smallloop_loop #3#21\Z![-#4]}% \def\XINT_FL_fac_smallloop_loop #1.#2.% {% \ifnum #1>#2 \expandafter\XINT_FL_fac_loop_exit\fi @@ -25552,7 +26520,7 @@ $1$ or $-1$. \def\XINT_FL_fac_smallloop_mul #1!% {% \expandafter\XINT_FL_fac_mul - \the\numexpr + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% }%[[ \def\XINT_FL_fac_loop_exit #1!#2]#3{#3#2]}% @@ -25592,9 +26560,18 @@ $1$ or $-1$. \xint_gob_til_Z #3\XINT_FL_fac_smallmul_end\Z \XINT_FL_fac_minimulwc_a #2!#3!{#1}{#2}% }% +% \end{macrocode} +% \lverb|This is the crucial ending. I note that I used here an \ifnum test +% rather than the gob_til_eightzeroes thing. Actually for eight digits there +% is much less difference than for only four. +% +% The "carry" situation is marked by a final !-1 rather than !-2 for no-carry. +% (a \numexpr muste be stopped, and leaving a - as delimiter is good as it +% will not arise earlier.)| +% \begin{macrocode} \def\XINT_FL_fac_smallmul_end\Z\XINT_FL_fac_minimulwc_a #1!\Z!#2#3[#4]% {% - \ifnum #2=\xint_c_ + \ifnum #2=\xint_c_ \expandafter\xint_firstoftwo\else \expandafter\xint_secondoftwo \fi @@ -25603,201 +26580,414 @@ $1$ or $-1$. [\the\numexpr #4+\xint_c_viii]}% }% % \end{macrocode} -% \subsection{\csh{xintFloatSqrt}, \csh{XINTinFloatSqrt}} -% \lverb|1.08. Note 2015/11/16: I absolutely must document what's happening -% here, I have a file with comments from June 2013 which however is not -% completely explicit (as I did the rounding integer square root \xintiiSqrtR -% more than one year later, I am not -% 100$char37 $space sure the one here does correct rounding, and I don't -% have time to check now.)| +% \subsection{\csh{xintFloatPFactorial}, \csh{XINTinFloatPFactorial}} +% \lverb|2015/11/29 for 1.2f. Partial factorial pfactorial(a,b)=(a+1)...b, +% only for non-negative integers with a<=b<10^8.| % \begin{macrocode} -\def\xintFloatSqrt {\romannumeral0\xintfloatsqrt }% -\def\xintfloatsqrt #1{\XINT_flsqrt_chkopt \xintfloat #1\xint_relax }% -\def\XINTinFloatSqrt {\romannumeral0\XINTinfloatsqrt }% -\def\XINTinfloatsqrt #1{\XINT_flsqrt_chkopt \XINTinfloat #1\xint_relax }% -\def\XINT_flsqrt_chkopt #1#2% +\def\xintFloatPFactorial {\romannumeral0\xintfloatpfactorial}% +\def\xintfloatpfactorial #1{\XINT_flpfac_chkopt \xintfloat #1\xint_relax }% +\def\XINTinFloatPFactorial {\romannumeral0\XINTinfloatpfactorial }% +\def\XINTinfloatpfactorial #1{\XINT_flpfac_chkopt \XINTinfloat #1\xint_relax }% +\def\XINT_flpfac_chkopt #1#2% {% - \ifx [#2\expandafter\XINT_flsqrt_opt - \else\expandafter\XINT_flsqrt_noopt - \fi #1#2% + \ifx [#2\expandafter\XINT_flpfac_opt + \else\expandafter\XINT_flpfac_noopt + \fi + #1#2% }% -\def\XINT_flsqrt_noopt #1#2\xint_relax +\def\XINT_flpfac_noopt #1#2\xint_relax #3% {% - #1[\XINTdigits]{\XINT_FL_sqrt \XINTdigits {#2}}% + \expandafter\XINT_FL_pfac_fork + \the\numexpr \xintNum{#2}\expandafter.% + \the\numexpr \xintNum{#3}.\xint_c_i{\XINTdigits}{#1[\XINTdigits]}% }% -\def\XINT_flsqrt_opt #1[\xint_relax #2]#3% +\def\XINT_flpfac_opt #1[\xint_relax #2]% {% - #1[#2]{\XINT_FL_sqrt {#2}{#3}}% + \expandafter\XINT_flpfac_opt_b\the\numexpr #2.#1% }% -\def\XINT_FL_sqrt #1% +\def\XINT_flpfac_opt_b #1.#2#3#4% {% - \ifnum\numexpr #1<\xint_c_xviii - \xint_afterfi {\XINT_FL_sqrt_a\xint_c_xviii}% - \else - \xint_afterfi {\XINT_FL_sqrt_a {#1+\xint_c_i}}% - \fi + \expandafter\XINT_FL_pfac_fork + \the\numexpr \xintNum{#3}\expandafter.% + \the\numexpr \xintNum{#4}.\xint_c_i{#1}{#2[#1]}% }% -\def\XINT_FL_sqrt_a #1#2% +\def\XINT_FL_pfac_fork #1#2.#3.% {% - \expandafter\XINT_FL_sqrt_checkifzeroorneg - \romannumeral0\XINTinfloat [#1]{#2}% + \if-#1\xint_dothis\XINT_FL_pfac_outofrange\fi + \ifnum #1#2=#3 \xint_dothis\XINT_FL_pfac_one\fi + \ifnum #1#2>#3 \xint_dothis\XINT_FL_pfac_outofrange\fi + \ifnum #3>\xint_c_x^viii_mone + \xint_dothis\XINT_FL_pfac_outofrange\fi + \xint_orthat \XINT_FL_pfac_increaseP #1#2.#3.% }% -\def\XINT_FL_sqrt_checkifzeroorneg #1% +\def\XINT_FL_pfac_outofrange #1.#2.#3#4#5{\xintError:OutOfRangePFac #5{0/1[0]}}% +\def\XINT_FL_pfac_one #1.#2.#3#4#5{#5{1/1[0]}}% +% \end{macrocode} +% \lverb|See the comments for \XINT_FL_pfac_increaseP. Case of b=a+1 should be +% filtered out perhaps. We only needed here to copy the \xintPFactorial macros and +% re-use \XINT_FL_fac_mul/\XINT_FL_fac_out. Had to modify a bit +% \XINT_FL_pfac_addzeroes. We can enter here directly with #3 equal to specify +% the precision (the calculated value before final rounding has a relative +% error less than #3.10^{-#4-1}), and #5 would hold the macro doing the final +% rounding (or truncating, if I make a FloatTrunc available) to a given number +% of digits, possibly not #4. By default the #3 is 1, but FloatBinomial calls +% it with #3=4.| +% \begin{macrocode} +\def\XINT_FL_pfac_increaseP #1.#2.#3#4% {% - \xint_UDzerominusfork - #1-\XINT_FL_sqrt_iszero - 0#1\XINT_FL_sqrt_isneg - 0-{\XINT_FL_sqrt_b #1}% - \krof + \expandafter\XINT_FL_pfac_a + \the\numexpr \xint_c_viii*((\xint_c_iv+#4+\expandafter + \XINT_FL_fac_countdigits\the\numexpr (#2-#1-\xint_c_i)% + /\ifnum #2>\xint_c_x^iv #3\else(#3*\xint_c_ii)\fi\relax + 87654321\Z)/\xint_c_viii).#1.#2.% }% -\def\XINT_FL_sqrt_iszero #1[#2]{0[0]}% -\def\XINT_FL_sqrt_isneg #1[#2]{\xintError:RootOfNegative 0[0]}% -\def\XINT_FL_sqrt_b #1[#2]% +\def\XINT_FL_pfac_a #1.#2.#3.% {% - \ifodd #2 - \xint_afterfi{\XINT_FL_sqrt_c 01}% - \else - \xint_afterfi{\XINT_FL_sqrt_c {}0}% - \fi - {#1}{#2}% + \expandafter\XINT_FL_pfac_b\the\numexpr \xint_c_i+#2\expandafter.% + \the\numexpr#3\expandafter.% + \romannumeral0\XINT_FL_pfac_addzeroes #1.100000001!1\Z![-#1]% }% -\def\XINT_FL_sqrt_c #1#2#3#4% +\def\XINT_FL_pfac_addzeroes #1.% {% - \expandafter\XINT_flsqrt\expandafter {\the\numexpr #4-#2}{#3#1}% + \ifnum #1=\xint_c_viii \expandafter\XINT_FL_pfac_addzeroes_exit\fi + \expandafter\XINT_FL_pfac_addzeroes\the\numexpr #1-\xint_c_viii.100000000!% }% -\def\XINT_flsqrt #1#2% +\def\XINT_FL_pfac_addzeroes_exit #1.{ }% +\def\XINT_FL_pfac_b #1.% {% - \expandafter\XINT_sqrt_a - \expandafter{\romannumeral0\xintlength {#2}}\XINT_flsqrt_big_d {#2}{#1}% + \ifnum #1>9999 \xint_dothis\XINT_FL_pfac_vbigloop \fi + \ifnum #1>463 \xint_dothis\XINT_FL_pfac_bigloop \fi + \ifnum #1>98 \xint_dothis\XINT_FL_pfac_medloop \fi + \xint_orthat\XINT_FL_pfac_smallloop #1.% }% -\def\XINT_flsqrt_big_d #1#2% +\def\XINT_FL_pfac_smallloop #1.#2.% {% - \ifodd #2 - \expandafter\expandafter\expandafter\XINT_flsqrt_big_eB - \else - \expandafter\expandafter\expandafter\XINT_flsqrt_big_eA - \fi - \expandafter {\the\numexpr (#2-\xint_c_i)/\xint_c_ii }{#1}% + \ifcase\numexpr #2-#1\relax + \expandafter\XINT_FL_pfac_end_ + \or \expandafter\XINT_FL_pfac_end_i + \or \expandafter\XINT_FL_pfac_end_ii + \or \expandafter\XINT_FL_pfac_end_iii + \else\expandafter\XINT_FL_pfac_smallloop_a + \fi #1.#2.% }% -\def\XINT_flsqrt_big_eA #1#2#3% +\def\XINT_FL_pfac_smallloop_a #1.#2.% {% - \XINT_flsqrt_big_eA_a #3\Z {#2}{#1}{#3}% + \expandafter\XINT_FL_pfac_smallloop_b + \the\numexpr #1+\xint_c_iv\expandafter.% + \the\numexpr #2\expandafter.% + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% }% -\def\XINT_flsqrt_big_eA_a #1#2#3#4#5#6#7#8#9\Z +\def\XINT_FL_pfac_smallloop_b #1.% {% - \XINT_flsqrt_big_eA_b {#1#2#3#4#5#6#7#8}% + \ifnum #1>98 \expandafter\XINT_FL_pfac_medloop \else + \expandafter\XINT_FL_pfac_smallloop \fi #1.% }% -\def\XINT_flsqrt_big_eA_b #1#2% +\def\XINT_FL_pfac_medloop #1.#2.% {% - \expandafter\XINT_flsqrt_big_f - \romannumeral0\XINT_flsqrt_small_e {#2001}{#1}% + \ifcase\numexpr #2-#1\relax + \expandafter\XINT_FL_pfac_end_ + \or \expandafter\XINT_FL_pfac_end_i + \or \expandafter\XINT_FL_pfac_end_ii + \else\expandafter\XINT_FL_pfac_medloop_a + \fi #1.#2.% }% -\def\XINT_flsqrt_big_eB #1#2#3% +\def\XINT_FL_pfac_medloop_a #1.#2.% {% - \XINT_flsqrt_big_eB_a #3\Z {#2}{#1}{#3}% + \expandafter\XINT_FL_pfac_medloop_b + \the\numexpr #1+\xint_c_iii\expandafter.% + \the\numexpr #2\expandafter.% + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% }% -\def\XINT_flsqrt_big_eB_a #1#2#3#4#5#6#7#8#9% +\def\XINT_FL_pfac_medloop_b #1.% {% - \XINT_flsqrt_big_eB_b {#1#2#3#4#5#6#7#8#9}% + \ifnum #1>463 \expandafter\XINT_FL_pfac_bigloop \else + \expandafter\XINT_FL_pfac_medloop \fi #1.% }% -\def\XINT_flsqrt_big_eB_b #1#2\Z #3% +\def\XINT_FL_pfac_bigloop #1.#2.% {% - \expandafter\XINT_flsqrt_big_f - \romannumeral0\XINT_flsqrt_small_e {#30001}{#1}% + \ifcase\numexpr #2-#1\relax + \expandafter\XINT_FL_pfac_end_ + \or \expandafter\XINT_FL_pfac_end_i + \else\expandafter\XINT_FL_pfac_bigloop_a + \fi #1.#2.% }% -\def\XINT_flsqrt_small_e #1#2% +\def\XINT_FL_pfac_bigloop_a #1.#2.% {% - \expandafter\XINT_flsqrt_small_f\expandafter - {\the\numexpr #1*#1-#2-\xint_c_i}{#1}% + \expandafter\XINT_FL_pfac_bigloop_b + \the\numexpr #1+\xint_c_ii\expandafter.% + \the\numexpr #2\expandafter.% + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!% }% -\def\XINT_flsqrt_small_f #1#2% +\def\XINT_FL_pfac_bigloop_b #1.% {% - \expandafter\XINT_flsqrt_small_g\expandafter - {\the\numexpr (#1+#2)/(2*#2)-\xint_c_i }{#1}{#2}% + \ifnum #1>9999 \expandafter\XINT_FL_pfac_vbigloop \else + \expandafter\XINT_FL_pfac_bigloop \fi #1.% }% -\def\XINT_flsqrt_small_g #1% +\def\XINT_FL_pfac_vbigloop #1.#2.% {% - \ifnum #1>\xint_c_ - \expandafter\XINT_flsqrt_small_h - \else - \expandafter\XINT_flsqrt_small_end - \fi - {#1}% + \ifnum #2=#1 + \expandafter\XINT_FL_pfac_end_ + \else\expandafter\XINT_FL_pfac_vbigloop_a + \fi #1.#2.% }% -\def\XINT_flsqrt_small_h #1#2#3% +\def\XINT_FL_pfac_vbigloop_a #1.#2.% {% - \expandafter\XINT_flsqrt_small_f\expandafter - {\the\numexpr #2-\xint_c_ii*#1*#3+#1*#1\expandafter}\expandafter - {\the\numexpr #3-#1}% + \expandafter\XINT_FL_pfac_vbigloop + \the\numexpr #1+\xint_c_i\expandafter.% + \the\numexpr #2\expandafter.% + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr\xint_c_x^viii+#1!% }% -\def\XINT_flsqrt_small_end #1#2#3% +\def\XINT_FL_pfac_end_iii #1.#2.% {% - \expandafter\space\expandafter - {\the\numexpr \xint_c_i+#3*\xint_c_x^iv- - (#2*\xint_c_x^iv+#3)/(\xint_c_ii*#3)}% + \expandafter\XINT_FL_fac_out + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% }% -\def\XINT_flsqrt_big_f #1% +\def\XINT_FL_pfac_end_ii #1.#2.% {% - \expandafter\XINT_flsqrt_big_fa\expandafter - {\romannumeral0\xintiisqr {#1}}{#1}% + \expandafter\XINT_FL_fac_out + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% }% -\def\XINT_flsqrt_big_fa #1#2#3#4% +\def\XINT_FL_pfac_end_i #1.#2.% {% - \expandafter\XINT_flsqrt_big_fb\expandafter - {\romannumeral0\XINT_dsx_addzerosnofuss - {\numexpr #3-\xint_c_viii\relax}{#2}}% - {\romannumeral0\xintiisub - {\XINT_dsx_addzerosnofuss - {\numexpr \xint_c_ii*(#3-\xint_c_viii)\relax}{#1}}{#4}}% - {#3}% + \expandafter\XINT_FL_fac_out + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!% }% -\def\XINT_flsqrt_big_fb #1#2% +\def\XINT_FL_pfac_end_ #1.#2.% {% - \expandafter\XINT_flsqrt_big_g\expandafter {#2}{#1}% + \expandafter\XINT_FL_fac_out + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr \xint_c_x^viii+#1!% }% -\def\XINT_flsqrt_big_g #1#2% +% \end{macrocode} +% \subsection{\csh{xintFloatBinomial}, \csh{XINTinFloatBinomial}} +% \lverb|1.2f. We compute binomial(x,y) as pfac(x-y,x)/y!, where the numerator +% and denominator are computed with a relative error at most 4.10^{-P-2}, then +% rounded (once I have a float truncation, I will use truncation rather) to +% P+3 digits, and finally the quotient is correctly rounded to P digits. This +% will guarantee that the exact value X differs from the computed one Y by at +% most 0.6 ulp(Y). (2015/12/01).| +% \begin{macrocode} +\def\xintFloatBinomial {\romannumeral0\xintfloatbinomial}% +\def\xintfloatbinomial #1{\XINT_flbinom_chkopt \xintfloat #1\xint_relax }% +\def\XINTinFloatBinomial {\romannumeral0\XINTinfloatbinomial }% +\def\XINTinfloatbinomial #1{\XINT_flbinom_chkopt \XINTinfloat #1\xint_relax }% +\def\XINT_flbinom_chkopt #1#2% {% - \expandafter\XINT_flsqrt_big_j - \romannumeral0\xintiidivision - {#1}{\romannumeral0\XINT_dbl_pos #2\Z}{#2}% + \ifx [#2\expandafter\XINT_flbinom_opt + \else\expandafter\XINT_flbinom_noopt + \fi #1#2% }% -\def\XINT_flsqrt_big_j #1% +\def\XINT_flbinom_noopt #1#2\xint_relax #3% {% - \if0\XINT_Sgn #1\Z - \expandafter \XINT_flsqrt_big_end_a - \else \expandafter \XINT_flsqrt_big_k - \fi {#1}% + \expandafter\XINT_FL_binom_a + \the\numexpr\xintNum{#2}\expandafter.\the\numexpr\xintNum{#3}.\XINTdigits.#1% }% -\def\XINT_flsqrt_big_k #1#2#3% +\def\XINT_flbinom_opt #1[\xint_relax #2]#3#4% {% - \expandafter\XINT_flsqrt_big_l\expandafter - {\romannumeral0\xintiisub {#3}{#1}}% - {\romannumeral0\xintiiadd {#2}{\romannumeral0\XINT_sqr #1\Z}}% + \expandafter\XINT_FL_binom_a + \the\numexpr\xintNum{#3}\expandafter.\the\numexpr\xintNum{#4}\expandafter.% + \the\numexpr #2.#1% }% -\def\XINT_flsqrt_big_l #1#2% +\def\XINT_FL_binom_a #1.#2.% {% - \expandafter\XINT_flsqrt_big_g\expandafter - {#2}{#1}% + \expandafter\XINT_FL_binom_fork \the\numexpr #1-#2.#2.#1.% +}% +\def\XINT_FL_binom_fork #1#2.#3#4.#5.% +{% + \if-#1\xint_dothis \XINT_FL_binom_outofrange\fi + \if-#3\xint_dothis \XINT_FL_binom_outofrange\fi + \if0#1\xint_dothis \XINT_FL_binom_one\fi + \if0#3\xint_dothis \XINT_FL_binom_one\fi + \ifnum #5>\xint_c_x^viii_mone \xint_dothis\XINT_FL_binom_outofrange\fi + \ifnum #1#2>#3#4 \xint_dothis\XINT_FL_binom_ab \fi + \xint_orthat\XINT_FL_binom_aa + #1#2.#3#4.#5.% +}% +\def\XINT_FL_binom_outofrange #1.#2.#3.#4.#5% + {\xintError:OutOfRangeBinomial #5[#4]{0/1[0]}}% +\def\XINT_FL_binom_one #1.#2.#3.#4.#5{#5[#4]{1/1[0]}}% +\def\XINT_FL_binom_aa #1.#2.#3.#4.#5% +{% + #5[#4]{\xintDiv{\XINT_FL_pfac_increaseP + #2.#3.\xint_c_iv{#4+\xint_c_i}{\XINTinfloat[#4+\xint_c_iii]}}% + {\XINT_FL_fac_fork_b + #1.\xint_c_iv{#4+\xint_c_i}\XINT_FL_fac_out{\XINTinfloat[#4+\xint_c_iii]}}}% +}% +\def\XINT_FL_binom_ab #1.#2.#3.#4.#5% +{% + #5[#4]{\xintDiv{\XINT_FL_pfac_increaseP + #1.#3.\xint_c_iv{#4+\xint_c_i}{\XINTinfloat[#4+\xint_c_iii]}}% + {\XINT_FL_fac_fork_b + #2.\xint_c_iv{#4+\xint_c_i}\XINT_FL_fac_out{\XINTinfloat[#4+\xint_c_iii]}}}% +}% +% \end{macrocode} +% \subsection{\csh{xintFloatSqrt}, \csh{XINTinFloatSqrt}} +% \lverb|First done for 1.08. +% +% The float version was developed at the same time as the integer one and even +% a bit earlier. As a result the integer variant had some sub-optimal parts. +% Anyway, for 1.2f I have rewritten the integer variant, and the float variant +% delegates all preparatory wrok for it until the last step. In particular the +% very low precisions are not penalized anymore from doing computations for at +% least 17 or 18 digits. Both the large and small precisions give quite +% shorter computation times. +% +% Also, after examining more closely the achieved precision I decided to +% extend the float version in order for it to obtain the correct rounding (for +% inputs already of at most P digits with P the precision) of the theoretical +% exact value. +% +% Beyond about 500 digits of precision the efficiency decreases swiftly, +% as is the case generally speaking with xintcore/xint/xintfrac arithmetic +% macros. +% +% Final note: with 1.2f the input is always first rounded to P significant +% places. +% +% +% | +% \begin{macrocode} +\def\xintFloatSqrt {\romannumeral0\xintfloatsqrt }% +\def\xintfloatsqrt #1{\XINT_flsqrt_chkopt \xintfloat #1\xint_relax }% +\def\XINTinFloatSqrt {\romannumeral0\XINTinfloatsqrt }% +\def\XINTinfloatsqrt #1{\XINT_flsqrt_chkopt \XINTinfloat #1\xint_relax }% +\def\XINT_flsqrt_chkopt #1#2% +{% + \ifx [#2\expandafter\XINT_flsqrt_opt + \else\expandafter\XINT_flsqrt_noopt + \fi #1#2% +}% +\def\XINT_flsqrt_noopt #1#2\xint_relax +{% + \expandafter\XINT_FL_sqrt_a + \romannumeral0\XINTinfloat[\XINTdigits]{#2}\XINTdigits.#1% +}% +\def\XINT_flsqrt_opt #1[\xint_relax #2]%#3% +{% + \expandafter\XINT_flsqrt_opt_a\the\numexpr #2.#1% +}% +\def\XINT_flsqrt_opt_a #1.#2#3% +{% + \expandafter\XINT_FL_sqrt_a\romannumeral0\XINTinfloat[#1]{#3}#1.#2% +}% +\def\XINT_FL_sqrt_a #1% +{% + \xint_UDzerominusfork + #1-\XINT_FL_sqrt_iszero + 0#1\XINT_FL_sqrt_isneg + 0-{\XINT_FL_sqrt_pos #1}% + \krof +}%[ +\def\XINT_FL_sqrt_iszero #1]#2.#3{#3[#2]{0[0]}}% +\def\XINT_FL_sqrt_isneg #1]#2.#3{\xintError:RootOfNegative #3[#2]{0[0]}}% +\def\XINT_FL_sqrt_pos #1[#2]#3.% +{% + \expandafter\XINT_flsqrt + \the\numexpr #3\ifodd #2 \xint_dothis {+\xint_c_iii.(#2+\xint_c_i).0}\fi + \xint_orthat {+\xint_c_ii.#2.{}}#100.#3.% }% -\def\XINT_flsqrt_big_end_a #1#2#3#4#5% +\def\XINT_flsqrt #1.#2.% {% - \expandafter\XINT_flsqrt_big_end_b\expandafter - {\the\numexpr -#4+#5/\xint_c_ii\expandafter}\expandafter - {\romannumeral0\xintiisub - {\XINT_dsx_addzerosnofuss {#4}{#3}}% - {\xintHalf{\xintiiQuo{\XINT_dsx_addzerosnofuss {#4}{#2}}{#3}}}}% + \expandafter\XINT_flsqrt_a + \the\numexpr #2/\xint_c_ii-(#1-\xint_c_i)/\xint_c_ii.#1.% }% -\def\XINT_flsqrt_big_end_b #1#2{#2[#1]}% +\def\XINT_flsqrt_a #1.#2.#3#4.#5.% +{% + \expandafter\XINT_flsqrt_b + \the\numexpr (#2-\xint_c_i)/\xint_c_ii\expandafter.% + \romannumeral0\XINT_sqrt_start #2.#4#3.#5.#2.#4#3.#5.#1.% +}% +\def\XINT_flsqrt_b #1.#2#3% +{% + \expandafter\XINT_flsqrt_c + \romannumeral0\xintiisub + {\XINT_dsx_addzerosnofuss {#1}{#2}}% + {\xintiiDivRound{\XINT_dsx_addzerosnofuss {#1}{#3}}{\XINT_dbl_pos#2\Z}}.% +}% +\def\XINT_flsqrt_c #1.#2.% +{% + \expandafter\XINT_flsqrt_d + \romannumeral0\XINT_split_fromleft_loop #2.{}#1\W\W\W\W\W\W\W\W\Z +}% +\def\XINT_flsqrt_d #1.#2#3.% +{% + \ifnum #2=\xint_c_v + \expandafter\XINT_flsqrt_f\else\expandafter\XINT_flsqrt_finish\fi + #2#3.#1.% +}% +\def\XINT_flsqrt_finish #1#2.#3.#4.#5.#6.#7.#8{#8[#6]{#3#1[#7]}}% +\def\XINT_flsqrt_f 5#1.% + {\xintiiifGt{\xintiNum{#1}}{2}{\XINT_flsqrt_finish 5.}{\XINT_flsqrt_again}}% +\def\XINT_flsqrt_again #1.#2.% +{% + \expandafter\XINT_flsqrt_again_a\the\numexpr #2+\xint_c_viii.% +}% +\def\XINT_flsqrt_again_a #1.#2.#3.% +{% + \expandafter\XINT_flsqrt_b + \the\numexpr (#1-\xint_c_i)/\xint_c_ii\expandafter.% + \romannumeral0\XINT_sqrt_start #1.#200000000.#3.% + #1.#200000000.#3.% +}% +% \end{macrocode} +% \subsection{\csh{xintFloatE}, \csh{XINTinFloatE}} +% \begin{macrocode} +\def\xintFloatE {\romannumeral0\xintfloate }% +\def\xintfloate #1{\XINT_floate_chkopt #1\xint_relax }% +\def\XINT_floate_chkopt #1% +{% + \ifx [#1\expandafter\XINT_floate_opt + \else\expandafter\XINT_floate_noopt + \fi #1% +}% +\def\XINT_floate_noopt #1\xint_relax +{% + \expandafter\XINT_floate_a\expandafter\XINTdigits + \romannumeral0\XINT_infrac {#1}% +}% +\def\XINT_floate_opt [\xint_relax #1]#2% +{% + \expandafter\XINT_floate_a\expandafter + {\the\numexpr #1\expandafter}\romannumeral0\XINT_infrac {#2}% +}% +\def\XINT_floate_a #1#2#3#4#5% +{% + \expandafter\XINT_float_a\the\numexpr#1\expandafter.% + \expandafter{\the\numexpr #2+#5}{#3}{#4}\XINT_float_Q +}% +\def\XINTinFloatE {\romannumeral0\XINTinfloate }% +\def\XINTinfloate + {\expandafter\XINT_infloate\romannumeral0\XINTinfloat [\XINTdigits]}% +\def\XINT_infloate #1[#2]#3% + {\expandafter\XINT_infloate_end\the\numexpr #3+#2.{#1}}% +\def\XINT_infloate_end #1.#2{ #2[#1]}% +% \end{macrocode} +% \subsection{\csh{XINTinFloatMod}} +% \begin{macrocode} +\def\XINTinFloatMod {\romannumeral0\XINTinfloatmod [\XINTdigits]}% +\def\XINTinfloatmod [#1]#2#3{\expandafter\XINT_infloatmod\expandafter + {\romannumeral0\XINTinfloat[#1]{#2}}% + {\romannumeral0\XINTinfloat[#1]{#3}}{#1}}% +\def\XINT_infloatmod #1#2{\expandafter\XINT_infloatmod_a\expandafter {#2}{#1}}% +\def\XINT_infloatmod_a #1#2#3{\XINTinfloat [#3]{\xintMod {#2}{#1}}}% \XINT_restorecatcodes_endinput% % \end{macrocode} -%\catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11 -%\let</xintfrac>\relax -%\def<*xintseries>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 } -%</xintfrac> -%<*xintseries> % % \StoreCodelineNo {xintfrac} % +%\gardesactifs +%\let</xintfrac>\relax +%\let<*xintseries>\gardesinactifs +%</xintfrac>^^A--------------------------------------------------- +%<*xintseries>^^A------------------------------------------------- +% \clearpage % \section{Package \xintseriesnameimp implementation} % \label{sec:seriesimp} % @@ -25862,13 +27052,9 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintseries}% - [2015/11/22 v1.2e Expandable partial sums with xint package (jfB)]% + [2016/03/12 1.2f Expandable partial sums with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintSeries}} -% \lverb|& -% Modified in 1.06 to give the indices first to a \numexpr rather than expanding -% twice. I just use \the\numexpr and maintain the previous code after that. -% 1.08a adds the forgotten optimization following that previous change.| % \begin{macrocode} \def\xintSeries {\romannumeral0\xintseries }% \def\xintseries #1#2% @@ -25898,10 +27084,6 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{\csh{xintiSeries}} -% \lverb|& -% Modified in 1.06 to give the indices first to a \numexpr rather than expanding -% twice. I just use \the\numexpr and maintain the previous code after that. -% 1.08a adds the forgotten optimization following that previous change.| % \begin{macrocode} \def\xintiSeries {\romannumeral0\xintiseries }% \def\xintiseries #1#2% @@ -26055,7 +27237,7 @@ $1$ or $-1$. % \end{macrocode} % \subsection{\csh{xintRationalSeriesX}} % \lverb|& -% a,b,initial,ratiofunction,x$\ +% a,b,initial,ratiofunction,x$\ % This computes F(a,x)+...+F(b,x) on the basis of the value of F(a,x) and the % ratios F(n,x)/F(n-1,x). The argument x is first expanded and it is the value % resulting from this which is used then throughout. The initial term F(a,x) @@ -26147,7 +27329,7 @@ $1$ or $-1$. % \end{macrocode} % \subsection{\csh{xintFxPtPowerSeriesX}} % \lverb|& -% a,b,coeff,x,D$\ +% a,b,coeff,x,D$\ % Modified in 1.06 to give the indices first to a \numexpr rather than expanding % twice. I just use \the\numexpr and maintain the previous code after that. % 1.08a adds the forgotten optimization following that previous change.| @@ -26289,14 +27471,15 @@ $1$ or $-1$. }% \XINT_restorecatcodes_endinput% % \end{macrocode} -%\catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11 -%\let</xintseries>\relax -%\def<*xintcfrac>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 } -%</xintseries> -%<*xintcfrac> % % \StoreCodelineNo {xintseries} % +%\gardesactifs +%\let</xintseries>\relax +%\let<*xintcfrac>\gardesinactifs +%</xintseries>^^A------------------------------------------------- +%<*xintcfrac>^^A-------------------------------------------------- +% \clearpage % \section{Package \xintcfracnameimp implementation} % \label{sec:cfracimp} % @@ -26367,7 +27550,7 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintcfrac}% - [2015/11/22 v1.2e Expandable continued fractions with xint package (jfB)]% + [2016/03/12 1.2f Expandable continued fractions with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintCFrac}} % \begin{macrocode} @@ -27465,14 +28648,15 @@ $1$ or $-1$. \def\XINT_gctgc_end_b #1#2#3{ #3{#1}}% \XINT_restorecatcodes_endinput% % \end{macrocode} -%\catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11 -%\let</xintcfrac>\relax -%\def<*xintexpr>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 } -%</xintcfrac> -%<*xintexpr> % % \StoreCodelineNo {xintcfrac} % +%\gardesactifs +%\let</xintcfrac>\relax +%\let<*xintexpr>\gardesinactifs +%</xintcfrac>^^A-------------------------------------------------- +%<*xintexpr>^^A--------------------------------------------------- +% \clearpage % \section{Package \xintexprnameimp implementation} % \label{sec:exprimp} % @@ -27579,7 +28763,7 @@ $1$ or $-1$. % \item multi-letter infix binary words |'and'|, |'or'|, |'xor'|, |'mod'| % (quotes mandatory), % -% \item functions |even|, |odd|, +% \item functions |even|, |odd|, % % \item |\xintdefvar A3:=3.1415;| for variable definitions (non expandable, % naturally), usable in subsequent expressions; variable names may contain @@ -27635,7 +28819,7 @@ $1$ or $-1$. % \end{description} % % Comments dating back to earlier releases: -% +% % Roughly speaking, the parser mechanism is as follows: at any given time the % last found ``operator'' has its associated |until| macro awaiting some news % from the token flow; first |getnext| expands forward in the hope to construct @@ -27668,7 +28852,7 @@ $1$ or $-1$. % % \begin{description} % \item[{|1.08b [2013/06/14]|}] corrected a problem originating in the attempt -% to attribute a special rôle to braces: expansion could be stopped by space +% to attribute a special rôle to braces: expansion could be stopped by space % tokens, as various macros tried to expand without grabbing what came next. % They now have a doubled |\romannumeral-`0|. % @@ -27685,7 +28869,7 @@ $1$ or $-1$. % |\xintboolexpr|, and |\xintNewNumExpr|, |\xintNewBoolExpr|. The code for % |\xintNewExpr| is shared with |float|, |num|, and |bool|-expressions. Also the % precedence level of the postfix operators |!|, |?| and |:| has been made lower -% than the one of functions. +% than the one of functions. % % \item[{|1.09i| |[2013/12/18]|}] unpacks count and dimen registers and control % squences, with tacit multiplication. It has also made small improvements. @@ -27796,7 +28980,7 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintexpr}% - [2015/11/22 v1.2e Expandable expression parser (jfB)]% + [2016/03/12 1.2f Expandable expression parser (JFB)]% \catcode`! 11 % \end{macrocode} % \subsection{Locking and unlocking} @@ -27823,13 +29007,13 @@ $1$ or $-1$. % fractional part), and in a second stage to apply \xintHexToDec to do the % actual conversion. This should be faster than updating on the fly the number % (which would be hard for the fraction part...). The macro \xintHexToDec -% could probably be made faster by using techniques similar as the ones v1.2 +% could probably be made faster by using techniques similar as the ones 1.2 % uses in xintcore.sty.| % \begin{macrocode} \def\xint_gob_til_! #1!{}% catcode 11 ! default in xintexpr.sty code. \edef\XINT_expr_lockscan#1!% not used for decimal numbers in xintexpr 1.2 {\noexpand\expandafter\space\noexpand\csname .=#1\endcsname }% -\edef\XINT_expr_lockit +\edef\XINT_expr_lockit #1{\noexpand\expandafter\space\noexpand\csname .=#1\endcsname }% \def\XINT_expr_unlock_hex_in #1% expanded inside \csname..\endcsname {\expandafter\XINT_expr_inhex\romannumeral`&&@\XINT_expr_unlock#1;}% @@ -27841,7 +29025,6 @@ $1$ or $-1$. [\the\numexpr-4*\xintLength{#3}]% \fi }% -%%%%%%%%%%%% \def\XINT_expr_unlock {\expandafter\XINT_expr_unlock_a\string }% \def\XINT_expr_unlock_a #1.={}% \def\XINT_expr_unexpectedtoken {\xintError:ignored }% @@ -27871,11 +29054,11 @@ $1$ or $-1$. \def\xintiexpr {\romannumeral0\xintieval }% \def\xintfloatexpr {\romannumeral0\xintfloateval }% \def\xintiiexpr {\romannumeral0\xintiieval }% -\def\xinttheexpr +\def\xinttheexpr {\romannumeral`&&@\expandafter\XINT_expr_print\romannumeral0\xintbareeval }% \def\xinttheiexpr {\romannumeral`&&@\xintthe\xintiexpr }% \def\xintthefloatexpr {\romannumeral`&&@\xintthe\xintfloatexpr }% -\def\xinttheiiexpr +\def\xinttheiiexpr {\romannumeral`&&@\expandafter\XINT_iiexpr_print\romannumeral0\xintbareiieval }% % \end{macrocode} % \subsection{\csh{xintthe}} @@ -27884,7 +29067,7 @@ $1$ or $-1$. % \end{macrocode} % \subsection{\csh{xintthecoords}} % \lverb|1.1 Wraps up an even number of comma separated items into pairs of -% TikZ coordinates; for use in the following way: +% TikZ coordinates; for use in the following way: % % coordinates {\xintthecoords\xintfloatexpr ... \relax} % @@ -27910,11 +29093,11 @@ $1$ or $-1$. % \end{macrocode} % \subsection{\csh{xintbareeval}, \csh{xintbarefloateval}, \csh{xintbareiieval}} % \begin{macrocode} -\def\xintbareeval +\def\xintbareeval {\expandafter\XINT_expr_until_end_a\romannumeral`&&@\XINT_expr_getnext }% -\def\xintbarefloateval +\def\xintbarefloateval {\expandafter\XINT_flexpr_until_end_a\romannumeral`&&@\XINT_expr_getnext }% -\def\xintbareiieval +\def\xintbareiieval {\expandafter\XINT_iiexpr_until_end_a\romannumeral`&&@\XINT_expr_getnext }% % \end{macrocode} % \subsection{\csh{xintthebareeval}, \csh{xintthebarefloateval}, \csh{xintthebareiieval}} @@ -27933,18 +29116,18 @@ $1$ or $-1$. % \begin{macrocode} \def\xintieval #1% {\ifx [#1\expandafter\XINT_iexpr_withopt\else\expandafter\XINT_iexpr_noopt \fi #1}% -\def\XINT_iexpr_noopt +\def\XINT_iexpr_noopt {\expandafter\XINT_iexpr_wrap \expandafter 0\romannumeral0\xintbareeval }% \def\XINT_iexpr_withopt [#1]% {% \expandafter\XINT_iexpr_wrap\expandafter {\the\numexpr \xint_zapspaces #1 \xint_gobble_i\expandafter}% - \romannumeral0\xintbareeval + \romannumeral0\xintbareeval }% \def\XINT_iexpr_wrap #1#2% {% \expandafter\XINT_expr_wrap - \csname .=\xintRound::csv {#1}{\XINT_expr_unlock #2}\endcsname + \csname .=\xintRound::csv {#1}{\XINT_expr_unlock #2}\endcsname }% % \end{macrocode} % \subsection{\csh{xintfloateval}, \csh{XINT_flexpr_wrap}, \csh{XINT_flexpr_print}} @@ -27958,18 +29141,18 @@ $1$ or $-1$. \def\XINT_flexpr_noopt {% \expandafter\XINT_flexpr_withopt_b\expandafter\xinttheDigits - \romannumeral0\xintbarefloateval + \romannumeral0\xintbarefloateval }% \def\XINT_flexpr_withopt_a [#1]% {% \expandafter\XINT_flexpr_withopt_b\expandafter {\the\numexpr\xint_zapspaces #1 \xint_gobble_i\expandafter}% - \romannumeral0\xintbarefloateval + \romannumeral0\xintbarefloateval }% \def\XINT_flexpr_withopt_b #1#2% {% \expandafter\XINT_flexpr_wrap\csname .;#1.=% ; and not : as before b'cause NewExpr - \XINTinFloat::csv {#1}{\XINT_expr_unlock #2}\endcsname + \XINTinFloat::csv {#1}{\XINT_expr_unlock #2}\endcsname }% \def\XINT_flexpr_wrap { !\XINT_expr_usethe\XINT_protectii\XINT_flexpr_print }% \def\XINT_flexpr_print #1% @@ -28002,17 +29185,13 @@ $1$ or $-1$. % \lverb|Changed completely for 1.1, which adds the optional arguments to % \xintiexpr and \xintfloatexpr.| % \subsubsection{\csh{XINT_::_end}} -% \lverb|Le mécanisme est le suivant, #2 est dans des accolades et commence par -% ,<sp>. Donc le gobble se débarrasse du, et le <sp> après brace stripping -% arrête un \romannumeral0 ou \romannumeral-`0| +% \lverb|Le mécanisme est le suivant, #2 est dans des accolades et commence par +% ,<sp>. Donc le gobble se débarrasse du, et le <sp> après brace stripping +% arrête un \romannumeral0 ou \romannumeral-`0| % \begin{macrocode} \def\XINT_::_end #1,#2{\xint_gobble_i #2}% % \end{macrocode} % \subsubsection{\csh{xintCSV::csv}} -% \lverb|pour \xinttheiiexpr. 1.1a adds the \romannumeral-`0 for each item, -% which have no use for \xintiiexpr etc..., but are necessary for \xintNewExpr -% to be able to handle comma separated inputs. I am not sure but I think I had -% them just prior to releasing 1.1 but removed them foolishsly.| % \begin{macrocode} \def\xintCSV::csv #1{\expandafter\XINT_csv::_a\romannumeral`&&@#1,^,}% \def\XINT_csv::_a {\XINT_csv::_b {}}% @@ -28021,13 +29200,6 @@ $1$ or $-1$. \def\XINT_csv::_d #1,#2{\XINT_csv::_b {#2, #1}}% possibly, item #1 is empty. % \end{macrocode} % \subsubsection{\csh{xintSPRaw}, \csh{xintSPRaw::csv}} -% \lverb|Pour \xinttheexpr. -% J'avais voulu optimiser en testant si présence ou non de [N], -% cependant reduce() produit résultat sans, et du coup, le /1 peut ne pas -% être retiré. Bon je rajoute un [0] dans reduce. 14/10/25 au moment de -% boucler. -% -% Same added \romannumeral-`0 in 1.1a for \xintNewExpr purposes.| % \begin{macrocode} \def\xintSPRaw {\romannumeral0\xintspraw }% \def\xintspraw #1{\expandafter\XINT_spraw\romannumeral`&&@#1[\W]}% @@ -28055,10 +29227,6 @@ $1$ or $-1$. \def\XINT_istrue::_e #1,#2{\XINT_istrue::_b {#2, #1}}% % \end{macrocode} % \subsubsection{\csh{xintRound::csv}} -% \lverb|Pour \xintiexpr avec argument optionnel (finalement, malgré un -% certain overhead lors de l'exécution, pour économiser du code je ne -% distingue plus les deux cas). Reason for annoying expansion bridge is -% related to \xintNewExpr. Attention utilise \XINT_:::_end.| % \begin{macrocode} \def\XINT_:::_end #1,#2#3{\xint_gobble_i #3}% \def\xintRound::csv #1#2{\romannumeral0\expandafter\XINT_round::_b\expandafter @@ -28073,15 +29241,6 @@ $1$ or $-1$. \def\XINT_round::_e #1,#2#3{\XINT_round::_b {#2}{#3, #1}}% % \end{macrocode} % \subsubsection{\csh{XINTinFloat::csv}} -% \lverb|Pour \xintfloatexpr. Attention, prépare sous la forme digits[N] pour -% traitement par les macros. Pas utilisé en sortie. Utilise \XINT_:::_end. -% -% 1.1a: I believe this is not needed for \xintNewExpr, as it is removed by -% re-defined \XINT_flexpr_wrap code, hence no need to add the extra -% \romannumeral-`0. Sub-expressions in \xintNewExpr are not supported. -% -% I didn't start and don't want now to think about it at all. -%| % \begin{macrocode} \def\XINTinFloat::csv #1#2{\romannumeral0\expandafter\XINT_infloat::_b\expandafter {\the\numexpr #1\expandafter}\expandafter{\expandafter}\romannumeral`&&@#2,^,}% @@ -28094,8 +29253,6 @@ $1$ or $-1$. \def\XINT_infloat::_e #1,#2#3{\XINT_infloat::_b {#2}{#3, #1}}% % \end{macrocode} % \subsubsection{\csh{xintPFloat::csv}} -% \lverb|Expansion à cause de \xintNewExpr. Attention à l'ordre, pas le même que pour -% \XINTinFloat::csv. Donc c'est cette routine qui imprime. Utilise \XINT_:::_end| % \begin{macrocode} \def\xintPFloat::csv #1#2{\romannumeral0\expandafter\XINT_pfloat::_b\expandafter {\the\numexpr #1\expandafter}\expandafter{\expandafter}\romannumeral`&&@#2,^,}% @@ -28164,7 +29321,7 @@ $1$ or $-1$. % \lverb@1.2 release has replaced chains of \romannumeral-`0 by \csname % governed expansion. Thus there is no more the limit at about 5000 digits for % parsed numbers. -% +% % In order to avoid having to lock and unlock in succession to handle the % scientific part and adjust the exponent according to the number of digits of % the decimal part, the parsing of this decimal part counts on the fly the @@ -28189,7 +29346,7 @@ $1$ or $-1$. % hexadecimal numbers leading zeroes are stripped in a second stage by the % \xintHexToDec macro. % -% With v1.2, \xinttheexpr . \relax does not work anymore (it did in earlier +% With 1.2, \xinttheexpr . \relax does not work anymore (it did in earlier % releases). There must be digits either before or after the decimal mark. Thus % both \xinttheexpr 1.\relax and \xinttheexpr .1\relax are legal. % @@ -28328,10 +29485,6 @@ $1$ or $-1$. \if E#1\xint_dothis{[\the\numexpr#3\XINT_expr_scanexp_a +}\fi \xint_orthat {[#3]\endcsname #1}% }% -% \end{macrocode} -% \lverb|For bugfix release 1.2a, I only need code that works, I will think -% another day about making it perhaps more elegant/efficient.| -% \begin{macrocode} \def\XINT_expr_gobz_scandec_b #1.#2% {% \ifcat \relax #2\expandafter\XINT_expr_gobz_scandec_endbycs\expandafter#2\fi @@ -28340,11 +29493,6 @@ $1$ or $-1$. {\expandafter\XINT_expr_gobz_scandec_b}% {\string#2\expandafter\XINT_expr_scandec_d}\the\numexpr#1-\xint_c_i.% }% -% \end{macrocode} -% \lverb|Even if number is zero leave a trace in [..] of its formation ? for -% code tracing purposes ? Finally no. But in case of exponential part, yes as -% I don't want to write extra code just to handle that case.| -% \begin{macrocode} \def\XINT_expr_gobz_scandec_endbycs #1#2\xint_c_i.{0[0]\endcsname #1}% \def\XINT_expr_gobz_scandec_c\if0#1#2\fi #3\xint_c_i.% {% @@ -28481,13 +29629,13 @@ $1$ or $-1$. % multiplication) 4) 5) 6) 7) acceptable components of a variable or function % names: @, underscore, digits, letters (or chars of category code letter.) % -% The short lived v1.2d which followed the even shorter lived 1.2c managed to +% The short lived 1.2d which followed the even shorter lived 1.2c managed to % introduce a bug here as it removed the check for catcode 11 !, which must be % recognized if ! is not to be taken as part of a variable name. Don't know % what I was thinking, it was the time when I was moving the handling of tacit % mutliplication entirely to the \XINT_expr_getop side. Fixed in 1.2e. % -% I almost decided to remove the \ifcat\relax test whose rôle is to avoid the +% I almost decided to remove the \ifcat\relax test whose rôle is to avoid the % \string#1 to do something bad is the escape char is a digit! Perhaps I will % remove it at some point ! I truly almost did it, but also the case of no % escape char is a problem (\string\0, if \0 is a count ...) @@ -28503,7 +29651,7 @@ $1$ or $-1$. \def\XINT_expr_scanfunc_b #1% {% \ifx !#1\xint_dothis{(_}\fi - \ifcat \relax#1\xint_dothis{(_}\fi + \ifcat \relax#1\xint_dothis{(_}\fi \if (#1\xint_dothis{\xint_firstoftwo{(`}}\fi \if @#1\xint_dothis \XINT_expr_scanfunc_a \fi \if _#1\xint_dothis \XINT_expr_scanfunc_a \fi @@ -28538,7 +29686,7 @@ $1$ or $-1$. % thing is more efficient. % % 1.2c had \def\XINT_expr_func #1(#2{\xint_c_xviii #2{#1}} -% +% % In \XINT_expr_func the #2 is _ if #1 must be a variable name, or #2=` if #1 % must be either a function name or possibly a variable name which will then % have to be followed by tacit multiplication before the opening parenthesis. @@ -28646,7 +29794,7 @@ $1$ or $-1$. % 1.2c, see the subsection where omit and abort are discussed.| % \begin{macrocode} \catcode`) 11 -\def\XINT_tmpa #1#2#3#4% (avant #4#5) +\def\XINT_tmpa #1#2#3#4% {% \def#1##1% {% @@ -28683,7 +29831,7 @@ $1$ or $-1$. \krof }% \def #4##1##2{\ifcase ##1\expandafter\XINT_expr_missing_) \or \csname XINT_#6_op_##2\expandafter\endcsname - \else + \else \xint_afterfi{\expandafter #3\romannumeral`&&@\csname XINT_#6_op_##2\endcsname }% \fi }% @@ -28691,7 +29839,7 @@ $1$ or $-1$. \def\XINT_expr_missing_) {\xintError:inserted \xint_c_ \XINT_expr_done }% % \end{macrocode} % \lverb|We should be using until_( notation to stay synchronous with until_+, -% until_* etc..., but I found that until_) said more.| +% until_* etc..., but I found that until_) was more telling.| % \begin{macrocode} \catcode`) 12 \xintFor #1 in {expr,flexpr,iiexpr} \do {% @@ -28716,7 +29864,7 @@ $1$ or $-1$. % \lverb|This is all very clever and only need setting some suitable precedence % levels, if only I could understand what I did in 2014... just joking. Notice % that op_) macros are defined here in the \xintFor loop. -% +% % There is some clever business going on here with the letter a for handling % constructs such as [3..5]*2 (I think...). % @@ -28740,7 +29888,7 @@ $1$ or $-1$. % operator. I thought I had in mind an example to show that having defined % op_a and precedence_a for the letter a caused a reduction in syntax for this % letter, but it seems I am lacking now an example. -% +% % 2015/11/18: for 1.2d I accelerate \XINT_expr_op_] to jump over the % \XINT_expr_getop_a which now does tacit multiplications also in front of % letters, for reasons of things like, (x+y)z, hence it must not see the "a". @@ -28770,7 +29918,7 @@ $1$ or $-1$. % \numexpr compatible form in the iteration loops.| % \begin{macrocode} \expandafter\def\csname XINT_#1_op_++)\endcsname ##1##2\relax - {\expandafter\XINT_expr_foundend \expandafter + {\expandafter\XINT_expr_foundend \expandafter {\expandafter\.=+\csname .=\xintiCeil{\XINT_expr_unlock ##1}\endcsname }}% }% \catcode`. 12 \catcode`= 12 \catcode`+ 12 @@ -28786,10 +29934,13 @@ $1$ or $-1$. \catcode`& 7 \expandafter\let\csname XINT_expr_precedence_***\endcsname \xint_c_viii % \end{macrocode} -% \subsubsection{The \textbar, \&, xor, <, >, =, <=, >=, !=, //, /: and .. -% operators for expr and floatexpr} +% \subsubsection{The \textbar, \&, xor, <, >, =, <=, >=, !=, //, /:, .., +, +% \textendash, \texorpdfstring{\protect\lowast}{*}, /, \textasciicircum, ..[, +% and ].. operators for expr, floatexpr and iiexpr operators} +% \lverb|1.2d needed some room between /, * and ^. Hence precedence for ^ +% is now at 9| % \begin{macrocode} -\def\XINT_tmpc #1#2#3#4#5#6#7#8% +\def\XINT_expr_defbin_c #1#2#3#4#5#6#7#8% {% \def #1##1% \XINT_expr_op_<op> ou flexpr ou iiexpr {% keep value, get next number and operator, then do until @@ -28801,7 +29952,7 @@ $1$ or $-1$. \krof }% \def #3##1##2##3##4% \XINT_expr_until_<op>_b ou flexpr ou iiexpr {% either execute next operation now, or first do next (possibly unary) - \ifnum ##2>#5% + \ifnum ##2>#7% \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@% \csname XINT_#8_op_##3\endcsname {##4}}% \else \xint_afterfi {\expandafter ##2\expandafter ##3% @@ -28809,89 +29960,74 @@ $1$ or $-1$. \fi }% \let #7#5% }% -\def\XINT_tmpb #1#2#3#4#5#6% +\def\XINT_expr_defbin_b #1#2#3#4#5% {% - \expandafter\XINT_tmpc - \csname XINT_#1_op_#3\expandafter\endcsname - \csname XINT_#1_until_#3_a\expandafter\endcsname - \csname XINT_#1_until_#3_b\expandafter\endcsname - \csname XINT_#1_op_-#5\expandafter\endcsname - \csname xint_c_#4\expandafter\endcsname - \csname #2#6\expandafter\endcsname - \csname XINT_expr_precedence_#3\endcsname {#1}% -}% -\catcode`& 12 -\xintFor #1 in {expr, flexpr} \do {% - \def\XINT_tmpa ##1{\XINT_tmpb {#1}{xint}##1}% - \xintApplyInline {\XINT_tmpa }{% - {|{iii}{vi}{OR}}% - {&{iv}{vi}{AND}}% - {{xor}{iii}{vi}{XOR}}% - {<{v}{vi}{Lt}}% - {>{v}{vi}{Gt}}% - {={v}{vi}{Eq}}% - {{<=}{v}{vi}{LtorEq}}% - {{>=}{v}{vi}{GtorEq}}% - {{!=}{v}{vi}{Neq}}% - {{..}{iii}{vi}{Seq::csv}}% - {{//}{vii}{vii}{DivTrunc}}% - {{/:}{vii}{vii}{Mod}}% - }% -}% -\catcode`& 7 -% \end{macrocode} -% \subsubsection{The +, \textendash, \texorpdfstring{\protect\lowast}{*}, /, -% \textasciicircum, ..[, and ].. operators for expr and floatexpr} -% \lverb|1.2d needed some room between /, * and ^. Hence precedence for ^ is -% now at 9.| -% \begin{macrocode} -\def\XINT_tmpa #1{\XINT_tmpb {expr}{xint}#1}% -\xintApplyInline {\XINT_tmpa }{% - {+{vi}{vi}{Add}}% - {-{vi}{vi}{Sub}}% - {*{vii}{vii}{Mul}}% - {/{vii}{vii}{Div}}% - {^{ix}{ix}{Pow}}% - {{..[}{iii}{vi}{SeqA::csv}}% - {{]..}{iii}{vi}{SeqB::csv}}% -}% -\def\XINT_tmpa #1{\XINT_tmpb {flexpr}{XINTinFloat}#1}% -\xintApplyInline {\XINT_tmpa }{% - {+{vi}{vi}{Add}}% - {-{vi}{vi}{Sub}}% - {*{vii}{vii}{Mul}}% - {/{vii}{vii}{Div}}% - {^{ix}{ix}{Power}}% - {{..[}{iii}{vi}{SeqA::csv}}% - {{]..}{iii}{vi}{SeqB::csv}}% -}% -% \end{macrocode} -% \subsubsection{The previous operators for iiexpr} -% \begin{macrocode} -\def\XINT_tmpa #1{\XINT_tmpb {iiexpr}{xint}#1}% -\catcode`& 12 -\xintApplyInline {\XINT_tmpa }{% - {|{iii}{vi}{OR}}% - {&{iv}{vi}{AND}}% - {{xor}{iii}{vi}{XOR}}% - {<{v}{vi}{iiLt}}% - {>{v}{vi}{iiGt}}% - {={v}{vi}{iiEq}}% - {{<=}{v}{vi}{iiLtorEq}}% - {{>=}{v}{vi}{iiGtorEq}}% - {{!=}{v}{vi}{iiNeq}}% - {+{vi}{vi}{iiAdd}}% - {-{vi}{vi}{iiSub}}% - {*{vii}{vii}{iiMul}}% - {/{vii}{vii}{iiDivRound}}% CHANGED IN 1.1! PREVIOUSLY DID EUCLIDEAN QUOTIENT - {^{ix}{ix}{iiPow}}% - {{..[}{iii}{vi}{iiSeqA::csv}}% - {{]..}{iii}{vi}{iiSeqB::csv}}% - {{..}{iii}{vi}{iiSeq::csv}}% - {{//}{vii}{vii}{iiDivTrunc}}% - {{/:}{vii}{vii}{iiMod}}% + \expandafter\XINT_expr_defbin_c + \csname XINT_#1_op_#2\expandafter\endcsname + \csname XINT_#1_until_#2_a\expandafter\endcsname + \csname XINT_#1_until_#2_b\expandafter\endcsname + \csname XINT_#1_op_-#4\expandafter\endcsname + \csname xint_c_#3\expandafter\endcsname + \csname #5\expandafter\endcsname + \csname XINT_expr_precedence_#2\endcsname {#1}% }% -\catcode`& 7 +\XINT_expr_defbin_b {expr} | {iii}{vi} {xintOR}% +\XINT_expr_defbin_b {flexpr} | {iii}{vi} {xintOR}% +\XINT_expr_defbin_b {iiexpr} | {iii}{vi} {xintOR}% +\XINT_expr_defbin_b {expr} & {iv}{vi} {xintAND}% +\XINT_expr_defbin_b {flexpr} & {iv}{vi} {xintAND}% +\XINT_expr_defbin_b {iiexpr} & {iv}{vi} {xintAND}% +\XINT_expr_defbin_b {expr} {xor}{iii}{vi} {xintXOR}% +\XINT_expr_defbin_b {flexpr}{xor}{iii}{vi} {xintXOR}% +\XINT_expr_defbin_b {iiexpr}{xor}{iii}{vi} {xintXOR}% +\XINT_expr_defbin_b {expr} < {v}{vi} {xintLt}% +\XINT_expr_defbin_b {flexpr} < {v}{vi} {xintLt}% +\XINT_expr_defbin_b {iiexpr} < {v}{vi} {xintiiLt}% +\XINT_expr_defbin_b {expr} > {v}{vi} {xintGt}% +\XINT_expr_defbin_b {flexpr} > {v}{vi} {xintGt}% +\XINT_expr_defbin_b {iiexpr} > {v}{vi} {xintiiGt}% +\XINT_expr_defbin_b {expr} = {v}{vi} {xintEq}% +\XINT_expr_defbin_b {flexpr} = {v}{vi} {xintEq}% +\XINT_expr_defbin_b {iiexpr} = {v}{vi} {xintiiEq}% +\XINT_expr_defbin_b {expr} {<=} {v}{vi} {xintLtorEq}% +\XINT_expr_defbin_b {flexpr}{<=} {v}{vi} {xintLtorEq}% +\XINT_expr_defbin_b {iiexpr}{<=} {v}{vi} {xintiiLtorEq}% +\XINT_expr_defbin_b {expr} {>=} {v}{vi} {xintGtorEq}% +\XINT_expr_defbin_b {flexpr}{>=} {v}{vi} {xintGtorEq}% +\XINT_expr_defbin_b {iiexpr}{>=} {v}{vi} {xintiiGtorEq}% +\XINT_expr_defbin_b {expr} {!=} {v}{vi} {xintNeq}% +\XINT_expr_defbin_b {flexpr}{!=} {v}{vi} {xintNeq}% +\XINT_expr_defbin_b {iiexpr}{!=} {v}{vi} {xintiiNeq}% +\XINT_expr_defbin_b {expr} {..} {iii}{vi} {xintSeq::csv}% +\XINT_expr_defbin_b {flexpr}{..} {iii}{vi} {xintSeq::csv}% +\XINT_expr_defbin_b {iiexpr}{..} {iii}{vi} {xintiiSeq::csv}% +\XINT_expr_defbin_b {expr} {//} {vii}{vii}{xintDivTrunc}% +\XINT_expr_defbin_b {flexpr}{//} {vii}{vii}{xintDivTrunc}% +\XINT_expr_defbin_b {iiexpr}{//} {vii}{vii}{xintiiDivTrunc}% +\XINT_expr_defbin_b {expr} {/:} {vii}{vii}{xintMod}% +\XINT_expr_defbin_b {flexpr}{/:} {vii}{vii}{xintMod}% +\XINT_expr_defbin_b {iiexpr}{/:} {vii}{vii}{xintiiMod}% +\XINT_expr_defbin_b {expr} + {vi}{vi} {xintAdd}% +\XINT_expr_defbin_b {flexpr} + {vi}{vi} {XINTinFloatAdd}% +\XINT_expr_defbin_b {iiexpr} + {vi}{vi} {xintiiAdd}% +\XINT_expr_defbin_b {expr} - {vi}{vi} {xintSub}% +\XINT_expr_defbin_b {flexpr} - {vi}{vi} {XINTinFloatSub}% +\XINT_expr_defbin_b {iiexpr} - {vi}{vi} {xintiiSub}% +\XINT_expr_defbin_b {expr} * {vii}{vii}{xintMul}% +\XINT_expr_defbin_b {flexpr} * {vii}{vii}{XINTinFloatMul}% +\XINT_expr_defbin_b {iiexpr} * {vii}{vii}{xintiiMul}% +\XINT_expr_defbin_b {expr} / {vii}{vii}{xintDiv}% +\XINT_expr_defbin_b {flexpr} / {vii}{vii}{XINTinFloatDiv}% +\XINT_expr_defbin_b {iiexpr} / {vii}{vii}{xintiiDivRound}% CHANGED IN 1.1! +\XINT_expr_defbin_b {expr} ^ {ix}{ix} {xintPow}% +\XINT_expr_defbin_b {flexpr} ^ {ix}{ix} {XINTinFloatPowerH}% +\XINT_expr_defbin_b {iiexpr} ^ {ix}{ix} {xintiiPow}% +\XINT_expr_defbin_b {expr} {..[}{iii}{vi} {xintSeqA::csv}% +\XINT_expr_defbin_b {flexpr}{..[}{iii}{vi} {XINTinFloatSeqA::csv}% +\XINT_expr_defbin_b {iiexpr}{..[}{iii}{vi} {xintiiSeqA::csv}% +\XINT_expr_defbin_b {expr} {]..}{iii}{vi} {xintSeqB::csv}% +\XINT_expr_defbin_b {flexpr}{]..}{iii}{vi} {XINTinFloatSeqB::csv}% +\XINT_expr_defbin_b {iiexpr}{]..}{iii}{vi} {xintiiSeqB::csv}% % \end{macrocode} % \subsubsection{The ]+, ]\textendash, ]\texorpdfstring{\protect\lowast}{*}, ]/, ]\textasciicircum, +[, \textendash[, \texorpdfstring{\protect\lowast}{*}[, /[, and \textasciicircum[ list % operators} @@ -28909,7 +30045,7 @@ $1$ or $-1$. \def\XINT_expr_binop_inline_d #1,#2{,#2{#1}\XINT_expr_binop_inline_b {#2}}% \def\XINT_expr_binop_inline_e #1,#2{,\XINT_expr_binop_inline_b {#2}}% \def\XINT_expr_binop_inline_end #1,#2{}% -\def\XINT_tmpc #1#2#3#4#5#6#7#8% +\def\XINT_expr_deflistopr_c #1#2#3#4#5#6#7#8% {% \def #1##1% \XINT_expr_op_<op> ou flexpr ou iiexpr {% keep value, get next number and operator, then do until @@ -28921,7 +30057,7 @@ $1$ or $-1$. \krof }% \def #3##1##2##3##4% \XINT_expr_until_<op>_b ou flexpr ou iiexpr {% either execute next operation now, or first do next (possibly unary) - \ifnum ##2>#5% + \ifnum ##2>#7% \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@% \csname XINT_#8_op_##3\endcsname {##4}}% \else \xint_afterfi {\expandafter ##2\expandafter ##3% @@ -28933,9 +30069,9 @@ $1$ or $-1$. \fi }% \let #7#5% }% -\def\XINT_tmpb #1#2#3#4% +\def\XINT_expr_deflistopr_b #1#2#3#4% {% - \expandafter\XINT_tmpc + \expandafter\XINT_expr_deflistopr_c \csname XINT_#1_op_#2\expandafter\endcsname \csname XINT_#1_until_#2_a\expandafter\endcsname \csname XINT_#1_until_#2_b\expandafter\endcsname @@ -28948,30 +30084,28 @@ $1$ or $-1$. % \lverb|This is for [x..y]*z syntax etc.... Attention that with 1.2d, % precedence level of ^ raised to ix to make room for ***.| % \begin{macrocode} -\xintApplyInline {\expandafter\XINT_tmpb \xint_firstofone}{% - {{expr}{a+}{vi}{xintAdd}}% - {{expr}{a-}{vi}{xintSub}}% - {{expr}{a*}{vii}{xintMul}}% - {{expr}{a/}{vii}{xintDiv}}% - {{expr}{a^}{ix}{xintPow}}% - {{iiexpr}{a+}{vi}{xintiiAdd}}% - {{iiexpr}{a-}{vi}{xintiiSub}}% - {{iiexpr}{a*}{vii}{xintiiMul}}% - {{iiexpr}{a/}{vii}{xintiiDivRound}}% - {{iiexpr}{a^}{ix}{xintiiPow}}% - {{flexpr}{a+}{vi}{XINTinFloatAdd}}% - {{flexpr}{a-}{vi}{XINTinFloatSub}}% - {{flexpr}{a*}{vii}{XINTinFloatMul}}% - {{flexpr}{a/}{vii}{XINTinFloatDiv}}% - {{flexpr}{a^}{ix}{XINTinFloatPower}}% -}% -\def\XINT_tmpc #1#2#3#4#5#6#7% +\XINT_expr_deflistopr_b {expr} {a+}{vi} {xintAdd}% +\XINT_expr_deflistopr_b {expr} {a-}{vi} {xintSub}% +\XINT_expr_deflistopr_b {expr} {a*}{vii}{xintMul}% +\XINT_expr_deflistopr_b {expr} {a/}{vii}{xintDiv}% +\XINT_expr_deflistopr_b {expr} {a^}{ix} {xintPow}% +\XINT_expr_deflistopr_b {iiexpr}{a+}{vi} {xintiiAdd}% +\XINT_expr_deflistopr_b {iiexpr}{a-}{vi} {xintiiSub}% +\XINT_expr_deflistopr_b {iiexpr}{a*}{vii}{xintiiMul}% +\XINT_expr_deflistopr_b {iiexpr}{a/}{vii}{xintiiDivRound}% +\XINT_expr_deflistopr_b {iiexpr}{a^}{ix} {xintiiPow}% +\XINT_expr_deflistopr_b {flexpr}{a+}{vi} {XINTinFloatAdd}% +\XINT_expr_deflistopr_b {flexpr}{a-}{vi} {XINTinFloatSub}% +\XINT_expr_deflistopr_b {flexpr}{a*}{vii}{XINTinFloatMul}% +\XINT_expr_deflistopr_b {flexpr}{a/}{vii}{XINTinFloatDiv}% +\XINT_expr_deflistopr_b {flexpr}{a^}{ix} {XINTinFloatPowerH}% +\def\XINT_expr_deflistopl_c #1#2#3#4#5#6#7% {% \def #1##1{\expandafter#2\expandafter##1\romannumeral`&&@% \expandafter #3\romannumeral`&&@\XINT_expr_getnext }% \def #2##1##2##3##4% {% either execute next operation now, or first do next (possibly unary) - \ifnum ##2>#4% + \ifnum ##2>#6% \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@% \csname XINT_#7_op_##3\endcsname {##4}}% \else \xint_afterfi {\expandafter ##2\expandafter ##3% @@ -28982,9 +30116,9 @@ $1$ or $-1$. \fi }% \let #6#4% }% -\def\XINT_tmpb #1#2#3#4% +\def\XINT_expr_deflistopl_b #1#2#3#4% {% - \expandafter\XINT_tmpc + \expandafter\XINT_expr_deflistopl_c \csname XINT_#1_op_#2\expandafter\endcsname \csname XINT_#1_until_#2\expandafter\endcsname \csname XINT_#1_until_)_a\expandafter\endcsname @@ -28995,23 +30129,21 @@ $1$ or $-1$. % \end{macrocode} % \lverb|This is for z*[x..y] syntax etc...| % \begin{macrocode} -\xintApplyInline {\expandafter\XINT_tmpb\xint_firstofone }{% - {{expr}{+[}{vi}{xintAdd}}% - {{expr}{-[}{vi}{xintSub}}% - {{expr}{*[}{vii}{xintMul}}% - {{expr}{/[}{vii}{xintDiv}}% - {{expr}{^[}{ix}{xintPow}}% - {{iiexpr}{+[}{vi}{xintiiAdd}}% - {{iiexpr}{-[}{vi}{xintiiSub}}% - {{iiexpr}{*[}{vii}{xintiiMul}}% - {{iiexpr}{/[}{vii}{xintiiDivRound}}% - {{iiexpr}{^[}{ix}{xintiiPow}}% - {{flexpr}{+[}{vi}{XINTinFloatAdd}}% - {{flexpr}{-[}{vi}{XINTinFloatSub}}% - {{flexpr}{*[}{vii}{XINTinFloatMul}}% - {{flexpr}{/[}{vii}{XINTinFloatDiv}}% - {{flexpr}{^[}{ix}{XINTinFloatPower}}% -}% +\XINT_expr_deflistopl_b {expr} {+[}{vi} {xintAdd}% +\XINT_expr_deflistopl_b {expr} {-[}{vi} {xintSub}% +\XINT_expr_deflistopl_b {expr} {*[}{vii}{xintMul}% +\XINT_expr_deflistopl_b {expr} {/[}{vii}{xintDiv}% +\XINT_expr_deflistopl_b {expr} {^[}{ix} {xintPow}% +\XINT_expr_deflistopl_b {iiexpr}{+[}{vi} {xintiiAdd}% +\XINT_expr_deflistopl_b {iiexpr}{-[}{vi} {xintiiSub}% +\XINT_expr_deflistopl_b {iiexpr}{*[}{vii}{xintiiMul}% +\XINT_expr_deflistopl_b {iiexpr}{/[}{vii}{xintiiDivRound}% +\XINT_expr_deflistopl_b {iiexpr}{^[}{ix} {xintiiPow}% +\XINT_expr_deflistopl_b {flexpr}{+[}{vi} {XINTinFloatAdd}% +\XINT_expr_deflistopl_b {flexpr}{-[}{vi} {XINTinFloatSub}% +\XINT_expr_deflistopl_b {flexpr}{*[}{vii}{XINTinFloatMul}% +\XINT_expr_deflistopl_b {flexpr}{/[}{vii}{XINTinFloatDiv}% +\XINT_expr_deflistopl_b {flexpr}{^[}{ix} {XINTinFloatPowerH}% % \end{macrocode} % \subsubsection{The \textquotesingle and\textquotesingle, \textquotesingle % or\textquotesingle, \textquotesingle xor\textquotesingle, and @@ -29092,12 +30224,12 @@ $1$ or $-1$. \krof }% \def #3##1##2##3##4% \XINT_expr_until_][_b {% - \ifnum ##2>\xint_c_ii + \ifnum ##2>#5% \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@% \csname XINT_#6_op_##3\endcsname {##4}}% \else \xint_afterfi - {\expandafter ##2\expandafter ##3\csname + {\expandafter ##2\expandafter ##3\csname .=\expandafter\xintListSel::csv \romannumeral`&&@\XINT_expr_unlock ##4;% \XINT_expr_unlock ##1;\endcsname % unlock added for \xintNewExpr }% @@ -29126,15 +30258,15 @@ $1$ or $-1$. \krof }% \def #3##1##2##3##4% \XINT_expr_until_:_b {% - \ifnum ##2>\xint_c_iii + \ifnum ##2>#5% \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@% \csname XINT_#6_op_##3\endcsname {##4}}% \else \xint_afterfi - {\expandafter ##2\expandafter ##3\csname + {\expandafter ##2\expandafter ##3\csname .=:\xintiiifSgn{\XINT_expr_unlock ##1}NPP.% \xintiiifSgn{\XINT_expr_unlock ##4}NPP.% - \xintNum{\XINT_expr_unlock ##1};\xintNum{\XINT_expr_unlock ##4}\endcsname + \xintNum{\XINT_expr_unlock ##1};\xintNum{\XINT_expr_unlock ##4}\endcsname }% \fi }% @@ -29206,15 +30338,15 @@ $1$ or $-1$. \def\XINT_listsel:_PO\XINT_listsel:_PP #1;#2;{\XINT_listsel:_PP #1;0;}% % \end{macrocode} %\subsection{Macros for a..b list generation} -% \localtableofcontents -% -% \lverb|Ne produit que des listes d'entiers inférieurs à la borne +% \localtableofcontents +% +% \lverb|Ne produit que des listes d'entiers inférieurs à la borne % de TeX ! mais sous la forme N/1[0] en ce qui concerne \xintSeq::csv.| % %\subsubsection{\csh{xintSeq::csv}} %\lverb|Commence par remplacer a par ceil(a) et b par floor(b) et renvoie -% ensuite les entiers entre les deux, possiblement en décroissant, et -% extrémités comprises. Si a=b est non entier en obtient donc ceil(a) et +% ensuite les entiers entre les deux, possiblement en décroissant, et +% extrémités comprises. Si a=b est non entier en obtient donc ceil(a) et % floor(a). Ne renvoie jamais une liste vide. % % Note: le a..b dans \xintfloatexpr utilise cette routine.| @@ -29299,25 +30431,14 @@ $1$ or $-1$. \def\XINT_seq::csv_e #1,{ }% % \end{macrocode} %\subsection{Macros for a..[d]..b list generation} -% \localtableofcontents +% \localtableofcontents % % \lverb|Contrarily to a..b which is limited to small integers, this works -% with a, b, and d (big) fractions. It will produce a «nil» list, if a>b and +% with a, b, and d (big) fractions. It will produce a «nil» list, if a>b and % d<0 or a<b and d>0.| % %\subsubsection{\csh{xintSeqA::csv}, \csh{xintiiSeqA::csv}, \csh{XINTinFloatSeqA::csv}} % -% \lverb|2015/11/11 Naturally, I did not document anything in 2014, and today -% I was perplexed about what these macros do; and why something was wrong with -% \xintNewIIExpr and a..[b]..c things therein. In fact \xintiiSeqB:f:csv had a -% typo in its name, but this had escaped my 2014 tests; and if I had corrected -% it I would have seen another problem with a..[b]..C in \xintNewIIExpr, the -% \xintiiSeqB:f:csv macro calls \xintiiSeqA::csv with arguments which have no -% more a \XINT_expr_unlock. But \xintiiSeqA::csv tried to be clever and -% assumed the \XINT_expr_unlock were there. The other two expanded either in -% \xintraw or \XINTinfloat, hence no problem arose in -% \xintNewExpr/\xintNewFloatExpr. The fix has been to let \xintiiSeqA::csv act -% a bit more like the other two.| % \begin{macrocode} \def\xintSeqA::csv #1% {\expandafter\XINT_seqa::csv\expandafter{\romannumeral0\xintraw {#1}}}% @@ -29486,7 +30607,7 @@ $1$ or $-1$. % \subsection{? as two-way and ?? as three-way conditionals with braced branches} % \lverb|In 1.1, I overload ? with ??, as : will be used for list extraction, % problem with (stuff)?{?(1)}{0} for example, one should put a space (stuff)?{ -% ?(1)}{0} will work. Small idiosyncrasy. +% ?(1)}{0} will work. Small idiosyncrasy. % % syntax: ?{yes}{no} and ??{<0}{=0}{>0}. % @@ -29496,7 +30617,7 @@ $1$ or $-1$. % \begin{macrocode} \let\XINT_expr_precedence_? \xint_c_x \def\XINT_expr_op_? #1#2{\if ?#2\expandafter \XINT_expr_op_??\fi - \XINT_expr_op_?a #1{#2}}% + \XINT_expr_op_?a #1{#2}}% \def\XINT_expr_op_?a #1#2#3% {% \xintiiifNotZero{\XINT_expr_unlock #1}{\XINT_expr_getnext #2}{\XINT_expr_getnext #3}% @@ -29510,11 +30631,12 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{! as postfix factorial operator} -% \lverb|A float version \xintFloatFac was at last done 2015/10/06.| +% \lverb|A float version \xintFloatFac was at last done 2015/10/06 for 1.2. +% Attention 2015/11/29 for 1.2f: no more \xintFac, but \xintiFac.| % \begin{macrocode} \let\XINT_expr_precedence_! \xint_c_x \def\XINT_expr_op_! #1{\expandafter\XINT_expr_getop - \csname .=\xintFac{\XINT_expr_unlock #1}\endcsname }% + \csname .=\xintiFac{\XINT_expr_unlock #1}\endcsname }% \def\XINT_flexpr_op_! #1{\expandafter\XINT_expr_getop \csname .=\XINTinFloatFac{\XINT_expr_unlock #1}\endcsname }% \def\XINT_iiexpr_op_! #1{\expandafter\XINT_expr_getop @@ -29564,7 +30686,7 @@ $1$ or $-1$. % a variable or a function, the parser will apply the correct interpretation % which is decided by the presence or not of an opening parenthesis next.| % \begin{macrocode} -\def\XINT_tmpa #1#2#3{% +\def\XINT_tmpa #1#2#3{% \def #1##1% {% \ifcsname XINT_#3_func_##1\endcsname @@ -29618,10 +30740,9 @@ $1$ or $-1$. {\expandafter\XINT_expr_getop\csname .=\XINTinFloatdigits{#1}\endcsname }% % \end{macrocode} % \subsection{\csh{XINT_expr_op__} for recognizing variables} -% \lverb|The 1.1 mechanism for \XINT_expr_var_<varname> has been modified in 1.2c. -% The <varname> associated macro is now only expanded once, not twice. -% -% We arrive here via \XINT_expr_func.| +% \lverb|The 1.1 mechanism for \XINT_expr_var_<varname> has been +% modified in 1.2c. The <varname> associated macro is now only expanded +% once, not twice. We arrive here via \XINT_expr_func.| % \begin{macrocode} \def\XINT_expr_op__ #1% op__ with two _'s {% @@ -29663,17 +30784,18 @@ $1$ or $-1$. % is allowed, the only thing to know is that if an opening parenthesis follows % it is the function meaning which prevails. % -% 2015/11/13: I now first do an a priori complete expansion of #1, and then apply -% \detokenize to the result, and remove spaces. +% 2015/11/13: I now first do an a priori complete expansion of #1, and +% then apply \detokenize to the result, and remove spaces. +% % 2015/11/21: finally I do not detokenize the variable name. Because this % complicated the \xintunassignvar if it did the same and we wanted to use it -% to redeclare a letter as dummy variable. +% to redeclare a letter as dummy variable. % % Documentation of 1.2d said that the tacit multiplication always was done % with increased precedence, but I had not at that time made up my mind for % the case of variable(stuff) and pushed to CTAN early because I need to fix % the bug I had introduced in 1.2c which itself I had pushed to CTAN early -% because I had to fix the 1.2 bug with subtraction.... +% because I had to fix the 1.2 bug with subtraction.... % % Finally I decide to do it indeed. Hence for 1.2e. This only impacts % situations such as A/B(stuff), which are thus interpreted as A/(B*(stuff)).| @@ -29687,12 +30809,12 @@ $1$ or $-1$. {Error: impossible to declare variable with empty name.}% \else \edef\XINT_expr_tmpb {\romannumeral0#1#3\relax }% - \expandafter\edef\csname XINT_expr_var_\XINT_expr_tmpa\endcsname + \expandafter\edef\csname XINT_expr_var_\XINT_expr_tmpa\endcsname {\expandafter\noexpand\XINT_expr_tmpb}% \expandafter\edef\csname XINT_expr_onlitteral_\XINT_expr_tmpa\endcsname {\XINT_expr_precedence_*** *\expandafter\noexpand\XINT_expr_tmpb (}% \ifxintverbose\xintMessage {xintexpr}{Info} - {Variable "\XINT_expr_tmpa" defined with value + {Variable "\XINT_expr_tmpa" defined with value \expandafter\XINT_expr_unlock\XINT_expr_tmpb.}% \fi \fi @@ -29705,9 +30827,10 @@ $1$ or $-1$. \catcode`: 11 % \end{macrocode} % \subsection{\csbh{xintunassignvar}} -% \lverb|1.2e. Currently not possible to genuinely ``undefine'' a variable, -% all we can do is to let it stand for zero and generate an error. The reason is that I -% chose to use \ifcsname tests in \XINT_expr_op__ and \XINT_expr_op_`.| +% \lverb|1.2e. Currently not possible to genuinely ``undefine'' a +% variable, all we can do is to let it stand for zero and generate an +% error. The reason is that I chose to use \ifcsname tests in +% \XINT_expr_op__ and \XINT_expr_op_`.| % \begin{macrocode} \def\xintunassignvar #1{% \edef\XINT_expr_tmpa{#1}% @@ -29746,18 +30869,21 @@ $1$ or $-1$. % I added subs, and iter in October (also the [:n], [n:] list extractors), % proving I did at least understand a bit (or rather could imitate) my earlier % code (but don't ask me to explain \xintNewExpr !) -% -% The \XINT_expr_onlitteral_seq_a parses: "expression, variable=list)" (when it is called -% the opening ( has been swallowed, and it looks for the ending one.) Both expression and -% list may themselves contain parentheses and commas, we allow nesting. For example -% "x^2,x=1..10)", at the end of seq_a we have {variable{expression}}{list}, in this -% example {x{x^2}}{1..10}, or more complicated "seq(add(y,y=1..x),x=1..10)" will work -% too. The variable is a single lowercase Latin letter. -% -% The complications with \xint_c_xviii in seq_f is for the recurrent thing that we don't -% know in what type of expressions we are, hence we must move back up, with some loss of -% efficiency (superfluous check for minus sign, etc...). But the code manages -% simultaneously expr, flexpr and iiexpr.| +% +% The \XINT_expr_onlitteral_seq_a parses: "expression, variable=list)" +% (when it is called the opening ( has been swallowed, and it looks for +% the ending one.) Both expression and list may themselves contain +% parentheses and commas, we allow nesting. For example "x^2,x=1..10)", +% at the end of seq_a we have {variable{expression}}{list}, in this +% example {x{x^2}}{1..10}, or more complicated +% "seq(add(y,y=1..x),x=1..10)" will work too. The variable is a single +% lowercase Latin letter. +% +% The complications with \xint_c_xviii in seq_f is for the recurrent +% thing that we don't know in what type of expressions we are, hence we +% must move back up, with some loss of efficiency (superfluous check for +% minus sign, etc...). But the code manages simultaneously expr, flexpr +% and iiexpr.| % % \subsubsection{All letters usable as dummy variables} % \lverb|The nil variable was introduced in 1.1 but isn't used under that @@ -29801,51 +30927,51 @@ $1$ or $-1$. \xintApplyUnbraced \XINT_expr_makedummy {abcdefghijklmnopqrstuvwxyz}% \xintApplyUnbraced \XINT_expr_makedummy {ABCDEFGHIJKLMNOPQRSTUVWXYZ}% \edef\XINT_expr_var_nil {\expandafter\noexpand\csname .= \endcsname}% -\edef\XINT_expr_onlitteral_nil +\edef\XINT_expr_onlitteral_nil {\XINT_expr_precedence_*** *\expandafter\noexpand\csname .= \endcsname (}% \catcode`* 12 % \end{macrocode} % \subsubsection{omit and abort} -% \lverb|& attention à ce & qui est de catcode 14 dans les \lverb -% June 24 and 25, 2014. +% \lverb|& attention à ce & qui est de catcode 14 dans les \lverb +% June 24 and 25, 2014. +% +% Added comments 2015/11/13: % -% Added comments 2015/11/13: -% % Et la documentation ? on n'y comprend plus rien. Trop -% rusé.$newline +% rusé.$newline % \def\XINT_expr_var_omit #1\relax !{1^C!{}{}{}\.=!\relax !}$newline % \def\XINT_expr_var_abort #1\relax !{1^C!{}{}{}\.=^\relax !}$newline -% C'était accompagné de \XINT_expr_precedence_^C=0 et d'un hack au sein même +% C'était accompagné de \XINT_expr_precedence_^C=0 et d'un hack au sein même % des macros until de plus bas niveau. % -% Le mécanisme sioux était le suivant: ^C est déclaré comme un opérateur de -% précédence nulle. Lorsque le parseur trouve un "omit" dans un seq ou autre, -% il va insérer dans le stream \XINT_expr_getop suivi du texte de -% remplacement. Donc ici on avait un 1 comme place holder, puis l'opérateur -% ^C. Celui-ci étant de précédence zéro provoque la finalisation de tous les -% calculs antérieurs dans le sous-bareeval. Mais j'ai dû hacker le until_end_b -% (et le until_)_b) qui confronté à ^C, va se relancer à zéro, le getnext va -% trouver le !{}{}{}\.=! et ensuite il y aura \relax, et le résultat sera \.=! +% Le mécanisme sioux était le suivant: ^C est déclaré comme un opérateur de +% précédence nulle. Lorsque le parseur trouve un "omit" dans un seq ou autre, +% il va insérer dans le stream \XINT_expr_getop suivi du texte de +% remplacement. Donc ici on avait un 1 comme place holder, puis l'opérateur +% ^C. Celui-ci étant de précédence zéro provoque la finalisation de tous les +% calculs antérieurs dans le sous-bareeval. Mais j'ai dû hacker le until_end_b +% (et le until_)_b) qui confronté à ^C, va se relancer à zéro, le getnext va +% trouver le !{}{}{}\.=! et ensuite il y aura \relax, et le résultat sera \.=! % pour omit ou \.=^ pour abort. Les routines des boucles seq, iter, etc... -% peuvent alors repérer le ! ou ^ et agir en conséquence (un long paragraphe -% pour ne décrire que partiellement une ou deux lignes de codes...). +% peuvent alors repérer le ! ou ^ et agir en conséquence (un long paragraphe +% pour ne décrire que partiellement une ou deux lignes de codes...). % -% Mais ^C a été fait alors que je n'avais pas encore les variables muettes. Je +% Mais ^C a été fait alors que je n'avais pas encore les variables muettes. Je % dois trouver autre chose, car seq(2^C, C=1..5) est alors impossible. De -% toute façon ce ^C était à usage interne uniquement. +% toute façon ce ^C était à usage interne uniquement. % -% Il me faut un symbole d'opérateur qui ne rentre pas en conflit. Bon je vais +% Il me faut un symbole d'opérateur qui ne rentre pas en conflit. Bon je vais % prendre !?. Ensuite au lieu de hacker until_end, il vaut mieux lui donner -% précédence 2 (mais ça ne pourra pas marcher à l'intérieur de parenthèses il +% précédence 2 (mais ça ne pourra pas marcher à l'intérieur de parenthèses il % faut d'abord les fermer manuellement) et lui associer un simplement un op -% spécial. Je n'avais pas fait cela peut-être pour éviter d'avoir à définir -% plusieurs macros. Le #1 dans la définition de \XINT_expr_op_!? est le -% résultat de l'évaluation forcée précédente. +% spécial. Je n'avais pas fait cela peut-être pour éviter d'avoir à définir +% plusieurs macros. Le #1 dans la définition de \XINT_expr_op_!? est le +% résultat de l'évaluation forcée précédente. % -% Attention que les premier ! doiventt être de catcode 12 sinon ils -% signalent une sous-expression qui déclenche une multiplication tacite. +% Attention que les premier ! doiventt être de catcode 12 sinon ils +% signalent une sous-expression qui déclenche une multiplication tacite. % -% 2015/11/13| +% | % \begin{macrocode} \edef\XINT_expr_var_omit #1\relax !{1\string !?!\relax !}% \edef\XINT_expr_var_abort #1\relax !{1\string !?^\relax !}% @@ -29854,7 +30980,7 @@ $1$ or $-1$. \let\XINT_flexpr_op_!? \XINT_expr_op_!? % \end{macrocode} % \subsubsection{The special variables @, @1, @2, @3, @4, @@, @@(1), \dots, @@@, -% @@@(1), \dots for recursion} +% @@@(1), \dots for recursion} % \lverb|October 2014: I had completely forgotten what the @@@ etc... stuff % were supposed to do: this is for nesting recursions! (I was mad back in % June). @@(N) gives the Nth back, @@@(N) gives the Nth back of the higher @@ -29863,7 +30989,7 @@ $1$ or $-1$. % 1.2c adds the needed "onlitteral" now that tacit multiplication between a % variable and a ( has a new mechanism. 1.2e does this tacit multiplication % with higher precedence. -% +% % For the record, the ~ has catcode 3 in this code.| % \begin{macrocode} \catcode`? 3 \catcode`* 11 @@ -29883,17 +31009,17 @@ $1$ or $-1$. \catcode`* 12 \def\XINT_expr_func_@@ #1#2#3#4~#5?% {% - \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand + \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand {\xintNum{\XINT_expr_unlock#3}}{#5}#4~#5?% }% \def\XINT_expr_func_@@@ #1#2#3#4~#5~#6?% {% - \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand + \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand {\xintNum{\XINT_expr_unlock#3}}{#6}#4~#5~#6?% }% \def\XINT_expr_func_@@@@ #1#2#3#4~#5~#6~#7?% {% - \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand + \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand {\xintNum{\XINT_expr_unlock#3}}{#7}#4~#5~#6~#7?% }% \let\XINT_flexpr_func_@@\XINT_expr_func_@@ @@ -29901,31 +31027,31 @@ $1$ or $-1$. \let\XINT_flexpr_func_@@@@\XINT_expr_func_@@@@ \def\XINT_iiexpr_func_@@ #1#2#3#4~#5?% {% - \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand + \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand {\XINT_expr_unlock#3}{#5}#4~#5?% }% \def\XINT_iiexpr_func_@@@ #1#2#3#4~#5~#6?% {% - \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand + \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand {\XINT_expr_unlock#3}{#6}#4~#5~#6?% }% \def\XINT_iiexpr_func_@@@@ #1#2#3#4~#5~#6~#7?% {% - \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand + \expandafter#1\expandafter#2\romannumeral0\xintntheltnoexpand {\XINT_expr_unlock#3}{#7}#4~#5~#6~#7?% }% \catcode`? 11 % \end{macrocode} % \subsubsection{\csh{XINT_expr_onlitteral_seq}} % \begin{macrocode} -\def\XINT_expr_onlitteral_seq +\def\XINT_expr_onlitteral_seq {\expandafter\XINT_expr_onlitteral_seq_f\romannumeral`&&@\XINT_expr_onlitteral_seq_a {}}% \def\XINT_expr_onlitteral_seq_f #1#2{\xint_c_xviii `{seqx}#2)\relax #1}% % \end{macrocode} % \subsubsection{\csh{XINT_expr_onlitteral_seq_a}} % \begin{macrocode} \def\XINT_expr_onlitteral_seq_a #1#2,% -{% checks balancing of parentheses +{% \ifcase\XINT_isbalanced_a \relax #1#2(\xint_bye)\xint_bye \expandafter\XINT_expr_onlitteral_seq_c \or\expandafter\XINT_expr_onlitteral_seq_b @@ -30075,10 +31201,10 @@ $1$ or $-1$. % explicitely the associated macro names for +, * but this makes other things % more efficient, and the code more readable.| % \begin{macrocode} -\def\XINT_expr_onlitteral_add +\def\XINT_expr_onlitteral_add {\expandafter\XINT_expr_onlitteral_add_f\romannumeral`&&@\XINT_expr_onlitteral_seq_a {}}% \def\XINT_expr_onlitteral_add_f #1#2{\xint_c_xviii `{opxadd}#2)\relax #1}% -\def\XINT_expr_onlitteral_mul +\def\XINT_expr_onlitteral_mul {\expandafter\XINT_expr_onlitteral_mul_f\romannumeral`&&@\XINT_expr_onlitteral_seq_a {}}% \def\XINT_expr_onlitteral_mul_f #1#2{\xint_c_xviii `{opxmul}#2)\relax #1}% % \end{macrocode} @@ -30093,10 +31219,10 @@ $1$ or $-1$. \def\XINT_flexpr_func_opxmul #1#2{\XINT_allexpr_opx \xintbarefloateval {\XINTinFloatMul 1}}% \def\XINT_iiexpr_func_opxmul #1#2{\XINT_allexpr_opx \xintbareiieval {\xintiiMul 1}}% % \end{macrocode} -% \lverb|#1=bareval etc, #2={Add0} ou {Mul1}, #3=liste encapsulée, #4=la variable, #5=expression| +% \lverb|#1=bareval etc, #2={Add0} ou {Mul1}, #3=liste encapsulée, #4=la variable, #5=expression| % \begin{macrocode} \def\XINT_allexpr_opx #1#2#3#4#5% -{% +{% \expandafter\XINT_expr_getop \csname.=\romannumeral`&&@\expandafter\XINT_expr_op:_a \romannumeral`&&@\XINT_expr_unlock #3!{#1#5\relax !#4}{#2}\endcsname @@ -30115,16 +31241,17 @@ $1$ or $-1$. }% \def\XINT_expr_op:_c #1#2#3#4{\expandafter\XINT_expr_op:_d\romannumeral0#2#1#3{#4}{#2}}% \def\XINT_expr_op:_d #1!#2#3#4#5% - {\expandafter\XINT_expr_op:_b\expandafter #4\expandafter + {\expandafter\XINT_expr_op:_b\expandafter #4\expandafter {\romannumeral`&&@#4{\XINT_expr_unlock#1}{#5}}}% \def\XINT_expr_op:_noop\csname.=,#1\endcsname #2#3#4{\XINT_expr_seq:_b #3{#4}{#2}#1,}% \def\XINT_expr_op:_end \csname.=^\endcsname #1#2#3{#3}% % \end{macrocode} % \subsection{subs} -% \lverb|Got simpler with 1.2c as now the dummy variable fetches an already encapsulated -% value, which is anyhow the form in which we get it.| +% \lverb|Got simpler with 1.2c as now the dummy variable fetches an +% already encapsulated value, which is anyhow the form in which we get +% it.| % \begin{macrocode} -\def\XINT_expr_onlitteral_subs +\def\XINT_expr_onlitteral_subs {\expandafter\XINT_expr_onlitteral_subs_f\romannumeral`&&@\XINT_expr_onlitteral_seq_a {}}% \def\XINT_expr_onlitteral_subs_f #1#2{\xint_c_xviii `{subx}#2)\relax #1}% \def\XINT_expr_func_subx #1#2{\XINT_allexpr_subx \xintbareeval }% @@ -30138,10 +31265,10 @@ $1$ or $-1$. \def\XINT_expr_subx:_end #1!#2#3{#1}% % \end{macrocode} % \subsection{rseq} -% \localtableofcontents +% \localtableofcontents % % \lverb|When func_rseq has its turn, initial segment has been scanned by -% oparen, the ; mimicking the rôle of a closing parenthesis, and stopping +% oparen, the ; mimicking the rôle of a closing parenthesis, and stopping % further expansion. Notice that the ; is discovered during standard parsing % mode, it may be for example {;} or arise from expansion as rseq does not use % a delimited macro to locate it. @@ -30199,7 +31326,7 @@ $1$ or $-1$. \if ?#1\xint_dothis\XINT_expr_rseq:_break\fi \if !#1\xint_dothis\XINT_expr_rseq:_omit\fi \xint_orthat{\XINT_expr_rseq:_goon #1}}% -\def\XINT_expr_rseq:_goon #1!#2#3~#4#5{,#1\expandafter\XINT_expr_rseq:_b +\def\XINT_expr_rseq:_goon #1!#2#3~#4#5{,#1\expandafter\XINT_expr_rseq:_b \romannumeral0\XINT_expr_lockit {#1}{#5}}% \def\XINT_expr_rseq:_omit #1!#2#3~{\XINT_expr_rseq:_b }% \def\XINT_expr_rseq:_abort #1!#2#3~#4#5#6^,{}% @@ -30227,8 +31354,10 @@ $1$ or $-1$. % \end{macrocode} % \subsection{rrseq} % \localtableofcontents -% \lverb|When func_rrseq has its turn, initial segment has been scanned by oparen, the ; -% mimicking the rôle of a closing parenthesis, and stopping further expansion.| +% +% \lverb|When func_rrseq has its turn, initial segment has been scanned +% by oparen, the ; mimicking the rôle of a closing parenthesis, and +% stopping further expansion.| % \begin{macrocode} \def\XINT_expr_func_rrseq {\XINT_allexpr_rrseq \xintbareeval \xintthebareeval }% \def\XINT_flexpr_func_rrseq {\XINT_allexpr_rrseq \xintbarefloateval \xintthebarefloateval }% @@ -30474,10 +31603,10 @@ $1$ or $-1$. % \end{macrocode} % \subsubsection{\csh{xintMaxof:csv}, \csh{xintiiMaxof:csv}} % \lverb|1.09i. Rewritten for 1.1. Compatible avec liste vide donnant valeur par -% défaut. Pas compatible avec items manquants. -% ah je m'aperçois au dernier moment que je n'ai pas en effet de \xintiiMax. +% défaut. Pas compatible avec items manquants. +% ah je m'aperçois au dernier moment que je n'ai pas en effet de \xintiiMax. % Je devrais le rajouter. En tout cas ici c'est uniquement pour xintiiexpr, -% dans il faut bien sûr ne pas faire de xintNum, donc il faut un iimax.| +% dans il faut bien sûr ne pas faire de xintNum, donc il faut un iimax.| % \begin{macrocode} \def\xintMaxof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintmax \expandafter\xint_firstofone\romannumeral`&&@#1,^,{0/1[0]}}% @@ -30509,7 +31638,7 @@ $1$ or $-1$. \expandafter\xint_firstofone\romannumeral`&&@#1,^,1}% % \end{macrocode} % \subsubsection{\csh{xintGCDof:csv}, \csh{xintLCMof:csv}} -% \lverb|1.09a. Rewritten for 1.1. For use by \xintexpr. Expansion réinstaurée +% \lverb|1.09a. Rewritten for 1.1. For use by \xintexpr. Expansion réinstaurée % pour besoins de xintNewExpr de version 1.1| % \begin{macrocode} \def\xintGCDof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintgcd @@ -30518,18 +31647,19 @@ $1$ or $-1$. \expandafter\xint_firstofone\romannumeral`&&@#1,^,0}% % \end{macrocode} % \subsubsection{\csh{xintiiGCDof:csv}, \csh{xintiiLCMof:csv}} -% \lverb|1.1a pour \xintiiexpr. Ces histoires de ii sont pénibles à la fin.| +% \lverb|1.1a pour \xintiiexpr. Ces histoires de ii sont pénibles à la fin.| % \begin{macrocode} \def\xintiiGCDof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintiigcd \expandafter\xint_firstofone\romannumeral`&&@#1,^,1}% \def\xintiiLCMof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintiilcm \expandafter\xint_firstofone\romannumeral`&&@#1,^,0}% % \end{macrocode} -% \subsubsection{\csh{XINTinFloatdigits}, \csh{XINTinFloatSqrtdigits}} +% \subsubsection{\csh{XINTinFloatdigits}, \csh{XINTinFloatSqrtdigits}, \csh{XINTinFloatFacdigits}} % \lverb|for \xintNewExpr matters, mainly.| % \begin{macrocode} -\def\XINTinFloatdigits {\XINTinFloat [\XINTdigits]}% -\def\XINTinFloatSqrtdigits {\XINTinFloatSqrt [\XINTdigits]}% +\def\XINTinFloatdigits {\XINTinFloat [\XINTdigits]}% +\def\XINTinFloatSqrtdigits {\XINTinFloatSqrt[\XINTdigits]}% +\def\XINTinFloatFacdigits {\XINTinFloatFac [\XINTdigits]}% % \end{macrocode} % \subsubsection{\csh{XINTinFloatMaxof:csv}, \csh{XINTinFloatMinof:csv}} % \lverb|1.09a. Rewritten for 1.1. For use by \xintfloatexpr. Name changed in 1.09h| @@ -30551,7 +31681,7 @@ $1$ or $-1$. % round, trunc, mod, quo, rem, gcd, lcm, max, min, \textasciigrave % +\textasciigrave, \textasciigrave % \texorpdfstring{\protect\lowast}{*}\textasciigrave, ?, !, not, all, any, -% xor, if, ifsgn, first, last, even, odd, and reversed functions} +% xor, if, ifsgn, first, last, even, odd, reversed, factorial and binomial functions} % \localtableofcontents % \begin{macrocode} \def\XINT_expr_twoargs #1,#2,{{#1}{#2}}% @@ -30594,7 +31724,7 @@ $1$ or $-1$. {\expandafter #1\expandafter #2\csname.=\xintiiSgn {\XINT_expr_unlock #3}\endcsname }% \def\XINT_expr_func_frac #1#2#3% {\expandafter #1\expandafter #2\csname.=\xintTFrac {\XINT_expr_unlock #3}\endcsname }% -\def\XINT_flexpr_func_frac #1#2#3{\expandafter #1\expandafter #2\csname +\def\XINT_flexpr_func_frac #1#2#3{\expandafter #1\expandafter #2\csname .=\XINTinFloatFracdigits {\XINT_expr_unlock #3}\endcsname }% % \end{macrocode} % \lverb|no \XINT_iiexpr_func_frac| @@ -30623,6 +31753,24 @@ $1$ or $-1$. \expandafter #1\expandafter #2\csname .=\XINTinFloatMul{\XINT_expr_unlock #3}{\XINT_expr_unlock #3}\endcsname }% +\def\XINT_expr_func_factorial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\XINT_expr_argandopt + \romannumeral`&&@\XINT_expr_unlock#3,,.\xintiFac\XINTinFloatFac + \endcsname +}% +\def\XINT_flexpr_func_factorial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\XINT_expr_argandopt + \romannumeral`&&@\XINT_expr_unlock#3,,.\XINTinFloatFacdigits\XINTinFloatFac + \endcsname +}% +\def\XINT_iiexpr_func_factorial #1#2#3% +{% + \expandafter #1\expandafter #2\csname.=\xintiiFac{\XINT_expr_unlock #3}\endcsname +}% \def\XINT_iiexpr_func_sqr #1#2#3% {\expandafter #1\expandafter #2\csname.=\xintiiSqr {\XINT_expr_unlock #3}\endcsname }% \def\XINT_expr_func_sqrt #1#2#3% @@ -30695,6 +31843,48 @@ $1$ or $-1$. \expandafter\XINT_expr_twoargs \romannumeral`&&@\XINT_expr_unlock #3,\endcsname }% +\def\XINT_expr_func_binomial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\expandafter\expandafter\xintiBinomial + \expandafter\XINT_expr_twoargs + \romannumeral`&&@\XINT_expr_unlock #3,\endcsname +}% +\def\XINT_flexpr_func_binomial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\expandafter\expandafter\XINTinFloatBinomial + \expandafter\XINT_expr_twoargs + \romannumeral`&&@\XINT_expr_unlock #3,\endcsname +}% +\def\XINT_iiexpr_func_binomial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\expandafter\expandafter\xintiiBinomial + \expandafter\XINT_expr_twoargs + \romannumeral`&&@\XINT_expr_unlock #3,\endcsname +}% +\def\XINT_expr_func_pfactorial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\expandafter\expandafter\xintiPFactorial + \expandafter\XINT_expr_twoargs + \romannumeral`&&@\XINT_expr_unlock #3,\endcsname +}% +\def\XINT_flexpr_func_pfactorial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\expandafter\expandafter\XINTinFloatPFactorial + \expandafter\XINT_expr_twoargs + \romannumeral`&&@\XINT_expr_unlock #3,\endcsname +}% +\def\XINT_iiexpr_func_pfactorial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\expandafter\expandafter\xintiiPFactorial + \expandafter\XINT_expr_twoargs + \romannumeral`&&@\XINT_expr_unlock #3,\endcsname +}% \def\XINT_expr_func_quo #1#2#3% {% \expandafter #1\expandafter #2\csname .=% @@ -30818,36 +32008,36 @@ $1$ or $-1$. \let\XINT_flexpr_func_ifsgn\XINT_expr_func_ifsgn \let\XINT_iiexpr_func_ifsgn\XINT_expr_func_ifsgn \def\XINT_expr_func_first #1#2#3% - {\expandafter #1\expandafter #2\csname.=\expandafter\XINT_expr_func_firsta + {\expandafter #1\expandafter #2\csname.=\expandafter\XINT_expr_func_firsta \romannumeral`&&@\XINT_expr_unlock #3,^\endcsname }% \def\XINT_expr_func_firsta #1,#2^{#1}% \let\XINT_flexpr_func_first\XINT_expr_func_first \let\XINT_iiexpr_func_first\XINT_expr_func_first \def\XINT_expr_func_last #1#2#3% will not work in \xintNewExpr if macro param involved - {\expandafter #1\expandafter #2\csname.=\expandafter\XINT_expr_func_lasta + {\expandafter #1\expandafter #2\csname.=\expandafter\XINT_expr_func_lasta \romannumeral`&&@\XINT_expr_unlock #3,^\endcsname }% \def\XINT_expr_func_lasta #1,#2% {\if ^#2 #1\expandafter\xint_gobble_ii\fi \XINT_expr_func_lasta #2}% \let\XINT_flexpr_func_last\XINT_expr_func_last \let\XINT_iiexpr_func_last\XINT_expr_func_last \def\XINT_expr_func_odd #1#2#3% - {\expandafter #1\expandafter #2\csname.=\xintOdd{\XINT_expr_unlock #3}\endcsname}% + {\expandafter #1\expandafter #2\csname.=\xintOdd{\XINT_expr_unlock #3}\endcsname}% \let\XINT_flexpr_func_odd\XINT_expr_func_odd \def\XINT_iiexpr_func_odd #1#2#3% - {\expandafter #1\expandafter #2\csname.=\xintiiOdd{\XINT_expr_unlock #3}\endcsname}% + {\expandafter #1\expandafter #2\csname.=\xintiiOdd{\XINT_expr_unlock #3}\endcsname}% \def\XINT_expr_func_even #1#2#3% - {\expandafter #1\expandafter #2\csname.=\xintEven{\XINT_expr_unlock #3}\endcsname}% + {\expandafter #1\expandafter #2\csname.=\xintEven{\XINT_expr_unlock #3}\endcsname}% \let\XINT_flexpr_func_even\XINT_expr_func_even \def\XINT_iiexpr_func_even #1#2#3% - {\expandafter #1\expandafter #2\csname.=\xintiiEven{\XINT_expr_unlock #3}\endcsname}% + {\expandafter #1\expandafter #2\csname.=\xintiiEven{\XINT_expr_unlock #3}\endcsname}% \def\XINT_expr_func_nuple #1#2#3% {\expandafter #1\expandafter #2\csname .=\XINT_expr_unlock #3\endcsname }% \let\XINT_flexpr_func_nuple\XINT_expr_func_nuple \let\XINT_iiexpr_func_nuple\XINT_expr_func_nuple % \end{macrocode} -% \lverb|1.2c -% hesitated but left the function "reversed" from 1.1 with this name, not "reverse". -% But the inner not public macro got renamed into \xintReverse::csv.| +% \lverb|1.2c I hesitated but left the function "reversed" from 1.1 with +% this name, not "reverse". But the inner not public macro got renamed +% into \xintReverse::csv.| % \begin{macrocode} \def\XINT_expr_func_reversed #1#2#3% {\expandafter #1\expandafter #2\csname .=% @@ -30857,8 +32047,8 @@ $1$ or $-1$. \def\xintReverse::csv #1% should be done directly, of course {\xintListWithSep,{\xintRevWithBraces {\xintCSVtoListNonStripped{#1}}}}% % \end{macrocode} -% \subsection{f-expandable versions of the \csh{xintSeqB::csv} and alike routines, for -% \csh{xintNewExpr}} +% \subsection{f-expandable versions of the \csh{xintSeqB::csv} and alike +% routines, for \csh{xintNewExpr}} % \localtableofcontents % \subsubsection{\csh{xintSeqB:f:csv}} % \lverb|Produces in f-expandable way. If the step is zero, gives empty result @@ -30978,7 +32168,15 @@ $1$ or $-1$. % % 2015/11/21: no more \detokenize on the function names. Also I use % #1(#2)#3:=#4 rather than #1(#2):=#3. Ah, rather #1(#2)#3=#4, then I don't -% have to worry about active :.| +% have to worry about active :. +% +% 2016/02/22: 1.2f la macro associée à la fonction ne débute plus par un +% \romannumeral, de toute façon est pour emploi dans \csname..\endcsname. +% +% 2016/03/08: adding a pair of braces thus allowing comma separated +% expressions; until then the user had to do \xintdeffunc foo(x,..):=(.., .., +% ..)\relax. +% | % \begin{macrocode} \catcode`: 12 \def\XINT_tmpa #1#2#3#4% @@ -30987,7 +32185,7 @@ $1$ or $-1$. \edef\XINT_expr_tmpa {##1}% \edef\XINT_expr_tmpa {\xint_zapspaces_o \XINT_expr_tmpa}% \def\XINT_expr_tmpb {0}% - \def\XINT_expr_tmpc {##4}% + \def\XINT_expr_tmpc {(##4)}% \xintFor ####1 in {##2} \do {\edef\XINT_expr_tmpb {\the\numexpr\XINT_expr_tmpb+\xint_c_i}% \edef\XINT_expr_tmpc {subs(\unexpanded\expandafter{\XINT_expr_tmpc},% @@ -31000,7 +32198,7 @@ $1$ or $-1$. \csname XINT_#2_userfunc_\XINT_expr_tmpa\endcsname \ifxintverbose\xintMessage {xintexpr}{Info} {Function \XINT_expr_tmpa\space for \string\xint #4 parser - associated to \string\XINT_#2_userfunc_\XINT_expr_tmpa\space + associated to \string\XINT_#2_userfunc_\XINT_expr_tmpa\space with meaning \expandafter\meaning \csname XINT_#2_userfunc_\XINT_expr_tmpa\endcsname}% \fi @@ -31020,8 +32218,6 @@ $1$ or $-1$. % \csh{xintNewIIExpr}} % \localtableofcontents % \subsubsection{\csh{xintApply::csv}} -% \lverb|Don't ask me what this if for. I wrote it in June 2014, and we are now -% late October 2014.| % \begin{macrocode} \def\xintApply::csv #1#2% {\expandafter\XINT_applyon::_a\expandafter {\romannumeral`&&@#2}{#1}}% @@ -31097,7 +32293,10 @@ $1$ or $-1$. % are stuck (how could test for omit, abort, break work ?). Or we would need % macro versions. % -% ~ and $ of catcode 12 in what follows.| +% ~ and $ of catcode 12 in what follows. +% +% 1.2f adds the forgotten iiLt, iiGt, iiEq, iiLtorEq, iiGtorEq, iiNeq. +% | % \begin{macrocode} \catcode`$ 12 % $ \def\XINT_xptwo_getab_b #1#2!#3% @@ -31124,9 +32323,15 @@ $1$ or $-1$. \xint_orthat {\csname #4NE\endcsname #6}{#1#2}% }% \toks0 {}% -\xintFor #1 in {DivTrunc,iiDivTrunc,iiDivRound,Mod,iiMod,iRound,Round,iTrunc,Trunc,% - Lt,Gt,Eq,LtorEq,GtorEq,Neq,AND,OR,XOR,iQuo,iRem,Add,Sub,Mul,Div,Pow,E,% - iiAdd,iiSub,iiMul,iiPow,iiQuo,iiRem,iiE,SeqA::csv,iiSeqA::csv}\do +\xintFor #1 in + {DivTrunc,Mod,Round,Trunc,iRound,iTrunc,iQuo,iRem, + iiDivTrunc,iiDivRound,iiMod,iiQuo,iiRem,% + Lt,Gt,Eq,LtorEq,GtorEq,Neq,% + iiLt,iiGt,iiEq,iiLtorEq,iiGtorEq,iiNeq,% + Add,Sub,Mul,Div,Pow,E,% + iiAdd,iiSub,iiMul,iiPow,iiE,% + AND,OR,XOR,% + SeqA::csv,iiSeqA::csv}\do {\toks0 \expandafter{\the\toks0% no space! \expandafter\let\csname xint#1NE\expandafter\endcsname\csname xint#1\expandafter @@ -31135,14 +32340,16 @@ $1$ or $-1$. \romannumeral`&&@\expandafter\XINT_xptwo_getab_b \romannumeral`&&@####2!{####1}{~xint#1}{xint#1}}% }% -}% cela aurait-il un sens d'ajouter Raw et iNum (à cause de qint, qfrac, - % qfloat?). Pas le temps d'y réfléchir. Je ne fais rien. +}% +% cela aurait-il un sens d'ajouter Raw et iNum (à cause de qint, qfrac, +% qfloat?). Pas le temps d'y réfléchir. Je ne fais rien. \xintFor #1 in {Num,Irr,Abs,iiAbs,Sgn,iiSgn,TFrac,Floor,iFloor,Ceil,iCeil,% - Sqr,iiSqr,iiSqrt,iiSqrtR,iiIsZero,iiIsNotZero,iiifNotZero,iiifSgn,% - Odd,Even,iiOdd,iiEven,Opp,iiOpp,iiifZero,Fac,iiFac,Bool,Toggle}\do -{\toks0 - \expandafter{\the\toks0% - \expandafter\let\csname xint#1NE\expandafter\endcsname\csname xint#1\expandafter + Sqr,iiSqr,iiSqrt,iiSqrtR,iiIsZero,iiIsNotZero,iiifNotZero,iiifSgn,% + Odd,Even,iiOdd,iiEven,Opp,iiOpp,iiifZero,iFac,iBinomial,% + iPFactorial,iiFac,iiBinomial,iiPFactorial,Bool,Toggle}\do +{\toks0 \expandafter{\the\toks0% + \expandafter\let\csname xint#1NE\expandafter\endcsname\csname + xint#1\expandafter \endcsname\expandafter\def\csname xint#1\endcsname ####1{% \expandafter\XINT_NEfork_one\romannumeral`&&@####1!{~xint#1}{xint#1}{}{}}% }% @@ -31154,7 +32361,7 @@ $1$ or $-1$. \expandafter\XINT_NEfork_one \romannumeral`&&@##1!{~XINTinFloatFac}{XINTinFloatFac}{}{}}% }% -\xintFor #1 in {Add,Sub,Mul,Div,Power,E,Mod,SeqA::csv}\do +\xintFor #1 in {Add,Sub,Mul,Div,Binomial,PFactorial,PowerH,E,Mod,SeqA::csv}\do {\toks0 \expandafter{\the\toks0% \expandafter\let\csname XINTinFloat#1NE\expandafter\endcsname @@ -31165,7 +32372,7 @@ $1$ or $-1$. \romannumeral`&&@####2!{####1}{~XINTinFloat#1}{XINTinFloat#1}}% }% }% -\xintFor #1 in {XINTinFloatdigits,XINTinFloatFracdigits,XINTinFloatSqrtdigits}\do +\xintFor #1 in {XINTinFloatdigits,XINTinFloatFracdigits,XINTinFloatSqrtdigits,XINTinFloatFacdigits}\do {\toks0 \expandafter{\the\toks0% \expandafter\let\csname #1NE\expandafter\endcsname\csname #1\expandafter @@ -31203,6 +32410,10 @@ $1$ or $-1$. \def\XINTinFloatSqrt [##1]##2{% \expandafter\XINT_NEfork_one \romannumeral`&&@##2!{~XINTinFloatSqrt[##1]}{XINTinFloatSqrt}{}{[##1]}}% + \let\XINTinFloatFacNE\XINTinFloatFac + \def\XINTinFloatFac [##1]##2{% + \expandafter\XINT_NEfork_one + \romannumeral`&&@##2!{~XINTinFloatFac[##1]}{XINTinFloatFac}{}{[##1]}}% }% \xintFor #1 in {ANDof,ORof,XORof,iiMaxof,iiMinof,iiSum,iiPrd, GCDof,LCMof,Sum,Prd,Maxof,Minof}\do @@ -31235,24 +32446,18 @@ $1$ or $-1$. \def\XINT_flexpr_withopt_b ##1##2% {\expandafter\XINT_flexpr_wrap\csname .;##1.=\XINT_expr_unlock ##2\endcsname }% \def\XINT_expr_unlock_sp ##1.;##2##3.=##4!% - {\if -##2\expandafter\xint_firstoftwo\else\expandafter\xint_secondoftwo\fi + {\if -##2\expandafter\xint_firstoftwo\else\expandafter\xint_secondoftwo\fi \XINTdigits{{##2##3}}{##4}}% - \def\XINT_expr_print ##1{\expandafter\xintSPRaw::csv\expandafter + \def\XINT_expr_print ##1{\expandafter\xintSPRaw::csv\expandafter {\romannumeral`&&@\XINT_expr_unlock ##1}}% - \def\XINT_iiexpr_print ##1{\expandafter\xintCSV::csv\expandafter + \def\XINT_iiexpr_print ##1{\expandafter\xintCSV::csv\expandafter {\romannumeral`&&@\XINT_expr_unlock ##1}}% \def\XINT_boolexpr_print ##1{\expandafter\xintIsTrue::csv\expandafter {\romannumeral`&&@\XINT_expr_unlock ##1}}% % \end{macrocode} -% \lverb|$indent 1) spaces after ::csv needed to separate from possible later stuff. -% Well I currently don't recall what I meant by that. -% -% 2) due to redefinitions done above of \XINT_flexpr_noopt, etc..., no need to -% redefine \xintFloat::csv as it is not used (sub-expressions not supported), -% it is \xintPFloat::csv which is neutralized.| % \begin{macrocode} \def\xintCSV::csv {~xintCSV::csv }% - \def\xintSPRaw::csv {~xintSPRaw::csv }% + \def\xintSPRaw::csv {~xintSPRaw::csv }% \def\xintPFloat::csv {~xintPFloat::csv }% \def\xintIsTrue::csv {~xintIsTrue::csv }% \def\xintRound::csv {~xintRound::csv }% @@ -31260,53 +32465,61 @@ $1$ or $-1$. \toks0 {}% % \end{macrocode} % \subsubsection{\csh{xintNewExpr}, ..., at last.} -% \lverb|1.2c modifications to accomodate \XINT_expr_deffunc_newexpr etc..| -% \begin{macrocode} -\def\xintNewExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone\xinttheexpr }% -\def\xintNewFloatExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone\xintthefloatexpr }% -\def\xintNewIExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone\xinttheiexpr }% -\def\xintNewIIExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone\xinttheiiexpr }% -\def\xintNewBoolExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone\xinttheboolexpr }% +% \lverb|& +% 1.2c modifications to accomodate \XINT_expr_deffunc_newexpr etc.. +% +% 1.2f adds token \XINT_newexpr_clean to be able to have a different +% \XINT_newfunc_clean | +% \begin{macrocode} +\def\xintNewExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone + \xinttheexpr\XINT_newexpr_clean}% +\def\xintNewFloatExpr{\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone + \xintthefloatexpr\XINT_newexpr_clean}% +\def\xintNewIExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone + \xinttheiexpr\XINT_newexpr_clean}% +\def\xintNewIIExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone + \xinttheiiexpr\XINT_newexpr_clean}% +\def\xintNewBoolExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone + \xinttheboolexpr\XINT_newexpr_clean}% +\def\XINT_newexpr_clean #1>{\noexpand\romannumeral`&&@}% % \end{macrocode} % \lverb|1.2c for \xintdeffunc, \xintdefiifunc, \xintdeffloatfunc.| % \begin{macrocode} -\def\XINT_NewFunc {\XINT_NewExpr,{}\xint_gobble_i\xintthebareeval }% -\def\XINT_NewFloatFunc {\XINT_NewExpr,{}\xint_gobble_i\xintthebarefloateval }% -\def\XINT_NewIIFunc {\XINT_NewExpr,{}\xint_gobble_i\xintthebareiieval }% -\def\XINT_newexpr_clean #1>{\noexpand\romannumeral`&&@}% +\def\XINT_NewFunc + {\XINT_NewExpr,{}\xint_gobble_i\xintthebareeval \XINT_newfunc_clean }% +\def\XINT_NewFloatFunc + {\XINT_NewExpr,{}\xint_gobble_i\xintthebarefloateval\XINT_newfunc_clean }% +\def\XINT_NewIIFunc + {\XINT_NewExpr,{}\xint_gobble_i\xintthebareiieval \XINT_newfunc_clean }% +\def\XINT_newfunc_clean #1>{}% % \end{macrocode} % \lverb|1.2c adds optional logging. For this needed to pass to _NewExpr_a the % macro name as parameter. And _NewExpr itself receives two new parameters to % treat both \xintNewExpr and \xintdeffunc. % -% The #4 stands for the macro to be defined. Versions earlier than 1.2c had -% #1#2[#3], which was very bad for people applying LaTeX syntax -% \xintNewExpr {\foo} [5] for example as #2 would be {\foo}<space>. That -% didn't bother me much, but there is also the issue of \2<space>. Changed in -% 1.2d. -% % Up to and including 1.2c the definition was global. Starting with 1.2d it is -% done locally.| +% done locally. +% | % \begin{macrocode} -\def\XINT_NewExpr #1#2#3#4#5#6[#7]% +\def\XINT_NewExpr #1#2#3#4#5#6#7[#8]% {% \begingroup - \ifcase #7\relax - \toks0 {\endgroup\def#5}% - \or \toks0 {\endgroup\def#5##1#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1##3#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1##3#1##4#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1##3#1##4#1##5#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1##3#1##4#1##5#1##6#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1##3#1##4#1##5#1##6#1##7#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1##3#1##4#1##5#1##6#1##7#1##8#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1##3#1##4#1##5#1##6#1##7#1##8#1##9#1}% + \ifcase #8\relax + \toks0 {\endgroup\def#6}% + \or \toks0 {\endgroup\def#6##1#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1##3#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1##3#1##4#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1##3#1##4#1##5#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1##3#1##4#1##5#1##6#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1##3#1##4#1##5#1##6#1##7#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1##3#1##4#1##5#1##6#1##7#1##8#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1##3#1##4#1##5#1##6#1##7#1##8#1##9#1}% \fi \xintexprSafeCatcodes \XINT_expr_redefinemacros #2% - \XINT_NewExpr_a #3#4#5% + \XINT_NewExpr_a #3#4#5#6% }% % \end{macrocode} % \lverb|& attention que & est de catcode 14 @@ -31322,11 +32535,11 @@ $1$ or $-1$. % definition was global.| % \begin{macrocode} \catcode`~ 13 \catcode`@ 14 \catcode`\% 6 \catcode`# 12 \catcode`$ 11 @ $ -\def\XINT_NewExpr_a %1%2%3%4@ +\def\XINT_NewExpr_a %1%2%3%4%5@ {@ - \def\XINT_tmpa %%1%%2%%3%%4%%5%%6%%7%%8%%9{%4}@ + \def\XINT_tmpa %%1%%2%%3%%4%%5%%6%%7%%8%%9{%5}@ \def~{$noexpand$}@ - \catcode`: 11 \catcode`_ 11 + \catcode`: 11 \catcode`_ 11 \catcode`# 12 \catcode`~ 13 \escapechar 126 \endlinechar -1 \everyeof {\noexpand }@ \edef\XINT_tmpb @@ -31335,11 +32548,11 @@ $1$ or $-1$. }@ \escapechar 92 \catcode`# 6 \catcode`$ 0 @ $ \edef\XINT_tmpa %%1%%2%%3%%4%%5%%6%%7%%8%%9@ - {\scantokens\expandafter{\expandafter\XINT_newexpr_clean\meaning\XINT_tmpb}}@ + {\scantokens\expandafter{\expandafter%3\meaning\XINT_tmpb}}@ \the\toks0\expandafter{\XINT_tmpa{%%1}{%%2}{%%3}{%%4}{%%5}{%%6}{%%7}{%%8}{%%9}}@ %1{\ifxintverbose \xintMessage{xintexpr}{Info}@ - {\string%3\space now with meaning \meaning%3}@ + {\string%4\space now with meaning \meaning%4}@ \fi}@ }@ \catcode`% 14 @@ -31398,12 +32611,43 @@ $1$ or $-1$. \let\XINT_tmpa\relax \let\XINT_tmpb\relax \let\XINT_tmpc\relax \XINT_restorecatcodes_endinput% % \end{macrocode} -% \DeleteShortVerb{\|} +% +% \StoreCodelineNo {xintexpr} +% % \MakePercentComment -%</xintexpr> -%<*dtx> -\StoreCodelineNo {xintexpr} - +%</xintexpr>------------------------------------------------------ +%<*dtx>----------------------------------------------------------- +\iffalse +% grep -c -e "^{%" xint*sty +xint.sty:233 +xintbinhex.sty:69 +xintcfrac.sty:183 +xintcore.sty:287 +xintexpr.sty:142 +xintfrac.sty:460 +xintgcd.sty:59 +xintkernel.sty:7 +xintseries.sty:48 +xinttools.sty:128 +\fi +% grep -o "^{%" xint*sty | wc -l +\def\totala{ 1616} +\iffalse +% grep -c -e "^}%" xint*sty +xint.sty:233 +xintbinhex.sty:69 +xintcfrac.sty:183 +xintcore.sty:287 +xintexpr.sty:172 +xintfrac.sty:460 +xintgcd.sty:61 +xintkernel.sty:9 +xintseries.sty:48 +xinttools.sty:128 +\fi +% grep -o "^}%" xint*sty | wc -l +\def\totalb{ 1650} +\DeleteShortVerb{\|} \def\mymacro #1{\mymacroaux #1} \def\mymacroaux #1#2{\strut \csname #1nameimp\endcsname:& \dtt{ #2.}\tabularnewline } \indent @@ -31415,41 +32659,15 @@ $1$ or $-1$. \parbox[t]{10cm}{Total number of code lines: \dtt{\the\numexpr \xintListWithSep+{\xintApply\mymacro\storedlinecounts}\relax }. - Among those, release 1.2 has about 3000 lines starting with either - \{\% or \}\%.% en fait 3013 mais je devrais automatiser. + \ifdefined\totala + (but \dtt{\the\numexpr \totala+\totalb\relax} lines among them + start either with \{\% or with \}\%.)\fi Each package starts with circa \dtt{50} lines dealing with catcodes, package identification and reloading management, also for Plain \TeX\strut. Version {\xintbndlversion} of {\xintbndldate}.\par } -% il faut que je patche doc.sty pour faire ça automatiquement: -% -% $ grep -c -e "^{%" xint*sty -% xint.sty:170 -% xintbinhex.sty:69 -% xintcfrac.sty:183 -% xintcore.sty:290 -% xintexpr.sty:133 -% xintfrac.sty:415 -% xintgcd.sty:59 -% xintkernel.sty:7 -% xintseries.sty:48 -% xinttools.sty:128 -% (total 1502) -% $ grep -c -e "^}%" xint*sty -% xint.sty:170 -% xintbinhex.sty:69 -% xintcfrac.sty:183 -% xintcore.sty:290 -% xintexpr.sty:169 -% xintfrac.sty:415 -% xintgcd.sty:61 -% xintkernel.sty:9 -% xintseries.sty:48 -% xinttools.sty:128 -% (total 1542) - \CharacterTable {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z @@ -31465,7 +32683,7 @@ $1$ or $-1$. Right bracket \] Circumflex \^ Underscore \_ Grave accent \` Left brace \{ Vertical bar \| Right brace \} Tilde \~} -\CheckSum {27232}% +\CheckSum {29302}% \makeatletter\check@checksum\makeatother \Finale %% End of file xint.dtx diff --git a/Master/texmf-dist/source/generic/xint/xint.ins b/Master/texmf-dist/source/generic/xint/xint.ins index ffb24cbab95..0dac9845ec7 100644 --- a/Master/texmf-dist/source/generic/xint/xint.ins +++ b/Master/texmf-dist/source/generic/xint/xint.ins @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle v1.2e 2015/11/22 -%% Copyright (C) 2013-2015 by Jean-Francois Burnol +%% The xint bundle 1.2f 2016/03/12 +%% Copyright (C) 2013-2016 by Jean-Francois Burnol %% --------------------------------------------------------------- %% %% tex xint.ins extracts all package files from xint.dtx, as well as diff --git a/Master/texmf-dist/tex/generic/xint/xint.sty b/Master/texmf-dist/tex/generic/xint/xint.sty index 9c485509d83..85e1274744c 100644 --- a/Master/texmf-dist/tex/generic/xint/xint.sty +++ b/Master/texmf-dist/tex/generic/xint/xint.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle v1.2e 2015/11/22 -%% Copyright (C) 2013-2015 by Jean-Francois Burnol +%% The xint bundle 1.2f 2016/03/12 +%% Copyright (C) 2013-2016 by Jean-Francois Burnol %% xint: Expandable operations on big integers %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty (loaded by xintcore.sty) \XINT_providespackage \ProvidesPackage{xint}% - [2015/11/22 v1.2e Expandable operations on big integers (jfB)]% + [2016/03/12 1.2f 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}% @@ -378,9 +378,7 @@ \fi { -1}{ 1}% }% -%%%%%%%%%%%% \def\XINT_cmp_aa {\expandafter\XINT_cmp_w\the\numexpr\XINT_cmp_a \xint_c_i }% -%%%%%%%%%%%% \def\XINT_cmp_a #1!#2!#3!#4!#5\W #6!#7!#8!#9!% {% \XINT_cmp_b #1!#6!#2!#7!#3!#8!#4!#9!#5\W @@ -441,7 +439,6 @@ {% \XINT_cmp_k #1#2!% }% -%%%%%%%%%%%% \def\XINT_cmp_k #1#2\W {% \xint_UDzerofork @@ -533,8 +530,8 @@ {% \expandafter\XINT_geq_fork\expandafter #1\romannumeral`&&@#3\Z #2\Z }% -\let\XINT_geq_pre \xintiigeq % TEMPORAIRE -\let\XINT_Geq \xintGeq % TEMPORAIRE ATTENTION FAIT xintNum +\let\XINT_geq_pre \xintiigeq % TEMPORAIRE (oui, mais depuis quand ?) +\let\XINT_Geq \xintGeq % TEMPORAIRE ATTENTION FAIT xintNum (et alors?) \def\XINT_geq #1#2\Z #3% {% \expandafter\XINT_geq_fork\expandafter #1\romannumeral0\xintnum{#3}\Z #2\Z @@ -590,7 +587,7 @@ \else \expandafter\xint_secondoftwo \fi - \XINT_geq_aa {\XINT_geq_distinctlengths {#1}{#2}} + \XINT_geq_aa {\XINT_geq_distinctlengths {#1}{#2}}% }% \def\XINT_geq_distinctlengths #1#2#3\W #4\W {% @@ -601,9 +598,7 @@ \fi { 1}{ 0}% }% -%%%%%%%%%%%% \def\XINT_geq_aa {\expandafter\XINT_geq_w\the\numexpr\XINT_geq_a \xint_c_i }% -%%%%%%%%%%%% \def\XINT_geq_a #1!#2!#3!#4!#5\W #6!#7!#8!#9!% {% \XINT_geq_b #1!#6!#2!#7!#3!#8!#4!#9!#5\W @@ -664,7 +659,6 @@ {% \XINT_geq_k #1#2!% }% -%%%%%%%%%%%% \def\XINT_geq_k #1#2\W {% \xint_UDzerofork @@ -1012,7 +1006,7 @@ 0-{\XINT_dsx_xisPos #1}% \krof }% -\def\XINT_dsx_xisZero #1\Z #2{ {#2}{0}}% attention comme x > 0 +\def\XINT_dsx_xisZero #1\Z #2{{#2}{0}}% attention comme x > 0 \def\XINT_dsx_xisNeg_checkA #1\Z #2% {% \XINT_dsx_xisNeg_checkA_ #2\Z {#1}% @@ -1020,34 +1014,21 @@ \def\XINT_dsx_xisNeg_checkA_ #1#2\Z #3% {% \xint_gob_til_zero #1\XINT_dsx_xisNeg_Azero 0% - \XINT_dsx_xisNeg_checkx {#3}{#3}{}\Z {#1#2}% + \XINT_dsx_zeroloop #3.{}\Z {#1#2}% }% \def\XINT_dsx_xisNeg_Azero #1\Z #2{ 0}% -\def\XINT_dsx_xisNeg_checkx #1% +\def\XINT_dsx_addzerosnofuss #1{\XINT_dsx_zeroloop #1.{}\Z }% +\def\XINT_dsx_zeroloop #1.#2% {% - \ifnum #1>1000000 - \xint_afterfi - {\xintError:TooBigDecimalShift - \expandafter\space\expandafter 0\xint_gobble_iv }% - \else - \expandafter \XINT_dsx_zeroloop - \fi -}% -\def\XINT_dsx_addzerosnofuss #1{\XINT_dsx_zeroloop {#1}{}\Z }% -\def\XINT_dsx_zeroloop #1#2% -{% - \ifnum #1<\xint_c_ix \XINT_dsx_exita\fi - \expandafter\XINT_dsx_zeroloop\expandafter - {\the\numexpr #1-\xint_c_viii}{#200000000}% -}% -\def\XINT_dsx_exita\fi\expandafter\XINT_dsx_zeroloop -{% - \fi\expandafter\XINT_dsx_exitb + \ifnum #1<\xint_c_ix \expandafter\XINT_dsx_exita\fi + \expandafter\XINT_dsx_zeroloop\the\numexpr #1-\xint_c_viii.{#200000000}% }% -\def\XINT_dsx_exitb #1#2% +\def\XINT_dsx_exita + \expandafter\XINT_dsx_zeroloop\the\numexpr #1-\xint_c_viii.#2% {% \expandafter\expandafter\expandafter - \XINT_dsx_addzeros\csname xint_gobble_\romannumeral -#1\endcsname #2% + \XINT_dsx_addzeros\csname xint_gobble_\expandafter + \romannumeral\numexpr \xint_c_viii-(#1)\endcsname #2% }% \def\XINT_dsx_addzeros #1\Z #2{ #2#1}% \def\XINT_dsx_xisPos #1\Z #2% @@ -1062,28 +1043,23 @@ 0-{\XINT_dsx_AisPos #1}% \krof }% -\def\XINT_dsx_AisZero #1\Z #2{ {0}{0}}% +\def\XINT_dsx_AisZero #1\Z #2{{0}{0}}% \def\XINT_dsx_AisNeg #1\Z #2% {% - \expandafter\XINT_dsx_AisNeg_dosplit_andcheckfirst - \romannumeral0\XINT_split_checksizex {#2}{#1}% -}% -\def\XINT_dsx_AisNeg_dosplit_andcheckfirst #1% -{% - \XINT_dsx_AisNeg_checkiffirstempty #1\Z + \expandafter\XINT_dsx_AisNeg_checkiffirstempty + \romannumeral0\XINT_split_xfork #2.#1\W\W\W\W\W\W\W\W\Z }% \def\XINT_dsx_AisNeg_checkiffirstempty #1% {% - \xint_gob_til_Z #1\XINT_dsx_AisNeg_finish_zero\Z + \xint_gob_til_dot #1\XINT_dsx_AisNeg_finish_zero.% \XINT_dsx_AisNeg_finish_notzero #1% }% -\def\XINT_dsx_AisNeg_finish_zero\Z - \XINT_dsx_AisNeg_finish_notzero\Z #1% +\def\XINT_dsx_AisNeg_finish_zero.\XINT_dsx_AisNeg_finish_notzero.#1.% {% \expandafter\XINT_dsx_end \expandafter {\romannumeral0\XINT_num {-#1}}{0}% }% -\def\XINT_dsx_AisNeg_finish_notzero #1\Z #2% +\def\XINT_dsx_AisNeg_finish_notzero #1.#2.% {% \expandafter\XINT_dsx_end \expandafter {\romannumeral0\XINT_num {#2}}{-#1}% @@ -1091,57 +1067,39 @@ \def\XINT_dsx_AisPos #1\Z #2% {% \expandafter\XINT_dsx_AisPos_finish - \romannumeral0\XINT_split_checksizex {#2}{#1}% + \romannumeral0\XINT_split_xfork #2.#1\W\W\W\W\W\W\W\W\Z }% -\def\XINT_dsx_AisPos_finish #1#2% +\def\XINT_dsx_AisPos_finish #1.#2.% {% \expandafter\XINT_dsx_end \expandafter {\romannumeral0\XINT_num {#2}}% {\romannumeral0\XINT_num {#1}}% }% -\edef\XINT_dsx_end #1#2% -{% - \noexpand\expandafter\space\noexpand\expandafter{#2}{#1}% -}% -\def\xintDecSplitL {\romannumeral0\xintdecsplitl }% -\def\xintDecSplitR {\romannumeral0\xintdecsplitr }% -\def\xintdecsplitl -{% - \expandafter\xint_firstoftwo_thenstop - \romannumeral0\xintdecsplit -}% -\def\xintdecsplitr -{% - \expandafter\xint_secondoftwo_thenstop - \romannumeral0\xintdecsplit -}% +\def\XINT_dsx_end #1#2{\expandafter{#2}{#1}}% \def\xintDecSplit {\romannumeral0\xintdecsplit }% \def\xintdecsplit #1#2% {% - \expandafter \xint_split \expandafter - {\romannumeral0\xintiiabs {#2}}{#1}% fait expansion de A + \expandafter\XINT_split_finish + \romannumeral0\expandafter\XINT_split_xfork + \the\numexpr #1\expandafter.\romannumeral0\xintiiabs {#2}\W\W\W\W\W\W\W\W\Z }% -\def\xint_split #1#2% +\def\xintDecSplitL {\romannumeral0\xintdecsplitl }% +\def\xintdecsplitl #1#2% {% - \expandafter\XINT_split_checksizex\expandafter{\the\numexpr #2}{#1}% + \expandafter\XINT_splitl_finish + \romannumeral0\expandafter\XINT_split_xfork + \the\numexpr #1\expandafter.\romannumeral0\xintiiabs {#2}\W\W\W\W\W\W\W\W\Z }% -\def\XINT_split_checksizex #1% 999999999 is anyhow very big, could be reduced +\def\xintDecSplitR {\romannumeral0\xintdecsplitr }% +\def\xintdecsplitr #1#2% {% - \ifnum\numexpr\XINT_Abs{#1}>999999999 - \xint_afterfi {\xintError:TooBigDecimalSplit\XINT_split_bigx }% - \else - \expandafter\XINT_split_xfork - \fi - #1\Z -}% -\def\XINT_split_bigx #1\Z #2% -{% - \ifcase\XINT_cntSgn #1\Z - \or \xint_afterfi { {}{#2}}% positive big x - \else - \xint_afterfi { {#2}{}}% negative big x - \fi + \expandafter\XINT_splitr_finish + \romannumeral0\expandafter\XINT_split_xfork + \the\numexpr #1\expandafter.\romannumeral0\xintiiabs {#2}\W\W\W\W\W\W\W\W\Z }% +\def\XINT_split_finish #1.#2.{{#1}{#2}}% +\def\XINT_splitl_finish #1.#2.{{#1}}% +\def\XINT_splitr_finish #1.#2.{{#2}}% \def\XINT_split_xfork #1% {% \xint_UDzerominusfork @@ -1150,36 +1108,35 @@ 0-{\XINT_split_fromright #1}% \krof }% -\def\XINT_split_zerosplit #1\Z #2{ {#2}{}}% -\def\XINT_split_fromleft #1\Z #2% +\def\XINT_split_zerosplit #1.#2\W\W\W\W\W\W\W\W\Z{ #2..}% +\def\XINT_split_fromleft #1.%#2\W\W\W\W\W\W\W\W\Z {% - \XINT_split_fromleft_loop {#1}{}#2\W\W\W\W\W\W\W\W\Z + \XINT_split_fromleft_loop #1.{}%#2\W\W\W\W\W\W\W\W\Z }% -\def\XINT_split_fromleft_loop #1% +\def\XINT_split_fromleft_loop #1.% {% - \ifnum #1<\xint_c_viii\XINT_split_fromleft_exita\fi - \expandafter\XINT_split_fromleft_loop_perhaps\expandafter - {\the\numexpr #1-\xint_c_viii\expandafter}\XINT_split_fromleft_eight + \ifnum #1<\xint_c_viii\expandafter\XINT_split_fromleft_exita\fi + \expandafter\XINT_split_fromleft_loop_perhaps + \the\numexpr #1-\xint_c_viii\expandafter.\XINT_split_fromleft_eight }% \def\XINT_split_fromleft_eight #1#2#3#4#5#6#7#8#9{#9{#1#2#3#4#5#6#7#8#9}}% -\def\XINT_split_fromleft_loop_perhaps #1#2% +\def\XINT_split_fromleft_loop_perhaps #1.#2% {% \xint_gob_til_W #2\XINT_split_fromleft_toofar\W - \XINT_split_fromleft_loop {#1}% + \XINT_split_fromleft_loop #1.% }% -\def\XINT_split_fromleft_toofar\W\XINT_split_fromleft_loop #1#2#3\Z +\def\XINT_split_fromleft_toofar\W\XINT_split_fromleft_loop #1.#2#3\Z {% \XINT_split_fromleft_toofar_b #2\Z }% -\def\XINT_split_fromleft_toofar_b #1\W #2\Z { {#1}{}}% -\def\XINT_split_fromleft_exita\fi - \expandafter\XINT_split_fromleft_loop_perhaps\expandafter #1#2% - {\fi \XINT_split_fromleft_exitb #1}% -\def\XINT_split_fromleft_exitb\the\numexpr #1-\xint_c_viii\expandafter +\def\XINT_split_fromleft_toofar_b #1\W #2\Z { #1..}% +\def\XINT_split_fromleft_exita + \expandafter\XINT_split_fromleft_loop_perhaps + \the\numexpr #1-\xint_c_viii\expandafter.\XINT_split_fromleft_eight {% \csname XINT_split_fromleft_endsplit_\romannumeral #1\endcsname }% -\def\XINT_split_fromleft_endsplit_ #1#2\W #3\Z { {#1}{#2}}% +\def\XINT_split_fromleft_endsplit_ #1#2\W #3\Z { #1.#2.}% \def\XINT_split_fromleft_endsplit_i #1#2% {\XINT_split_fromleft_checkiftoofar #2{#1#2}}% \def\XINT_split_fromleft_endsplit_ii #1#2#3% @@ -1196,47 +1153,41 @@ {\XINT_split_fromleft_checkiftoofar #8{#1#2#3#4#5#6#7#8}}% \def\XINT_split_fromleft_checkiftoofar #1#2#3\W #4\Z {% - \xint_gob_til_W #1\XINT_split_fromleft_wenttoofar\W - \space {#2}{#3}% + \xint_gob_til_W #1\XINT_split_fromleft_wenttoofar\W \space#2.#3.% }% -\def\XINT_split_fromleft_wenttoofar\W\space #1% +\def\XINT_split_fromleft_wenttoofar\W\space #1.% {% \XINT_split_fromleft_wenttoofar_b #1\Z }% -\def\XINT_split_fromleft_wenttoofar_b #1\W #2\Z { {#1}}% -\def\XINT_split_fromright #1\Z #2% -{% - \expandafter \XINT_split_fromright_a \expandafter - {\romannumeral0\xintreverseorder {#2}}{#1}{#2}% -}% -\def\XINT_split_fromright_a #1#2% +\def\XINT_split_fromleft_wenttoofar_b #1\W #2\Z { #1.}% +\def\XINT_split_fromright #1.#2\W\W\W\W\W\W\W\W\Z {% - \XINT_split_fromright_loop {#2}{}#1\W\W\W\W\W\W\W\W\Z + \expandafter\XINT_split_fromright_loop + \the\numexpr #1\expandafter.\expandafter{\expandafter}% + \romannumeral0\xintreverseorder{#2}\W\W\W\W\W\W\W\W\Z #2.% }% -\def\XINT_split_fromright_loop #1% +\def\XINT_split_fromright_loop #1.% {% - \ifnum #1<\xint_c_viii\XINT_split_fromright_exita\fi - \expandafter\XINT_split_fromright_loop_perhaps\expandafter - {\the\numexpr #1-\xint_c_viii\expandafter }\XINT_split_fromright_eight + \ifnum #1<\xint_c_viii\expandafter\XINT_split_fromright_exita\fi + \expandafter\XINT_split_fromright_loop_perhaps + \the\numexpr #1-\xint_c_viii\expandafter.\XINT_split_fromright_eight }% \def\XINT_split_fromright_eight #1#2#3#4#5#6#7#8#9{#9{#9#8#7#6#5#4#3#2#1}}% -\def\XINT_split_fromright_loop_perhaps #1#2% +\def\XINT_split_fromright_loop_perhaps #1.#2% {% \xint_gob_til_W #2\XINT_split_fromright_toofar\W - \XINT_split_fromright_loop {#1}% + \XINT_split_fromright_loop #1.% }% -\def\XINT_split_fromright_toofar\W\XINT_split_fromright_loop #1#2#3\Z { {}}% -\def\XINT_split_fromright_exita\fi - \expandafter\XINT_split_fromright_loop_perhaps\expandafter #1#2% - {\fi \XINT_split_fromright_exitb #1}% -\def\XINT_split_fromright_exitb\the\numexpr #1-\xint_c_viii\expandafter +\def\XINT_split_fromright_toofar\W\XINT_split_fromright_loop #1\Z {.}% +\def\XINT_split_fromright_exita + \expandafter\XINT_split_fromright_loop_perhaps + \the\numexpr #1-\xint_c_viii\expandafter.\XINT_split_fromright_eight {% \csname XINT_split_fromright_endsplit_\romannumeral #1\endcsname }% -\edef\XINT_split_fromright_endsplit_ #1#2\W #3\Z #4% +\def\XINT_split_fromright_endsplit_ #1#2\W #3\Z #4.% {% - \noexpand\expandafter\space\noexpand\expandafter - {\noexpand\romannumeral0\noexpand\xintreverseorder {#2}}{#1}% + \xintreverseorder {#2}.#1.% }% \def\XINT_split_fromright_endsplit_i #1#2% {\XINT_split_fromright_checkiftoofar #2{#2#1}}% @@ -1257,8 +1208,8 @@ \xint_gob_til_W #1\XINT_split_fromright_wenttoofar\W \XINT_split_fromright_endsplit_ }% -\def\XINT_split_fromright_wenttoofar\W\XINT_split_fromright_endsplit_ #1\Z #2% - { {}{#2}}% +\def\XINT_split_fromright_wenttoofar\W + \XINT_split_fromright_endsplit_ #1\Z {.}% \def\xintiiSqrt {\romannumeral0\xintiisqrt }% \def\xintiiSqrtR {\romannumeral0\xintiisqrtr }% \def\xintiiSquareRoot {\romannumeral0\xintiisquareroot }% @@ -1284,159 +1235,649 @@ \edef\XINT_sqrt_isneg #1\Z {\noexpand\xintError:RootOfNegative\space 11}% \def\XINT_sqrt #1\Z {% - \expandafter\XINT_sqrt_start\expandafter {\romannumeral0\xintlength {#1}}{#1}% + \expandafter\XINT_sqrt_start\romannumeral0\xintlength {#1}.#1.% }% -\def\XINT_sqrt_start #1% +\def\XINT_sqrt_start #1.% {% - \ifnum #1<\xint_c_x - \expandafter\XINT_sqrt_small_a - \else - \expandafter\XINT_sqrt_big_a - \fi - {#1}% + \ifnum #1<\xint_c_x\xint_dothis\XINT_sqrt_small_a\fi + \xint_orthat\XINT_sqrt_big_a #1.% }% -\def\XINT_sqrt_small_a #1{\XINT_sqrt_a {#1}\XINT_sqrt_small_d }% -\def\XINT_sqrt_big_a #1{\XINT_sqrt_a {#1}\XINT_sqrt_big_d }% -\def\XINT_sqrt_a #1% +\def\XINT_sqrt_small_a #1.{\XINT_sqrt_a #1.\XINT_sqrt_small_d }% +\def\XINT_sqrt_big_a #1.{\XINT_sqrt_a #1.\XINT_sqrt_big_d }% +\def\XINT_sqrt_a #1.% {% \ifodd #1 - \expandafter\XINT_sqrt_bB + \expandafter\XINT_sqrt_bO \else - \expandafter\XINT_sqrt_bA + \expandafter\XINT_sqrt_bE \fi - {#1}% + #1.% }% -\def\XINT_sqrt_bA #1#2#3% +\def\XINT_sqrt_bE #1.#2#3#4% {% - \XINT_sqrt_bA_b #3\Z #2{#1}{#3}% + \XINT_sqrt_c {#3#4}#2{#1}#3#4% }% -\def\XINT_sqrt_bA_b #1#2#3\Z +\def\XINT_sqrt_bO #1.#2#3% {% - \XINT_sqrt_c {#1#2}% + \XINT_sqrt_c #3#2{#1}#3% }% -\def\XINT_sqrt_bB #1#2#3% +\def\XINT_sqrt_c #1#2% {% - \XINT_sqrt_bB_b #3\Z #2{#1}{#3}% + \expandafter #2% + \the\numexpr \ifnum #1>\xint_c_ii + \ifnum #1>\xint_c_vi + \ifnum #1>12 \ifnum #1>20 \ifnum #1>30 + \ifnum #1>42 \ifnum #1>56 \ifnum #1>72 + \ifnum #1>90 + 10\else 9\fi \else 8\fi \else 7\fi \else 6\fi \else 5\fi + \else 4\fi \else 3\fi \else 2\fi \else 1\fi .% }% -\def\XINT_sqrt_bB_b #1#2\Z +\def\XINT_sqrt_small_d #1.#2% {% - \XINT_sqrt_c #1% + \expandafter\XINT_sqrt_small_e + \the\numexpr #1\ifcase \numexpr #2/\xint_c_ii-\xint_c_i\relax + \or 0\or 00\or 000\or 0000\fi .% }% -\def\XINT_sqrt_c #1#2% +\def\XINT_sqrt_small_e #1.#2.% {% - \expandafter #2\expandafter - {\the\numexpr\ifnum #1>\xint_c_iii - \ifnum #1>\xint_c_viii - \ifnum #1>15 \ifnum #1>24 \ifnum #1>35 - \ifnum #1>48 \ifnum #1>63 \ifnum #1>80 - 10\else 9\fi \else 8\fi \else 7\fi \else 6\fi - \else 5\fi \else 4\fi \else 3\fi \else 2\fi \relax }% + \expandafter\XINT_sqrt_small_ea\the\numexpr #1*#1-#2.#1.% }% -\def\XINT_sqrt_small_d #1#2% +\def\XINT_sqrt_small_ea #1% {% - \expandafter\XINT_sqrt_small_e\expandafter - {\the\numexpr #1\ifcase \numexpr #2/\xint_c_ii-\xint_c_i\relax - \or 0\or 00\or 000\or 0000\fi }% + \if0#1\xint_dothis\XINT_sqrt_small_ez\fi + \if-#1\xint_dothis\XINT_sqrt_small_eb\fi + \xint_orthat\XINT_sqrt_small_f #1% }% -\def\XINT_sqrt_small_e #1#2% +\def\XINT_sqrt_small_ez 0.#1.{\expandafter{\the\numexpr#1+\xint_c_i + \expandafter}\expandafter{\the\numexpr #1*\xint_c_ii+\xint_c_i}}% +\def\XINT_sqrt_small_eb -#1.#2.% {% - \expandafter\XINT_sqrt_small_f\expandafter {\the\numexpr #1*#1-#2}{#1}% + \expandafter\XINT_sqrt_small_ec \the\numexpr + (#1-\xint_c_i+#2)/(\xint_c_ii*#2).#1.#2.% }% -\def\XINT_sqrt_small_f #1#2% +\def\XINT_sqrt_small_ec #1.#2.#3.% {% - \expandafter\XINT_sqrt_small_g\expandafter - {\the\numexpr ((#1+#2)/(\xint_c_ii*#2))-\xint_c_i}{#1}{#2}% + \expandafter\XINT_sqrt_small_f \the\numexpr + -#2+\xint_c_ii*#3*#1+#1*#1\expandafter.\the\numexpr #3+#1.% }% -\def\XINT_sqrt_small_g #1% +\def\XINT_sqrt_small_f #1.#2.% {% - \ifnum #1>\xint_c_ - \expandafter\XINT_sqrt_small_h - \else + \expandafter\XINT_sqrt_small_g + \the\numexpr (#1+#2)/(\xint_c_ii*#2)-\xint_c_i.#1.#2.% +}% +\def\XINT_sqrt_small_g #1#2.% +{% + \if 0#1% \expandafter\XINT_sqrt_small_end + \else + \expandafter\XINT_sqrt_small_h \fi - {#1}% + #1#2.% }% -\def\XINT_sqrt_small_h #1#2#3% +\def\XINT_sqrt_small_h #1.#2.#3.% {% - \expandafter\XINT_sqrt_small_f\expandafter - {\the\numexpr #2-\xint_c_ii*#1*#3+#1*#1\expandafter}\expandafter - {\the\numexpr #3-#1}% + \expandafter\XINT_sqrt_small_f + \the\numexpr #2-\xint_c_ii*#1*#3+#1*#1\expandafter.% + \the\numexpr #3-#1.% }% -\def\XINT_sqrt_small_end #1#2#3{ {#3}{#2}}% -\def\XINT_sqrt_big_d #1#2% +\def\XINT_sqrt_small_end #1.#2.#3.{{#3}{#2}}% +\def\XINT_sqrt_big_d #1.#2% {% - \ifodd #2 - \expandafter\expandafter\expandafter\XINT_sqrt_big_eB - \else - \expandafter\expandafter\expandafter\XINT_sqrt_big_eA - \fi - \expandafter {\the\numexpr #2/\xint_c_ii }{#1}% + \ifodd #2 \xint_dothis{\expandafter\XINT_sqrt_big_eO}\fi + \xint_orthat{\expandafter\XINT_sqrt_big_eE}% + \the\numexpr (#2-\xint_c_i)/\xint_c_ii.#1;% +}% +\def\XINT_sqrt_big_eE #1;#2#3#4#5#6#7#8#9% +{% + \XINT_sqrt_big_eE_a #1;{#2#3#4#5#6#7#8#9}% +}% +\def\XINT_sqrt_big_eE_a #1.#2;#3% +{% + \expandafter\XINT_sqrt_bigormed_f + \romannumeral0\XINT_sqrt_small_e #2000.#3.#1;% +}% +\def\XINT_sqrt_big_eO #1;#2#3#4#5#6#7#8#9% +{% + \XINT_sqrt_big_eO_a #1;{#2#3#4#5#6#7#8#9}% }% -\def\XINT_sqrt_big_eA #1#2#3% +\def\XINT_sqrt_big_eO_a #1.#2;#3#4% {% - \XINT_sqrt_big_eA_a #3\Z {#2}{#1}{#3}% + \expandafter\XINT_sqrt_bigormed_f + \romannumeral0\XINT_sqrt_small_e #20000.#3#4.#1;% }% -\def\XINT_sqrt_big_eA_a #1#2#3#4#5#6#7#8#9\Z +\def\XINT_sqrt_bigormed_f #1#2#3;% {% - \XINT_sqrt_big_eA_b {#1#2#3#4#5#6#7#8}% + \ifnum#3<\xint_c_ix + \xint_dothis {\csname XINT_sqrt_med_f\romannumeral#3\endcsname}% + \fi + \xint_orthat\XINT_sqrt_big_f #1.#2.#3;% +}% +\def\XINT_sqrt_med_fv {\XINT_sqrt_med_fa .}% +\def\XINT_sqrt_med_fvi {\XINT_sqrt_med_fa 0.}% +\def\XINT_sqrt_med_fvii {\XINT_sqrt_med_fa 00.}% +\def\XINT_sqrt_med_fviii{\XINT_sqrt_med_fa 000.}% +\def\XINT_sqrt_med_fa #1.#2.#3.#4;% +{% + \expandafter\XINT_sqrt_med_fb + \the\numexpr (#30#1-5#1)/(\xint_c_ii*#2).#1.#2.#3.% +}% +\def\XINT_sqrt_med_fb #1.#2.#3.#4.#5.% +{% + \expandafter\XINT_sqrt_small_ea + \the\numexpr (#40#2-\xint_c_ii*#3*#1)*10#2+(#1*#1-#5)\expandafter.% + \the\numexpr #30#2-#1.% +}% +\def\XINT_sqrt_big_f #1;#2#3#4#5#6#7#8#9% +{% + \XINT_sqrt_big_fa #1;{#2#3#4#5#6#7#8#9}% +}% +\def\XINT_sqrt_big_fa #1.#2.#3;#4% +{% + \expandafter\XINT_sqrt_big_ga + \the\numexpr #3-\xint_c_viii\expandafter.% + \romannumeral0\XINT_sqrt_med_fa 000.#1.#2.;#4.% +}% +\def\XINT_sqrt_big_ga #1.#2#3% +{% + \ifnum #1>\xint_c_viii + \expandafter\XINT_sqrt_big_gb\else + \expandafter\XINT_sqrt_big_ka + \fi #1.#3.#2.% +}% +\def\XINT_sqrt_big_gb #1.#2.#3.% +{% + \expandafter\XINT_sqrt_big_gc + \the\numexpr (\xint_c_ii*#2-\xint_c_i)*\xint_c_x^viii/(\xint_c_iv*#3).% + #3.#2.#1;% +}% +\def\XINT_sqrt_big_gc #1.#2.#3.% +{% + \expandafter\XINT_sqrt_big_gd + \romannumeral0\xintiiadd + {\xintiiSub {#300000000}{\xintDouble{\xintiiMul{#2}{#1}}}00000000}% + {\xintiiSqr {#1}}.% + \romannumeral0\xintiisub{#200000000}{#1}.% +}% +\def\XINT_sqrt_big_gd #1.#2.% +{% + \expandafter\XINT_sqrt_big_ge #2.#1.% +}% +\def\XINT_sqrt_big_ge #1;#2#3#4#5#6#7#8#9% + {\XINT_sqrt_big_gf #1.#2#3#4#5#6#7#8#9;}% +\def\XINT_sqrt_big_gf #1;#2#3#4#5#6#7#8#9% + {\XINT_sqrt_big_gg #1#2#3#4#5#6#7#8#9.}% +\def\XINT_sqrt_big_gg #1.#2.#3.#4.% +{% + \expandafter\XINT_sqrt_big_gloop + \expandafter\xint_c_xvi\expandafter.% + \the\numexpr #3-\xint_c_viii\expandafter.% + \romannumeral0\xintiisub {#2}{\xintiNum{#4}}.#1.% +}% +\def\XINT_sqrt_big_gloop #1.#2.% +{% + \unless\ifnum #1<#2 \xint_dothis\XINT_sqrt_big_ka \fi + \xint_orthat{\XINT_sqrt_big_gi #1.}#2.% +}% +\def\XINT_sqrt_big_gi #1.% +{% + \expandafter\XINT_sqrt_big_gj + \romannumeral0\XINT_dsx_addzerosnofuss{#1}{}.#1.% }% -\def\XINT_sqrt_big_eA_b #1#2% +\def\XINT_sqrt_big_gj #1.#2.#3.#4.#5.% {% - \expandafter\XINT_sqrt_big_f - \romannumeral0\XINT_sqrt_small_e {#2000}{#1}{#1}% + \expandafter\XINT_sqrt_big_gk + \romannumeral0\xintiidivision {#4#1}{\XINT_dbl_pos #5\Z}.% + #1.#5.#2.#3.% }% -\def\XINT_sqrt_big_eB #1#2#3% +\def\XINT_sqrt_big_gk #1#2.#3.#4.% {% - \XINT_sqrt_big_eB_a #3\Z {#2}{#1}{#3}% + \expandafter\XINT_sqrt_big_gl + \romannumeral0\xintiiadd {#2#3}{\xintiiSqr{#1}}.% + \romannumeral0\xintiisub {#4#3}{#1}.% }% -\def\XINT_sqrt_big_eB_a #1#2#3#4#5#6#7#8#9% +\def\XINT_sqrt_big_gl #1.#2.% {% - \XINT_sqrt_big_eB_b {#1#2#3#4#5#6#7#8#9}% + \expandafter\XINT_sqrt_big_gm #2.#1.% }% -\def\XINT_sqrt_big_eB_b #1#2\Z #3% +\def\XINT_sqrt_big_gm #1.#2.#3.#4.#5.% {% - \expandafter\XINT_sqrt_big_f - \romannumeral0\XINT_sqrt_small_e {#30000}{#1}{#1}% + \expandafter\XINT_sqrt_big_gn + \romannumeral0\expandafter\XINT_split_fromleft_loop + \the\numexpr\xint_c_ii*#3.{}#5\W\W\W\W\W\W\W\W\Z + #1.#2.#3.#4.% }% -\def\XINT_sqrt_big_f #1#2#3#4% +\def\XINT_sqrt_big_gn #1.#2.#3.#4.#5.#6.% {% - \expandafter\XINT_sqrt_big_f_a\expandafter - {\the\numexpr #2+#3\expandafter}\expandafter - {\romannumeral0\XINT_dsx_addzerosnofuss - {\numexpr #4-\xint_c_iv\relax}{#1}}{#4}% + \expandafter\XINT_sqrt_big_gloop + \the\numexpr \xint_c_ii*#5\expandafter.% + \the\numexpr #6-#5\expandafter.% + \romannumeral0\xintiisub{#4}{\xintiNum{#1}}.#3.#2.% }% -\def\XINT_sqrt_big_f_a #1#2#3#4% +\def\XINT_sqrt_big_ka #1.#2.#3.#4.% {% - \expandafter\XINT_sqrt_big_g\expandafter - {\romannumeral0\xintiisub - {\XINT_dsx_addzerosnofuss - {\numexpr \xint_c_ii*#3-\xint_c_viii\relax}{#1}}{#4}}% - {#2}{#3}% + \expandafter\XINT_sqrt_big_kb + \romannumeral0\XINT_dsx_addzerosnofuss {#1}{#3}.% + \romannumeral0\xintiisub + {\XINT_dsx_addzerosnofuss {\numexpr\xint_c_ii*#1}{#2}}% + {\xintiNum{#4}}.% }% -\def\XINT_sqrt_big_g #1#2% +\def\XINT_sqrt_big_kb #1.#2.% {% - \expandafter\XINT_sqrt_big_j + \expandafter\XINT_sqrt_big_kc #2.#1.% +}% +\def\XINT_sqrt_big_kc #1% +{% + \if0#1\xint_dothis\XINT_sqrt_big_kz\fi + \xint_orthat\XINT_sqrt_big_kloop #1% +}% +\def\XINT_sqrt_big_kz 0.#1.% +{% + \expandafter\XINT_sqrt_big_kend + \romannumeral0\xintinc{\XINT_dbl_pos #1\Z}.#1.% +}% +\def\XINT_sqrt_big_kend #1.#2.% +{% + \expandafter{\romannumeral0\xintinc{#2}}{#1}% +}% +\def\XINT_sqrt_big_kloop #1.#2.% +{% + \expandafter\XINT_sqrt_big_ke \romannumeral0\xintiidivision{#1}{\romannumeral0\XINT_dbl_pos #2\Z}{#2}% }% -\def\XINT_sqrt_big_j #1% +\def\XINT_sqrt_big_ke #1% {% \if0\XINT_Sgn #1\Z \expandafter \XINT_sqrt_big_end - \else \expandafter \XINT_sqrt_big_k + \else \expandafter \XINT_sqrt_big_kf \fi {#1}% }% -\def\XINT_sqrt_big_k #1#2#3% +\def\XINT_sqrt_big_kf #1#2#3% +{% + \expandafter\XINT_sqrt_big_kg + \romannumeral0\xintiisub {#3}{#1}.% + \romannumeral0\xintiiadd {#2}{\xintiiSqr {#1}}.% +}% +\def\XINT_sqrt_big_kg #1.#2.% +{% + \expandafter\XINT_sqrt_big_kloop #2.#1.% +}% +\def\XINT_sqrt_big_end #1#2#3{{#3}{#2}}% +\def\xintiiBinomial {\romannumeral0\xintiibinomial }% +\def\xintiibinomial #1#2% +{% + \expandafter\XINT_binom_pre\the\numexpr #1\expandafter.\the\numexpr #2.% +}% +\def\XINT_binom_pre #1.#2.% +{% + \expandafter\XINT_binom_fork \the\numexpr#1-#2.#2.#1.% +}% +\def\xintiBinomial{\romannumeral0\xintibinomial}% +\let\xintibinomial\xintiibinomial +\def\XINT_binom_fork #1#2.#3#4.#5#6.% +{% + \if-#1\xint_dothis {\xintError:OutOfRangeBinomial\space 0}\fi + \if-#3\xint_dothis {\xintError:OutOfRangeBinomial\space 0}\fi + \if0#1\xint_dothis{ 1}\fi + \if0#3\xint_dothis{ 1}\fi + \ifnum #5#6>\xint_c_x^viii_mone\xint_dothis{\xintError:OutOfRangeBinomial\space 0}\fi + \ifnum #1#2>#3#4 \xint_dothis{\XINT_binom_a #1#2.#3#4.}\fi + \xint_orthat{\XINT_binom_a #3#4.#1#2.}% +}% +\def\XINT_binom_a #1.#2.% +{% + \expandafter\XINT_binom_b\the\numexpr \xint_c_i+#1.1.#2.100000001!1!\Z!0!% +}% +\def\XINT_binom_b #1.% +{% + \ifnum #1>9999 \xint_dothis\XINT_binom_vbigloop \fi + \ifnum #1>463 \xint_dothis\XINT_binom_bigloop \fi + \ifnum #1>98 \xint_dothis\XINT_binom_medloop \fi + \ifnum #1>29 \xint_dothis\XINT_binom_smallloop \fi + \xint_orthat\XINT_binom_vsmallloop #1.% +}% +\def\XINT_binom_smallloop #1.#2.#3.% +{% + \ifcase\numexpr #3-#2\relax + \expandafter\XINT_binom_end_ + \or \expandafter\XINT_binom_end_i + \or \expandafter\XINT_binom_end_ii + \or \expandafter\XINT_binom_end_iii + \else\expandafter\XINT_binom_smallloop_a + \fi #1.#2.#3.% +}% +\def\XINT_binom_smallloop_a #1.#2.#3.% +{% + \expandafter\XINT_binom_smallloop_b + \the\numexpr #1+\xint_c_iv\expandafter.% + \the\numexpr #2+\xint_c_iv\expandafter.% + \the\numexpr #3\expandafter.% + \the\numexpr\expandafter\XINT_binom_div + \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)*(#2+\xint_c_iii)\expandafter + !\romannumeral0\expandafter\XINT_binom_mul + \the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% +}% +\def\XINT_binom_smallloop_b #1.% +{% + \ifnum #1>98 \expandafter\XINT_binom_medloop \else + \expandafter\XINT_binom_smallloop \fi #1.% +}% +\def\XINT_binom_medloop #1.#2.#3.% +{% + \ifcase\numexpr #3-#2\relax + \expandafter\XINT_binom_end_ + \or \expandafter\XINT_binom_end_i + \or \expandafter\XINT_binom_end_ii + \else\expandafter\XINT_binom_medloop_a + \fi #1.#2.#3.% +}% +\def\XINT_binom_medloop_a #1.#2.#3.% +{% + \expandafter\XINT_binom_medloop_b + \the\numexpr #1+\xint_c_iii\expandafter.% + \the\numexpr #2+\xint_c_iii\expandafter.% + \the\numexpr #3\expandafter.% + \the\numexpr\expandafter\XINT_binom_div + \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)\expandafter + !\romannumeral0\expandafter\XINT_binom_mul + \the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% +}% +\def\XINT_binom_medloop_b #1.% +{% + \ifnum #1>463 \expandafter\XINT_binom_bigloop \else + \expandafter\XINT_binom_medloop \fi #1.% +}% +\def\XINT_binom_bigloop #1.#2.#3.% +{% + \ifcase\numexpr #3-#2\relax + \expandafter\XINT_binom_end_ + \or \expandafter\XINT_binom_end_i + \else\expandafter\XINT_binom_bigloop_a + \fi #1.#2.#3.% +}% +\def\XINT_binom_bigloop_a #1.#2.#3.% +{% + \expandafter\XINT_binom_bigloop_b + \the\numexpr #1+\xint_c_ii\expandafter.% + \the\numexpr #2+\xint_c_ii\expandafter.% + \the\numexpr #3\expandafter.% + \the\numexpr\expandafter\XINT_binom_div + \the\numexpr #2*(#2+\xint_c_i)\expandafter + !\romannumeral0\expandafter\XINT_binom_mul + \the\numexpr #1*(#1+\xint_c_i)!% +}% +\def\XINT_binom_bigloop_b #1.% +{% + \ifnum #1>9999 \expandafter\XINT_binom_vbigloop \else + \expandafter\XINT_binom_bigloop \fi #1.% +}% +\def\XINT_binom_vbigloop #1.#2.#3.% +{% + \ifnum #3=#2 + \expandafter\XINT_binom_end_ + \else\expandafter\XINT_binom_vbigloop_a + \fi #1.#2.#3.% +}% +\def\XINT_binom_vbigloop_a #1.#2.#3.% +{% + \expandafter\XINT_binom_vbigloop + \the\numexpr #1+\xint_c_i\expandafter.% + \the\numexpr #2+\xint_c_i\expandafter.% + \the\numexpr #3\expandafter.% + \the\numexpr\expandafter\XINT_binom_div\the\numexpr #2\expandafter + !\romannumeral0\XINT_binom_mul #1!% +}% +\def\XINT_binom_vsmallloop #1.#2.#3.% +{% + \ifcase\numexpr #3-#2\relax + \expandafter\XINT_binom_vsmallend_ + \or \expandafter\XINT_binom_vsmallend_i + \or \expandafter\XINT_binom_vsmallend_ii + \or \expandafter\XINT_binom_vsmallend_iii + \else\expandafter\XINT_binom_vsmallloop_a + \fi #1.#2.#3.% +}% +\def\XINT_binom_vsmallloop_a #1.% +{% + \ifnum #1>26 \expandafter\XINT_binom_smallloop_a \else + \expandafter\XINT_binom_vsmallloop_b \fi #1.% +}% +\def\XINT_binom_vsmallloop_b #1.#2.#3.% +{% + \expandafter\XINT_binom_vsmallloop + \the\numexpr #1+\xint_c_iv\expandafter.% + \the\numexpr #2+\xint_c_iv\expandafter.% + \the\numexpr #3\expandafter.% + \the\numexpr \expandafter\XINT_binom_vsmallmuldiv + \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)*(#2+\xint_c_iii)\expandafter + !\the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% +}% +\def\XINT_binom_mul #1!#21!\Z!0!% +{% + \expandafter\XINT_rev_nounsep\expandafter{\expandafter}% + \the\numexpr\expandafter\XINT_smallmul + \the\numexpr\xint_c_x^viii+#1\expandafter + !\romannumeral0\XINT_rev_nounsep {}1\Z!#2% + \R!\R!\R!\R!\R!\R!\R!\R!\W + \R!\R!\R!\R!\R!\R!\R!\R!\W + 1\Z!% +}% +\def\XINT_binom_div #1!1\Z!% +{% + \expandafter\XINT_smalldivx_a + \the\numexpr #1/\xint_c_ii\expandafter.% + \the\numexpr \xint_c_x^viii+#1!% +}% +\def\XINT_binom_vsmallmuldiv #1!#2!1#3!{\xint_c_x^viii+#2*#3/#1!}% +\def\XINT_binom_end_iii #1.#2.#3.% +{% + \expandafter\XINT_binom_finish + \the\numexpr\expandafter\XINT_binom_div + \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)*(#2+\xint_c_iii)\expandafter + !\romannumeral0\expandafter\XINT_binom_mul + \the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% +}% +\def\XINT_binom_end_ii #1.#2.#3.% +{% + \expandafter\XINT_binom_finish + \the\numexpr\expandafter\XINT_binom_div + \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)\expandafter + !\romannumeral0\expandafter\XINT_binom_mul + \the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% +}% +\def\XINT_binom_end_i #1.#2.#3.% +{% + \expandafter\XINT_binom_finish + \the\numexpr\expandafter\XINT_binom_div + \the\numexpr #2*(#2+\xint_c_i)\expandafter + !\romannumeral0\expandafter\XINT_binom_mul + \the\numexpr #1*(#1+\xint_c_i)!% +}% +\def\XINT_binom_end_ #1.#2.#3.% +{% + \expandafter\XINT_binom_finish + \the\numexpr\expandafter\XINT_binom_div\the\numexpr #2\expandafter + !\romannumeral0\XINT_binom_mul #1!% +}% +\def\XINT_binom_finish #1\Z!0!% + {\XINT_unsep_cuzsmall #11\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W }% +\def\XINT_binom_vsmallend_iii #1.% +{% + \ifnum #1>26 \expandafter\XINT_binom_end_iii \else + \expandafter\XINT_binom_vsmallend_iiib \fi #1.% +}% +\def\XINT_binom_vsmallend_iiib #1.#2.#3.% +{% + \expandafter\XINT_binom_vsmallfinish + \the\numexpr \expandafter\XINT_binom_vsmallmuldiv + \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)*(#2+\xint_c_iii)\expandafter + !\the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% +}% +\def\XINT_binom_vsmallend_ii #1.% +{% + \ifnum #1>27 \expandafter\XINT_binom_end_ii \else + \expandafter\XINT_binom_vsmallend_iib \fi #1.% +}% +\def\XINT_binom_vsmallend_iib #1.#2.#3.% +{% + \expandafter\XINT_binom_vsmallfinish + \the\numexpr \expandafter\XINT_binom_vsmallmuldiv + \the\numexpr #2*(#2+\xint_c_i)*(#2+\xint_c_ii)\expandafter + !\the\numexpr #1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% +}% +\def\XINT_binom_vsmallend_i #1.% +{% + \ifnum #1>28 \expandafter\XINT_binom_end_i \else + \expandafter\XINT_binom_vsmallend_ib \fi #1.% +}% +\def\XINT_binom_vsmallend_ib #1.#2.#3.% +{% + \expandafter\XINT_binom_vsmallfinish + \the\numexpr \expandafter\XINT_binom_vsmallmuldiv + \the\numexpr #2*(#2+\xint_c_i)\expandafter + !\the\numexpr #1*(#1+\xint_c_i)!% +}% +\def\XINT_binom_vsmallend_ #1.% +{% + \ifnum #1>29 \expandafter\XINT_binom_end_ \else + \expandafter\XINT_binom_vsmallend_b \fi #1.% +}% +\def\XINT_binom_vsmallend_b #1.#2.#3.% +{% + \expandafter\XINT_binom_vsmallfinish + \the\numexpr\XINT_binom_vsmallmuldiv #2!#1!% +}% +\edef\XINT_binom_vsmallfinish 1#1!1!\Z!0!% + {\noexpand\expandafter\space\noexpand\the\numexpr #1\relax}% +\def\xintiiPFactorial {\romannumeral0\xintiipfactorial }% +\def\xintiipfactorial #1#2% +{% + \expandafter\XINT_pfac_fork\the\numexpr#1\expandafter.\the\numexpr #2.% +}% +\def\xintiPFactorial{\romannumeral0\xintipfactorial}% +\let\xintipfactorial\xintiipfactorial +\def\XINT_pfac_fork #1#2.#3.% +{% + \if-#1\xint_dothis {\xintError:OutOfRangePFac\space 0}\fi + \ifnum #1#2=#3 \xint_dothis{ 1}\fi + \ifnum #1#2>#3 \xint_dothis{\xintError:OutOfRangePFac\space 0}\fi + \ifnum #3>\xint_c_x^viii_mone\xint_dothis{\xintError:OutOfRangePFac\space 0}\fi + \xint_orthat {\XINT_pfac_a #1#2.#3.}% +}% +\def\XINT_pfac_a #1.#2.% +{% + \expandafter\XINT_pfac_b\the\numexpr \xint_c_i+#1.#2.100000001!1\Z!% + 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W +}% +\def\XINT_pfac_b #1.% +{% + \ifnum #1>9999 \xint_dothis\XINT_pfac_vbigloop \fi + \ifnum #1>463 \xint_dothis\XINT_pfac_bigloop \fi + \ifnum #1>98 \xint_dothis\XINT_pfac_medloop \fi + \xint_orthat\XINT_pfac_smallloop #1.% +}% +\def\XINT_pfac_smallloop #1.#2.% +{% + \ifcase\numexpr #2-#1\relax + \expandafter\XINT_pfac_end_ + \or \expandafter\XINT_pfac_end_i + \or \expandafter\XINT_pfac_end_ii + \or \expandafter\XINT_pfac_end_iii + \else\expandafter\XINT_pfac_smallloop_a + \fi #1.#2.% +}% +\def\XINT_pfac_smallloop_a #1.#2.% +{% + \expandafter\XINT_pfac_smallloop_b + \the\numexpr #1+\xint_c_iv\expandafter.% + \the\numexpr #2\expandafter.% + \the\numexpr\expandafter\XINT_smallmul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% +}% +\def\XINT_pfac_smallloop_b #1.% +{% + \ifnum #1>98 \expandafter\XINT_pfac_medloop \else + \expandafter\XINT_pfac_smallloop \fi #1.% +}% +\def\XINT_pfac_medloop #1.#2.% +{% + \ifcase\numexpr #2-#1\relax + \expandafter\XINT_pfac_end_ + \or \expandafter\XINT_pfac_end_i + \or \expandafter\XINT_pfac_end_ii + \else\expandafter\XINT_pfac_medloop_a + \fi #1.#2.% +}% +\def\XINT_pfac_medloop_a #1.#2.% +{% + \expandafter\XINT_pfac_medloop_b + \the\numexpr #1+\xint_c_iii\expandafter.% + \the\numexpr #2\expandafter.% + \the\numexpr\expandafter\XINT_smallmul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% +}% +\def\XINT_pfac_medloop_b #1.% +{% + \ifnum #1>463 \expandafter\XINT_pfac_bigloop \else + \expandafter\XINT_pfac_medloop \fi #1.% +}% +\def\XINT_pfac_bigloop #1.#2.% +{% + \ifcase\numexpr #2-#1\relax + \expandafter\XINT_pfac_end_ + \or \expandafter\XINT_pfac_end_i + \else\expandafter\XINT_pfac_bigloop_a + \fi #1.#2.% +}% +\def\XINT_pfac_bigloop_a #1.#2.% +{% + \expandafter\XINT_pfac_bigloop_b + \the\numexpr #1+\xint_c_ii\expandafter.% + \the\numexpr #2\expandafter.% + \the\numexpr\expandafter + \XINT_smallmul\the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!% +}% +\def\XINT_pfac_bigloop_b #1.% +{% + \ifnum #1>9999 \expandafter\XINT_pfac_vbigloop \else + \expandafter\XINT_pfac_bigloop \fi #1.% +}% +\def\XINT_pfac_vbigloop #1.#2.% +{% + \ifnum #2=#1 + \expandafter\XINT_pfac_end_ + \else\expandafter\XINT_pfac_vbigloop_a + \fi #1.#2.% +}% +\def\XINT_pfac_vbigloop_a #1.#2.% +{% + \expandafter\XINT_pfac_vbigloop + \the\numexpr #1+\xint_c_i\expandafter.% + \the\numexpr #2\expandafter.% + \the\numexpr\expandafter\XINT_smallmul\the\numexpr\xint_c_x^viii+#1!% +}% +\def\XINT_pfac_end_iii #1.#2.% +{% + \expandafter\XINT_mul_out + \the\numexpr\expandafter\XINT_smallmul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% +}% +\def\XINT_pfac_end_ii #1.#2.% +{% + \expandafter\XINT_mul_out + \the\numexpr\expandafter\XINT_smallmul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% +}% +\def\XINT_pfac_end_i #1.#2.% {% - \expandafter\XINT_sqrt_big_l\expandafter - {\romannumeral0\xintiisub {#3}{#1}}% - {\romannumeral0\xintiiadd {#2}{\xintiiSqr {#1}}}% + \expandafter\XINT_mul_out + \the\numexpr\expandafter\XINT_smallmul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!% }% -\def\XINT_sqrt_big_l #1#2% +\def\XINT_pfac_end_ #1.#2.% {% - \expandafter\XINT_sqrt_big_g\expandafter - {#2}{#1}% + \expandafter\XINT_mul_out + \the\numexpr\expandafter\XINT_smallmul\the\numexpr \xint_c_x^viii+#1!% }% -\def\XINT_sqrt_big_end #1#2#3#4{ {#3}{#2}}% \def\xintiiE {\romannumeral0\xintiie }% used in \xintMod. \def\xintiie #1#2% {\expandafter\XINT_iie\the\numexpr #2\expandafter.\expandafter{\romannumeral`&&@#1}}% diff --git a/Master/texmf-dist/tex/generic/xint/xintbinhex.sty b/Master/texmf-dist/tex/generic/xint/xintbinhex.sty index b06dd6b8443..061e629acca 100644 --- a/Master/texmf-dist/tex/generic/xint/xintbinhex.sty +++ b/Master/texmf-dist/tex/generic/xint/xintbinhex.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle v1.2e 2015/11/22 -%% Copyright (C) 2013-2015 by Jean-Francois Burnol +%% The xint bundle 1.2f 2016/03/12 +%% Copyright (C) 2013-2016 by Jean-Francois Burnol %% xintbinhex: Expandable binary and hexadecimal conversions %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintbinhex}% - [2015/11/22 v1.2e Expandable binary and hexadecimal conversions (jfB)]% + [2016/03/12 1.2f 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 \newcount\xint_c_x^v \xint_c_x^v 100000 diff --git a/Master/texmf-dist/tex/generic/xint/xintcfrac.sty b/Master/texmf-dist/tex/generic/xint/xintcfrac.sty index c2ee3e85658..6f516f56bfb 100644 --- a/Master/texmf-dist/tex/generic/xint/xintcfrac.sty +++ b/Master/texmf-dist/tex/generic/xint/xintcfrac.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle v1.2e 2015/11/22 -%% Copyright (C) 2013-2015 by Jean-Francois Burnol +%% The xint bundle 1.2f 2016/03/12 +%% Copyright (C) 2013-2016 by Jean-Francois Burnol %% xintcfrac: Expandable continued fractions with xint package %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintcfrac}% - [2015/11/22 v1.2e Expandable continued fractions with xint package (jfB)]% + [2016/03/12 1.2f 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 94980e62be4..5088cdefa12 100644 --- a/Master/texmf-dist/tex/generic/xint/xintcore.sty +++ b/Master/texmf-dist/tex/generic/xint/xintcore.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle v1.2e 2015/11/22 -%% Copyright (C) 2013-2015 by Jean-Francois Burnol +%% The xint bundle 1.2f 2016/03/12 +%% Copyright (C) 2013-2016 by Jean-Francois Burnol %% xintcore: Expandable arithmetic on big integers %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintcore}% - [2015/11/22 v1.2e Expandable arithmetic on big integers (jfB)]% + [2016/03/12 1.2f Expandable arithmetic on big integers (JFB)]% \ifdefined\m@ne\let\xint_c_mone\m@ne \else\csname newcount\endcsname\xint_c_mone \xint_c_mone -1 \fi \newcount\xint_c_x^viii \xint_c_x^viii 100000000 @@ -122,28 +122,26 @@ {% \noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4#5#6#7#8\relax }% -%%%%%%%%%%%% \def\XINT_cuz #1#2#3#4#5#6#7#8#9% {% \xint_gob_til_R #9\XINT_cuz_e \R \xint_gob_til_eightzeroes #1#2#3#4#5#6#7#8\XINT_cuz_z 00000000% - \XINT_cuz_clean #1#2#3#4#5#6#7#8#9% + \XINT_cuz_done #1#2#3#4#5#6#7#8#9% }% -\edef\XINT_cuz_clean #1#2#3#4#5#6#7#8#9\R +\def\XINT_cuz_z 00000000\XINT_cuz_done 00000000{\XINT_cuz }% +\edef\XINT_cuz_done #1#2#3#4#5#6#7#8#9\R {\noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4#5#6#7#8\relax #9}% -\edef\XINT_cuz_e\R #1\XINT_cuz_clean #2\R +\edef\XINT_cuz_e\R #1\XINT_cuz_done #2\R {\noexpand\expandafter\space\noexpand\the\numexpr #2\relax }% -\def\XINT_cuz_z 00000000\XINT_cuz_clean 00000000{\XINT_cuz }% -%%%%%%%%%%%% \def\XINT_cuz_byviii #1#2#3#4#5#6#7#8#9% {% \xint_gob_til_R #9\XINT_cuz_byviii_e \R \xint_gob_til_eightzeroes #1#2#3#4#5#6#7#8\XINT_cuz_byviii_z 00000000% - \XINT_cuz_byviii_clean #1#2#3#4#5#6#7#8#9% + \XINT_cuz_byviii_done #1#2#3#4#5#6#7#8#9% }% -\def\XINT_cuz_byviii_clean #1\R { #1}% -\def\XINT_cuz_byviii_e\R #1\XINT_cuz_byviii_clean #2\R{ #2}% -\def\XINT_cuz_byviii_z 00000000\XINT_cuz_byviii_clean 00000000{\XINT_cuz_byviii}% +\def\XINT_cuz_byviii_z 00000000\XINT_cuz_byviii_done 00000000{\XINT_cuz_byviii}% +\def\XINT_cuz_byviii_done #1\R { #1}% +\def\XINT_cuz_byviii_e\R #1\XINT_cuz_byviii_done #2\R{ #2}% \def\XINT_zeroes_forviii #1#2#3#4#5#6#7#8% {% \xint_gob_til_R #8\XINT_zeroes_forviii_end\R\XINT_zeroes_forviii @@ -152,7 +150,6 @@ {% \noexpand\expandafter\space\noexpand\xint_gob_til_one #2#3#4#5#6#7#8% }% -%%%%%%%%%%%% \def\XINT_rsepbyviii #1#2#3#4#5#6#7#8% {% \XINT_rsepbyviii_b {#1#2#3#4#5#6#7#8}% @@ -164,7 +161,6 @@ }% \def\XINT_rsepbyviii_end_B #1\relax #2#3{#2.}% \def\XINT_rsepbyviii_end_A #11#2\expandafter #3\relax #4#5{#2.1#5.}% -%%%%%%%%%%%% \def\XINT_sepandrev {% \expandafter\XINT_sepandrev_a\the\numexpr 1\XINT_rsepbyviii @@ -177,7 +173,6 @@ }% \def\XINT_sepandrev_end\R\XINT_sepandrev_b #1#2\W {\XINT_sepandrev_done #1}% \def\XINT_sepandrev_done #11#2!{ }% -%%%%%%%%%%%% \def\XINT_sepandrev_andcount {% \expandafter\XINT_sepandrev_andcount_a\the\numexpr 1\XINT_rsepbyviii @@ -220,13 +215,11 @@ {% #2\expandafter!\the\numexpr#3\expandafter!\the\numexpr#4\expandafter !\the\numexpr#5\expandafter!\the\numexpr#6\expandafter!\the\numexpr - #7\expandafter - !\the\numexpr#8\expandafter!\the\numexpr#9\expandafter!\the\numexpr + #7\expandafter!\the\numexpr#8\expandafter!\the\numexpr#9\expandafter!\the\numexpr \expandafter\XINT_sepbyviii_andcount_b\the\numexpr #1+\xint_c_viii.% }% \def\XINT_sepbyviii_andcount_end #1\XINT_sepbyviii_andcount_b\the\numexpr #2+\xint_c_viii.#3#4\W {\expandafter.\the\numexpr #2+#3.}% -%%%%%%%%%%%% \def\XINT_rev_nounsep #1#2!#3!#4!#5!#6!#7!#8!#9!% {% \xint_gob_til_R #9\XINT_rev_nounsep_end\R @@ -234,13 +227,11 @@ }% \def\XINT_rev_nounsep_end\R\XINT_rev_nounsep #1#2\W {\XINT_rev_nounsep_done #1}% \def\XINT_rev_nounsep_done #11{ 1}% -%%%%%%%%%%%% \def\XINT_sepbyviii_Z #1#2#3#4#5#6#7#8% {% 1#1#2#3#4#5#6#7#8\expandafter!\the\numexpr\XINT_sepbyviii_Z }% \def\XINT_sepbyviii_Z_end #1\relax {\relax\Z!}% -%%%%%%%%%%%% \def\XINT_unsep_cuzsmall #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!% {% \xint_gob_til_R #9\XINT_unsep_cuzsmall_end\R @@ -250,7 +241,6 @@ \XINT_unsep_cuzsmall #1{\XINT_unsep_cuzsmall_done #1}% \def\XINT_unsep_cuzsmall_done #1\R #2\W{\XINT_cuz_small #1}% \def\XINT_unsep_delim {1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W}% -%%%%%%%%%%%% \def\XINT_div_unsepQ #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!% {% \xint_gob_til_R #9\XINT_div_unsepQ_end\R @@ -267,7 +257,6 @@ {\the\numexpr #1\relax \Z}% \def\XINT_div_unsepQ_y #1.#2\R #3\W{\XINT_cuz_small #2\Z}% \def\XINT_div_unsepQ_done #1.#2\R #3\W { #1#2\Z}% -%%%%%%%%%%%% \def\XINT_div_unsepR #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!% {% \xint_gob_til_R #9\XINT_div_unsepR_end\R @@ -826,15 +815,24 @@ }% \def\XINT_sub_l #1{\xint_UDzerofork #1\XINT_sub_l_carry 0\XINT_sub_l_nocarry\krof}% \def\XINT_sub_l_nocarry 1{1\relax }% -\def\XINT_sub_l_carry #1!{\expandafter\XINT_sub_m\the\numexpr 1#1-\xint_c_i!}% -\def\XINT_sub_m 1#1{\xint_UDzerofork #1\XINT_sub_n_carry 0\XINT_sub_n_nocarry\krof}% -\def\XINT_sub_n_carry #1!{1#1\expandafter!\the\numexpr\XINT_sub_l_carry }% -\def\XINT_sub_n_nocarry #1!#2#3!% +\def\XINT_sub_l_carry 1#1!{\ifcase #1 + \expandafter \XINT_sub_l_zeroa\or\expandafter\XINT_sub_l_one\else + \expandafter \XINT_sub_l_done\fi 1#1!}% +\def\XINT_sub_l_done {-\xint_c_i+}% +\def\XINT_sub_l_one 1#1!#2% {% - \xint_gob_til_Z #2\xint_gob_til_eightzeroes #1\XINT_sub_n_zero - 00000000\xint_gob_til_Z\Z 1\relax #1!#2#3!% + \xint_gob_til_Z #2\XINT_sub_l_oneone\Z 1\relax 00000000!#2% }% -\def\XINT_sub_n_zero 00000000\xint_gob_til_Z\Z 1\relax 00000000!{1!}% +\def\XINT_sub_l_oneone #1\W {1\relax \XINT_cuz_byviii!\Z 0\W\R }% +\def\XINT_sub_l_zeroa 1#1!{199999999\expandafter!\the\numexpr \XINT_sub_l_zerob }% +\def\XINT_sub_l_zerob 1#1!{\ifcase #1 + \expandafter \XINT_sub_l_zeroa\or\expandafter\XINT_sub_l_zone\else + \expandafter \XINT_sub_l_done\fi 1#1!}% +\def\XINT_sub_l_zone 1#1!#2% +{% + \xint_gob_til_Z #2\XINT_sub_l_zoneone\Z 1\relax 00000000!#2% +}% +\def\XINT_sub_l_zoneone\Z 1\relax 00000000{1}% \def\XINT_sub_p\Z\XINT_sub_l #1#2\W {% \xint_UDzerofork @@ -1085,62 +1083,55 @@ 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W }% \def\xintiiPow {\romannumeral0\xintiipow }% -\def\xintiipow #1% +\def\xintiipow #1#2% {% - \expandafter\xint_pow\romannumeral`&&@#1\Z% + \expandafter\xint_pow\the\numexpr #2\expandafter.\romannumeral`&&@#1\Z% }% -\def\xintiPow {\romannumeral0\xintipow }% -\def\xintipow #1% +\def\xintiPow {\romannumeral0\xintipow }% +\def\xintipow #1#2% {% - \expandafter\xint_pow\romannumeral0\xintnum{#1}\Z% + \expandafter\xint_pow\the\numexpr #2\expandafter.\romannumeral0\xintnum{#1}\Z% }% -\def\xint_pow #1#2\Z +\def\xint_pow #1.#2%#3\Z {% - \xint_UDsignfork - #1\XINT_pow_Aneg - -\XINT_pow_Anonneg - \krof - #1{#2}% + \xint_UDzerominusfork + #2-\XINT_pow_AisZero + 0#2\XINT_pow_Aneg + 0-{\XINT_pow_Apos #2}% + \krof {#1}% }% -\def\XINT_pow_Aneg #1#2#3% +\def\XINT_pow_AisZero #1#2\Z {% - \expandafter\XINT_pow_Aneg_\expandafter{\the\numexpr #3}#2\Z + \ifcase\XINT_cntSgn #1\Z + \xint_afterfi { 1}% + \or + \xint_afterfi { 0}% + \else + \xint_afterfi {\xintError:DivisionByZero\space 0}% + \fi }% -\def\XINT_pow_Aneg_ #1% +\def\XINT_pow_Aneg #1% {% \ifodd #1 - \expandafter\XINT_pow_Aneg_Bodd + \expandafter\XINT_opp\romannumeral0% \fi - \XINT_pow_Anonneg_ {#1}% -}% -\def\XINT_pow_Aneg_Bodd #1% -{% - \expandafter\XINT_opp\romannumeral0\XINT_pow_Anonneg_ + \XINT_pow_Apos {}{#1}% }% -\def\XINT_pow_Anonneg #1#2#3% +\def\XINT_pow_Apos #1#2{\XINT_pow_Apos_a {#2}#1}% +\def\XINT_pow_Apos_a #1#2#3% {% - \expandafter\XINT_pow_Anonneg_\expandafter {\the\numexpr #3}#1#2\Z + \xint_gob_til_Z #3\XINT_pow_Apos_short\Z + \XINT_pow_AatleastTwo {#1}#2#3% }% -\def\XINT_pow_Anonneg_ #1#2#3\Z +\def\XINT_pow_Apos_short\Z\XINT_pow_AatleastTwo #1#2\Z {% - \if\relax #3\relax\xint_dothis - {\ifcase #2 \expandafter\XINT_pow_AisZero - \or\expandafter\XINT_pow_AisOne - \else\expandafter\XINT_pow_AatleastTwo - \fi }\fi - \xint_orthat \XINT_pow_AatleastTwo {#1}{#2#3}% -}% -\def\XINT_pow_AisOne #1#2{ 1}% -\def\XINT_pow_AisZero #1#2% -{% - \ifcase\XINT_cntSgn #1\Z - \xint_afterfi { 1}% - \or - \xint_afterfi { 0}% - \else - \xint_afterfi {\xintError:DivisionByZero\space 0}% - \fi + \ifcase #2 + \xintError:thiscannothappen! + \or \expandafter\XINT_pow_AisOne + \else\expandafter\XINT_pow_AatleastTwo + \fi {#1}#2\Z }% +\def\XINT_pow_AisOne #1\Z{ 1}% \def\XINT_pow_AatleastTwo #1% {% \ifcase\XINT_cntSgn #1\Z @@ -1152,10 +1143,10 @@ \fi {#1}% }% -\edef\XINT_pow_BisNegative #1#2% +\edef\XINT_pow_BisNegative #1\Z {\noexpand\xintError:FractionRoundedToZero\space 0}% -\def\XINT_pow_BisZero #1#2{ 1}% -\def\XINT_pow_I_in #1#2% +\def\XINT_pow_BisZero #1\Z{ 1}% +\def\XINT_pow_I_in #1#2\Z {% \expandafter\XINT_pow_I_loop \the\numexpr #1\expandafter.% @@ -1229,33 +1220,24 @@ \the\numexpr #1\expandafter.% \the\numexpr\XINT_pow_mulbutcheckifsmall #3\W #3\W #2\W }% -\def\xintiFac {\romannumeral0\xintifac }% -\def\xintifac #1% -{% - \expandafter\XINT_fac_fork\expandafter {\the\numexpr#1}% -}% \def\xintiiFac {\romannumeral0\xintiifac }% -\def\xintiifac #1% -{% - \expandafter\XINT_fac_fork\expandafter {\romannumeral`&&@#1}% -}% -\let\xintFac\xintiFac \let\xintfac\xintifac -\def\XINT_fac_fork #1% +\def\xintiifac #1{\expandafter\XINT_fac_fork\the\numexpr#1.}% +\def\xintiFac {\romannumeral0\xintifac }% +\let\xintifac\xintiifac +\def\XINT_fac_fork #1#2.% {% - \ifcase\XINT_cntSgn #1\Z - \xint_afterfi{\expandafter\space\expandafter 1\xint_gobble_i }% - \or - \expandafter\XINT_fac_checksize - \else - \xint_afterfi{\expandafter\xintError:FactorialOfNegativeNumber - \expandafter\space\expandafter 1\xint_gobble_i }% - \fi - {#1}% + \xint_UDzerominusfork + #1-\XINT_fac_zero + 0#1\XINT_fac_neg + 0-\XINT_fac_checksize + \krof #1#2.% }% -\def\XINT_fac_checksize #1% +\def\XINT_fac_zero #1.{ 1}% +\edef\XINT_fac_neg #1.{\noexpand\xintError:FactorialOfNegative\space 1}% +\def\XINT_fac_checksize #1.% {% - \ifnum #1>9999 - \xint_dothis{\expandafter\xintError:FactorialOfTooBigNumber + \ifnum #1>\xint_c_x^iv + \xint_dothis{\expandafter\xintError:TooBigFactorial \expandafter\space\expandafter 1\xint_gob_til_W }\fi \ifnum #1>465 \xint_dothis{\XINT_fac_bigloop_a #1.}\fi \ifnum #1>101 \xint_dothis{\XINT_fac_medloop_a #1.\XINT_mul_out}\fi @@ -1401,7 +1383,6 @@ \expandafter\xint_exchangetwo_keepbraces \expandafter{\romannumeral0\XINT_sub_mm_a {}{}#3\Z #2\Z}{#1}% r-> b-r }% -%%%%%%%%%%%% \def\XINT_div_prepare #1% {% \XINT_div_prepare_a #1\R\R\R\R\R\R\R\R {10}0000001\W !{#1}% @@ -1411,7 +1392,6 @@ \xint_gob_til_R #9\XINT_div_prepare_small\R \XINT_div_prepare_b #9% }% -%%%%%%%%%%%% \def\XINT_div_prepare_small\R #1!#2% {% \ifcase #2 @@ -1462,7 +1442,6 @@ {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #3-#1*#2}}% \def\XINT_div_dosmalldiv {{\expandafter\XINT_sdiv_out\the\numexpr\XINT_smalldivx_a}}% -%%%%%%%%%%%% \def\XINT_div_prepare_b {\expandafter\XINT_div_prepare_c\romannumeral0\XINT_zeroes_forviii }% \def\XINT_div_prepare_c #1!% @@ -1854,8 +1833,7 @@ {% -\ifnum 0#1=\xint_c_ 1\else2\fi\relax }% -%%%%%%%%%%%% -\def\XINT_sdiv_out #1\Z #2\W% +\def\XINT_sdiv_out #1\Z!#2!% {\expandafter {\romannumeral0\XINT_unsep_cuzsmall#11\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W}% {#2}}% @@ -1864,22 +1842,22 @@ \expandafter\XINT_smalldivx_b \the\numexpr (#3+#1)/#2-\xint_c_i!#1.#2!#3!% }% -\def\XINT_smalldivx_b #1!% +\def\XINT_smalldivx_b #1#2!% {% \if0#1\else - \xint_c_x^viii+#1\xint_afterfi{\expandafter!\the\numexpr}\fi - \XINT_smalldiv_c #1!% + \xint_c_x^viii+#1#2\xint_afterfi{\expandafter!\the\numexpr}\fi + \XINT_smalldiv_c #1#2!% }% \def\XINT_smalldiv_c #1!#2.#3!#4!% {% \expandafter\XINT_smalldiv_d\the\numexpr #4-#1*#3!#2.#3!% }% -\def\XINT_smalldiv_d #1!#2!#3#4!% +\def\XINT_smalldiv_d #1!#2!1#3#4!% {% - \xint_gob_til_Z #4\XINT_smalldiv_end \Z - \XINT_smalldiv_e #1!#2!#3#4!% + \xint_gob_til_Z #3\XINT_smalldiv_end \Z + \XINT_smalldiv_e #1!#2!1#3#4!% }% -\def\XINT_smalldiv_end\Z\XINT_smalldiv_e #1!#2!1\Z!{1!\Z #1\W }% +\def\XINT_smalldiv_end\Z\XINT_smalldiv_e #1!#2!1\Z!{1!\Z!#1!}% \def\XINT_smalldiv_e #1!#2.#3!% {% \expandafter\XINT_smalldiv_f\the\numexpr @@ -1899,18 +1877,15 @@ }% \def\XINT_smalldiv_g 1#1!1#2!#3!#4!#5!#6!% {% - \expandafter\XINT_smalldiv_h - \the\numexpr 1#6-#1.#2!#5!#3!#4!% + \expandafter\XINT_smalldiv_h\the\numexpr 1#6-#1.#2!#5!#3!#4!% }% \def\XINT_smalldiv_h 1#1#2.#3!#4!% {% - \expandafter\XINT_smalldiv_i - \the\numexpr #4-#3+#1-\xint_c_i.#2!% + \expandafter\XINT_smalldiv_i\the\numexpr #4-#3+#1-\xint_c_i.#2!% }% \def\XINT_smalldiv_i #1.#2!#3!#4.#5!% {% - \expandafter\XINT_smalldiv_j - \the\numexpr (#1#2+#4)/#5-\xint_c_i!#3!#1#2!#4.#5!% + \expandafter\XINT_smalldiv_j\the\numexpr (#1#2+#4)/#5-\xint_c_i!#3!#1#2!#4.#5!% }% \def\XINT_smalldiv_j #1!#2!% {% diff --git a/Master/texmf-dist/tex/generic/xint/xintexpr.sty b/Master/texmf-dist/tex/generic/xint/xintexpr.sty index 5c2f726146b..ab7896f4fe0 100644 --- a/Master/texmf-dist/tex/generic/xint/xintexpr.sty +++ b/Master/texmf-dist/tex/generic/xint/xintexpr.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle v1.2e 2015/11/22 -%% Copyright (C) 2013-2015 by Jean-Francois Burnol +%% The xint bundle 1.2f 2016/03/12 +%% Copyright (C) 2013-2016 by Jean-Francois Burnol %% xintexpr: Expandable expression parser %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -81,7 +81,7 @@ \XINTsetupcatcodes% \XINT_providespackage \ProvidesPackage{xintexpr}% - [2015/11/22 v1.2e Expandable expression parser (jfB)]% + [2016/03/12 1.2f Expandable expression parser (JFB)]% \catcode`! 11 \def\xint_gob_til_! #1!{}% catcode 11 ! default in xintexpr.sty code. \edef\XINT_expr_lockscan#1!% not used for decimal numbers in xintexpr 1.2 @@ -98,7 +98,6 @@ [\the\numexpr-4*\xintLength{#3}]% \fi }% -%%%%%%%%%%%% \def\XINT_expr_unlock {\expandafter\XINT_expr_unlock_a\string }% \def\XINT_expr_unlock_a #1.={}% \def\XINT_expr_unexpectedtoken {\xintError:ignored }% @@ -583,7 +582,7 @@ \def\XINT_expr_unknown_operator #1{\xintError:removed \xint_gobble_i {#1}}% \def\XINT_expr_foundop #1{\csname XINT_expr_precedence_#1\endcsname #1}% \catcode`) 11 -\def\XINT_tmpa #1#2#3#4% (avant #4#5) +\def\XINT_tmpa #1#2#3#4% {% \def#1##1% {% @@ -660,7 +659,7 @@ \do {\expandafter\def\csname XINT_expr_itself_#1\endcsname {#1}}% \catcode`& 7 \expandafter\let\csname XINT_expr_precedence_***\endcsname \xint_c_viii -\def\XINT_tmpc #1#2#3#4#5#6#7#8% +\def\XINT_expr_defbin_c #1#2#3#4#5#6#7#8% {% \def #1##1% \XINT_expr_op_<op> ou flexpr ou iiexpr {% keep value, get next number and operator, then do until @@ -672,7 +671,7 @@ \krof }% \def #3##1##2##3##4% \XINT_expr_until_<op>_b ou flexpr ou iiexpr {% either execute next operation now, or first do next (possibly unary) - \ifnum ##2>#5% + \ifnum ##2>#7% \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@% \csname XINT_#8_op_##3\endcsname {##4}}% \else \xint_afterfi {\expandafter ##2\expandafter ##3% @@ -680,80 +679,74 @@ \fi }% \let #7#5% }% -\def\XINT_tmpb #1#2#3#4#5#6% +\def\XINT_expr_defbin_b #1#2#3#4#5% {% - \expandafter\XINT_tmpc - \csname XINT_#1_op_#3\expandafter\endcsname - \csname XINT_#1_until_#3_a\expandafter\endcsname - \csname XINT_#1_until_#3_b\expandafter\endcsname - \csname XINT_#1_op_-#5\expandafter\endcsname - \csname xint_c_#4\expandafter\endcsname - \csname #2#6\expandafter\endcsname - \csname XINT_expr_precedence_#3\endcsname {#1}% -}% -\catcode`& 12 -\xintFor #1 in {expr, flexpr} \do {% - \def\XINT_tmpa ##1{\XINT_tmpb {#1}{xint}##1}% - \xintApplyInline {\XINT_tmpa }{% - {|{iii}{vi}{OR}}% - {&{iv}{vi}{AND}}% - {{xor}{iii}{vi}{XOR}}% - {<{v}{vi}{Lt}}% - {>{v}{vi}{Gt}}% - {={v}{vi}{Eq}}% - {{<=}{v}{vi}{LtorEq}}% - {{>=}{v}{vi}{GtorEq}}% - {{!=}{v}{vi}{Neq}}% - {{..}{iii}{vi}{Seq::csv}}% - {{//}{vii}{vii}{DivTrunc}}% - {{/:}{vii}{vii}{Mod}}% - }% -}% -\catcode`& 7 -\def\XINT_tmpa #1{\XINT_tmpb {expr}{xint}#1}% -\xintApplyInline {\XINT_tmpa }{% - {+{vi}{vi}{Add}}% - {-{vi}{vi}{Sub}}% - {*{vii}{vii}{Mul}}% - {/{vii}{vii}{Div}}% - {^{ix}{ix}{Pow}}% - {{..[}{iii}{vi}{SeqA::csv}}% - {{]..}{iii}{vi}{SeqB::csv}}% -}% -\def\XINT_tmpa #1{\XINT_tmpb {flexpr}{XINTinFloat}#1}% -\xintApplyInline {\XINT_tmpa }{% - {+{vi}{vi}{Add}}% - {-{vi}{vi}{Sub}}% - {*{vii}{vii}{Mul}}% - {/{vii}{vii}{Div}}% - {^{ix}{ix}{Power}}% - {{..[}{iii}{vi}{SeqA::csv}}% - {{]..}{iii}{vi}{SeqB::csv}}% -}% -\def\XINT_tmpa #1{\XINT_tmpb {iiexpr}{xint}#1}% -\catcode`& 12 -\xintApplyInline {\XINT_tmpa }{% - {|{iii}{vi}{OR}}% - {&{iv}{vi}{AND}}% - {{xor}{iii}{vi}{XOR}}% - {<{v}{vi}{iiLt}}% - {>{v}{vi}{iiGt}}% - {={v}{vi}{iiEq}}% - {{<=}{v}{vi}{iiLtorEq}}% - {{>=}{v}{vi}{iiGtorEq}}% - {{!=}{v}{vi}{iiNeq}}% - {+{vi}{vi}{iiAdd}}% - {-{vi}{vi}{iiSub}}% - {*{vii}{vii}{iiMul}}% - {/{vii}{vii}{iiDivRound}}% CHANGED IN 1.1! PREVIOUSLY DID EUCLIDEAN QUOTIENT - {^{ix}{ix}{iiPow}}% - {{..[}{iii}{vi}{iiSeqA::csv}}% - {{]..}{iii}{vi}{iiSeqB::csv}}% - {{..}{iii}{vi}{iiSeq::csv}}% - {{//}{vii}{vii}{iiDivTrunc}}% - {{/:}{vii}{vii}{iiMod}}% + \expandafter\XINT_expr_defbin_c + \csname XINT_#1_op_#2\expandafter\endcsname + \csname XINT_#1_until_#2_a\expandafter\endcsname + \csname XINT_#1_until_#2_b\expandafter\endcsname + \csname XINT_#1_op_-#4\expandafter\endcsname + \csname xint_c_#3\expandafter\endcsname + \csname #5\expandafter\endcsname + \csname XINT_expr_precedence_#2\endcsname {#1}% }% -\catcode`& 7 +\XINT_expr_defbin_b {expr} | {iii}{vi} {xintOR}% +\XINT_expr_defbin_b {flexpr} | {iii}{vi} {xintOR}% +\XINT_expr_defbin_b {iiexpr} | {iii}{vi} {xintOR}% +\XINT_expr_defbin_b {expr} & {iv}{vi} {xintAND}% +\XINT_expr_defbin_b {flexpr} & {iv}{vi} {xintAND}% +\XINT_expr_defbin_b {iiexpr} & {iv}{vi} {xintAND}% +\XINT_expr_defbin_b {expr} {xor}{iii}{vi} {xintXOR}% +\XINT_expr_defbin_b {flexpr}{xor}{iii}{vi} {xintXOR}% +\XINT_expr_defbin_b {iiexpr}{xor}{iii}{vi} {xintXOR}% +\XINT_expr_defbin_b {expr} < {v}{vi} {xintLt}% +\XINT_expr_defbin_b {flexpr} < {v}{vi} {xintLt}% +\XINT_expr_defbin_b {iiexpr} < {v}{vi} {xintiiLt}% +\XINT_expr_defbin_b {expr} > {v}{vi} {xintGt}% +\XINT_expr_defbin_b {flexpr} > {v}{vi} {xintGt}% +\XINT_expr_defbin_b {iiexpr} > {v}{vi} {xintiiGt}% +\XINT_expr_defbin_b {expr} = {v}{vi} {xintEq}% +\XINT_expr_defbin_b {flexpr} = {v}{vi} {xintEq}% +\XINT_expr_defbin_b {iiexpr} = {v}{vi} {xintiiEq}% +\XINT_expr_defbin_b {expr} {<=} {v}{vi} {xintLtorEq}% +\XINT_expr_defbin_b {flexpr}{<=} {v}{vi} {xintLtorEq}% +\XINT_expr_defbin_b {iiexpr}{<=} {v}{vi} {xintiiLtorEq}% +\XINT_expr_defbin_b {expr} {>=} {v}{vi} {xintGtorEq}% +\XINT_expr_defbin_b {flexpr}{>=} {v}{vi} {xintGtorEq}% +\XINT_expr_defbin_b {iiexpr}{>=} {v}{vi} {xintiiGtorEq}% +\XINT_expr_defbin_b {expr} {!=} {v}{vi} {xintNeq}% +\XINT_expr_defbin_b {flexpr}{!=} {v}{vi} {xintNeq}% +\XINT_expr_defbin_b {iiexpr}{!=} {v}{vi} {xintiiNeq}% +\XINT_expr_defbin_b {expr} {..} {iii}{vi} {xintSeq::csv}% +\XINT_expr_defbin_b {flexpr}{..} {iii}{vi} {xintSeq::csv}% +\XINT_expr_defbin_b {iiexpr}{..} {iii}{vi} {xintiiSeq::csv}% +\XINT_expr_defbin_b {expr} {//} {vii}{vii}{xintDivTrunc}% +\XINT_expr_defbin_b {flexpr}{//} {vii}{vii}{xintDivTrunc}% +\XINT_expr_defbin_b {iiexpr}{//} {vii}{vii}{xintiiDivTrunc}% +\XINT_expr_defbin_b {expr} {/:} {vii}{vii}{xintMod}% +\XINT_expr_defbin_b {flexpr}{/:} {vii}{vii}{xintMod}% +\XINT_expr_defbin_b {iiexpr}{/:} {vii}{vii}{xintiiMod}% +\XINT_expr_defbin_b {expr} + {vi}{vi} {xintAdd}% +\XINT_expr_defbin_b {flexpr} + {vi}{vi} {XINTinFloatAdd}% +\XINT_expr_defbin_b {iiexpr} + {vi}{vi} {xintiiAdd}% +\XINT_expr_defbin_b {expr} - {vi}{vi} {xintSub}% +\XINT_expr_defbin_b {flexpr} - {vi}{vi} {XINTinFloatSub}% +\XINT_expr_defbin_b {iiexpr} - {vi}{vi} {xintiiSub}% +\XINT_expr_defbin_b {expr} * {vii}{vii}{xintMul}% +\XINT_expr_defbin_b {flexpr} * {vii}{vii}{XINTinFloatMul}% +\XINT_expr_defbin_b {iiexpr} * {vii}{vii}{xintiiMul}% +\XINT_expr_defbin_b {expr} / {vii}{vii}{xintDiv}% +\XINT_expr_defbin_b {flexpr} / {vii}{vii}{XINTinFloatDiv}% +\XINT_expr_defbin_b {iiexpr} / {vii}{vii}{xintiiDivRound}% CHANGED IN 1.1! +\XINT_expr_defbin_b {expr} ^ {ix}{ix} {xintPow}% +\XINT_expr_defbin_b {flexpr} ^ {ix}{ix} {XINTinFloatPowerH}% +\XINT_expr_defbin_b {iiexpr} ^ {ix}{ix} {xintiiPow}% +\XINT_expr_defbin_b {expr} {..[}{iii}{vi} {xintSeqA::csv}% +\XINT_expr_defbin_b {flexpr}{..[}{iii}{vi} {XINTinFloatSeqA::csv}% +\XINT_expr_defbin_b {iiexpr}{..[}{iii}{vi} {xintiiSeqA::csv}% +\XINT_expr_defbin_b {expr} {]..}{iii}{vi} {xintSeqB::csv}% +\XINT_expr_defbin_b {flexpr}{]..}{iii}{vi} {XINTinFloatSeqB::csv}% +\XINT_expr_defbin_b {iiexpr}{]..}{iii}{vi} {xintiiSeqB::csv}% \def\XINT_expr_binop_inline_a {\expandafter\xint_gobble_i\romannumeral`&&@\XINT_expr_binop_inline_b }% \def\XINT_expr_binop_inline_b #1#2,{\XINT_expr_binop_inline_c #2,{#1}}% @@ -764,7 +757,7 @@ \def\XINT_expr_binop_inline_d #1,#2{,#2{#1}\XINT_expr_binop_inline_b {#2}}% \def\XINT_expr_binop_inline_e #1,#2{,\XINT_expr_binop_inline_b {#2}}% \def\XINT_expr_binop_inline_end #1,#2{}% -\def\XINT_tmpc #1#2#3#4#5#6#7#8% +\def\XINT_expr_deflistopr_c #1#2#3#4#5#6#7#8% {% \def #1##1% \XINT_expr_op_<op> ou flexpr ou iiexpr {% keep value, get next number and operator, then do until @@ -776,7 +769,7 @@ \krof }% \def #3##1##2##3##4% \XINT_expr_until_<op>_b ou flexpr ou iiexpr {% either execute next operation now, or first do next (possibly unary) - \ifnum ##2>#5% + \ifnum ##2>#7% \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@% \csname XINT_#8_op_##3\endcsname {##4}}% \else \xint_afterfi {\expandafter ##2\expandafter ##3% @@ -788,9 +781,9 @@ \fi }% \let #7#5% }% -\def\XINT_tmpb #1#2#3#4% +\def\XINT_expr_deflistopr_b #1#2#3#4% {% - \expandafter\XINT_tmpc + \expandafter\XINT_expr_deflistopr_c \csname XINT_#1_op_#2\expandafter\endcsname \csname XINT_#1_until_#2_a\expandafter\endcsname \csname XINT_#1_until_#2_b\expandafter\endcsname @@ -799,30 +792,28 @@ \csname #4\expandafter\endcsname \csname XINT_expr_precedence_#2\endcsname {#1}% }% -\xintApplyInline {\expandafter\XINT_tmpb \xint_firstofone}{% - {{expr}{a+}{vi}{xintAdd}}% - {{expr}{a-}{vi}{xintSub}}% - {{expr}{a*}{vii}{xintMul}}% - {{expr}{a/}{vii}{xintDiv}}% - {{expr}{a^}{ix}{xintPow}}% - {{iiexpr}{a+}{vi}{xintiiAdd}}% - {{iiexpr}{a-}{vi}{xintiiSub}}% - {{iiexpr}{a*}{vii}{xintiiMul}}% - {{iiexpr}{a/}{vii}{xintiiDivRound}}% - {{iiexpr}{a^}{ix}{xintiiPow}}% - {{flexpr}{a+}{vi}{XINTinFloatAdd}}% - {{flexpr}{a-}{vi}{XINTinFloatSub}}% - {{flexpr}{a*}{vii}{XINTinFloatMul}}% - {{flexpr}{a/}{vii}{XINTinFloatDiv}}% - {{flexpr}{a^}{ix}{XINTinFloatPower}}% -}% -\def\XINT_tmpc #1#2#3#4#5#6#7% +\XINT_expr_deflistopr_b {expr} {a+}{vi} {xintAdd}% +\XINT_expr_deflistopr_b {expr} {a-}{vi} {xintSub}% +\XINT_expr_deflistopr_b {expr} {a*}{vii}{xintMul}% +\XINT_expr_deflistopr_b {expr} {a/}{vii}{xintDiv}% +\XINT_expr_deflistopr_b {expr} {a^}{ix} {xintPow}% +\XINT_expr_deflistopr_b {iiexpr}{a+}{vi} {xintiiAdd}% +\XINT_expr_deflistopr_b {iiexpr}{a-}{vi} {xintiiSub}% +\XINT_expr_deflistopr_b {iiexpr}{a*}{vii}{xintiiMul}% +\XINT_expr_deflistopr_b {iiexpr}{a/}{vii}{xintiiDivRound}% +\XINT_expr_deflistopr_b {iiexpr}{a^}{ix} {xintiiPow}% +\XINT_expr_deflistopr_b {flexpr}{a+}{vi} {XINTinFloatAdd}% +\XINT_expr_deflistopr_b {flexpr}{a-}{vi} {XINTinFloatSub}% +\XINT_expr_deflistopr_b {flexpr}{a*}{vii}{XINTinFloatMul}% +\XINT_expr_deflistopr_b {flexpr}{a/}{vii}{XINTinFloatDiv}% +\XINT_expr_deflistopr_b {flexpr}{a^}{ix} {XINTinFloatPowerH}% +\def\XINT_expr_deflistopl_c #1#2#3#4#5#6#7% {% \def #1##1{\expandafter#2\expandafter##1\romannumeral`&&@% \expandafter #3\romannumeral`&&@\XINT_expr_getnext }% \def #2##1##2##3##4% {% either execute next operation now, or first do next (possibly unary) - \ifnum ##2>#4% + \ifnum ##2>#6% \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@% \csname XINT_#7_op_##3\endcsname {##4}}% \else \xint_afterfi {\expandafter ##2\expandafter ##3% @@ -833,9 +824,9 @@ \fi }% \let #6#4% }% -\def\XINT_tmpb #1#2#3#4% +\def\XINT_expr_deflistopl_b #1#2#3#4% {% - \expandafter\XINT_tmpc + \expandafter\XINT_expr_deflistopl_c \csname XINT_#1_op_#2\expandafter\endcsname \csname XINT_#1_until_#2\expandafter\endcsname \csname XINT_#1_until_)_a\expandafter\endcsname @@ -843,23 +834,21 @@ \csname #4\expandafter\endcsname \csname XINT_expr_precedence_#2\endcsname {#1}% }% -\xintApplyInline {\expandafter\XINT_tmpb\xint_firstofone }{% - {{expr}{+[}{vi}{xintAdd}}% - {{expr}{-[}{vi}{xintSub}}% - {{expr}{*[}{vii}{xintMul}}% - {{expr}{/[}{vii}{xintDiv}}% - {{expr}{^[}{ix}{xintPow}}% - {{iiexpr}{+[}{vi}{xintiiAdd}}% - {{iiexpr}{-[}{vi}{xintiiSub}}% - {{iiexpr}{*[}{vii}{xintiiMul}}% - {{iiexpr}{/[}{vii}{xintiiDivRound}}% - {{iiexpr}{^[}{ix}{xintiiPow}}% - {{flexpr}{+[}{vi}{XINTinFloatAdd}}% - {{flexpr}{-[}{vi}{XINTinFloatSub}}% - {{flexpr}{*[}{vii}{XINTinFloatMul}}% - {{flexpr}{/[}{vii}{XINTinFloatDiv}}% - {{flexpr}{^[}{ix}{XINTinFloatPower}}% -}% +\XINT_expr_deflistopl_b {expr} {+[}{vi} {xintAdd}% +\XINT_expr_deflistopl_b {expr} {-[}{vi} {xintSub}% +\XINT_expr_deflistopl_b {expr} {*[}{vii}{xintMul}% +\XINT_expr_deflistopl_b {expr} {/[}{vii}{xintDiv}% +\XINT_expr_deflistopl_b {expr} {^[}{ix} {xintPow}% +\XINT_expr_deflistopl_b {iiexpr}{+[}{vi} {xintiiAdd}% +\XINT_expr_deflistopl_b {iiexpr}{-[}{vi} {xintiiSub}% +\XINT_expr_deflistopl_b {iiexpr}{*[}{vii}{xintiiMul}% +\XINT_expr_deflistopl_b {iiexpr}{/[}{vii}{xintiiDivRound}% +\XINT_expr_deflistopl_b {iiexpr}{^[}{ix} {xintiiPow}% +\XINT_expr_deflistopl_b {flexpr}{+[}{vi} {XINTinFloatAdd}% +\XINT_expr_deflistopl_b {flexpr}{-[}{vi} {XINTinFloatSub}% +\XINT_expr_deflistopl_b {flexpr}{*[}{vii}{XINTinFloatMul}% +\XINT_expr_deflistopl_b {flexpr}{/[}{vii}{XINTinFloatDiv}% +\XINT_expr_deflistopl_b {flexpr}{^[}{ix} {XINTinFloatPowerH}% \xintFor #1 in {and,or,xor,mod} \do {% \expandafter\def\csname XINT_expr_itself_#1\endcsname {#1}}% \expandafter\let\csname XINT_expr_precedence_and\expandafter\endcsname @@ -915,7 +904,7 @@ \krof }% \def #3##1##2##3##4% \XINT_expr_until_][_b {% - \ifnum ##2>\xint_c_ii + \ifnum ##2>#5% \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@% \csname XINT_#6_op_##3\endcsname {##4}}% \else @@ -949,7 +938,7 @@ \krof }% \def #3##1##2##3##4% \XINT_expr_until_:_b {% - \ifnum ##2>\xint_c_iii + \ifnum ##2>#5% \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral`&&@% \csname XINT_#6_op_##3\endcsname {##4}}% \else @@ -1243,7 +1232,7 @@ }% \let\XINT_expr_precedence_! \xint_c_x \def\XINT_expr_op_! #1{\expandafter\XINT_expr_getop - \csname .=\xintFac{\XINT_expr_unlock #1}\endcsname }% + \csname .=\xintiFac{\XINT_expr_unlock #1}\endcsname }% \def\XINT_flexpr_op_! #1{\expandafter\XINT_expr_getop \csname .=\XINTinFloatFac{\XINT_expr_unlock #1}\endcsname }% \def\XINT_iiexpr_op_! #1{\expandafter\XINT_expr_getop @@ -1435,7 +1424,7 @@ {\expandafter\XINT_expr_onlitteral_seq_f\romannumeral`&&@\XINT_expr_onlitteral_seq_a {}}% \def\XINT_expr_onlitteral_seq_f #1#2{\xint_c_xviii `{seqx}#2)\relax #1}% \def\XINT_expr_onlitteral_seq_a #1#2,% -{% checks balancing of parentheses +{% \ifcase\XINT_isbalanced_a \relax #1#2(\xint_bye)\xint_bye \expandafter\XINT_expr_onlitteral_seq_c \or\expandafter\XINT_expr_onlitteral_seq_b @@ -1807,8 +1796,9 @@ \expandafter\xint_firstofone\romannumeral`&&@#1,^,1}% \def\xintiiLCMof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintiilcm \expandafter\xint_firstofone\romannumeral`&&@#1,^,0}% -\def\XINTinFloatdigits {\XINTinFloat [\XINTdigits]}% -\def\XINTinFloatSqrtdigits {\XINTinFloatSqrt [\XINTdigits]}% +\def\XINTinFloatdigits {\XINTinFloat [\XINTdigits]}% +\def\XINTinFloatSqrtdigits {\XINTinFloatSqrt[\XINTdigits]}% +\def\XINTinFloatFacdigits {\XINTinFloatFac [\XINTdigits]}% \def\XINTinFloatMaxof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintmax \expandafter\XINTinFloatdigits\romannumeral`&&@#1,^,{0[0]}}% \def\XINTinFloatMinof:csv #1{\expandafter\XINT_oncsv:_a\expandafter\xintmin @@ -1876,6 +1866,24 @@ \expandafter #1\expandafter #2\csname .=\XINTinFloatMul{\XINT_expr_unlock #3}{\XINT_expr_unlock #3}\endcsname }% +\def\XINT_expr_func_factorial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\XINT_expr_argandopt + \romannumeral`&&@\XINT_expr_unlock#3,,.\xintiFac\XINTinFloatFac + \endcsname +}% +\def\XINT_flexpr_func_factorial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\XINT_expr_argandopt + \romannumeral`&&@\XINT_expr_unlock#3,,.\XINTinFloatFacdigits\XINTinFloatFac + \endcsname +}% +\def\XINT_iiexpr_func_factorial #1#2#3% +{% + \expandafter #1\expandafter #2\csname.=\xintiiFac{\XINT_expr_unlock #3}\endcsname +}% \def\XINT_iiexpr_func_sqr #1#2#3% {\expandafter #1\expandafter #2\csname.=\xintiiSqr {\XINT_expr_unlock #3}\endcsname }% \def\XINT_expr_func_sqrt #1#2#3% @@ -1947,6 +1955,48 @@ \expandafter\XINT_expr_twoargs \romannumeral`&&@\XINT_expr_unlock #3,\endcsname }% +\def\XINT_expr_func_binomial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\expandafter\expandafter\xintiBinomial + \expandafter\XINT_expr_twoargs + \romannumeral`&&@\XINT_expr_unlock #3,\endcsname +}% +\def\XINT_flexpr_func_binomial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\expandafter\expandafter\XINTinFloatBinomial + \expandafter\XINT_expr_twoargs + \romannumeral`&&@\XINT_expr_unlock #3,\endcsname +}% +\def\XINT_iiexpr_func_binomial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\expandafter\expandafter\xintiiBinomial + \expandafter\XINT_expr_twoargs + \romannumeral`&&@\XINT_expr_unlock #3,\endcsname +}% +\def\XINT_expr_func_pfactorial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\expandafter\expandafter\xintiPFactorial + \expandafter\XINT_expr_twoargs + \romannumeral`&&@\XINT_expr_unlock #3,\endcsname +}% +\def\XINT_flexpr_func_pfactorial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\expandafter\expandafter\XINTinFloatPFactorial + \expandafter\XINT_expr_twoargs + \romannumeral`&&@\XINT_expr_unlock #3,\endcsname +}% +\def\XINT_iiexpr_func_pfactorial #1#2#3% +{% + \expandafter #1\expandafter #2\csname .=% + \expandafter\expandafter\expandafter\xintiiPFactorial + \expandafter\XINT_expr_twoargs + \romannumeral`&&@\XINT_expr_unlock #3,\endcsname +}% \def\XINT_expr_func_quo #1#2#3% {% \expandafter #1\expandafter #2\csname .=% @@ -2195,7 +2245,7 @@ \edef\XINT_expr_tmpa {##1}% \edef\XINT_expr_tmpa {\xint_zapspaces_o \XINT_expr_tmpa}% \def\XINT_expr_tmpb {0}% - \def\XINT_expr_tmpc {##4}% + \def\XINT_expr_tmpc {(##4)}% \xintFor ####1 in {##2} \do {\edef\XINT_expr_tmpb {\the\numexpr\XINT_expr_tmpb+\xint_c_i}% \edef\XINT_expr_tmpc {subs(\unexpanded\expandafter{\XINT_expr_tmpc},% @@ -2274,9 +2324,15 @@ \xint_orthat {\csname #4NE\endcsname #6}{#1#2}% }% \toks0 {}% -\xintFor #1 in {DivTrunc,iiDivTrunc,iiDivRound,Mod,iiMod,iRound,Round,iTrunc,Trunc,% - Lt,Gt,Eq,LtorEq,GtorEq,Neq,AND,OR,XOR,iQuo,iRem,Add,Sub,Mul,Div,Pow,E,% - iiAdd,iiSub,iiMul,iiPow,iiQuo,iiRem,iiE,SeqA::csv,iiSeqA::csv}\do +\xintFor #1 in + {DivTrunc,Mod,Round,Trunc,iRound,iTrunc,iQuo,iRem, + iiDivTrunc,iiDivRound,iiMod,iiQuo,iiRem,% + Lt,Gt,Eq,LtorEq,GtorEq,Neq,% + iiLt,iiGt,iiEq,iiLtorEq,iiGtorEq,iiNeq,% + Add,Sub,Mul,Div,Pow,E,% + iiAdd,iiSub,iiMul,iiPow,iiE,% + AND,OR,XOR,% + SeqA::csv,iiSeqA::csv}\do {\toks0 \expandafter{\the\toks0% no space! \expandafter\let\csname xint#1NE\expandafter\endcsname\csname xint#1\expandafter @@ -2285,14 +2341,14 @@ \romannumeral`&&@\expandafter\XINT_xptwo_getab_b \romannumeral`&&@####2!{####1}{~xint#1}{xint#1}}% }% -}% cela aurait-il un sens d'ajouter Raw et iNum (à cause de qint, qfrac, - % qfloat?). Pas le temps d'y réfléchir. Je ne fais rien. +}% \xintFor #1 in {Num,Irr,Abs,iiAbs,Sgn,iiSgn,TFrac,Floor,iFloor,Ceil,iCeil,% - Sqr,iiSqr,iiSqrt,iiSqrtR,iiIsZero,iiIsNotZero,iiifNotZero,iiifSgn,% - Odd,Even,iiOdd,iiEven,Opp,iiOpp,iiifZero,Fac,iiFac,Bool,Toggle}\do -{\toks0 - \expandafter{\the\toks0% - \expandafter\let\csname xint#1NE\expandafter\endcsname\csname xint#1\expandafter + Sqr,iiSqr,iiSqrt,iiSqrtR,iiIsZero,iiIsNotZero,iiifNotZero,iiifSgn,% + Odd,Even,iiOdd,iiEven,Opp,iiOpp,iiifZero,iFac,iBinomial,% + iPFactorial,iiFac,iiBinomial,iiPFactorial,Bool,Toggle}\do +{\toks0 \expandafter{\the\toks0% + \expandafter\let\csname xint#1NE\expandafter\endcsname\csname + xint#1\expandafter \endcsname\expandafter\def\csname xint#1\endcsname ####1{% \expandafter\XINT_NEfork_one\romannumeral`&&@####1!{~xint#1}{xint#1}{}{}}% }% @@ -2304,7 +2360,7 @@ \expandafter\XINT_NEfork_one \romannumeral`&&@##1!{~XINTinFloatFac}{XINTinFloatFac}{}{}}% }% -\xintFor #1 in {Add,Sub,Mul,Div,Power,E,Mod,SeqA::csv}\do +\xintFor #1 in {Add,Sub,Mul,Div,Binomial,PFactorial,PowerH,E,Mod,SeqA::csv}\do {\toks0 \expandafter{\the\toks0% \expandafter\let\csname XINTinFloat#1NE\expandafter\endcsname @@ -2315,7 +2371,7 @@ \romannumeral`&&@####2!{####1}{~XINTinFloat#1}{XINTinFloat#1}}% }% }% -\xintFor #1 in {XINTinFloatdigits,XINTinFloatFracdigits,XINTinFloatSqrtdigits}\do +\xintFor #1 in {XINTinFloatdigits,XINTinFloatFracdigits,XINTinFloatSqrtdigits,XINTinFloatFacdigits}\do {\toks0 \expandafter{\the\toks0% \expandafter\let\csname #1NE\expandafter\endcsname\csname #1\expandafter @@ -2353,6 +2409,10 @@ \def\XINTinFloatSqrt [##1]##2{% \expandafter\XINT_NEfork_one \romannumeral`&&@##2!{~XINTinFloatSqrt[##1]}{XINTinFloatSqrt}{}{[##1]}}% + \let\XINTinFloatFacNE\XINTinFloatFac + \def\XINTinFloatFac [##1]##2{% + \expandafter\XINT_NEfork_one + \romannumeral`&&@##2!{~XINTinFloatFac[##1]}{XINTinFloatFac}{}{[##1]}}% }% \xintFor #1 in {ANDof,ORof,XORof,iiMaxof,iiMinof,iiSum,iiPrd, GCDof,LCMof,Sum,Prd,Maxof,Minof}\do @@ -2391,39 +2451,48 @@ \def\xintRound::csv {~xintRound::csv }% }% \toks0 {}% -\def\xintNewExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone\xinttheexpr }% -\def\xintNewFloatExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone\xintthefloatexpr }% -\def\xintNewIExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone\xinttheiexpr }% -\def\xintNewIIExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone\xinttheiiexpr }% -\def\xintNewBoolExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone\xinttheboolexpr }% -\def\XINT_NewFunc {\XINT_NewExpr,{}\xint_gobble_i\xintthebareeval }% -\def\XINT_NewFloatFunc {\XINT_NewExpr,{}\xint_gobble_i\xintthebarefloateval }% -\def\XINT_NewIIFunc {\XINT_NewExpr,{}\xint_gobble_i\xintthebareiieval }% +\def\xintNewExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone + \xinttheexpr\XINT_newexpr_clean}% +\def\xintNewFloatExpr{\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone + \xintthefloatexpr\XINT_newexpr_clean}% +\def\xintNewIExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone + \xinttheiexpr\XINT_newexpr_clean}% +\def\xintNewIIExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone + \xinttheiiexpr\XINT_newexpr_clean}% +\def\xintNewBoolExpr {\XINT_NewExpr{}\XINT_expr_redefineprints\xint_firstofone + \xinttheboolexpr\XINT_newexpr_clean}% \def\XINT_newexpr_clean #1>{\noexpand\romannumeral`&&@}% -\def\XINT_NewExpr #1#2#3#4#5#6[#7]% +\def\XINT_NewFunc + {\XINT_NewExpr,{}\xint_gobble_i\xintthebareeval \XINT_newfunc_clean }% +\def\XINT_NewFloatFunc + {\XINT_NewExpr,{}\xint_gobble_i\xintthebarefloateval\XINT_newfunc_clean }% +\def\XINT_NewIIFunc + {\XINT_NewExpr,{}\xint_gobble_i\xintthebareiieval \XINT_newfunc_clean }% +\def\XINT_newfunc_clean #1>{}% +\def\XINT_NewExpr #1#2#3#4#5#6#7[#8]% {% \begingroup - \ifcase #7\relax - \toks0 {\endgroup\def#5}% - \or \toks0 {\endgroup\def#5##1#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1##3#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1##3#1##4#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1##3#1##4#1##5#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1##3#1##4#1##5#1##6#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1##3#1##4#1##5#1##6#1##7#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1##3#1##4#1##5#1##6#1##7#1##8#1}% - \or \toks0 {\endgroup\def#5##1#1##2#1##3#1##4#1##5#1##6#1##7#1##8#1##9#1}% + \ifcase #8\relax + \toks0 {\endgroup\def#6}% + \or \toks0 {\endgroup\def#6##1#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1##3#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1##3#1##4#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1##3#1##4#1##5#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1##3#1##4#1##5#1##6#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1##3#1##4#1##5#1##6#1##7#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1##3#1##4#1##5#1##6#1##7#1##8#1}% + \or \toks0 {\endgroup\def#6##1#1##2#1##3#1##4#1##5#1##6#1##7#1##8#1##9#1}% \fi \xintexprSafeCatcodes \XINT_expr_redefinemacros #2% - \XINT_NewExpr_a #3#4#5% + \XINT_NewExpr_a #3#4#5#6% }% \catcode`~ 13 \catcode`@ 14 \catcode`\% 6 \catcode`# 12 \catcode`$ 11 @ $ -\def\XINT_NewExpr_a %1%2%3%4@ +\def\XINT_NewExpr_a %1%2%3%4%5@ {@ - \def\XINT_tmpa %%1%%2%%3%%4%%5%%6%%7%%8%%9{%4}@ + \def\XINT_tmpa %%1%%2%%3%%4%%5%%6%%7%%8%%9{%5}@ \def~{$noexpand$}@ \catcode`: 11 \catcode`_ 11 \catcode`# 12 \catcode`~ 13 \escapechar 126 @@ -2434,11 +2503,11 @@ }@ \escapechar 92 \catcode`# 6 \catcode`$ 0 @ $ \edef\XINT_tmpa %%1%%2%%3%%4%%5%%6%%7%%8%%9@ - {\scantokens\expandafter{\expandafter\XINT_newexpr_clean\meaning\XINT_tmpb}}@ + {\scantokens\expandafter{\expandafter%3\meaning\XINT_tmpb}}@ \the\toks0\expandafter{\XINT_tmpa{%%1}{%%2}{%%3}{%%4}{%%5}{%%6}{%%7}{%%8}{%%9}}@ %1{\ifxintverbose \xintMessage{xintexpr}{Info}@ - {\string%3\space now with meaning \meaning%3}@ + {\string%4\space now with meaning \meaning%4}@ \fi}@ }@ \catcode`% 14 diff --git a/Master/texmf-dist/tex/generic/xint/xintfrac.sty b/Master/texmf-dist/tex/generic/xint/xintfrac.sty index 50a961d49cd..39b9785986f 100644 --- a/Master/texmf-dist/tex/generic/xint/xintfrac.sty +++ b/Master/texmf-dist/tex/generic/xint/xintfrac.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle v1.2e 2015/11/22 -%% Copyright (C) 2013-2015 by Jean-Francois Burnol +%% The xint bundle 1.2f 2016/03/12 +%% Copyright (C) 2013-2016 by Jean-Francois Burnol %% xintfrac: Expandable operations on fractions %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintfrac}% - [2015/11/22 v1.2e Expandable operations on fractions (jfB)]% + [2016/03/12 1.2f Expandable operations on fractions (JFB)]% \def\XINT_cntSgnFork #1% {% \ifcase #1\expandafter\xint_secondofthree @@ -88,17 +88,16 @@ \expandafter\space \the\numexpr -1+\XINT_Abs {#1}+\XINT_Len {#2}+\XINT_Len {#3}\relax }% -\def\XINT_lenrord_loop #1#2#3#4#5#6#7#8#9% -{% faire \romannumeral`&&@\XINT_lenrord_loop 0{}#1\Z\W\W\W\W\W\W\W\Z +\def\XINT_lenrord_loop #1.#2#3#4#5#6#7#8#9% +{% \xint_gob_til_W #9\XINT_lenrord_W\W - \expandafter\XINT_lenrord_loop\expandafter - {\the\numexpr #1+7}{#9#8#7#6#5#4#3#2}% + \expandafter\XINT_lenrord_loop\the\numexpr #1+\xint_c_vii.{#9#8#7#6#5#4#3#2}% }% -\def\XINT_lenrord_W\W\expandafter\XINT_lenrord_loop\expandafter #1#2#3\Z +\def\XINT_lenrord_W\W\expandafter\XINT_lenrord_loop #1.#2#3\Z {% - \expandafter\XINT_lenrord_X\expandafter {#1}#2\Z + \expandafter\XINT_lenrord_X #1.#2\Z }% -\def\XINT_lenrord_X #1#2\Z +\def\XINT_lenrord_X #1.#2\Z {% \XINT_lenrord_Y #2\R\R\R\R\R\R\T {#1}% }% @@ -113,10 +112,7 @@ #2\XINT_lenrord_Z \xint_c_iii \W\XINT_lenrord_Z \xint_c_ii \Z }% -\def\XINT_lenrord_Z #1#2\Z #3% retourne: {longueur}renverse\Z -{% - \expandafter{\the\numexpr #3-#1\relax}% -}% +\def\XINT_lenrord_Z #1#2\Z #3{\the\numexpr #3-#1.}% \def\XINT_outfrac #1#2#3% {% \ifcase\XINT_cntSgn #3\Z @@ -173,11 +169,11 @@ #1/#2% }% \def\XINT_infrac_res_ca #1[#2]/\XINT_W[\XINT_W\XINT_T - {\expandafter{\the\numexpr 0#2}{#1}{1}}% + {\expandafter{\the\numexpr #2}{#1}{1}}% \def\XINT_infrac_res_cb #1/#2[% {\expandafter\XINT_infrac_res_cc\romannumeral`&&@#2~#1[}% \def\XINT_infrac_res_cc #1~#2[#3]/\XINT_W[\XINT_W\XINT_T - {\expandafter{\the\numexpr 0#3}{#2}{#1}}% + {\expandafter{\the\numexpr #3}{#2}{#1}}% \def\XINT_frac_gen #1/#2% {% \xint_UDXINTWfork @@ -201,14 +197,14 @@ #1.#2% }% \def\XINT_frac_gen_Bb #1e#2e#3\XINT_Z - {\expandafter\XINT_frac_gen_C\the\numexpr 0#2~#1!}% + {\expandafter\XINT_frac_gen_C\the\numexpr #2+\xint_c_~#1!}% \def\XINT_frac_gen_Bc #1.#2e% {% \expandafter\XINT_frac_gen_Bd\romannumeral`&&@#2.#1e% }% \def\XINT_frac_gen_Bd #1.#2e#3e#4\XINT_Z {% - \expandafter\XINT_frac_gen_C\the\numexpr 0#3-\romannumeral0\expandafter + \expandafter\XINT_frac_gen_C\the\numexpr #3-\romannumeral0\expandafter \XINT_length_loop 0.#1\xint_relax\xint_relax\xint_relax\xint_relax \xint_relax\xint_relax\xint_relax\xint_relax\xint_bye~#2#1!% @@ -370,10 +366,10 @@ }% \def\XINT_addm_A #1#2#3#4#5#6% {% - \xint_gob_til_W #3\xint_addm_az\W + \xint_gob_til_W #3\XINT_addm_az\W \XINT_addm_AB #1{#3#4#5#6}{#2}% }% -\def\xint_addm_az\W\XINT_addm_AB #1#2% +\def\XINT_addm_az\W\XINT_addm_AB #1#2% {% \XINT_addm_AC_checkcarry #1% }% @@ -391,9 +387,9 @@ }% \def\XINT_addm_AC_checkcarry #1% {% - \xint_gob_til_zero #1\xint_addm_AC_nocarry 0\XINT_addm_C + \xint_gob_til_zero #1\XINT_addm_AC_nocarry 0\XINT_addm_C }% -\def\xint_addm_AC_nocarry 0\XINT_addm_C #1#2\W\X\Y\Z +\def\XINT_addm_AC_nocarry 0\XINT_addm_C #1#2\W\X\Y\Z {% \expandafter \xint_cleanupzeros_andstop @@ -408,10 +404,10 @@ \def\XINT_addm_C #1#2#3#4#5% {% \xint_gob_til_W - #5\xint_addm_cw - #4\xint_addm_cx - #3\xint_addm_cy - #2\xint_addm_cz + #5\XINT_addm_cw + #4\XINT_addm_cx + #3\XINT_addm_cy + #2\XINT_addm_cz \W\XINT_addm_CD {#5#4#3#2}{#1}% }% \def\XINT_addm_CD #1% @@ -422,10 +418,10 @@ {% \XINT_addm_AC_checkcarry #2{#3#4}% }% -\def\xint_addm_cw - #1\xint_addm_cx - #2\xint_addm_cy - #3\xint_addm_cz +\def\XINT_addm_cw + #1\XINT_addm_cx + #2\XINT_addm_cy + #3\XINT_addm_cz \W\XINT_addm_CD {% \expandafter\XINT_addm_CDw\the\numexpr 1+#1#2#3.% @@ -434,9 +430,9 @@ {% \XINT_addm_end #1#3% }% -\def\xint_addm_cx - #1\xint_addm_cy - #2\xint_addm_cz +\def\XINT_addm_cx + #1\XINT_addm_cy + #2\XINT_addm_cz \W\XINT_addm_CD {% \expandafter\XINT_addm_CDx\the\numexpr 1+#1#2.% @@ -445,8 +441,8 @@ {% \XINT_addm_end #1#3% }% -\def\xint_addm_cy - #1\xint_addm_cz +\def\XINT_addm_cy + #1\XINT_addm_cz \W\XINT_addm_CD {% \expandafter\XINT_addm_CDy\the\numexpr 1+#1.% @@ -455,7 +451,7 @@ {% \XINT_addm_end #1#3% }% -\def\xint_addm_cz\W\XINT_addm_CD #1#2#3{\XINT_addm_end #1#3}% +\def\XINT_addm_cz\W\XINT_addm_CD #1#2#3{\XINT_addm_end #1#3}% \edef\XINT_addm_end #1#2#3#4#5% {\noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4#5\relax}% \def\xintRaw {\romannumeral0\xintraw }% @@ -690,38 +686,9 @@ }% \def\XINT_e #1#2#3#4% {% - \expandafter\XINT_e_end\expandafter{\the\numexpr #1+#4}{#2}{#3}% -}% -\def\XINT_e_end #1#2#3{ #2/#3[#1]}% -\def\xintFloatE {\romannumeral0\xintfloate }% -\def\xintfloate #1{\XINT_floate_chkopt #1\xint_relax }% -\def\XINT_floate_chkopt #1% -{% - \ifx [#1\expandafter\XINT_floate_opt - \else\expandafter\XINT_floate_noopt - \fi #1% -}% -\def\XINT_floate_noopt #1\xint_relax -{% - \expandafter\XINT_floate_a\expandafter\XINTdigits - \romannumeral0\XINT_infrac {#1}% -}% -\def\XINT_floate_opt [\xint_relax #1]#2% -{% - \expandafter\XINT_floate_a\expandafter - {\the\numexpr #1\expandafter}\romannumeral0\XINT_infrac {#2}% -}% -\def\XINT_floate_a #1#2#3#4#5% -{% - \expandafter\expandafter\expandafter\XINT_float_a - \expandafter\xint_exchangetwo_keepbraces\expandafter - {\the\numexpr #2+#5}{#1}{#3}{#4}\XINT_float_Q + \expandafter\XINT_e_end\the\numexpr #1+#4.{#2}{#3}% }% -\def\XINTinFloatE {\romannumeral0\XINTinfloate }% -\def\XINTinfloate {\expandafter\XINT_infloate\romannumeral0\XINTinfloat [\XINTdigits]}% -\def\XINT_infloate #1[#2]#3% - {\expandafter\XINT_infloate_end\expandafter {\the\numexpr #3+#2}{#1}}% -\def\XINT_infloate_end #1#2{ #2[#1]}% +\def\XINT_e_end #1.#2#3{ #2/#3[#1]}% \def\xintIrr {\romannumeral0\xintirr }% \def\xintirr #1% {% @@ -767,9 +734,9 @@ }% \def\XINT_irr_loop_e #1#2\Z {% - \xint_gob_til_zero #1\xint_irr_loop_exit0\XINT_irr_loop_a {#1#2}% + \xint_gob_til_zero #1\XINT_irr_loop_exit0\XINT_irr_loop_a {#1#2}% }% -\def\xint_irr_loop_exit0\XINT_irr_loop_a #1#2#3#4% +\def\XINT_irr_loop_exit0\XINT_irr_loop_a #1#2#3#4% {% \expandafter\XINT_irr_loop_exitb\expandafter {\romannumeral0\xintiiquo {#3}{#2}}% @@ -845,9 +812,9 @@ }% \def\XINT_jrr_loop_e #1#2\Z {% - \xint_gob_til_zero #1\xint_jrr_loop_exit0\XINT_jrr_loop_a {#1#2}% + \xint_gob_til_zero #1\XINT_jrr_loop_exit0\XINT_jrr_loop_a {#1#2}% }% -\def\xint_jrr_loop_exit0\XINT_jrr_loop_a #1#2#3#4#5#6% +\def\XINT_jrr_loop_exit0\XINT_jrr_loop_a #1#2#3#4#5#6% {% \XINT_irr_finish {#3}{#4}% }% @@ -864,12 +831,6 @@ \def\XINT_tfrac_zero #1\Z { 0/1[0]}% \def\XINT_tfrac_P #1/#2\Z {\expandafter\XINT_rez_AB \romannumeral0\xintiirem{#1}{#2}\Z {0}{#2}}% -\def\XINTinFloatFracdigits {\romannumeral0\XINTinfloatfracdigits }% -\def\XINTinfloatfracdigits #1% -{% - \expandafter\XINT_infloatfracdg_a\expandafter {\romannumeral0\xinttfrac{#1}}% -}% -\def\XINT_infloatfracdg_a {\XINTinfloat [\XINTdigits]}% \def\xintTrunc {\romannumeral0\xinttrunc }% \def\xintiTrunc {\romannumeral0\xintitrunc }% \def\xinttrunc #1% @@ -916,13 +877,13 @@ \def\XINT_trunc_C #1#2#3% {% \expandafter\XINT_trunc_CE\expandafter - {\romannumeral0\XINT_dsx_zeroloop {-#1}{}\Z {#3}}{#2}% + {\romannumeral0\XINT_dsx_zeroloop -#1.{}\Z {#3}}{#2}% }% \def\XINT_trunc_CE #1#2{\XINT_trunc_E #2.{#1}}% \def\XINT_trunc_D #1#2% {% \expandafter\XINT_trunc_E - \romannumeral0\XINT_dsx_zeroloop {#1}{}\Z {#2}.% + \romannumeral0\XINT_dsx_zeroloop #1.{}\Z {#2}.% }% \def\XINT_trunc_E #1% {% @@ -965,7 +926,7 @@ \def\XINT_trunc_Hb #1#2#3% {% \expandafter #3\expandafter0\expandafter.% - \romannumeral0\XINT_dsx_zeroloop {#1}{}\Z {}#2% #1=-0 autoris\'e ! + \romannumeral0\XINT_dsx_zeroloop #1.{}\Z {}#2% #1=-0 autoris\'e ! }% \def\xintTTrunc {\romannumeral0\xintttrunc }% \def\xintttrunc #1% @@ -1075,8 +1036,8 @@ }% \def\XINT_xtrunc_zero .#1#2#3#4#5% {% - 0.\romannumeral0\expandafter\XINT_dsx_zeroloop\expandafter - {\the\numexpr #5}{}\Z {}% + 0.\romannumeral0\expandafter\XINT_dsx_zeroloop + \the\numexpr #5.{}\Z {}% \xintiloop [#4+-1] \ifnum \xintiloopindex>\xint_c_ 0000000000000000000000000000000000000000000000000000000000000000% @@ -1136,12 +1097,12 @@ \def\XINT_xtrunc_negNDa #1#2% {% \expandafter\XINT_xtrunc_negNDb% - \romannumeral0\XINT_split_fromleft_loop {#1}{}#2\W\W\W\W\W\W\W\W\Z + \romannumeral0\XINT_split_fromleft_loop #1.{}#2\W\W\W\W\W\W\W\W\Z }% -\def\XINT_xtrunc_negNDb #1#2{#1.#2}% +\def\XINT_xtrunc_negNDb #1.#2.{#1.#2}% \def\XINT_xtrunc_negNE #1#2% {% - 0.\romannumeral0\XINT_dsx_zeroloop {-#1}{}\Z {}#2% + 0.\romannumeral0\XINT_dsx_zeroloop -#1.{}\Z {}#2% }% \def\XINT_xtrunc_negNW #1#2#3#4#5#6% {% @@ -1153,11 +1114,10 @@ \expandafter\XINT_xtrunc_negNC\expandafter {\the\numexpr\xintLength {#1}-#2}{#1}% }% -%%%%%%%%%%%% \def\XINT_xtrunc_BisOne #1#2#3#4#5#6#7% {% - #5.\romannumeral0\expandafter\XINT_dsx_zeroloop\expandafter - {\the\numexpr #7}{}\Z {}% + #5.\romannumeral0\expandafter\XINT_dsx_zeroloop + \the\numexpr #7.{}\Z {}% \xintiloop [#6+-1] \ifnum \xintiloopindex>\xint_c_ 0000000000000000000000000000000000000000000000000000000000000000% @@ -1166,18 +1126,17 @@ \def\XINT_xtrunc_BisTwo #1#2#3#4#5#6#7% {% \xintHalf {#5}.\ifodd\xintiiLDg{#5} 5\else 0\fi - \romannumeral0\expandafter\XINT_dsx_zeroloop\expandafter - {\the\numexpr #7-\xint_c_i}{}\Z {}% + \romannumeral0\expandafter\XINT_dsx_zeroloop + \the\numexpr #7-\xint_c_i.{}\Z {}% \xintiloop [#6+-1] \ifnum \xintiloopindex>\xint_c_ 0000000000000000000000000000000000000000000000000000000000000000% \repeat }% -%%%%%%%%%%%% \def\XINT_xtrunc_Q #1% {% \expandafter\XINT_xtrunc_prepare - \romannumeral0\XINT_dsx_zeroloop {#1}{}\Z + \romannumeral0\XINT_dsx_zeroloop #1.{}\Z }% \def\XINT_xtrunc_prepare #1.#2#3% {% @@ -1185,7 +1144,6 @@ {\romannumeral0% \XINT_xtrunc_prepare_a #2\R\R\R\R\R\R\R\R {10}0000001\W !{#2}}{#1}% }% -%%%%%%%%%%%% \def\XINT_xtrunc_prepare_a #1#2#3#4#5#6#7#8#9% {% \xint_gob_til_R #9\XINT_xtrunc_prepare_small\R @@ -1205,7 +1163,6 @@ \the\numexpr #1/\xint_c_ii\expandafter .\the\numexpr \xint_c_x^viii+#1!% }% -%%%%%%%%%%%% \def\XINT_xtrunc_small_a #1.#2!#3% {% \expandafter\XINT_div_small_b\the\numexpr #1\expandafter @@ -1213,7 +1170,6 @@ \romannumeral0\XINT_div_small_ba #3\R\R\R\R\R\R\R\R{10}0000001\W #3\XINT_sepbyviii_Z_end 2345678\relax }% -%%%%%%%%%%%% \def\XINT_xtrunc_prepare_b {\expandafter\XINT_xtrunc_prepare_c\romannumeral0\XINT_zeroes_forviii }% \def\XINT_xtrunc_prepare_c #1!% @@ -1242,7 +1198,6 @@ \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W \X }% -%%%%%%%%%%%% \def\XINT_xtrunc_Pa #1#2% {% \expandafter\XINT_xtrunc_Pb\romannumeral0#1{#2}{#1}% @@ -1261,8 +1216,8 @@ }% \def\XINT_xtrunc_D #1#2#3% {% - \romannumeral0\expandafter\XINT_dsx_zeroloop\expandafter - {\the\numexpr \xint_c_ii^vi-\xintLength{#1}}{}\Z {}#1% + \romannumeral0\expandafter\XINT_dsx_zeroloop + \the\numexpr \xint_c_ii^vi-\xintLength{#1}.{}\Z {}#1% \XINT_xtrunc_A {#3}{#2}% }% \def\XINT_xtrunc_transition\fi @@ -1271,7 +1226,7 @@ \fi \ifnum #4=\xint_c_ \XINT_xtrunc_abort\fi \expandafter\XINT_xtrunc_x\expandafter - {\romannumeral0\XINT_dsx_zeroloop {#4}{}\Z {#2}}{#3}{#4}% + {\romannumeral0\XINT_dsx_zeroloop #4.{}\Z {#2}}{#3}{#4}% }% \def\XINT_xtrunc_x #1#2% {% @@ -1279,330 +1234,17 @@ }% \def\XINT_xtrunc_y #1#2#3% {% - \romannumeral0\expandafter\XINT_dsx_zeroloop\expandafter - {\the\numexpr #3-\xintLength{#1}}{}\Z {}#1% + \romannumeral0\expandafter\XINT_dsx_zeroloop + \the\numexpr #3-\xintLength{#1}.{}\Z {}#1% }% \def\XINT_xtrunc_abort\fi\expandafter\XINT_xtrunc_x\expandafter #1#2#3{\fi}% \mathchardef\XINTdigits 16 \def\xintDigits #1#2% {\afterassignment \xint_gobble_i \mathchardef\XINTdigits=}% \def\xinttheDigits {\number\XINTdigits }% -\def\xintFloat {\romannumeral0\xintfloat }% -\def\xintfloat #1{\XINT_float_chkopt #1\xint_relax }% -\def\XINT_float_chkopt #1% -{% - \ifx [#1\expandafter\XINT_float_opt - \else\expandafter\XINT_float_noopt - \fi #1% -}% -\def\XINT_float_noopt #1\xint_relax -{% - \expandafter\XINT_float_a\expandafter\XINTdigits - \romannumeral0\XINT_infrac {#1}\XINT_float_Q -}% -\def\XINT_float_opt [\xint_relax #1]#2% -{% - \expandafter\XINT_float_a\expandafter - {\the\numexpr #1\expandafter}% - \romannumeral0\XINT_infrac {#2}\XINT_float_Q -}% -\def\XINT_float_a #1#2#3% #1=P, #2=n, #3=A, #4=B -{% - \XINT_float_fork #3\Z {#1}{#2}% #1 = precision, #2=n -}% -\def\XINT_float_fork #1% -{% - \xint_UDzerominusfork - #1-\XINT_float_zero - 0#1\XINT_float_J - 0-{\XINT_float_K #1}% - \krof -}% -\def\XINT_float_zero #1\Z #2#3#4#5{ 0.e0}% -\def\XINT_float_J {\expandafter\xint_minus_thenstop\romannumeral0\XINT_float_K }% -\def\XINT_float_K #1\Z #2% #1=A, #2=P, #3=n, #4=B -{% - \expandafter\XINT_float_L\expandafter - {\the\numexpr\xintLength{#1}\expandafter}\expandafter - {\the\numexpr #2+\xint_c_ii}{#1}{#2}% -}% -\def\XINT_float_L #1#2% -{% - \ifnum #1>#2 - \expandafter\XINT_float_Ma - \else - \expandafter\XINT_float_Mc - \fi {#1}{#2}% -}% -\def\XINT_float_Ma #1#2#3% -{% - \expandafter\XINT_float_Mb\expandafter - {\the\numexpr #1-#2\expandafter\expandafter\expandafter}% - \expandafter\expandafter\expandafter - {\expandafter\xint_firstoftwo - \romannumeral0\XINT_split_fromleft_loop {#2}{}#3\W\W\W\W\W\W\W\W\Z - }{#2}% -}% -\def\XINT_float_Mb #1#2#3#4#5#6% #2=A', #3=P+2, #4=P, #5=n, #6=B -{% - \expandafter\XINT_float_N\expandafter - {\the\numexpr\xintLength{#6}\expandafter}\expandafter - {\the\numexpr #3\expandafter}\expandafter - {\the\numexpr #1+#5}% - {#6}{#3}{#2}{#4}% -}% long de B, P+2, n', B, |A'|=P+2, A', P -\def\XINT_float_Mc #1#2#3#4#5#6% -{% - \expandafter\XINT_float_N\expandafter - {\romannumeral0\xintlength{#6}}{#2}{#5}{#6}{#1}{#3}{#4}% -}% long de B, P+2, n, B, |A|, A, P -\def\XINT_float_N #1#2% -{% - \ifnum #1>#2 - \expandafter\XINT_float_O - \else - \expandafter\XINT_float_P - \fi {#1}{#2}% -}% -\def\XINT_float_O #1#2#3#4% -{% - \expandafter\XINT_float_P\expandafter - {\the\numexpr #2\expandafter}\expandafter - {\the\numexpr #2\expandafter}\expandafter - {\the\numexpr #3-#1+#2\expandafter\expandafter\expandafter}% - \expandafter\expandafter\expandafter - {\expandafter\xint_firstoftwo - \romannumeral0\XINT_split_fromleft_loop {#2}{}#4\W\W\W\W\W\W\W\W\Z - }% -}% |B|,P+2,n,B,|A|,A,P -\def\XINT_float_P #1#2#3#4#5#6#7#8% -{% - \expandafter #8\expandafter {\the\numexpr #1-#5+#2-\xint_c_i}% - {#6}{#4}{#7}{#3}% -}% |B|-|A|+P+1,A,B,P,n -\def\XINT_float_Q #1% -{% - \ifnum #1<\xint_c_ - \expandafter\XINT_float_Ri - \else - \expandafter\XINT_float_Rii - \fi {#1}% -}% -\def\XINT_float_Ri #1#2#3% -{% - \expandafter\XINT_float_Sa - \romannumeral0\xintiiquo {#2}% - {\XINT_dsx_addzerosnofuss {-#1}{#3}}\Z {#1}% -}% -\def\XINT_float_Rii #1#2#3% -{% - \expandafter\XINT_float_Sa - \romannumeral0\xintiiquo - {\XINT_dsx_addzerosnofuss {#1}{#2}}{#3}\Z {#1}% -}% -\def\XINT_float_Sa #1% -{% - \if #19% - \xint_afterfi {\XINT_float_Sb\XINT_float_Wb }% - \else - \xint_afterfi {\XINT_float_Sb\XINT_float_Wa }% - \fi #1% -}% -\def\XINT_float_Sb #1#2\Z #3#4% -{% - \expandafter\XINT_float_T\expandafter - {\the\numexpr #4+\xint_c_i\expandafter}% - \romannumeral`&&@\XINT_lenrord_loop 0{}#2\Z\W\W\W\W\W\W\W\Z #1{#3}{#4}% -}% -\def\XINT_float_T #1#2#3% -{% - \ifnum #2>#1 - \xint_afterfi{\XINT_float_U\XINT_float_Xb}% - \else - \xint_afterfi{\XINT_float_U\XINT_float_Xa #3}% - \fi -}% -\def\XINT_float_U #1#2% -{% - \ifnum #2<\xint_c_v - \expandafter\XINT_float_Va - \else - \expandafter\XINT_float_Vb - \fi #1% -}% -\def\XINT_float_Va #1#2\Z #3% -{% - \expandafter#1% - \romannumeral0\expandafter\XINT_float_Wa - \romannumeral0\XINT_rord_main {}#2% - \xint_relax - \xint_bye\xint_bye\xint_bye\xint_bye - \xint_bye\xint_bye\xint_bye\xint_bye - \xint_relax \Z -}% -\def\XINT_float_Vb #1#2\Z #3% -{% - \expandafter #1% - \romannumeral0\expandafter #3% - \romannumeral0\XINT_addm_A 0{}1000\W\X\Y\Z #2000\W\X\Y\Z \Z -}% -\def\XINT_float_Wa #1{ #1.}% -\def\XINT_float_Wb #1#2% - {\if #11\xint_afterfi{ 10.}\else\xint_afterfi{ #1.#2}\fi }% -\def\XINT_float_Xa #1\Z #2#3#4% -{% - \expandafter\XINT_float_Y\expandafter - {\the\numexpr #3+#4-#2}{#1}% -}% -\def\XINT_float_Xb #1\Z #2#3#4% -{% - \expandafter\XINT_float_Y\expandafter - {\the\numexpr #3+#4+\xint_c_i-#2}{#1}% -}% -\def\XINT_float_Y #1#2{ #2e#1}% -\def\xintPFloat {\romannumeral0\xintpfloat }% -\def\xintpfloat #1{\XINT_pfloat_chkopt #1\xint_relax }% -\def\XINT_pfloat_chkopt #1% -{% - \ifx [#1\expandafter\XINT_pfloat_opt - \else\expandafter\XINT_pfloat_noopt - \fi #1% -}% -\def\XINT_pfloat_noopt #1\xint_relax -{% - \expandafter\XINT_pfloat_a\expandafter\XINTdigits - \romannumeral0\XINTinfloat [\XINTdigits]{#1}% -}% -\def\XINT_pfloat_opt [\xint_relax #1]%#2% -{% - \expandafter\XINT_pfloat_a\expandafter {\the\numexpr #1\expandafter}% - \romannumeral0\XINTinfloat [\numexpr #1\relax]%{#2}% -}% -\def\XINT_pfloat_a #1#2% -{% - \xint_UDzerominusfork - #2-\XINT_pfloat_zero - 0#2\XINT_pfloat_neg - 0-{\XINT_pfloat_pos #2}% - \krof {#1}% -}% -\def\XINT_pfloat_zero #1[#2]{ 0}% -\def\XINT_pfloat_neg - {\expandafter\xint_minus_thenstop\romannumeral0\XINT_pfloat_pos {}}% -\def\XINT_pfloat_pos #1#2#3[#4]% -{% - \ifnum#4>0 \xint_dothis\XINT_pfloat_no\fi - \ifnum#4>\numexpr-#2\relax \xint_dothis\XINT_pfloat_b\fi - \ifnum#4>\numexpr-#2-\xint_c_v\relax \xint_dothis\XINT_pfloat_B\fi - \xint_orthat\XINT_pfloat_no {#2}{#4}{#1#3}% -}% -\def\XINT_pfloat_no #1#2% -{% - \expandafter\XINT_pfloat_no_b\expandafter{\the\numexpr #2+#1-\xint_c_i\relax}% -}% -\def\XINT_pfloat_no_b #1#2{\XINT_pfloat_no_c #2e#1}% -\def\XINT_pfloat_no_c #1{ #1.}% -\def\XINT_pfloat_b #1#2#3% - {\expandafter\XINT_pfloat_c - \romannumeral0\expandafter\XINT_split_fromleft_loop - \expandafter {\the\numexpr #1+#2-\xint_c_i}#3\W\W\W\W\W\W\W\W\Z }% -\def\XINT_pfloat_c #1#2{ #1.#2}% #2 peut \^etre vide -\def\XINT_pfloat_B #1#2#3% - {\expandafter\XINT_pfloat_C - \romannumeral0\XINT_dsx_zeroloop {\numexpr -#1-#2}{}\Z {}#3}% -\def\XINT_pfloat_C { 0.}% -\def\XINTinFloat {\romannumeral0\XINTinfloat }% -\def\XINTinfloat [#1]#2% -{% - \expandafter\XINT_infloat_a\expandafter - {\the\numexpr #1\expandafter}% - \romannumeral0\XINT_infrac {#2}\XINT_infloat_Q -}% -\def\XINT_infloat_a #1#2#3% #1=P, #2=n, #3=A, #4=B -{% - \XINT_infloat_fork #3\Z {#1}{#2}% #1 = precision, #2=n -}% -\def\XINT_infloat_fork #1% -{% - \xint_UDzerominusfork - #1-\XINT_infloat_zero - 0#1\XINT_infloat_J - 0-{\XINT_float_K #1}% - \krof -}% -\def\XINT_infloat_zero #1\Z #2#3#4#5{ 0[0]}% -\def\XINT_infloat_J {\expandafter-\romannumeral0\XINT_float_K }% -\def\XINT_infloat_Q #1% -{% - \ifnum #1<\xint_c_ - \expandafter\XINT_infloat_Ri - \else - \expandafter\XINT_infloat_Rii - \fi {#1}% -}% -\def\XINT_infloat_Ri #1#2#3% -{% - \expandafter\XINT_infloat_S\expandafter - {\romannumeral0\xintiiquo {#2}% - {\XINT_dsx_addzerosnofuss {-#1}{#3}}}{#1}% -}% -\def\XINT_infloat_Rii #1#2#3% -{% - \expandafter\XINT_infloat_S\expandafter - {\romannumeral0\xintiiquo - {\XINT_dsx_addzerosnofuss {#1}{#2}}{#3}}{#1}% -}% -\def\XINT_infloat_S #1#2#3% -{% - \expandafter\XINT_infloat_T\expandafter - {\the\numexpr #3+\xint_c_i\expandafter}% - \romannumeral`&&@\XINT_lenrord_loop 0{}#1\Z\W\W\W\W\W\W\W\Z - {#2}% -}% -\def\XINT_infloat_T #1#2#3% -{% - \ifnum #2>#1 - \xint_afterfi{\XINT_infloat_U\XINT_infloat_Wb}% - \else - \xint_afterfi{\XINT_infloat_U\XINT_infloat_Wa #3}% - \fi -}% -\def\XINT_infloat_U #1#2% -{% - \ifnum #2<\xint_c_v - \expandafter\XINT_infloat_Va - \else - \expandafter\XINT_infloat_Vb - \fi #1% -}% -\def\XINT_infloat_Va #1#2\Z -{% - \expandafter#1% - \romannumeral0\XINT_rord_main {}#2% - \xint_relax - \xint_bye\xint_bye\xint_bye\xint_bye - \xint_bye\xint_bye\xint_bye\xint_bye - \xint_relax \Z -}% -\def\XINT_infloat_Vb #1#2\Z -{% - \expandafter #1% - \romannumeral0\XINT_addm_A 0{}1000\W\X\Y\Z #2000\W\X\Y\Z \Z -}% -\def\XINT_infloat_Wa #1\Z #2#3% -{% - \expandafter\XINT_infloat_X\expandafter - {\the\numexpr #3+\xint_c_i-#2}{#1}% -}% -\def\XINT_infloat_Wb #1\Z #2#3% -{% - \expandafter\XINT_infloat_X\expandafter - {\the\numexpr #3+\xint_c_ii-#2}{#1}% -}% -\def\XINT_infloat_X #1#2{ #2[#1]}% \def\xintAdd {\romannumeral0\xintadd }% -\def\xintadd #1{\expandafter\xint_fadd\romannumeral0\xintraw {#1}}% -\def\xint_fadd #1{\xint_gob_til_zero #1\XINT_fadd_Azero 0\XINT_fadd_a #1}% +\def\xintadd #1{\expandafter\XINT_fadd\romannumeral0\xintraw {#1}}% +\def\XINT_fadd #1{\xint_gob_til_zero #1\XINT_fadd_Azero 0\XINT_fadd_a #1}% \def\XINT_fadd_Azero #1]{\xintraw }% \def\XINT_fadd_a #1/#2[#3]#4% {\expandafter\XINT_fadd_b\romannumeral0\xintraw {#4}{#3}{#1}{#2}}% @@ -1626,13 +1268,13 @@ \def\XINT_fadd_Ba #1#2#3#4#5#6#7% {% \expandafter\XINT_fadd_C\expandafter - {\romannumeral0\XINT_dsx_zeroloop {#1}{}\Z {#6}}% + {\romannumeral0\XINT_dsx_zeroloop #1.{}\Z {#6}}% {#7}{#5}{#4}[#2]% }% \def\XINT_fadd_Bb #1#2#3#4#5#6#7% {% \expandafter\XINT_fadd_C\expandafter - {\romannumeral0\XINT_dsx_zeroloop {-#1}{}\Z {#4}}% + {\romannumeral0\XINT_dsx_zeroloop -#1.{}\Z {#4}}% {#5}{#7}{#6}[#3]% }% \def\XINT_fadd_C #1#2#3% @@ -1693,8 +1335,8 @@ \def\XINT_fadd_N #1#2{ #2/#1}% \edef\XINT_fadd_iszero\fi #1[#2]{\noexpand\fi\space 0/1[0]}% ou [#2] originel? \def\xintSub {\romannumeral0\xintsub }% -\def\xintsub #1{\expandafter\xint_fsub\romannumeral0\xintraw {#1}}% -\def\xint_fsub #1{\xint_gob_til_zero #1\XINT_fsub_Azero 0\XINT_fsub_a #1}% +\def\xintsub #1{\expandafter\XINT_fsub\romannumeral0\xintraw {#1}}% +\def\XINT_fsub #1{\xint_gob_til_zero #1\XINT_fsub_Azero 0\XINT_fsub_a #1}% \def\XINT_fsub_Azero #1]{\xintopp }% \def\XINT_fsub_a #1/#2[#3]#4% {\expandafter\XINT_fsub_b\romannumeral0\xintraw {#4}{#3}{#1}{#2}}% @@ -1723,8 +1365,8 @@ }% \def\XINT_fsum_finished #1\Z #2{ #2}% \def\xintMul {\romannumeral0\xintmul }% -\def\xintmul #1{\expandafter\xint_fmul\romannumeral0\xintraw {#1}.}% -\def\xint_fmul #1{\xint_gob_til_zero #1\XINT_fmul_zero 0\XINT_fmul_a #1}% +\def\xintmul #1{\expandafter\XINT_fmul\romannumeral0\xintraw {#1}.}% +\def\XINT_fmul #1{\xint_gob_til_zero #1\XINT_fmul_zero 0\XINT_fmul_a #1}% \def\XINT_fmul_a #1[#2].#3% {\expandafter\XINT_fmul_b\romannumeral0\xintraw {#3}#1[#2.]}% \def\XINT_fmul_b #1{\xint_gob_til_zero #1\XINT_fmul_zero 0\XINT_fmul_c #1}% @@ -1742,9 +1384,9 @@ \def\XINT_fmul_e #1#2{\XINT_outfrac {#2}{#1}}% \def\XINT_fmul_zero #1.#2{ 0/1[0]}% \def\xintSqr {\romannumeral0\xintsqr }% -\def\xintsqr #1{\expandafter\xint_fsqr\romannumeral0\xintraw {#1}}% -\def\xint_fsqr #1{\xint_gob_til_zero #1\XINT_fsqr_zero 0\XINT_fsqr_a #1}% -\def\xint_fsqr_a #1/#2[#3]% +\def\xintsqr #1{\expandafter\XINT_fsqr\romannumeral0\xintraw {#1}}% +\def\XINT_fsqr #1{\xint_gob_til_zero #1\XINT_fsqr_zero 0\XINT_fsqr_a #1}% +\def\XINT_fsqr_a #1/#2[#3]% {% \expandafter\XINT_fsqr_b \expandafter{\the\numexpr #3+#3\expandafter}% @@ -1753,12 +1395,16 @@ }% \def\XINT_fsqr_b #1#2#3{\expandafter \XINT_fmul_e \expandafter{#3}{#1}{#2}}% \def\XINT_fsqr_zero #1]{ 0/1[0]}% +\def\xintipow #1#2% +{% + \expandafter\xint_pow\the\numexpr \xintNum{#2}\expandafter.\romannumeral0\xintnum{#1}\Z% +}% \def\xintPow {\romannumeral0\xintpow }% \def\xintpow #1% {% - \expandafter\xint_fpow\expandafter {\romannumeral0\XINT_infrac {#1}}% + \expandafter\XINT_fpow\expandafter {\romannumeral0\XINT_infrac {#1}}% }% -\def\xint_fpow #1#2% +\def\XINT_fpow #1#2% {% \expandafter\XINT_fpow_fork\the\numexpr \xintNum{#2}\relax\Z #1% }% @@ -1791,10 +1437,16 @@ \expandafter\XINT_fpow_pos_B\expandafter {#3}{#1}{#2}% }% \def\XINT_fpow_pos_B #1#2{\XINT_outfrac {#2}{#1}}% -\def\xintFac {\romannumeral0\xintfac }% -\def\xintfac #1% +\def\xintifac #1{\expandafter\XINT_fac_fork\the\numexpr \xintNum{#1}.}% +\def\xintibinomial #1#2% +{% + \expandafter\XINT_binom_pre + \the\numexpr\xintNum{#1}\expandafter.\the\numexpr\xintNum{#2}.% +}% +\def\xintipfactorial #1#2% {% - \expandafter\XINT_fac_fork\expandafter{\the\numexpr \xintNum{#1}}% + \expandafter\XINT_pfac_fork + \the\numexpr\xintNum{#1}\expandafter.\the\numexpr\xintNum{#2}.% }% \def\xintPrd {\romannumeral0\xintprd }% \def\xintprd #1{\xintprdexpr #1\relax }% @@ -1818,9 +1470,9 @@ \def\xintDiv {\romannumeral0\xintdiv }% \def\xintdiv #1% {% - \expandafter\xint_fdiv\expandafter {\romannumeral0\XINT_infrac {#1}}% + \expandafter\XINT_fdiv\expandafter {\romannumeral0\XINT_infrac {#1}}% }% -\def\xint_fdiv #1#2% +\def\XINT_fdiv #1#2% {\expandafter\XINT_fdiv_A\romannumeral0\XINT_infrac {#2}#1}% \def\XINT_fdiv_A #1#2#3#4#5#6% {% @@ -1877,12 +1529,6 @@ {\xintiiE{\xintiiMul {#2}{#6}}{#4-#7}}% t fois n }% \def\XINT_mod_pos_a #1.#2#3#4{\xintiirem {#3}{#4}/#2[#1]}% -\def\XINTinFloatMod {\romannumeral0\XINTinfloatmod [\XINTdigits]}% -\def\XINTinfloatmod [#1]#2#3{\expandafter\XINT_infloatmod\expandafter - {\romannumeral0\XINTinfloat[#1]{#2}}% - {\romannumeral0\XINTinfloat[#1]{#3}}{#1}}% -\def\XINT_infloatmod #1#2{\expandafter\XINT_infloatmod_a\expandafter {#2}{#1}}% -\def\XINT_infloatmod_a #1#2#3{\XINTinfloat [#3]{\xintMod {#2}{#1}}}% \def\xintIsOne {\romannumeral0\xintisone }% \def\xintisone #1{\expandafter\XINT_fracisone \romannumeral0\xintrawwithzeros{#1}\Z }% @@ -1891,9 +1537,9 @@ \def\xintGeq {\romannumeral0\xintgeq }% \def\xintgeq #1% {% - \expandafter\xint_fgeq\expandafter {\romannumeral0\xintabs {#1}}% + \expandafter\XINT_fgeq\expandafter {\romannumeral0\xintabs {#1}}% }% -\def\xint_fgeq #1#2% +\def\XINT_fgeq #1#2% {% \expandafter\XINT_fgeq_A \romannumeral0\xintabs {#2}#1% }% @@ -1944,9 +1590,9 @@ \def\xintMax {\romannumeral0\xintmax }% \def\xintmax #1% {% - \expandafter\xint_fmax\expandafter {\romannumeral0\xintraw {#1}}% + \expandafter\XINT_fmax\expandafter {\romannumeral0\xintraw {#1}}% }% -\def\xint_fmax #1#2% +\def\XINT_fmax #1#2% {% \expandafter\XINT_fmax_A\romannumeral0\xintraw {#2}#1% }% @@ -1988,9 +1634,9 @@ \def\xintMin {\romannumeral0\xintmin }% \def\xintmin #1% {% - \expandafter\xint_fmin\expandafter {\romannumeral0\xintraw {#1}}% + \expandafter\XINT_fmin\expandafter {\romannumeral0\xintraw {#1}}% }% -\def\xint_fmin #1#2% +\def\XINT_fmin #1#2% {% \expandafter\XINT_fmin_A\romannumeral0\xintraw {#2}#1% }% @@ -2031,9 +1677,9 @@ \def\XINT_minof_e #1\Z #2\Z { #2}% \def\xintcmp #1% {% - \expandafter\xint_fcmp\expandafter {\romannumeral0\xintraw {#1}}% + \expandafter\XINT_fcmp\expandafter {\romannumeral0\xintraw {#1}}% }% -\def\xint_fcmp #1#2% +\def\XINT_fcmp #1#2% {% \expandafter\XINT_fcmp_A\romannumeral0\xintraw {#2}#1% }% @@ -2109,6 +1755,422 @@ \def\xintopp #1{\expandafter\XINT_opp\romannumeral0\xintraw {#1}}% \def\xintSgn {\romannumeral0\xintsgn }% \def\xintsgn #1{\expandafter\XINT_sgn\romannumeral0\xintraw {#1}\Z }% +\def\xintFloat {\romannumeral0\xintfloat }% +\def\xintfloat #1{\XINT_float_chkopt #1\xint_relax }% +\def\XINT_float_chkopt #1% +{% + \ifx [#1\expandafter\XINT_float_opt + \else\expandafter\XINT_float_noopt + \fi #1% +}% +\def\XINT_float_noopt #1\xint_relax +{% + \expandafter\XINT_float_a\expandafter\XINTdigits\expandafter.% + \romannumeral0\XINT_infrac {#1}\XINT_float_Q +}% +\def\XINT_float_opt [\xint_relax #1]#2% +{% + \expandafter\XINT_float_a\the\numexpr #1\expandafter.% + \romannumeral0\XINT_infrac {#2}\XINT_float_Q +}% +\def\XINT_float_a #1.#2#3% #1=P, #2=n, #3=A, #4=B +{% + \XINT_float_fork #3\Z {#1}{#2}% #1 = precision, #2=n +}% +\def\XINT_float_fork #1% +{% + \xint_UDzerominusfork + #1-\XINT_float_zero + 0#1\XINT_float_J + 0-{\XINT_float_K #1}% + \krof +}% +\def\XINT_float_zero #1\Z #2#3#4#5{ 0.e0}% +\def\XINT_float_J {\expandafter\xint_minus_thenstop\romannumeral0\XINT_float_K }% +\def\XINT_float_K #1\Z #2% #1=A, #2=P, #3=n, #4=B +{% + \expandafter\XINT_float_L + \the\numexpr\xintLength{#1}\expandafter.\the\numexpr #2+\xint_c_ii.{#1}{#2}% +}% +\def\XINT_float_L #1.#2.% +{% + \ifnum #1>#2 + \expandafter\XINT_float_Ma + \else + \expandafter\XINT_float_Mb + \fi #1.#2.% +}% +\def\XINT_float_Ma #1.#2.#3% +{% + \expandafter\XINT_float_MatoN + \the\numexpr #1-#2\expandafter.% + \romannumeral0\XINT_split_fromleft_loop #2.{}#3\W\W\W\W\W\W\W\W\Z + {#2}% +}% +\def\XINT_float_MatoN #1.#2.#3.#4#5#6#7% +{% + \expandafter\XINT_float_N + \the\numexpr\xintLength{#7}\expandafter.\the\numexpr #1+#6.#4.% + {#7}{#4}{#2}{#5}% +}% +\def\XINT_float_Mb #1.#2.#3#4#5#6% +{% + \expandafter\XINT_float_N + \romannumeral0\xintlength{#6}.#5.#2.{#6}{#1}{#3}{#4}% +}% +\def\XINT_float_N #1.#2.#3.% +{% + \ifnum #1>#3 \xint_dothis\XINT_float_N_Blong\fi + \ifnum #1=\xint_c_i\xint_dothis\XINT_float_N_Bshort\fi + \xint_orthat{\XINT_float_P 0.}% + #1.#2.#3.% +}% +\def\XINT_float_N_Blong #1.#2.#3.#4% +{% + \expandafter\XINT_float_NaP + \the\numexpr #2-#1+#3\expandafter.% + \romannumeral0\XINT_split_fromleft_loop #3.{}#4\W\W\W\W\W\W\W\W\Z {#3}% +}% +\def\XINT_float_NaP #1.#2.#3.#4{\XINT_float_P 0.#4.#1.#4.{#2}}% +\def\XINT_float_N_Bshort 1.#1.#2.#3% +{% + \ifnum #3=\xint_c_i \xint_dothis{\XINT_float_P 1.}\fi + \xint_orthat{\XINT_float_P 0.}1.#1.#2.#3% +}% +\def\XINT_float_P #1.#2.#3.#4.#5#6#7#8#9% +{% + \expandafter #9\expandafter#1% + \the\numexpr #2-#6+#4-\xint_c_i.{#7}{#5}{#8}{#3}% +}% +\def\XINT_float_Q #1% +{% + \if 1#1\expandafter\XINT_float_Ri\else\expandafter\XINT_float_Rii\fi +}% +\def\XINT_float_Ri #1.#2#3% +{% + \expandafter\XINT_float_Sa + \romannumeral0\XINT_dsx_addzerosnofuss {#1}{#2}\Z {#1}% +}% +\def\XINT_float_Rii #1.#2#3% +{% + \expandafter\XINT_float_Sa + \romannumeral0\xintiiquo{\XINT_dsx_addzerosnofuss {#1}{#2}}{#3}\Z {#1}% +}% +\def\XINT_float_Sa #1% +{% + \if #19\xint_dothis {\XINT_float_Sb\XINT_float_Wb }\fi + \xint_orthat {\XINT_float_Sb\XINT_float_Wa }#1% +}% +\def\XINT_float_Sb #1#2\Z #3#4% +{% + \expandafter\XINT_float_T + \the\numexpr #4+\xint_c_i\expandafter.% + \romannumeral`&&@\XINT_lenrord_loop 0.{}#2\Z\W\W\W\W\W\W\W\Z #1{#3}{#4}% +}% +\def\XINT_float_T #1.#2.#3% +{% + \ifnum #2>#1 \xint_dothis{\XINT_float_U\XINT_float_Xb}\fi + \xint_orthat{\XINT_float_U\XINT_float_Xa #3}% +}% +\def\XINT_float_U #1#2% +{% + \ifnum #2<\xint_c_v + \expandafter\XINT_float_Va + \else + \expandafter\XINT_float_Vb + \fi #1% +}% +\def\XINT_float_Va #1#2\Z #3% +{% + \expandafter#1% + \romannumeral0\expandafter\XINT_float_Wa + \romannumeral0\XINT_rord_main {}#2% + \xint_relax + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_relax \Z +}% +\def\XINT_float_Vb #1#2\Z #3% +{% + \expandafter #1% + \romannumeral0\expandafter #3% + \romannumeral0\XINT_addm_A 0{}1000\W\X\Y\Z #2000\W\X\Y\Z \Z +}% +\def\XINT_float_Wa #1{ #1.}% +\def\XINT_float_Wb #1#2{\if #11\xint_dothis{ 10.}\fi\xint_orthat{ #1.#2}}% +\def\XINT_float_Xa #1\Z #2#3#4% +{% + \expandafter\XINT_float_Y\the\numexpr #3+#4-#2.{#1}% +}% +\def\XINT_float_Xb #1\Z #2#3#4% +{% + \expandafter\XINT_float_Y\the\numexpr #3+#4+\xint_c_i-#2.{#1}% +}% +\def\XINT_float_Y #1.#2{ #2e#1}% +\def\XINTinFloat {\romannumeral0\XINTinfloat }% +\def\XINTinfloat [#1]#2% +{% + \expandafter\XINT_infloat\the\numexpr #1\expandafter.% + \romannumeral0\expandafter\XINT_infloat_in + \romannumeral`&&@#2/\XINT_W[\XINT_W\XINT_T\XINT_infloat_Q +}% +\def\XINT_infloat #1.#2{#2#1.}% +\def\XINT_infloat_in #1[#2% +{% + \xint_UDXINTWfork + #2\XINT_infloat_gen + \XINT_W\XINT_infloat_res_a + \krof + #1[#2% +}% +\edef\XINT_infloat_gen {\noexpand\expandafter\space\noexpand\expandafter + \noexpand\XINT_infloat_a + \noexpand\romannumeral0\noexpand\XINT_frac_gen }% +\def\XINT_infloat_res_a #1% +{% + \xint_gob_til_zero #1\XINT_infloat_res_zero 0\XINT_infloat_res_b #1% +}% +\def\XINT_infloat_res_zero #1\XINT_infloat_Q { \XINT_infloat_sp_zero}% +\def\XINT_infloat_sp_zero #1.{ 0[0]}% +\def\XINT_infloat_res_b #1/#2% +{% + \xint_UDXINTWfork + #2\XINT_infloat_res_ca + \XINT_W\XINT_infloat_res_cb + \krof + #1/#2% +}% +\def\XINT_infloat_res_ca #1[#2]/\XINT_W[\XINT_W\XINT_T\XINT_infloat_Q + { \XINT_infloat_sp #1.#2.}% +\def\XINT_infloat_res_cb #1/#2[% + {\expandafter\XINT_infloat_res_cc\romannumeral`&&@#2~#1[}% +\edef\XINT_infloat_res_cc #1~#2[#3]/\XINT_W[\XINT_W\XINT_T + {\noexpand\expandafter\space\noexpand\expandafter + \noexpand\XINT_infloat_a\noexpand\expandafter + {\noexpand\the\numexpr #3}{#2}{#1}}% +\def\XINT_infloat_sp #1.#2% +{% + \if-#2\xint_dothis{\expandafter-\romannumeral0\XINT_infloat_sp_a {}}\fi + \xint_orthat{\XINT_infloat_sp_a #2}#1.% +}% +\def\XINT_infloat_sp_a #1#2.#3.% +{% + \expandafter\XINT_infloat_sp_b\the\numexpr#2-\xintLength{#1#3}.#1#3.#2.% +}% +\def\XINT_infloat_sp_b #1% +{% + \xint_UDzerominusfork + #1-\XINT_infloat_sp_quick + 0#1\XINT_infloat_sp_c + 0-{\XINT_infloat_sp_addzeroes #1}% + \krof +}% +\def\XINT_infloat_sp_quick .#1.#2.#3.{ #1[#3]}% +\def\XINT_infloat_sp_addzeroes #1.#2.#3.#4.% +{% + \expandafter\XINT_infloat_sp_done + \the\numexpr #4-#1\expandafter.% + \romannumeral0\XINT_dsx_addzerosnofuss {#1}{#2};% +}% +\def\XINT_infloat_sp_done #1.#2;{ #2[#1]}% +\def\XINT_infloat_sp_c #1.#2% +{% + \if #29\xint_dothis {\XINT_infloat_sp_d\XINT_infloat_Wb }\fi + \xint_orthat {\XINT_infloat_sp_d\xint_c_ }#1.#2% +}% +\def\XINT_infloat_sp_d #1#2.#3.#4.%#5.% +{% + \expandafter\XINT_infloat_sp_e + \romannumeral0\expandafter\XINT_split_fromleft_loop + \the\numexpr #4+\xint_c_i.{}#3\W\W\W\W\W\W\W\W\Z #1#2.% +}% +\def\XINT_infloat_sp_e #1.#2.% +{% + \expandafter\XINT_infloat_sp_f + \romannumeral0\XINT_rord_main {}#1% + \xint_relax + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_relax ;% +}% +\def\XINT_infloat_sp_f #1% +{% + \ifnum #1<\xint_c_v + \expandafter\XINT_infloat_sp_ga\else\expandafter\XINT_infloat_sp_h\fi +}% +\def\XINT_infloat_sp_ga #1;#2#3.#4.% +{% + \expandafter\XINT_infloat_sp_done\the\numexpr #3+#4\expandafter.% + \romannumeral0\XINT_rord_main {}#1% + \xint_relax + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_relax ;% +}% +\def\XINT_infloat_sp_h #1;#2% +{% + \expandafter\XINT_infloat_sp_i + \romannumeral0\expandafter#2% + \romannumeral0\XINT_addm_A 0{}1000\W\X\Y\Z #1000\W\X\Y\Z;% +}% +\def\XINT_infloat_sp_i #1#2;#3.#4.% +{% + \expandafter\XINT_infloat_sp_done\the\numexpr #1+#3+#4.#2;% +}% +\def\XINT_infloat_a #1.#2#3% #1=P, #2=n, #3=A, #4=B +{% + \XINT_infloat_fork #3\Z {#1}{#2}% #1 = precision, #2=n +}% +\def\XINT_infloat_fork #1% +{% + \xint_UDzerominusfork + #1-\XINT_infloat_zero + 0#1\XINT_infloat_J + 0-{\XINT_float_K #1}% + \krof +}% +\def\XINT_infloat_zero #1\Z #2#3#4#5{ 0[0]}% +\def\XINT_infloat_J {\expandafter-\romannumeral0\XINT_float_K }% +\def\XINT_infloat_Q #1% +{% + \if 1#1\expandafter\XINT_infloat_Ri\else\expandafter\XINT_infloat_Rii\fi +}% +\def\XINT_infloat_Ri #1.#2#3% +{% + \expandafter\XINT_infloat_Sa + \romannumeral0\XINT_dsx_addzerosnofuss {#1}{#2}\Z {#1}% +}% +\def\XINT_infloat_Rii #1.#2#3% +{% + \expandafter\XINT_infloat_Sa + \romannumeral0\xintiiquo{\XINT_dsx_addzerosnofuss {#1}{#2}}{#3}\Z {#1}% +}% +\def\XINT_infloat_Sa #1% +{% + \if #19\xint_dothis {\XINT_infloat_Sb\XINT_infloat_Wb }\fi + \xint_orthat {\XINT_infloat_Sb\xint_c_ }#1% +}% +\def\XINT_infloat_Sb #1#2\Z #3#4% +{% + \expandafter\XINT_infloat_T + \the\numexpr #4+\xint_c_i\expandafter.% + \romannumeral`&&@\XINT_lenrord_loop 0.{}#2\Z\W\W\W\W\W\W\W\Z #1{#3}% +}% +\def\XINT_infloat_T #1.#2.#3% +{% + \ifnum #2>#1 \xint_dothis{\XINT_infloat_U\XINT_infloat_Xb}\fi + \xint_orthat{\XINT_infloat_U\XINT_infloat_Xa #3}% +}% +\def\XINT_infloat_U #1#2% +{% + \ifnum #2<\xint_c_v + \expandafter\XINT_infloat_Va + \else + \expandafter\XINT_infloat_Vb + \fi #1% +}% +\def\XINT_infloat_Va #1#2\Z #3% +{% + \expandafter#1% + \romannumeral0\expandafter\xint_c_ + \romannumeral0\XINT_rord_main {}#2% + \xint_relax + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_relax \Z +}% +\def\XINT_infloat_Vb #1#2\Z #3% +{% + \expandafter #1% + \romannumeral0\expandafter #3% + \romannumeral0\XINT_addm_A 0{}1000\W\X\Y\Z #2000\W\X\Y\Z \Z +}% +\def\XINT_infloat_Wb #1#2% + {\if #11\xint_dothis{\xint_c_i1}\fi\xint_orthat{\xint_c_#1#2}}% +\def\XINT_infloat_Xa #1#2\Z #3#4% +{% + \expandafter\XINT_infloat_Y\the\numexpr #1+\xint_c_i+#4-#3.{#2}% +}% +\def\XINT_infloat_Xb #1#2\Z #3#4% +{% + \expandafter\XINT_infloat_Y\the\numexpr #1+\xint_c_ii+#4-#3.{#2}% +}% +\def\XINT_infloat_Y #1.#2{ #2[#1]}% +\def\xintPFloat {\romannumeral0\xintpfloat }% +\def\xintpfloat #1{\XINT_pfloat_chkopt #1\xint_relax }% +\def\XINT_pfloat_chkopt #1% +{% + \ifx [#1\expandafter\XINT_pfloat_opt + \else\expandafter\XINT_pfloat_noopt + \fi #1% +}% +\def\XINT_pfloat_noopt #1\xint_relax +{% + \expandafter\XINT_pfloat_a + \romannumeral0\xintfloat [\XINTdigits]{#1};\XINTdigits.% +}% +\def\XINT_pfloat_opt [\xint_relax #1]%#2% +{% + \expandafter\XINT_pfloat_opt_a \the\numexpr #1.% +}% +\def\XINT_pfloat_opt_a #1.#2% +{% + \expandafter\XINT_pfloat_a\romannumeral0\xintfloat [#1]{#2};#1.% +}% +\def\XINT_pfloat_a #1% +{% + \xint_UDzerominusfork + #1-\XINT_pfloat_zero + 0#1\XINT_pfloat_neg + 0-{\XINT_pfloat_pos #1}% + \krof +}% +\def\XINT_pfloat_zero #1;#2.{ 0.}% +\def\XINT_pfloat_neg + {\expandafter\xint_minus_thenstop\romannumeral0\XINT_pfloat_pos }% +\def\XINT_pfloat_pos #1e#2;#3.% +{% + \ifnum #2>\xint_c_v \xint_dothis\XINT_pfloat_no\fi + \ifnum #2<-\xint_c_v \xint_dothis\XINT_pfloat_no\fi + \ifnum #2<\xint_c_ \xint_dothis\XINT_pfloat_N\fi + \ifnum #2>\numexpr #3-\xint_c_i\relax \xint_dothis\XINT_pfloat_Ps\fi + \xint_orthat\XINT_pfloat_P #1e#2;% +}% +\def\XINT_pfloat_no #1;{ #1}% +\def\XINT_pfloat_N #1#2.#3e#4;% +{% + \csname XINT_pfloat_N\romannumeral-#4\endcsname #2#10.#3;% +}% +\def\XINT_pfloat_Ni #1#2#3.#4;{ #2.#1#4}% +\def\XINT_pfloat_Nii #1#2#3.#4;{ 0.#2#1#4}% +\def\XINT_pfloat_Niii#1#2#3.#4;{ 0.0#2#1#4}% +\def\XINT_pfloat_Niv #1#2#3.#4;{ 0.00#2#1#4}% +\def\XINT_pfloat_Nv #1#2#3.#4;{ 0.000#2#1#4}% +\def\XINT_pfloat_P #1#2.#3e#4;% +{% + \csname XINT_pfloat_P_\romannumeral#4\endcsname #3.#1#2;% +}% +\def\XINT_pfloat_P_ #1.#2;{ #2.#1}% +\def\XINT_pfloat_P_i #1#2.#3;{ #3#1.#2}% +\def\XINT_pfloat_P_ii #1#2#3.#4;{ #4#1#2.#3}% +\def\XINT_pfloat_P_iii#1#2#3#4.#5;{ #5#1#2#3.#4}% +\def\XINT_pfloat_P_iv #1#2#3#4#5.#6;{ #6#1#2#3#4.#5}% +\def\XINT_pfloat_P_v #1#2#3#4#5#6.#7;{ #7#1#2#3#4#5.#6}% +\def\XINT_pfloat_Ps #1#2.#3e#4;% +{% + \csname XINT_pfloat_Ps\romannumeral#4\endcsname #300000.#1#2;% +}% +\def\XINT_pfloat_Psi #1#2.#3;{ #3#1.}% +\def\XINT_pfloat_Psii #1#2#3.#4;{ #4#1#2.}% +\def\XINT_pfloat_Psiii#1#2#3#4.#5;{ #5#1#2#3.}% +\def\XINT_pfloat_Psiv #1#2#3#4#5.#6;{ #6#1#2#3#4.}% +\def\XINT_pfloat_Psv #1#2#3#4#5#6.#7;{ #7#1#2#3#4#5.}% +\def\XINTinFloatFracdigits {\romannumeral0\XINTinfloatfracdigits }% +\def\XINTinfloatfracdigits #1% +{% + \expandafter\XINT_infloatfracdg_a\expandafter {\romannumeral0\xinttfrac{#1}}% +}% +\def\XINT_infloatfracdg_a {\XINTinfloat [\XINTdigits]}% \def\xintFloatAdd {\romannumeral0\xintfloatadd }% \def\xintfloatadd #1{\XINT_fladd_chkopt \xintfloat #1\xint_relax }% \def\XINTinFloatAdd {\romannumeral0\XINTinfloatadd }% @@ -2121,46 +2183,41 @@ }% \def\XINT_fladd_noopt #1#2\xint_relax #3% {% - #1[\XINTdigits]{\XINT_FL_Add {\XINTdigits+\xint_c_ii}{#2}{#3}}% + #1[\XINTdigits]% + {\expandafter\XINT_FL_add_a + \romannumeral0\XINTinfloat[\XINTdigits]{#2}\XINTdigits.{#3}}% }% -\def\XINT_fladd_opt #1[\xint_relax #2]#3#4% +\def\XINT_fladd_opt #1[\xint_relax #2]%#3#4% {% - #1[#2]{\XINT_FL_Add {#2+\xint_c_ii}{#3}{#4}}% + \expandafter\XINT_fladd_opt_a\the\numexpr #2.#1% }% -\def\XINT_FL_Add #1#2% +\def\XINT_fladd_opt_a #1.#2#3#4% {% - \expandafter\XINT_FL_Add_a\expandafter{\the\numexpr #1\expandafter}% - \expandafter{\romannumeral0\XINTinfloat [#1]{#2}}% + #2[#1]{\expandafter\XINT_FL_add_a\romannumeral0\XINTinfloat[#1]{#3}#1.{#4}}% }% -\def\XINT_FL_Add_a #1#2#3% +\def\XINT_FL_add_a #1% {% - \expandafter\XINT_FL_Add_b\romannumeral0\XINTinfloat [#1]{#3}#2{#1}% + \xint_gob_til_zero #1\XINT_FL_add_zero 0\XINT_FL_add_b #1% }% -\def\XINT_FL_Add_b #1% +\def\XINT_FL_add_zero #1.#2{#2}% +\def\XINT_FL_add_b #1]#2.#3% {% - \xint_gob_til_zero #1\XINT_FL_Add_zero 0\XINT_FL_Add_c #1% + \expandafter\XINT_FL_add_c\romannumeral0\XINTinfloat[#2]{#3}#2.#1]% }% -\def\XINT_FL_Add_c #1[#2]#3% +\def\XINT_FL_add_c #1% {% - \xint_gob_til_zero #3\XINT_FL_Add_zerobis 0\XINT_FL_Add_d #1[#2]#3% + \xint_gob_til_zero #1\XINT_FL_add_zero 0\XINT_FL_add_d #1% }% -\def\XINT_FL_Add_d #1[#2]#3[#4]#5% +\def\XINT_FL_add_d #1[#2]#3.#4[#5]% {% - \ifnum \numexpr #2-#4-#5>\xint_c_i - \expandafter \xint_secondofthree_thenstop - \else - \ifnum \numexpr #4-#2-#5>\xint_c_i - \expandafter\expandafter\expandafter\xint_thirdofthree_thenstop - \fi - \fi - \xintadd {#1[#2]}{#3[#4]}% + \ifnum\numexpr #2-#3-#5>\xint_c_\xint_dothis\xint_firstoftwo\fi + \ifnum\numexpr #5-#3-#2>\xint_c_\xint_dothis\xint_secondoftwo\fi + \xint_orthat\xintAdd {#1[#2]}{#4[#5]}% }% -\def\XINT_FL_Add_zero 0\XINT_FL_Add_c 0[0]#1[#2]#3{#1[#2]}% -\def\XINT_FL_Add_zerobis 0\XINT_FL_Add_d #1[#2]0[0]#3{#1[#2]}% -\def\xintFloatSub {\romannumeral0\xintfloatsub }% +\def\xintFloatSub {\romannumeral0\xintfloatsub }% \def\xintfloatsub #1{\XINT_flsub_chkopt \xintfloat #1\xint_relax }% -\def\XINTinFloatSub {\romannumeral0\XINTinfloatsub }% -\def\XINTinfloatsub #1{\XINT_flsub_chkopt \XINTinfloat #1\xint_relax }% +\def\XINTinFloatSub {\romannumeral0\XINTinfloatsub }% +\def\XINTinfloatsub #1{\XINT_flsub_chkopt \XINTinfloat #1\xint_relax }% \def\XINT_flsub_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flsub_opt @@ -2169,14 +2226,20 @@ }% \def\XINT_flsub_noopt #1#2\xint_relax #3% {% - #1[\XINTdigits]{\XINT_FL_Add {\XINTdigits+\xint_c_ii}{#2}{\xintOpp{#3}}}% + #1[\XINTdigits]% + {\expandafter\XINT_FL_add_a + \romannumeral0\XINTinfloat[\XINTdigits]{#2}\XINTdigits.{\xintOpp{#3}}}% +}% +\def\XINT_flsub_opt #1[\xint_relax #2]%#3#4% +{% + \expandafter\XINT_flsub_opt_a\the\numexpr #2.#1% }% -\def\XINT_flsub_opt #1[\xint_relax #2]#3#4% +\def\XINT_flsub_opt_a #1.#2#3#4% {% - #1[#2]{\XINT_FL_Add {#2+\xint_c_ii}{#3}{\xintOpp{#4}}}% + #2[#1]{\expandafter\XINT_FL_add_a\romannumeral0\XINTinfloat[#1]{#3}#1.{\xintOpp{#4}}}% }% -\def\xintFloatMul {\romannumeral0\xintfloatmul}% -\def\xintfloatmul #1{\XINT_flmul_chkopt \xintfloat #1\xint_relax }% +\def\xintFloatMul {\romannumeral0\xintfloatmul }% +\def\xintfloatmul #1{\XINT_flmul_chkopt \xintfloat #1\xint_relax }% \def\XINTinFloatMul {\romannumeral0\XINTinfloatmul }% \def\XINTinfloatmul #1{\XINT_flmul_chkopt \XINTinfloat #1\xint_relax }% \def\XINT_flmul_chkopt #1#2% @@ -2187,26 +2250,27 @@ }% \def\XINT_flmul_noopt #1#2\xint_relax #3% {% - #1[\XINTdigits]{\XINT_FL_Mul {\XINTdigits+\xint_c_ii}{#2}{#3}}% + #1[\XINTdigits]% + {\expandafter\XINT_FL_mul_a + \romannumeral0\XINTinfloat[\XINTdigits]{#2}\XINTdigits.{#3}}% }% -\def\XINT_flmul_opt #1[\xint_relax #2]#3#4% +\def\XINT_flmul_opt #1[\xint_relax #2]%#3#4% {% - #1[#2]{\XINT_FL_Mul {#2+\xint_c_ii}{#3}{#4}}% + \expandafter\XINT_flmul_opt_a\the\numexpr #2.#1% }% -\def\XINT_FL_Mul #1#2% +\def\XINT_flmul_opt_a #1.#2#3#4% {% - \expandafter\XINT_FL_Mul_a\expandafter{\the\numexpr #1\expandafter}% - \expandafter{\romannumeral0\XINTinfloat [#1]{#2}}% + #2[#1]{\expandafter\XINT_FL_mul_a\romannumeral0\XINTinfloat[#1]{#3}#1.{#4}}% }% -\def\XINT_FL_Mul_a #1#2#3% +\def\XINT_FL_mul_a #1[#2]#3.#4% {% - \expandafter\XINT_FL_Mul_b\romannumeral0\XINTinfloat [#1]{#3}#2% + \expandafter\XINT_FL_mul_b\romannumeral0\XINTinfloat [#3]{#4}#1[#2]% }% -\def\XINT_FL_Mul_b #1[#2]#3[#4]{\xintE{\xintiiMul {#1}{#3}}{#2+#4}}% -\def\xintFloatDiv {\romannumeral0\xintfloatdiv}% -\def\xintfloatdiv #1{\XINT_fldiv_chkopt \xintfloat #1\xint_relax }% -\def\XINTinFloatDiv {\romannumeral0\XINTinfloatdiv }% -\def\XINTinfloatdiv #1{\XINT_fldiv_chkopt \XINTinfloat #1\xint_relax }% +\def\XINT_FL_mul_b #1[#2]#3[#4]{\xintE{\xintiiMul {#3}{#1}}{#4+#2}}% +\def\xintFloatDiv {\romannumeral0\xintfloatdiv }% +\def\xintfloatdiv #1{\XINT_fldiv_chkopt \xintfloat #1\xint_relax }% +\def\XINTinFloatDiv {\romannumeral0\XINTinfloatdiv }% +\def\XINTinfloatdiv #1{\XINT_fldiv_chkopt \XINTinfloat #1\xint_relax }% \def\XINT_fldiv_chkopt #1#2% {% \ifx [#2\expandafter\XINT_fldiv_opt @@ -2215,23 +2279,24 @@ }% \def\XINT_fldiv_noopt #1#2\xint_relax #3% {% - #1[\XINTdigits]{\XINT_FL_Div {\XINTdigits+\xint_c_ii}{#2}{#3}}% + #1[\XINTdigits]% + {\expandafter\XINT_FL_div_a + \romannumeral0\XINTinfloat[\XINTdigits]{#2}\XINTdigits.{#3}}% }% -\def\XINT_fldiv_opt #1[\xint_relax #2]#3#4% +\def\XINT_fldiv_opt #1[\xint_relax #2]%#3#4% {% - #1[#2]{\XINT_FL_Div {#2+\xint_c_ii}{#3}{#4}}% + \expandafter\XINT_fldiv_opt_a\the\numexpr #2.#1% }% -\def\XINT_FL_Div #1#2% +\def\XINT_fldiv_opt_a #1.#2#3#4% {% - \expandafter\XINT_FL_Div_a\expandafter{\the\numexpr #1\expandafter}% - \expandafter{\romannumeral0\XINTinfloat [#1]{#2}}% + #2[#1]{\expandafter\XINT_FL_div_a\romannumeral0\XINTinfloat[#1]{#3}#1.{#4}}% }% -\def\XINT_FL_Div_a #1#2#3% +\def\XINT_FL_div_a #1[#2]#3.#4% {% - \expandafter\XINT_FL_Div_b\romannumeral0\XINTinfloat [#1]{#3}#2% + \expandafter\XINT_FL_div_b\romannumeral0\XINTinfloat[#3]{#4}#1[#2]% }% -\def\XINT_FL_Div_b #1[#2]#3[#4]{\xintE{#3/#1}{#4-#2}}% -\def\xintFloatPow {\romannumeral0\xintfloatpow}% +\def\XINT_FL_div_b #1[#2]#3[#4]{\xintE{#3/#1}{#4-#2}}% +\def\xintFloatPow {\romannumeral0\xintfloatpow}% \def\xintfloatpow #1{\XINT_flpow_chkopt \xintfloat #1\xint_relax }% \def\XINTinFloatPow {\romannumeral0\XINTinfloatpow }% \def\XINTinfloatpow #1{\XINT_flpow_chkopt \XINTinfloat #1\xint_relax }% @@ -2240,253 +2305,302 @@ \ifx [#2\expandafter\XINT_flpow_opt \else\expandafter\XINT_flpow_noopt \fi - #1#2% + #1#2% }% \def\XINT_flpow_noopt #1#2\xint_relax #3% {% - \expandafter\XINT_flpow_checkB_start\expandafter - {\the\numexpr #3\expandafter}\expandafter - {\the\numexpr \XINTdigits}{#2}{#1[\XINTdigits]}% + \expandafter\XINT_flpow_checkB_a + \the\numexpr #3.\XINTdigits.{#2}{#1[\XINTdigits]}% +}% +\def\XINT_flpow_opt #1[\xint_relax #2]% +{% + \expandafter\XINT_flpow_opt_a\the\numexpr #2.#1% }% -\def\XINT_flpow_opt #1[\xint_relax #2]#3#4% +\def\XINT_flpow_opt_a #1.#2#3#4% {% - \expandafter\XINT_flpow_checkB_start\expandafter - {\the\numexpr #4\expandafter}\expandafter - {\the\numexpr #2}{#3}{#1[#2]}% + \expandafter\XINT_flpow_checkB_a\the\numexpr #4.#1.{#3}{#2[#1]}% }% -\def\XINT_flpow_checkB_start #1{\XINT_flpow_checkB_a #1\Z }% \def\XINT_flpow_checkB_a #1% {% \xint_UDzerominusfork #1-\XINT_flpow_BisZero - 0#1{\XINT_flpow_checkB_b 1}% - 0-{\XINT_flpow_checkB_b 0#1}% + 0#1{\XINT_flpow_checkB_b -}% + 0-{\XINT_flpow_checkB_b {}#1}% \krof }% -\def\XINT_flpow_BisZero \Z #1#2#3{#3{1/1[0]}}% -\def\XINT_flpow_checkB_b #1#2\Z #3% +\def\XINT_flpow_BisZero .#1.#2#3{#3{1[0]}}% +\def\XINT_flpow_checkB_b #1#2.#3.% {% - \expandafter\XINT_flpow_checkB_c \expandafter - {\romannumeral0\xintlength{#2}}{#3}{#2}#1% + \expandafter\XINT_flpow_checkB_c + \the\numexpr\xintLength{#2}+\xint_c_iii.#3.#2.{#1}% }% -\def\XINT_flpow_checkB_c #1#2% +\def\XINT_flpow_checkB_c #1.#2.% {% - \expandafter\XINT_flpow_checkB_d \expandafter - {\the\numexpr \expandafter\xintLength\expandafter - {\the\numexpr #1*20/\xint_c_iii }+#1+#2+\xint_c_i }% + \expandafter\XINT_flpow_checkB_d\the\numexpr#1+#2.#1.#2.% }% -\def\XINT_flpow_checkB_d #1#2#3#4% +\def\XINT_flpow_checkB_d #1.#2.#3.#4.#5#6% {% - \expandafter \XINT_flpow_a - \romannumeral0\XINTinfloat [#1]{#4}{#1}{#2}#3% + \expandafter \XINT_flpow_aa + \romannumeral0\XINTinfloat [#3]{#6}{#2}{#1}{#4}{#5}% }% +\def\XINT_flpow_aa #1[#2]#3% +{% + \expandafter\XINT_flpow_ab\the\numexpr #2-#3\expandafter.% + \romannumeral0\XINT_dsx_addzerosnofuss {#3}{}.#1.% +}% +\def\XINT_flpow_ab #1.#2.#3.{\XINT_flpow_a #3#2[#1]}% \def\XINT_flpow_a #1% {% \xint_UDzerominusfork #1-\XINT_flpow_zero - 0#1{\XINT_flpow_b 1}% - 0-{\XINT_flpow_b 0#1}% + 0#1{\XINT_flpow_b \iftrue}% + 0-{\XINT_flpow_b \iffalse#1}% \krof }% +\def\XINT_flpow_zero #1[#2]#3#4#5#6% +{% + \if 1#51\xint_afterfi {#6{0[0]}}\else + \xint_afterfi {\xintError:DivisionByZero #6{1[2147483648]}}\fi +}% \def\XINT_flpow_b #1#2[#3]#4#5% {% - \XINT_flpow_loopI {#5}{#2[#3]}{\romannumeral0\XINTinfloatmul [#4]}% - {#1*\ifodd #5 1\else 0\fi}% + \XINT_flpow_loopI #5.#3.#2.#4.{#1\ifodd #5 \xint_c_i\fi\fi}% }% -\def\XINT_flpow_zero [#1]#2#3#4#5% +\def\XINT_flpow_truncate #1.#2.#3.% {% - \if #41\xint_afterfi {\xintError:DivisionByZero #5{1[2147483648]}}% - \else \xint_afterfi {#5{0[0]}}\fi + \expandafter\XINT_flpow_truncate_a + \romannumeral0\XINT_split_fromleft_loop #3.{}#2\W\W\W\W\W\W\W\W\Z + #1.#3.% }% -\def\XINT_flpow_loopI #1% +\def\XINT_flpow_truncate_a #1.#2.#3.{#3+\xintLength{#2}.#1.}% +\def\XINT_flpow_loopI #1.% {% - \ifnum #1=\xint_c_i\XINT_flpow_ItoIII\fi + \ifnum #1=\xint_c_i\expandafter\XINT_flpow_ItoIII\fi \ifodd #1 \expandafter\XINT_flpow_loopI_odd \else \expandafter\XINT_flpow_loopI_even \fi - {#1}% + #1.% }% -\def\XINT_flpow_ItoIII\fi #1\fi #2#3#4#5% +\def\XINT_flpow_ItoIII\ifodd #1\fi #2.#3.#4.#5.#6% {% - \fi\expandafter\XINT_flpow_III\the\numexpr #5\relax #3% + \expandafter\XINT_flpow_III\the\numexpr #6+\xint_c_.#3.#4.#5.% }% -\def\XINT_flpow_loopI_even #1#2#3% +\def\XINT_flpow_loopI_even #1.#2.#3.%#4.% {% - \expandafter\XINT_flpow_loopI\expandafter - {\the\numexpr #1/\xint_c_ii\expandafter}\expandafter - {#3{#2}{#2}}{#3}% + \expandafter\XINT_flpow_loopI + \the\numexpr #1/\xint_c_ii\expandafter.% + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.% }% -\def\XINT_flpow_loopI_odd #1#2#3% +\def\XINT_flpow_loopI_odd #1.#2.#3.#4.% {% - \expandafter\XINT_flpow_loopII\expandafter - {\the\numexpr #1/\xint_c_ii-\xint_c_i\expandafter}\expandafter - {#3{#2}{#2}}{#3}{#2}% + \expandafter\XINT_flpow_loopII + \the\numexpr #1/\xint_c_ii-\xint_c_i\expandafter.% + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.#4.#2.#3.% }% -\def\XINT_flpow_loopII #1% +\def\XINT_flpow_loopII #1.% {% - \ifnum #1 = \xint_c_i\XINT_flpow_IItoIII\fi + \ifnum #1 = \xint_c_i\expandafter\XINT_flpow_IItoIII\fi \ifodd #1 \expandafter\XINT_flpow_loopII_odd \else \expandafter\XINT_flpow_loopII_even \fi - {#1}% + #1.% }% -\def\XINT_flpow_loopII_even #1#2#3% +\def\XINT_flpow_loopII_even #1.#2.#3.%#4.% {% - \expandafter\XINT_flpow_loopII\expandafter - {\the\numexpr #1/\xint_c_ii\expandafter}\expandafter - {#3{#2}{#2}}{#3}% + \expandafter\XINT_flpow_loopII + \the\numexpr #1/\xint_c_ii\expandafter.% + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.% }% -\def\XINT_flpow_loopII_odd #1#2#3#4% +\def\XINT_flpow_loopII_odd #1.#2.#3.#4.#5.#6.% {% - \expandafter\XINT_flpow_loopII_odda\expandafter - {#3{#2}{#4}}{#1}{#2}{#3}% + \expandafter\XINT_flpow_loopII_odda + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr#2+#5\expandafter.\romannumeral0\xintiimul{#3}{#6}.#4.% + #1.#2.#3.% }% -\def\XINT_flpow_loopII_odda #1#2#3#4% +\def\XINT_flpow_loopII_odda #1.#2.#3.#4.#5.#6.% {% - \expandafter\XINT_flpow_loopII\expandafter - {\the\numexpr #2/\xint_c_ii-\xint_c_i\expandafter}\expandafter - {#4{#3}{#3}}{#4}{#1}% + \expandafter\XINT_flpow_loopII + \the\numexpr #4/\xint_c_ii-\xint_c_i\expandafter.% + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#5\expandafter.\romannumeral0\xintiisqr{#6}.#3.% + #1.#2.% }% -\def\XINT_flpow_IItoIII\fi #1\fi #2#3#4#5#6% +\def\XINT_flpow_IItoIII\ifodd #1\fi #2.#3.#4.#5.#6.#7.#8% {% - \fi\expandafter\XINT_flpow_III\the\numexpr #6\expandafter\relax - #4{#3}{#5}% + \expandafter\XINT_flpow_III\the\numexpr #8+\xint_c_\expandafter.% + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr#3+#6\expandafter.\romannumeral0\xintiimul{#4}{#7}.#5.% }% -\def\XINT_flpow_III #1#2[#3]#4% +\def\XINT_flpow_III #1.#2.#3.#4.#5% {% - \expandafter\XINT_flpow_IIIend\expandafter - {\the\numexpr\if #41-\fi#3\expandafter}% - \xint_UDzerofork - #4{{#2}}% - 0{{1/#2}}% + \expandafter\XINT_flpow_IIIend + \xint_UDsignfork + #5{{\xintNum{1/#3[\xint_c_ii*#4-\xint_c_i]}[\xint_c_i-\xint_c_ii*#4-#2]}}% + -{{#3[#2]}}% \krof #1% }% -\def\XINT_flpow_IIIend #1#2#3#4% -{% - \xint_UDzerofork - #3{#4{#2[#1]}}% - 0{#4{-#2[#1]}}% - \krof -}% -\def\xintFloatPower {\romannumeral0\xintfloatpower}% +\def\XINT_flpow_IIIend #1#2#3% + {#3{\if#21\xint_afterfi{\expandafter-\romannumeral`&&@}\fi#1}}% +\def\xintFloatPower {\romannumeral0\xintfloatpower}% \def\xintfloatpower #1{\XINT_flpower_chkopt \xintfloat #1\xint_relax }% -\def\XINTinFloatPower {\romannumeral0\XINTinfloatpower}% +\def\XINTinFloatPower {\romannumeral0\XINTinfloatpower }% \def\XINTinfloatpower #1{\XINT_flpower_chkopt \XINTinfloat #1\xint_relax }% +\def\XINTinFloatPowerH {\romannumeral0\XINTinfloatpowerH }% +\def\XINTinfloatpowerH #1#2% + {\expandafter\XINT_flpowerh_a \romannumeral0\xinttrunc 1{#2}.0;% + \XINTdigits.{#1}{\XINTinfloat[\XINTdigits]}}% +\def\XINT_flpowerh_a #1.#2% +{% + \ifnum#2>\xint_c_iv\xint_dothis\XINT_flpowerh_b\fi + \xint_orthat\XINT_flpowerh_i #1.#2% +}% +\def\XINT_flpowerh_i #1.#2;% + {\expandafter\XINT_flpower_checkB_a\romannumeral0\xintinum{#1}.}% +\def\XINT_flpowerh_b #1% +{% + \if#1-\xint_dothis\XINT_flpowerh_bneg\fi + \xint_orthat{\XINT_flpowerh_bpos #1}% +}% +\def\XINT_flpowerh_bpos #1.#2;\XINTdigits.#3#4% +{% + \expandafter\XINT_flpower_checkB_a + \romannumeral0\xintinc{\xintDouble{#1}}.% + \XINTdigits.{#3}{\XINTinfloatsqrt[\XINTdigits]}% +}% +\def\XINT_flpowerh_bneg #1.#2;\XINTdigits.#3#4% +{% + \expandafter\XINT_flpower_checkB_a + \expandafter-\romannumeral0\xintinc{\xintDouble{#1}}.% + \XINTdigits.{#3}{\XINTinfloatsqrt[\XINTdigits]}% +}% \def\XINT_flpower_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flpower_opt \else\expandafter\XINT_flpower_noopt \fi - #1#2% + #1#2% }% \def\XINT_flpower_noopt #1#2\xint_relax #3% {% - \expandafter\XINT_flpower_checkB_start\expandafter - {\the\numexpr \XINTdigits\expandafter}\expandafter - {\romannumeral0\xintnum{#3}}{#2}{#1[\XINTdigits]}% + \expandafter\XINT_flpower_checkB_a + \romannumeral0\xintnum{#3}.\XINTdigits.{#2}{#1[\XINTdigits]}% }% -\def\XINT_flpower_opt #1[\xint_relax #2]#3#4% +\def\XINT_flpower_opt #1[\xint_relax #2]% {% - \expandafter\XINT_flpower_checkB_start\expandafter - {\the\numexpr #2\expandafter}\expandafter - {\romannumeral0\xintnum{#4}}{#3}{#1[#2]}% + \expandafter\XINT_flpower_opt_a\the\numexpr #2.#1% +}% +\def\XINT_flpower_opt_a #1.#2#3#4% +{% + \expandafter\XINT_flpower_checkB_a + \romannumeral0\xintnum{#4}.#1.{#3}{#2[#1]}% }% -\def\XINT_flpower_checkB_start #1#2{\XINT_flpower_checkB_a #2\Z {#1}}% \def\XINT_flpower_checkB_a #1% {% \xint_UDzerominusfork #1-\XINT_flpower_BisZero - 0#1{\XINT_flpower_checkB_b 1}% - 0-{\XINT_flpower_checkB_b 0#1}% + 0#1{\XINT_flpower_checkB_b -}% + 0-{\XINT_flpower_checkB_b {}#1}% \krof }% -\def\XINT_flpower_BisZero \Z #1#2#3{#3{1/1[0]}}% -\def\XINT_flpower_checkB_b #1#2\Z #3% +\def\XINT_flpower_BisZero .#1.#2#3{#3{1[0]}}% +\def\XINT_flpower_checkB_b #1#2.#3.% +{% + \expandafter\XINT_flpower_checkB_c + \the\numexpr\xintLength{#2}+\xint_c_iii.#3.#2.{#1}% +}% +\def\XINT_flpower_checkB_c #1.#2.% {% - \expandafter\XINT_flpower_checkB_c \expandafter - {\romannumeral0\xintlength{#2}}{#3}{#2}#1% + \expandafter\XINT_flpower_checkB_d\the\numexpr#1+#2.#1.#2.% }% -\def\XINT_flpower_checkB_c #1#2% +\def\XINT_flpower_checkB_d #1.#2.#3.#4.#5#6% {% - \expandafter\XINT_flpower_checkB_d \expandafter - {\the\numexpr \expandafter\xintLength\expandafter - {\the\numexpr #1*20/\xint_c_iii }+#1+#2+\xint_c_i }% + \expandafter \XINT_flpower_aa + \romannumeral0\XINTinfloat [#3]{#6}{#2}{#1}{#4}{#5}% }% -\def\XINT_flpower_checkB_d #1#2#3#4% +\def\XINT_flpower_aa #1[#2]#3% {% - \expandafter \XINT_flpower_a - \romannumeral0\XINTinfloat [#1]{#4}{#1}{#2}#3% + \expandafter\XINT_flpower_ab\the\numexpr #2-#3\expandafter.% + \romannumeral0\XINT_dsx_addzerosnofuss {#3}{}.#1.% }% +\def\XINT_flpower_ab #1.#2.#3.{\XINT_flpower_a #3#2[#1]}% \def\XINT_flpower_a #1% {% \xint_UDzerominusfork #1-\XINT_flpow_zero - 0#1{\XINT_flpower_b 1}% - 0-{\XINT_flpower_b 0#1}% + 0#1{\XINT_flpower_b \iftrue}% + 0-{\XINT_flpower_b \iffalse#1}% \krof }% \def\XINT_flpower_b #1#2[#3]#4#5% {% - \XINT_flpower_loopI {#5}{#2[#3]}{\romannumeral0\XINTinfloatmul [#4]}% - {#1*\xintiiOdd {#5}}% + \XINT_flpower_loopI #5.#3.#2.#4.{#1\xintiiOdd{#5}\fi}% }% -\def\XINT_flpower_loopI #1% +\def\XINT_flpower_loopI #1.% {% - \if1\XINT_isOne {#1}\XINT_flpower_ItoIII\fi - \if1\xintiiOdd{#1}% - \expandafter\expandafter\expandafter\XINT_flpower_loopI_odd - \else - \expandafter\expandafter\expandafter\XINT_flpower_loopI_even - \fi - \expandafter {\romannumeral0\xinthalf{#1}}% + \if1\XINT_isOne {#1}\xint_dothis\XINT_flpower_ItoIII\fi + \if1\xintiiOdd {#1}\xint_dothis{\expandafter\XINT_flpower_loopI_odd}\fi + \xint_orthat{\expandafter\XINT_flpower_loopI_even}% + \romannumeral0\xinthalf{#1}.% }% -\def\XINT_flpower_ItoIII\fi #1\fi\expandafter #2#3#4#5% +\def\XINT_flpower_ItoIII #1.#2.#3.#4.#5% {% - \fi\expandafter\XINT_flpow_III \the\numexpr #5\relax #3% + \expandafter\XINT_flpow_III\the\numexpr #5+\xint_c_.#2.#3.#4.% }% -\def\XINT_flpower_loopI_even #1#2#3% +\def\XINT_flpower_loopI_even #1.#2.#3.#4.% {% - \expandafter\XINT_flpower_toI\expandafter {#3{#2}{#2}}{#1}{#3}% + \expandafter\XINT_flpower_toloopI + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.#4.#1.% }% -\def\XINT_flpower_loopI_odd #1#2#3% +\def\XINT_flpower_toloopI #1.#2.#3.#4.{\XINT_flpower_loopI #4.#1.#2.#3.}% +\def\XINT_flpower_loopI_odd #1.#2.#3.#4.% {% - \expandafter\XINT_flpower_toII\expandafter {#3{#2}{#2}}{#1}{#3}{#2}% + \expandafter\XINT_flpower_toloopII + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.#4.% + #1.#2.#3.% }% -\def\XINT_flpower_toI #1#2{\XINT_flpower_loopI {#2}{#1}}% -\def\XINT_flpower_toII #1#2{\XINT_flpower_loopII {#2}{#1}}% -\def\XINT_flpower_loopII #1% +\def\XINT_flpower_toloopII #1.#2.#3.#4.{\XINT_flpower_loopII #4.#1.#2.#3.}% +\def\XINT_flpower_loopII #1.% {% - \if1\XINT_isOne {#1}\XINT_flpower_IItoIII\fi - \if1\xintiiOdd{#1}% - \expandafter\expandafter\expandafter\XINT_flpower_loopII_odd - \else - \expandafter\expandafter\expandafter\XINT_flpower_loopII_even - \fi - \expandafter {\romannumeral0\xinthalf{#1}}% + \if1\XINT_isOne{#1}\xint_dothis\XINT_flpower_IItoIII\fi + \if1\xintiiOdd{#1}\xint_dothis{\expandafter\XINT_flpower_loopII_odd}\fi + \xint_orthat{\expandafter\XINT_flpower_loopII_even}% + \romannumeral0\xinthalf{#1}.% }% -\def\XINT_flpower_loopII_even #1#2#3% +\def\XINT_flpower_loopII_even #1.#2.#3.#4.% {% - \expandafter\XINT_flpower_toII\expandafter - {#3{#2}{#2}}{#1}{#3}% + \expandafter\XINT_flpower_toloopII + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#2\expandafter.\romannumeral0\xintiisqr{#3}.#4.#1.% }% -\def\XINT_flpower_loopII_odd #1#2#3#4% +\def\XINT_flpower_loopII_odd #1.#2.#3.#4.#5.#6.% {% - \expandafter\XINT_flpower_loopII_odda\expandafter - {#3{#2}{#4}}{#2}{#3}{#1}% + \expandafter\XINT_flpower_loopII_odda + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr#2+#5\expandafter.\romannumeral0\xintiimul{#3}{#6}.#4.% + #1.#2.#3.% }% -\def\XINT_flpower_loopII_odda #1#2#3#4% +\def\XINT_flpower_loopII_odda #1.#2.#3.#4.#5.#6.% {% - \expandafter\XINT_flpower_toII\expandafter - {#3{#2}{#2}}{#4}{#3}{#1}% + \expandafter\XINT_flpower_toloopII + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr\xint_c_ii*#5\expandafter.\romannumeral0\xintiisqr{#6}.#3.% + #4.#1.#2.% }% -\def\XINT_flpower_IItoIII\fi #1\fi\expandafter #2#3#4#5#6% +\def\XINT_flpower_IItoIII #1.#2.#3.#4.#5.#6.#7% {% - \fi\expandafter\XINT_flpow_III\the\numexpr #6\expandafter\relax - #4{#3}{#5}% + \expandafter\XINT_flpow_III\the\numexpr #7+\xint_c_\expandafter.% + \the\numexpr\expandafter\XINT_flpow_truncate + \the\numexpr#2+#5\expandafter.\romannumeral0\xintiimul{#3}{#6}.#4.% }% \def\xintFloatFac {\romannumeral0\xintfloatfac}% \def\xintfloatfac #1{\XINT_flfac_chkopt \xintfloat #1\xint_relax }% @@ -2501,53 +2615,63 @@ }% \def\XINT_flfac_noopt #1#2\xint_relax {% - \expandafter\XINT_FL_fac_start\expandafter - {\the\numexpr \xintNum{#2}}{\XINTdigits}{#1[\XINTdigits]}% + \expandafter\XINT_FL_fac_fork_a + \the\numexpr \xintNum{#2}.\xint_c_i \XINTdigits\XINT_FL_fac_out{#1[\XINTdigits]}% }% -\def\XINT_flfac_opt #1[\xint_relax #2]#3% +\def\XINT_flfac_opt #1[\xint_relax #2]% {% - \expandafter\XINT_FL_fac_start\expandafter - {\the\numexpr \xintNum{#3}\expandafter}\expandafter{\the\numexpr#2}{#1[#2]}% + \expandafter\XINT_flfac_opt_a\the\numexpr #2.#1% }% -\def\XINT_FL_fac_start #1% +\def\XINT_flfac_opt_a #1.#2#3% {% - \ifcase\XINT_cntSgn #1\Z - \expandafter\XINT_FL_fac_iszero - \or - \expandafter\XINT_FL_fac_increaseP - \else - \expandafter\XINT_FL_fac_isneg - \fi {#1}% + \expandafter\XINT_FL_fac_fork_a\the\numexpr \xintNum{#3}.\xint_c_i {#1}\XINT_FL_fac_out{#2[#1]}% }% -\def\XINT_FL_fac_iszero #1#2#3{#3{1/1[0]}}% -\def\XINT_FL_fac_isneg #1#2#3% - {\expandafter\xintError:FactorialOfNegativeNumber #3{1/1[0]}}% -\def\XINT_FL_fac_increaseP #1#2% +\def\XINT_FL_fac_fork_a #1% {% - \expandafter\XINT_FL_fac_fork - \the\numexpr \xint_c_viii*% - ((\xint_c_v+#2+\XINT_FL_fac_extradigits #187654321\Z)/\xint_c_viii).% - #1.% + \xint_UDzerominusfork + #1-\XINT_FL_fac_iszero + 0#1\XINT_FL_fac_isneg + 0-{\XINT_FL_fac_fork_b #1}% + \krof }% -\def\XINT_FL_fac_extradigits #1#2#3#4#5#6#7#8{\XINT_FL_fac_extra_a }% -\def\XINT_FL_fac_extra_a #1#2\Z {#1}% -\def\XINT_FL_fac_fork #1.#2.#3% +\def\XINT_FL_fac_iszero #1.#2#3#4#5{#5{1/1[0]}}% +\def\XINT_FL_fac_isneg #1.#2#3#4#5{\expandafter\xintError:FactorialOfNegative #5{0/1[0]}}% +\def\XINT_FL_fac_fork_b #1.% {% - \ifnum #2>99999999 \xint_dothis{\XINT_FL_fac_toobig }\fi - \ifnum #2>9999 \xint_dothis{\XINT_FL_fac_vbigloop_a }\fi - \ifnum #2>465 \xint_dothis{\XINT_FL_fac_bigloop_a }\fi - \ifnum #2>101 \xint_dothis{\XINT_FL_fac_medloop_a }\fi - \xint_orthat{\XINT_FL_fac_smallloop_a }% - #2.#1.{\XINT_FL_fac_out}{#3}% + \ifnum #1>\xint_c_x^viii_mone\xint_dothis\XINT_FL_fac_toobig\fi + \ifnum #1>\xint_c_x^iv\xint_dothis\XINT_FL_fac_vbig \fi + \ifnum #1>465 \xint_dothis\XINT_FL_fac_big\fi + \ifnum #1>101 \xint_dothis\XINT_FL_fac_med\fi + \xint_orthat\XINT_FL_fac_small + #1.% }% -\def\XINT_FL_fac_toobig #1.#2.#3#4% - {\expandafter\xintError:FactorialOfTooBigNumber #4{1/1[0]}}% +\def\XINT_FL_fac_toobig #1.#2#3#4#5{\expandafter\xintError:TooBigFactorial #5{1/1[0]}}% +\def\XINT_FL_fac_vbig + {\expandafter\XINT_FL_fac_vbigloop_a + \the\numexpr \XINT_FL_fac_increaseP \xint_c_i }% +\def\XINT_FL_fac_big + {\expandafter\XINT_FL_fac_bigloop_a + \the\numexpr \XINT_FL_fac_increaseP \xint_c_ii }% +\def\XINT_FL_fac_med + {\expandafter\XINT_FL_fac_medloop_a + \the\numexpr \XINT_FL_fac_increaseP \xint_c_iii }% +\def\XINT_FL_fac_small + {\expandafter\XINT_FL_fac_smallloop_a + \the\numexpr \XINT_FL_fac_increaseP \xint_c_iv }% +\def\XINT_FL_fac_increaseP #1#2.#3#4% +{% + #2\expandafter.\the\numexpr\xint_c_viii*% + ((\xint_c_iv+#4+\expandafter\XINT_FL_fac_countdigits + \the\numexpr #2/(#1*#3)\relax 87654321\Z)/\xint_c_viii).% +}% +\def\XINT_FL_fac_countdigits #1#2#3#4#5#6#7#8{\XINT_FL_fac_countdone }% +\def\XINT_FL_fac_countdone #1#2\Z {#1}% \def\XINT_FL_fac_out #1\Z![#2]#3{#3{\romannumeral0\XINT_mul_out #1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W [#2]}}% \def\XINT_FL_fac_vbigloop_a #1.#2.% {% - \XINT_FL_fac_bigloop_a 9999.#2.% - {\expandafter\XINT_FL_fac_vbigloop_loop\the\numexpr 100010000\expandafter.% + \XINT_FL_fac_bigloop_a \xint_c_x^iv.#2.% + {\expandafter\XINT_FL_fac_vbigloop_loop\the\numexpr 100010001\expandafter.% \the\numexpr \xint_c_x^viii+#1.}% }% \def\XINT_FL_fac_vbigloop_loop #1.#2.% @@ -2629,8 +2753,7 @@ \ifnum #1=\xint_c_viii \expandafter\XINT_FL_fac_addzeros_exit\fi \expandafter\XINT_FL_fac_addzeros\the\numexpr #1-\xint_c_viii.100000000!% }% -\def\XINT_FL_fac_addzeros_exit #1.#2.#3#4% - {\XINT_FL_fac_smallloop_loop #3#21\Z![-#4]}% +\def\XINT_FL_fac_addzeros_exit #1.#2.#3#4{\XINT_FL_fac_smallloop_loop #3#21\Z![-#4]}% \def\XINT_FL_fac_smallloop_loop #1.#2.% {% \ifnum #1>#2 \expandafter\XINT_FL_fac_loop_exit\fi @@ -2691,183 +2814,346 @@ {1#2\expandafter!\expandafter-\expandafter1\expandafter [\the\numexpr #4+\xint_c_viii]}% }% -\def\xintFloatSqrt {\romannumeral0\xintfloatsqrt }% -\def\xintfloatsqrt #1{\XINT_flsqrt_chkopt \xintfloat #1\xint_relax }% -\def\XINTinFloatSqrt {\romannumeral0\XINTinfloatsqrt }% -\def\XINTinfloatsqrt #1{\XINT_flsqrt_chkopt \XINTinfloat #1\xint_relax }% -\def\XINT_flsqrt_chkopt #1#2% +\def\xintFloatPFactorial {\romannumeral0\xintfloatpfactorial}% +\def\xintfloatpfactorial #1{\XINT_flpfac_chkopt \xintfloat #1\xint_relax }% +\def\XINTinFloatPFactorial {\romannumeral0\XINTinfloatpfactorial }% +\def\XINTinfloatpfactorial #1{\XINT_flpfac_chkopt \XINTinfloat #1\xint_relax }% +\def\XINT_flpfac_chkopt #1#2% {% - \ifx [#2\expandafter\XINT_flsqrt_opt - \else\expandafter\XINT_flsqrt_noopt - \fi #1#2% + \ifx [#2\expandafter\XINT_flpfac_opt + \else\expandafter\XINT_flpfac_noopt + \fi + #1#2% }% -\def\XINT_flsqrt_noopt #1#2\xint_relax +\def\XINT_flpfac_noopt #1#2\xint_relax #3% {% - #1[\XINTdigits]{\XINT_FL_sqrt \XINTdigits {#2}}% + \expandafter\XINT_FL_pfac_fork + \the\numexpr \xintNum{#2}\expandafter.% + \the\numexpr \xintNum{#3}.\xint_c_i{\XINTdigits}{#1[\XINTdigits]}% }% -\def\XINT_flsqrt_opt #1[\xint_relax #2]#3% +\def\XINT_flpfac_opt #1[\xint_relax #2]% {% - #1[#2]{\XINT_FL_sqrt {#2}{#3}}% + \expandafter\XINT_flpfac_opt_b\the\numexpr #2.#1% }% -\def\XINT_FL_sqrt #1% +\def\XINT_flpfac_opt_b #1.#2#3#4% {% - \ifnum\numexpr #1<\xint_c_xviii - \xint_afterfi {\XINT_FL_sqrt_a\xint_c_xviii}% - \else - \xint_afterfi {\XINT_FL_sqrt_a {#1+\xint_c_i}}% - \fi + \expandafter\XINT_FL_pfac_fork + \the\numexpr \xintNum{#3}\expandafter.% + \the\numexpr \xintNum{#4}.\xint_c_i{#1}{#2[#1]}% }% -\def\XINT_FL_sqrt_a #1#2% +\def\XINT_FL_pfac_fork #1#2.#3.% {% - \expandafter\XINT_FL_sqrt_checkifzeroorneg - \romannumeral0\XINTinfloat [#1]{#2}% + \if-#1\xint_dothis\XINT_FL_pfac_outofrange\fi + \ifnum #1#2=#3 \xint_dothis\XINT_FL_pfac_one\fi + \ifnum #1#2>#3 \xint_dothis\XINT_FL_pfac_outofrange\fi + \ifnum #3>\xint_c_x^viii_mone + \xint_dothis\XINT_FL_pfac_outofrange\fi + \xint_orthat \XINT_FL_pfac_increaseP #1#2.#3.% }% -\def\XINT_FL_sqrt_checkifzeroorneg #1% +\def\XINT_FL_pfac_outofrange #1.#2.#3#4#5{\xintError:OutOfRangePFac #5{0/1[0]}}% +\def\XINT_FL_pfac_one #1.#2.#3#4#5{#5{1/1[0]}}% +\def\XINT_FL_pfac_increaseP #1.#2.#3#4% {% - \xint_UDzerominusfork - #1-\XINT_FL_sqrt_iszero - 0#1\XINT_FL_sqrt_isneg - 0-{\XINT_FL_sqrt_b #1}% - \krof + \expandafter\XINT_FL_pfac_a + \the\numexpr \xint_c_viii*((\xint_c_iv+#4+\expandafter + \XINT_FL_fac_countdigits\the\numexpr (#2-#1-\xint_c_i)% + /\ifnum #2>\xint_c_x^iv #3\else(#3*\xint_c_ii)\fi\relax + 87654321\Z)/\xint_c_viii).#1.#2.% }% -\def\XINT_FL_sqrt_iszero #1[#2]{0[0]}% -\def\XINT_FL_sqrt_isneg #1[#2]{\xintError:RootOfNegative 0[0]}% -\def\XINT_FL_sqrt_b #1[#2]% +\def\XINT_FL_pfac_a #1.#2.#3.% {% - \ifodd #2 - \xint_afterfi{\XINT_FL_sqrt_c 01}% - \else - \xint_afterfi{\XINT_FL_sqrt_c {}0}% - \fi - {#1}{#2}% + \expandafter\XINT_FL_pfac_b\the\numexpr \xint_c_i+#2\expandafter.% + \the\numexpr#3\expandafter.% + \romannumeral0\XINT_FL_pfac_addzeroes #1.100000001!1\Z![-#1]% }% -\def\XINT_FL_sqrt_c #1#2#3#4% +\def\XINT_FL_pfac_addzeroes #1.% {% - \expandafter\XINT_flsqrt\expandafter {\the\numexpr #4-#2}{#3#1}% + \ifnum #1=\xint_c_viii \expandafter\XINT_FL_pfac_addzeroes_exit\fi + \expandafter\XINT_FL_pfac_addzeroes\the\numexpr #1-\xint_c_viii.100000000!% }% -\def\XINT_flsqrt #1#2% +\def\XINT_FL_pfac_addzeroes_exit #1.{ }% +\def\XINT_FL_pfac_b #1.% {% - \expandafter\XINT_sqrt_a - \expandafter{\romannumeral0\xintlength {#2}}\XINT_flsqrt_big_d {#2}{#1}% + \ifnum #1>9999 \xint_dothis\XINT_FL_pfac_vbigloop \fi + \ifnum #1>463 \xint_dothis\XINT_FL_pfac_bigloop \fi + \ifnum #1>98 \xint_dothis\XINT_FL_pfac_medloop \fi + \xint_orthat\XINT_FL_pfac_smallloop #1.% }% -\def\XINT_flsqrt_big_d #1#2% +\def\XINT_FL_pfac_smallloop #1.#2.% {% - \ifodd #2 - \expandafter\expandafter\expandafter\XINT_flsqrt_big_eB - \else - \expandafter\expandafter\expandafter\XINT_flsqrt_big_eA - \fi - \expandafter {\the\numexpr (#2-\xint_c_i)/\xint_c_ii }{#1}% + \ifcase\numexpr #2-#1\relax + \expandafter\XINT_FL_pfac_end_ + \or \expandafter\XINT_FL_pfac_end_i + \or \expandafter\XINT_FL_pfac_end_ii + \or \expandafter\XINT_FL_pfac_end_iii + \else\expandafter\XINT_FL_pfac_smallloop_a + \fi #1.#2.% }% -\def\XINT_flsqrt_big_eA #1#2#3% +\def\XINT_FL_pfac_smallloop_a #1.#2.% {% - \XINT_flsqrt_big_eA_a #3\Z {#2}{#1}{#3}% + \expandafter\XINT_FL_pfac_smallloop_b + \the\numexpr #1+\xint_c_iv\expandafter.% + \the\numexpr #2\expandafter.% + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% }% -\def\XINT_flsqrt_big_eA_a #1#2#3#4#5#6#7#8#9\Z +\def\XINT_FL_pfac_smallloop_b #1.% {% - \XINT_flsqrt_big_eA_b {#1#2#3#4#5#6#7#8}% + \ifnum #1>98 \expandafter\XINT_FL_pfac_medloop \else + \expandafter\XINT_FL_pfac_smallloop \fi #1.% }% -\def\XINT_flsqrt_big_eA_b #1#2% +\def\XINT_FL_pfac_medloop #1.#2.% {% - \expandafter\XINT_flsqrt_big_f - \romannumeral0\XINT_flsqrt_small_e {#2001}{#1}% + \ifcase\numexpr #2-#1\relax + \expandafter\XINT_FL_pfac_end_ + \or \expandafter\XINT_FL_pfac_end_i + \or \expandafter\XINT_FL_pfac_end_ii + \else\expandafter\XINT_FL_pfac_medloop_a + \fi #1.#2.% }% -\def\XINT_flsqrt_big_eB #1#2#3% +\def\XINT_FL_pfac_medloop_a #1.#2.% {% - \XINT_flsqrt_big_eB_a #3\Z {#2}{#1}{#3}% + \expandafter\XINT_FL_pfac_medloop_b + \the\numexpr #1+\xint_c_iii\expandafter.% + \the\numexpr #2\expandafter.% + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% }% -\def\XINT_flsqrt_big_eB_a #1#2#3#4#5#6#7#8#9% +\def\XINT_FL_pfac_medloop_b #1.% {% - \XINT_flsqrt_big_eB_b {#1#2#3#4#5#6#7#8#9}% + \ifnum #1>463 \expandafter\XINT_FL_pfac_bigloop \else + \expandafter\XINT_FL_pfac_medloop \fi #1.% }% -\def\XINT_flsqrt_big_eB_b #1#2\Z #3% +\def\XINT_FL_pfac_bigloop #1.#2.% {% - \expandafter\XINT_flsqrt_big_f - \romannumeral0\XINT_flsqrt_small_e {#30001}{#1}% + \ifcase\numexpr #2-#1\relax + \expandafter\XINT_FL_pfac_end_ + \or \expandafter\XINT_FL_pfac_end_i + \else\expandafter\XINT_FL_pfac_bigloop_a + \fi #1.#2.% }% -\def\XINT_flsqrt_small_e #1#2% +\def\XINT_FL_pfac_bigloop_a #1.#2.% {% - \expandafter\XINT_flsqrt_small_f\expandafter - {\the\numexpr #1*#1-#2-\xint_c_i}{#1}% + \expandafter\XINT_FL_pfac_bigloop_b + \the\numexpr #1+\xint_c_ii\expandafter.% + \the\numexpr #2\expandafter.% + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!% }% -\def\XINT_flsqrt_small_f #1#2% +\def\XINT_FL_pfac_bigloop_b #1.% {% - \expandafter\XINT_flsqrt_small_g\expandafter - {\the\numexpr (#1+#2)/(2*#2)-\xint_c_i }{#1}{#2}% + \ifnum #1>9999 \expandafter\XINT_FL_pfac_vbigloop \else + \expandafter\XINT_FL_pfac_bigloop \fi #1.% }% -\def\XINT_flsqrt_small_g #1% +\def\XINT_FL_pfac_vbigloop #1.#2.% {% - \ifnum #1>\xint_c_ - \expandafter\XINT_flsqrt_small_h - \else - \expandafter\XINT_flsqrt_small_end - \fi - {#1}% + \ifnum #2=#1 + \expandafter\XINT_FL_pfac_end_ + \else\expandafter\XINT_FL_pfac_vbigloop_a + \fi #1.#2.% +}% +\def\XINT_FL_pfac_vbigloop_a #1.#2.% +{% + \expandafter\XINT_FL_pfac_vbigloop + \the\numexpr #1+\xint_c_i\expandafter.% + \the\numexpr #2\expandafter.% + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr\xint_c_x^viii+#1!% }% -\def\XINT_flsqrt_small_h #1#2#3% +\def\XINT_FL_pfac_end_iii #1.#2.% {% - \expandafter\XINT_flsqrt_small_f\expandafter - {\the\numexpr #2-\xint_c_ii*#1*#3+#1*#1\expandafter}\expandafter - {\the\numexpr #3-#1}% + \expandafter\XINT_FL_fac_out + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% }% -\def\XINT_flsqrt_small_end #1#2#3% +\def\XINT_FL_pfac_end_ii #1.#2.% {% - \expandafter\space\expandafter - {\the\numexpr \xint_c_i+#3*\xint_c_x^iv- - (#2*\xint_c_x^iv+#3)/(\xint_c_ii*#3)}% + \expandafter\XINT_FL_fac_out + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% }% -\def\XINT_flsqrt_big_f #1% +\def\XINT_FL_pfac_end_i #1.#2.% {% - \expandafter\XINT_flsqrt_big_fa\expandafter - {\romannumeral0\xintiisqr {#1}}{#1}% + \expandafter\XINT_FL_fac_out + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!% }% -\def\XINT_flsqrt_big_fa #1#2#3#4% +\def\XINT_FL_pfac_end_ #1.#2.% {% - \expandafter\XINT_flsqrt_big_fb\expandafter - {\romannumeral0\XINT_dsx_addzerosnofuss - {\numexpr #3-\xint_c_viii\relax}{#2}}% - {\romannumeral0\xintiisub - {\XINT_dsx_addzerosnofuss - {\numexpr \xint_c_ii*(#3-\xint_c_viii)\relax}{#1}}{#4}}% - {#3}% + \expandafter\XINT_FL_fac_out + \romannumeral0\expandafter\XINT_FL_fac_mul + \the\numexpr \xint_c_x^viii+#1!% }% -\def\XINT_flsqrt_big_fb #1#2% +\def\xintFloatBinomial {\romannumeral0\xintfloatbinomial}% +\def\xintfloatbinomial #1{\XINT_flbinom_chkopt \xintfloat #1\xint_relax }% +\def\XINTinFloatBinomial {\romannumeral0\XINTinfloatbinomial }% +\def\XINTinfloatbinomial #1{\XINT_flbinom_chkopt \XINTinfloat #1\xint_relax }% +\def\XINT_flbinom_chkopt #1#2% {% - \expandafter\XINT_flsqrt_big_g\expandafter {#2}{#1}% + \ifx [#2\expandafter\XINT_flbinom_opt + \else\expandafter\XINT_flbinom_noopt + \fi #1#2% }% -\def\XINT_flsqrt_big_g #1#2% +\def\XINT_flbinom_noopt #1#2\xint_relax #3% {% - \expandafter\XINT_flsqrt_big_j - \romannumeral0\xintiidivision - {#1}{\romannumeral0\XINT_dbl_pos #2\Z}{#2}% + \expandafter\XINT_FL_binom_a + \the\numexpr\xintNum{#2}\expandafter.\the\numexpr\xintNum{#3}.\XINTdigits.#1% }% -\def\XINT_flsqrt_big_j #1% +\def\XINT_flbinom_opt #1[\xint_relax #2]#3#4% {% - \if0\XINT_Sgn #1\Z - \expandafter \XINT_flsqrt_big_end_a - \else \expandafter \XINT_flsqrt_big_k - \fi {#1}% + \expandafter\XINT_FL_binom_a + \the\numexpr\xintNum{#3}\expandafter.\the\numexpr\xintNum{#4}\expandafter.% + \the\numexpr #2.#1% +}% +\def\XINT_FL_binom_a #1.#2.% +{% + \expandafter\XINT_FL_binom_fork \the\numexpr #1-#2.#2.#1.% +}% +\def\XINT_FL_binom_fork #1#2.#3#4.#5.% +{% + \if-#1\xint_dothis \XINT_FL_binom_outofrange\fi + \if-#3\xint_dothis \XINT_FL_binom_outofrange\fi + \if0#1\xint_dothis \XINT_FL_binom_one\fi + \if0#3\xint_dothis \XINT_FL_binom_one\fi + \ifnum #5>\xint_c_x^viii_mone \xint_dothis\XINT_FL_binom_outofrange\fi + \ifnum #1#2>#3#4 \xint_dothis\XINT_FL_binom_ab \fi + \xint_orthat\XINT_FL_binom_aa + #1#2.#3#4.#5.% +}% +\def\XINT_FL_binom_outofrange #1.#2.#3.#4.#5% + {\xintError:OutOfRangeBinomial #5[#4]{0/1[0]}}% +\def\XINT_FL_binom_one #1.#2.#3.#4.#5{#5[#4]{1/1[0]}}% +\def\XINT_FL_binom_aa #1.#2.#3.#4.#5% +{% + #5[#4]{\xintDiv{\XINT_FL_pfac_increaseP + #2.#3.\xint_c_iv{#4+\xint_c_i}{\XINTinfloat[#4+\xint_c_iii]}}% + {\XINT_FL_fac_fork_b + #1.\xint_c_iv{#4+\xint_c_i}\XINT_FL_fac_out{\XINTinfloat[#4+\xint_c_iii]}}}% +}% +\def\XINT_FL_binom_ab #1.#2.#3.#4.#5% +{% + #5[#4]{\xintDiv{\XINT_FL_pfac_increaseP + #1.#3.\xint_c_iv{#4+\xint_c_i}{\XINTinfloat[#4+\xint_c_iii]}}% + {\XINT_FL_fac_fork_b + #2.\xint_c_iv{#4+\xint_c_i}\XINT_FL_fac_out{\XINTinfloat[#4+\xint_c_iii]}}}% +}% +\def\xintFloatSqrt {\romannumeral0\xintfloatsqrt }% +\def\xintfloatsqrt #1{\XINT_flsqrt_chkopt \xintfloat #1\xint_relax }% +\def\XINTinFloatSqrt {\romannumeral0\XINTinfloatsqrt }% +\def\XINTinfloatsqrt #1{\XINT_flsqrt_chkopt \XINTinfloat #1\xint_relax }% +\def\XINT_flsqrt_chkopt #1#2% +{% + \ifx [#2\expandafter\XINT_flsqrt_opt + \else\expandafter\XINT_flsqrt_noopt + \fi #1#2% +}% +\def\XINT_flsqrt_noopt #1#2\xint_relax +{% + \expandafter\XINT_FL_sqrt_a + \romannumeral0\XINTinfloat[\XINTdigits]{#2}\XINTdigits.#1% +}% +\def\XINT_flsqrt_opt #1[\xint_relax #2]%#3% +{% + \expandafter\XINT_flsqrt_opt_a\the\numexpr #2.#1% +}% +\def\XINT_flsqrt_opt_a #1.#2#3% +{% + \expandafter\XINT_FL_sqrt_a\romannumeral0\XINTinfloat[#1]{#3}#1.#2% +}% +\def\XINT_FL_sqrt_a #1% +{% + \xint_UDzerominusfork + #1-\XINT_FL_sqrt_iszero + 0#1\XINT_FL_sqrt_isneg + 0-{\XINT_FL_sqrt_pos #1}% + \krof +}%[ +\def\XINT_FL_sqrt_iszero #1]#2.#3{#3[#2]{0[0]}}% +\def\XINT_FL_sqrt_isneg #1]#2.#3{\xintError:RootOfNegative #3[#2]{0[0]}}% +\def\XINT_FL_sqrt_pos #1[#2]#3.% +{% + \expandafter\XINT_flsqrt + \the\numexpr #3\ifodd #2 \xint_dothis {+\xint_c_iii.(#2+\xint_c_i).0}\fi + \xint_orthat {+\xint_c_ii.#2.{}}#100.#3.% }% -\def\XINT_flsqrt_big_k #1#2#3% +\def\XINT_flsqrt #1.#2.% {% - \expandafter\XINT_flsqrt_big_l\expandafter - {\romannumeral0\xintiisub {#3}{#1}}% - {\romannumeral0\xintiiadd {#2}{\romannumeral0\XINT_sqr #1\Z}}% + \expandafter\XINT_flsqrt_a + \the\numexpr #2/\xint_c_ii-(#1-\xint_c_i)/\xint_c_ii.#1.% }% -\def\XINT_flsqrt_big_l #1#2% +\def\XINT_flsqrt_a #1.#2.#3#4.#5.% {% - \expandafter\XINT_flsqrt_big_g\expandafter - {#2}{#1}% + \expandafter\XINT_flsqrt_b + \the\numexpr (#2-\xint_c_i)/\xint_c_ii\expandafter.% + \romannumeral0\XINT_sqrt_start #2.#4#3.#5.#2.#4#3.#5.#1.% }% -\def\XINT_flsqrt_big_end_a #1#2#3#4#5% +\def\XINT_flsqrt_b #1.#2#3% {% - \expandafter\XINT_flsqrt_big_end_b\expandafter - {\the\numexpr -#4+#5/\xint_c_ii\expandafter}\expandafter - {\romannumeral0\xintiisub - {\XINT_dsx_addzerosnofuss {#4}{#3}}% - {\xintHalf{\xintiiQuo{\XINT_dsx_addzerosnofuss {#4}{#2}}{#3}}}}% + \expandafter\XINT_flsqrt_c + \romannumeral0\xintiisub + {\XINT_dsx_addzerosnofuss {#1}{#2}}% + {\xintiiDivRound{\XINT_dsx_addzerosnofuss {#1}{#3}}{\XINT_dbl_pos#2\Z}}.% }% -\def\XINT_flsqrt_big_end_b #1#2{#2[#1]}% +\def\XINT_flsqrt_c #1.#2.% +{% + \expandafter\XINT_flsqrt_d + \romannumeral0\XINT_split_fromleft_loop #2.{}#1\W\W\W\W\W\W\W\W\Z +}% +\def\XINT_flsqrt_d #1.#2#3.% +{% + \ifnum #2=\xint_c_v + \expandafter\XINT_flsqrt_f\else\expandafter\XINT_flsqrt_finish\fi + #2#3.#1.% +}% +\def\XINT_flsqrt_finish #1#2.#3.#4.#5.#6.#7.#8{#8[#6]{#3#1[#7]}}% +\def\XINT_flsqrt_f 5#1.% + {\xintiiifGt{\xintiNum{#1}}{2}{\XINT_flsqrt_finish 5.}{\XINT_flsqrt_again}}% +\def\XINT_flsqrt_again #1.#2.% +{% + \expandafter\XINT_flsqrt_again_a\the\numexpr #2+\xint_c_viii.% +}% +\def\XINT_flsqrt_again_a #1.#2.#3.% +{% + \expandafter\XINT_flsqrt_b + \the\numexpr (#1-\xint_c_i)/\xint_c_ii\expandafter.% + \romannumeral0\XINT_sqrt_start #1.#200000000.#3.% + #1.#200000000.#3.% +}% +\def\xintFloatE {\romannumeral0\xintfloate }% +\def\xintfloate #1{\XINT_floate_chkopt #1\xint_relax }% +\def\XINT_floate_chkopt #1% +{% + \ifx [#1\expandafter\XINT_floate_opt + \else\expandafter\XINT_floate_noopt + \fi #1% +}% +\def\XINT_floate_noopt #1\xint_relax +{% + \expandafter\XINT_floate_a\expandafter\XINTdigits + \romannumeral0\XINT_infrac {#1}% +}% +\def\XINT_floate_opt [\xint_relax #1]#2% +{% + \expandafter\XINT_floate_a\expandafter + {\the\numexpr #1\expandafter}\romannumeral0\XINT_infrac {#2}% +}% +\def\XINT_floate_a #1#2#3#4#5% +{% + \expandafter\XINT_float_a\the\numexpr#1\expandafter.% + \expandafter{\the\numexpr #2+#5}{#3}{#4}\XINT_float_Q +}% +\def\XINTinFloatE {\romannumeral0\XINTinfloate }% +\def\XINTinfloate + {\expandafter\XINT_infloate\romannumeral0\XINTinfloat [\XINTdigits]}% +\def\XINT_infloate #1[#2]#3% + {\expandafter\XINT_infloate_end\the\numexpr #3+#2.{#1}}% +\def\XINT_infloate_end #1.#2{ #2[#1]}% +\def\XINTinFloatMod {\romannumeral0\XINTinfloatmod [\XINTdigits]}% +\def\XINTinfloatmod [#1]#2#3{\expandafter\XINT_infloatmod\expandafter + {\romannumeral0\XINTinfloat[#1]{#2}}% + {\romannumeral0\XINTinfloat[#1]{#3}}{#1}}% +\def\XINT_infloatmod #1#2{\expandafter\XINT_infloatmod_a\expandafter {#2}{#1}}% +\def\XINT_infloatmod_a #1#2#3{\XINTinfloat [#3]{\xintMod {#2}{#1}}}% \XINT_restorecatcodes_endinput% \endinput %% diff --git a/Master/texmf-dist/tex/generic/xint/xintgcd.sty b/Master/texmf-dist/tex/generic/xint/xintgcd.sty index 874385ef298..78537efcf48 100644 --- a/Master/texmf-dist/tex/generic/xint/xintgcd.sty +++ b/Master/texmf-dist/tex/generic/xint/xintgcd.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle v1.2e 2015/11/22 -%% Copyright (C) 2013-2015 by Jean-Francois Burnol +%% The xint bundle 1.2f 2016/03/12 +%% Copyright (C) 2013-2016 by Jean-Francois Burnol %% xintgcd: Euclidean algorithm with xint package %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintgcd}% - [2015/11/22 v1.2e Euclide algorithm with xint package (jfB)]% + [2016/03/12 1.2f Euclide algorithm with xint package (JFB)]% \def\xintGCD {\romannumeral0\xintgcd }% \def\xintgcd #1% {% diff --git a/Master/texmf-dist/tex/generic/xint/xintkernel.sty b/Master/texmf-dist/tex/generic/xint/xintkernel.sty index 79a9bebef7d..9a001625dae 100644 --- a/Master/texmf-dist/tex/generic/xint/xintkernel.sty +++ b/Master/texmf-dist/tex/generic/xint/xintkernel.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle v1.2e 2015/11/22 -%% Copyright (C) 2013-2015 by Jean-Francois Burnol +%% The xint bundle 1.2f 2016/03/12 +%% Copyright (C) 2013-2016 by Jean-Francois Burnol %% xintkernel: Paraphernalia for the xint packages %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -156,7 +156,7 @@ \fi \XINT_providespackage \ProvidesPackage {xintkernel}% - [2015/11/22 v1.2e Paraphernalia for the xint packages (jfB)]% + [2016/03/12 1.2f Paraphernalia for the xint packages (JFB)]% \chardef\xint_c_ 0 \chardef\xint_c_i 1 \chardef\xint_c_ii 2 @@ -240,11 +240,11 @@ \long\def\xint_gob_til_xint_relax #1\xint_relax {}% \long\def\xint_afterfi #1#2\fi {\fi #1}% \long\def\xint_bye #1\xint_bye {}% -\long\def\xint_dothis #1#2\xint_orthat #3{\fi #1}% v1.1 +\long\def\xint_dothis #1#2\xint_orthat #3{\fi #1}% 1.1 \let\xint_orthat \xint_firstofone \long\def\xintdothis #1#2\xintorthat #3{\fi #1}% \let\xintorthat \xint_firstofone -\def\xint_zapspaces #1 #2{#1#2\xint_zapspaces }% v1.1 +\def\xint_zapspaces #1 #2{#1#2\xint_zapspaces }% 1.1 \def\xint_zapspaces_o #1{\expandafter\xint_zapspaces#1 \xint_gobble_i}% \def\xintodef #1{\expandafter\def\expandafter#1\expandafter }% \def\xintoodef #1{\expandafter\expandafter\expandafter\def diff --git a/Master/texmf-dist/tex/generic/xint/xintseries.sty b/Master/texmf-dist/tex/generic/xint/xintseries.sty index cdaf499c432..b9523bf4231 100644 --- a/Master/texmf-dist/tex/generic/xint/xintseries.sty +++ b/Master/texmf-dist/tex/generic/xint/xintseries.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle v1.2e 2015/11/22 -%% Copyright (C) 2013-2015 by Jean-Francois Burnol +%% The xint bundle 1.2f 2016/03/12 +%% Copyright (C) 2013-2016 by Jean-Francois Burnol %% xintseries: Expandable partial sums with xint package %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintseries}% - [2015/11/22 v1.2e Expandable partial sums with xint package (jfB)]% + [2016/03/12 1.2f 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 80e85234943..8fb291a28cd 100644 --- a/Master/texmf-dist/tex/generic/xint/xinttools.sty +++ b/Master/texmf-dist/tex/generic/xint/xinttools.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle v1.2e 2015/11/22 -%% Copyright (C) 2013-2015 by Jean-Francois Burnol +%% The xint bundle 1.2f 2016/03/12 +%% Copyright (C) 2013-2016 by Jean-Francois Burnol %% xinttools: Expandable and non-expandable utilities %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xinttools}% - [2015/11/22 v1.2e Expandable and non-expandable utilities (jfB)]% + [2016/03/12 1.2f Expandable and non-expandable utilities (JFB)]% \newtoks\XINT_toks \xint_firstofone{\let\XINT_sptoken= } %<- space here! \def\xintgodef {\global\xintodef }% |